/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.sync.engine.document.library.handler; import com.liferay.sync.engine.document.library.event.Event; import com.liferay.sync.engine.document.library.event.GetSyncContextEvent; import com.liferay.sync.engine.document.library.model.SyncDLObjectUpdate; import com.liferay.sync.engine.document.library.util.BatchEventManager; import com.liferay.sync.engine.document.library.util.FileEventUtil; import com.liferay.sync.engine.document.library.util.comparator.SyncFileSizeComparator; import com.liferay.sync.engine.file.system.Watcher; import com.liferay.sync.engine.file.system.util.WatcherManager; import com.liferay.sync.engine.model.SyncAccount; import com.liferay.sync.engine.model.SyncFile; import com.liferay.sync.engine.model.SyncSite; import com.liferay.sync.engine.service.SyncAccountService; import com.liferay.sync.engine.service.SyncFileService; import com.liferay.sync.engine.service.SyncSiteService; import com.liferay.sync.engine.session.Session; import com.liferay.sync.engine.session.SessionManager; import com.liferay.sync.engine.util.FileKeyUtil; import com.liferay.sync.engine.util.FileUtil; import com.liferay.sync.engine.util.GetterUtil; import com.liferay.sync.engine.util.IODeltaUtil; import com.liferay.sync.engine.util.JSONUtil; import com.liferay.sync.engine.util.SyncEngineUtil; import com.liferay.sync.engine.util.Validator; import java.io.IOException; import java.nio.file.AccessDeniedException; import java.nio.file.FileSystemException; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringEscapeUtils; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.StatusLine; import org.apache.http.client.methods.HttpPost; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Shinn Lok */ public class GetSyncDLObjectUpdateHandler extends BaseJSONHandler { public GetSyncDLObjectUpdateHandler(final Event event) { super(event); GetSyncContextEvent getSyncContextEvent = new GetSyncContextEvent( getSyncAccountId(), Collections.<String, Object>emptyMap()) { @Override public void executePost( String urlPath, Map<String, Object> parameters) throws Exception { SyncAccount syncAccount = SyncAccountService.fetchSyncAccount( getSyncAccountId()); Session session = SessionManager.getSession( getSyncAccountId(), true); HttpResponse httpResponse = session.execute( new HttpPost( syncAccount.getUrl() + "/api/jsonws" + urlPath)); StatusLine statusLine = httpResponse.getStatusLine(); if (statusLine.getStatusCode() != HttpStatus.SC_OK) { doCancel(); return; } Handler<Void> handler = event.getHandler(); String response = getResponseString(httpResponse); if (handler.handlePortalException(getException(response))) { doCancel(); return; } if (!_firedProcessingState) { SyncEngineUtil.fireSyncEngineStateChanged( getSyncAccountId(), SyncEngineUtil.SYNC_ENGINE_STATE_PROCESSING); _firedProcessingState = true; } } protected void doCancel() { if (_firedProcessingState) { SyncEngineUtil.fireSyncEngineStateChanged( getSyncAccountId(), SyncEngineUtil.SYNC_ENGINE_STATE_PROCESSED); _firedProcessingState = false; } event.cancel(); _scheduledFuture.cancel(true); } @Override protected void doRun() { SyncAccount syncAccount = SyncAccountService.fetchSyncAccount( getSyncAccountId()); SyncSite syncSite = SyncSiteService.fetchSyncSite( (Long)event.getParameterValue("repositoryId"), getSyncAccountId()); if ((syncAccount == null) || (syncAccount.getState() != SyncAccount.STATE_CONNECTED) || (syncSite == null) || !syncSite.isActive()) { doCancel(); return; } super.doRun(); } private boolean _firedProcessingState; }; _scheduledFuture = _scheduledExecutorService.scheduleWithFixedDelay( getSyncContextEvent, 10, 5, TimeUnit.SECONDS); } @Override public void processFinally() { _scheduledFuture.cancel(false); SyncEngineUtil.fireSyncEngineStateChanged( getSyncAccountId(), SyncEngineUtil.SYNC_ENGINE_STATE_PROCESSED); SyncSite syncSite = (SyncSite)getParameterValue("syncSite"); if (syncSite != null) { syncSite = SyncSiteService.fetchSyncSite( syncSite.getGroupId(), syncSite.getSyncAccountId()); syncSite.setState(SyncSite.STATE_SYNCED); SyncSiteService.update(syncSite); } else { SyncFile syncFile = SyncFileService.fetchSyncFile( (Long)getParameterValue("repositoryId"), getSyncAccountId(), (Long)getParameterValue("parentFolderId")); if (syncFile != null) { syncFile.setState(SyncFile.STATE_SYNCED); syncFile.setUiEvent(SyncFile.UI_EVENT_NONE); SyncFileService.update(syncFile); } } } @Override public void processResponse(String response) throws Exception { if (_syncDLObjectUpdate == null) { if (response.startsWith("\"")) { response = StringEscapeUtils.unescapeJava(response); response = response.replaceAll("\n", "\\n"); response = response.substring(1, response.length() - 1); } _syncDLObjectUpdate = JSONUtil.readValue( response, SyncDLObjectUpdate.class); } updateSettings(_syncDLObjectUpdate.getSettingsModifiedTimes()); List<SyncFile> syncFiles = _syncDLObjectUpdate.getSyncFiles(); if (!syncFiles.isEmpty()) { Collections.sort(syncFiles, _syncFileComparator); for (SyncFile syncFile : syncFiles) { processSyncFile(syncFile); } } if (getParameterValue("parentFolderId") == null) { SyncSite syncSite = SyncSiteService.fetchSyncSite( (Long)getParameterValue("repositoryId"), getSyncAccountId()); if ((syncSite == null) || ((Long)getParameterValue("lastAccessTime") != syncSite.getRemoteSyncTime())) { return; } long lastAccessTime = _syncDLObjectUpdate.getLastAccessTime(); if (lastAccessTime == -1) { lastAccessTime = 0; } syncSite.setRemoteSyncTime(lastAccessTime); if (_syncDLObjectUpdate.getResultsTotal() <= syncFiles.size()) { syncSite.setState(SyncSite.STATE_SYNCED); } SyncSiteService.update(syncSite); if (_syncDLObjectUpdate.getResultsTotal() > syncFiles.size()) { FileEventUtil.getUpdates( syncSite.getGroupId(), getSyncAccountId(), syncSite, GetterUtil.getBoolean( getParameterValue("retrieveFromCache"))); } } BatchEventManager.fireBatchDownloadEvents(); } protected void addFile(SyncFile syncFile, String filePathName) throws Exception { Path filePath = Paths.get(filePathName); if (isParentUnsynced(syncFile)) { if (syncFile.isFolder()) { syncFile.setFilePathName(filePath.toString()); syncFile.setModifiedTime(0); syncFile.setState(SyncFile.STATE_UNSYNCED); syncFile.setSyncAccountId(getSyncAccountId()); syncFile.setUiEvent(SyncFile.UI_EVENT_NONE); SyncFileService.update(syncFile); } return; } if (FileUtil.exists(filePath) && (syncFile.isFolder() || !FileUtil.isModified(syncFile, filePath))) { return; } syncFile.setFilePathName(filePathName); syncFile.setSyncAccountId(getSyncAccountId()); if (syncFile.isFolder()) { Files.createDirectories(filePath); syncFile.setState(SyncFile.STATE_SYNCED); syncFile.setUiEvent(SyncFile.UI_EVENT_ADDED_REMOTE); SyncFileService.update(syncFile); FileKeyUtil.writeFileKey( filePath, String.valueOf(syncFile.getSyncFileId()), false); } else { syncFile.setUiEvent(SyncFile.UI_EVENT_DOWNLOADING); SyncFileService.update(syncFile); downloadFile(syncFile, null, 0, false); } } protected boolean checkUnsynced( SyncFile sourceSyncFile, SyncFile targetSyncFile, String targetFilePathName) throws Exception { Path targetFilePath = Paths.get(targetFilePathName); if (isParentUnsynced(targetSyncFile)) { if (sourceSyncFile.isFolder()) { List<SyncFile> syncFiles = new ArrayList<>(); syncFiles.add(sourceSyncFile); List<SyncFile> childSyncFiles = SyncFileService.findSyncFiles( sourceSyncFile.getFilePathName()); syncFiles.addAll(childSyncFiles); SyncFileService.unsyncFolders(getSyncAccountId(), syncFiles); sourceSyncFile = SyncFileService.fetchSyncFile( sourceSyncFile.getSyncFileId()); SyncFileService.updateSyncFile( targetFilePath, targetSyncFile.getParentFolderId(), sourceSyncFile); } else { deleteFile(sourceSyncFile, targetSyncFile); } return true; } if (sourceSyncFile.isUnsynced()) { if (!isParentUnsynced(sourceSyncFile)) { return true; } List<SyncFile> syncFiles = new ArrayList<>(); syncFiles.add(sourceSyncFile); List<SyncFile> childSyncFiles = SyncFileService.findSyncFiles( sourceSyncFile.getFilePathName()); syncFiles.addAll(childSyncFiles); SyncFileService.resyncFolders(getSyncAccountId(), syncFiles); return true; } return false; } protected void copyFile(SyncFile sourceSyncFile, SyncFile targetSyncFile) throws Exception { if (_logger.isDebugEnabled()) { _logger.debug( "Copying file {} to {}", sourceSyncFile.getFilePathName(), targetSyncFile.getFilePathName()); } Path tempFilePath = FileUtil.getTempFilePath(targetSyncFile); Files.copy( Paths.get(sourceSyncFile.getFilePathName()), tempFilePath, StandardCopyOption.REPLACE_EXISTING); FileKeyUtil.writeFileKey( tempFilePath, String.valueOf(targetSyncFile.getSyncFileId()), false); FileUtil.setModifiedTime( tempFilePath, targetSyncFile.getModifiedTime()); Watcher watcher = WatcherManager.getWatcher(getSyncAccountId()); watcher.addDownloadedFilePathName(targetSyncFile.getFilePathName()); boolean exists = FileUtil.exists( Paths.get(targetSyncFile.getFilePathName())); try { Files.move( tempFilePath, Paths.get(targetSyncFile.getFilePathName()), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING); } catch (AccessDeniedException ade) { _logger.error(ade.getMessage(), ade); targetSyncFile.setState(SyncFile.STATE_ERROR); targetSyncFile.setUiEvent(SyncFile.UI_EVENT_ACCESS_DENIED_LOCAL); SyncFileService.update(targetSyncFile); return; } targetSyncFile.setState(SyncFile.STATE_SYNCED); if (GetterUtil.getBoolean( targetSyncFile.getLocalExtraSettingValue("restoreEvent"))) { targetSyncFile.unsetLocalExtraSetting("restoreEvent"); targetSyncFile.setUiEvent(SyncFile.UI_EVENT_RESTORED_REMOTE); } else if (exists) { targetSyncFile.setUiEvent(SyncFile.UI_EVENT_DOWNLOADED_UPDATE); } else { targetSyncFile.setUiEvent(SyncFile.UI_EVENT_DOWNLOADED_NEW); } SyncFileService.update(targetSyncFile); IODeltaUtil.copyChecksums(sourceSyncFile, targetSyncFile); } protected void deleteFile(SyncFile sourceSyncFile, SyncFile targetSyncFile) throws Exception { if (sourceSyncFile.getUiEvent() == SyncFile.UI_EVENT_DELETED_LOCAL) { return; } sourceSyncFile.setModifiedTime(targetSyncFile.getModifiedTime()); String event = targetSyncFile.getEvent(); if (event.equals(SyncFile.EVENT_TRASH)) { sourceSyncFile.setUiEvent(SyncFile.UI_EVENT_TRASHED_REMOTE); } else { sourceSyncFile.setUiEvent(SyncFile.UI_EVENT_DELETED_REMOTE); } sourceSyncFile.setUserId(targetSyncFile.getUserId()); sourceSyncFile.setUserName(targetSyncFile.getUserName()); if (!sourceSyncFile.isUnsynced()) { SyncFileService.deleteSyncFile(sourceSyncFile); } Path sourceFilePath = Paths.get(sourceSyncFile.getFilePathName()); if (FileUtil.notExists(sourceFilePath)) { return; } final Watcher watcher = WatcherManager.getWatcher(getSyncAccountId()); if (sourceSyncFile.isFile()) { watcher.addDeletedFilePathName(sourceSyncFile.getFilePathName()); FileUtil.deleteFile(sourceFilePath); return; } Files.walkFileTree( sourceFilePath, new SimpleFileVisitor<Path>() { @Override public FileVisitResult postVisitDirectory( Path filePath, IOException ioe) throws IOException { if (ioe != null) { return super.postVisitDirectory(filePath, ioe); } watcher.addDeletedFilePathName(filePath.toString()); FileUtil.deleteFile(filePath); return FileVisitResult.CONTINUE; } @Override public FileVisitResult preVisitDirectory( Path filePath, BasicFileAttributes basicFileAttributes) throws IOException { watcher.unregisterFilePath(filePath); return super.preVisitDirectory( filePath, basicFileAttributes); } @Override public FileVisitResult visitFile( Path filePath, BasicFileAttributes basicFileAttributes) throws IOException { watcher.addDeletedFilePathName(filePath.toString()); FileUtil.deleteFile(filePath); return FileVisitResult.CONTINUE; } }); } protected void downloadFile( SyncFile syncFile, String sourceVersion, long sourceVersionId, boolean patch) throws Exception { String checksum = syncFile.getChecksum(); if (!checksum.isEmpty() && (syncFile.getSize() > 0)) { SyncFile sourceSyncFile = SyncFileService.fetchSyncFile( checksum, SyncFile.STATE_SYNCED); if ((sourceSyncFile != null) && FileUtil.exists(Paths.get(sourceSyncFile.getFilePathName()))) { copyFile(sourceSyncFile, syncFile); return; } } String targetVersion = syncFile.getVersion(); if (patch && !sourceVersion.equals("PWC") && !targetVersion.equals("PWC") && (Double.valueOf(sourceVersion) < Double.valueOf(targetVersion))) { FileEventUtil.downloadPatch( sourceVersionId, getSyncAccountId(), syncFile, syncFile.getVersionId()); } else { FileEventUtil.downloadFile(getSyncAccountId(), syncFile); } } protected boolean isIgnoredFilePath( SyncFile syncFile, String filePathName) { if (syncFile != null) { filePathName = syncFile.getFilePathName(); } return FileUtil.isIgnoredFilePath(FileUtil.getFilePath(filePathName)); } protected boolean isParentUnsynced(SyncFile syncFile) { Path filePath = Paths.get(syncFile.getFilePathName()); if (FileUtil.isUnsynced(filePath.getParent())) { return true; } return false; } @Override protected void logResponse(String response) { try { if (response.startsWith("\"")) { response = StringEscapeUtils.unescapeJava(response); response = response.replaceAll("\n", "\\n"); response = response.substring(1, response.length() - 1); } _syncDLObjectUpdate = JSONUtil.readValue( response, SyncDLObjectUpdate.class); List<SyncFile> syncFiles = _syncDLObjectUpdate.getSyncFiles(); if (!syncFiles.isEmpty()) { super.logResponse(response); } else { super.logResponse(""); } } catch (Exception e) { _logger.error(e.getMessage(), e); } } protected void processDependentSyncFiles(SyncFile syncFile) { List<SyncFile> dependentSyncFiles = _dependentSyncFilesMap.remove( getSyncAccountId() + "#" + syncFile.getTypePK()); if (syncFile.isUnsynced() || (dependentSyncFiles == null)) { return; } for (SyncFile dependentSyncFile : dependentSyncFiles) { processSyncFile(dependentSyncFile); } } protected boolean processFilePathChange( SyncFile sourceSyncFile, SyncFile targetSyncFile) throws Exception { String sourceSyncFileName = FileUtil.getSanitizedFileName( sourceSyncFile.getName(), sourceSyncFile.getExtension()); String targetSyncFileName = FileUtil.getSanitizedFileName( targetSyncFile.getName(), targetSyncFile.getExtension()); if ((sourceSyncFile.getParentFolderId() != targetSyncFile.getParentFolderId()) || !sourceSyncFileName.equals(targetSyncFileName)) { SyncFile targetParentSyncFile = SyncFileService.fetchSyncFile( targetSyncFile.getRepositoryId(), getSyncAccountId(), targetSyncFile.getParentFolderId()); Path targetParentFilePath = Paths.get( targetParentSyncFile.getFilePathName()); Path targetFilePath = targetParentFilePath.resolve( targetSyncFileName); Path sourceFilePath = Paths.get(sourceSyncFile.getFilePathName()); sourceSyncFile.setUiEvent(SyncFile.UI_EVENT_NONE); SyncFileService.updateSyncFile( targetFilePath, targetSyncFile.getParentFolderId(), sourceSyncFile); if (FileUtil.exists(sourceFilePath)) { Watcher watcher = WatcherManager.getWatcher(getSyncAccountId()); watcher.addMovedFilePathName(targetSyncFile.getFilePathName()); FileUtil.moveFile(sourceFilePath, targetFilePath); } return true; } return false; } protected void processSyncFile(SyncFile targetSyncFile) { SyncFile sourceSyncFile = SyncFileService.fetchSyncFile( targetSyncFile.getRepositoryId(), getSyncAccountId(), targetSyncFile.getTypePK()); if ((sourceSyncFile != null) && (sourceSyncFile.getState() == SyncFile.STATE_ERROR)) { if (_logger.isDebugEnabled()) { _logger.debug( "Skipping file {}. File is in an error state.", sourceSyncFile.getFilePathName()); } return; } String event = targetSyncFile.getEvent(); if (event.equals(SyncFile.EVENT_DELETE) || event.equals(SyncFile.EVENT_TRASH)) { if (sourceSyncFile != null) { try { deleteFile(sourceSyncFile, targetSyncFile); } catch (Exception e) { _logger.error(e.getMessage(), e); } } return; } SyncFile parentSyncFile = SyncFileService.fetchSyncFile( targetSyncFile.getRepositoryId(), getSyncAccountId(), targetSyncFile.getParentFolderId()); if (parentSyncFile == null) { queueSyncFile(targetSyncFile.getParentFolderId(), targetSyncFile); return; } try { String filePathName = FileUtil.getFilePathName( parentSyncFile.getFilePathName(), FileUtil.getSanitizedFileName( targetSyncFile.getName(), targetSyncFile.getExtension())); if (sourceSyncFile == null) { sourceSyncFile = SyncFileService.fetchSyncFile(filePathName); } if (isIgnoredFilePath(sourceSyncFile, filePathName)) { return; } if ((sourceSyncFile != null) && (sourceSyncFile.getModifiedTime() == targetSyncFile.getModifiedTime())) { if (!Validator.isBlank(targetSyncFile.getChecksum())) { sourceSyncFile.setChecksum(targetSyncFile.getChecksum()); SyncFileService.update(sourceSyncFile); } return; } if ((sourceSyncFile != null) && !sourceSyncFile.isUnsynced()) { sourceSyncFile.setState(SyncFile.STATE_IN_PROGRESS); } targetSyncFile.setFilePathName(filePathName); targetSyncFile.setState(SyncFile.STATE_IN_PROGRESS); if (event.equals(SyncFile.EVENT_ADD) || event.equals(SyncFile.EVENT_GET) || event.equals(SyncFile.EVENT_MOVE) || event.equals(SyncFile.EVENT_UPDATE)) { if (sourceSyncFile == null) { addFile(targetSyncFile, filePathName); } else { updateFile(sourceSyncFile, targetSyncFile, filePathName); } } else if (event.equals(SyncFile.EVENT_RESTORE)) { if (Validator.isBlank(targetSyncFile.getName())) { // Workaround for SYNC-1690 return; } else if (sourceSyncFile != null) { updateFile(sourceSyncFile, targetSyncFile, filePathName); } else if (isParentUnsynced(targetSyncFile)) { if (targetSyncFile.isFolder()) { targetSyncFile.setModifiedTime(0); targetSyncFile.setState(SyncFile.STATE_UNSYNCED); targetSyncFile.setSyncAccountId(getSyncAccountId()); targetSyncFile.setUiEvent(SyncFile.UI_EVENT_NONE); SyncFileService.update(targetSyncFile); } return; } else { targetSyncFile.setLocalExtraSetting("restoreEvent", true); SyncFileService.update(targetSyncFile); addFile(targetSyncFile, filePathName); } } processDependentSyncFiles(targetSyncFile); if (getParameterValue("parentFolderId") != null) { SyncFile syncFile = SyncFileService.fetchSyncFile( (Long)getParameterValue("repositoryId"), getSyncAccountId(), (Long)getParameterValue("parentFolderId")); if (syncFile != null) { syncFile.setState(SyncFile.STATE_IN_PROGRESS); syncFile.setUiEvent(SyncFile.UI_EVENT_RESYNCING); SyncFileService.update(syncFile); } } } catch (FileSystemException fse) { String message = fse.getMessage(); if (message.contains("File name too long")) { targetSyncFile.setState(SyncFile.STATE_ERROR); targetSyncFile.setUiEvent(SyncFile.UI_EVENT_FILE_NAME_TOO_LONG); SyncFileService.update(targetSyncFile); } } catch (Exception e) { _logger.error(e.getMessage(), e); } } protected void queueSyncFile(long parentFolderId, SyncFile syncFile) { List<SyncFile> syncFiles = _dependentSyncFilesMap.get( getSyncAccountId() + "#" + parentFolderId); if (syncFiles == null) { syncFiles = new ArrayList<>(); _dependentSyncFilesMap.put( getSyncAccountId() + "#" + parentFolderId, syncFiles); } syncFiles.add(syncFile); } protected void updateFile( SyncFile sourceSyncFile, SyncFile targetSyncFile, String filePathName) throws Exception { if (checkUnsynced(sourceSyncFile, targetSyncFile, filePathName)) { return; } if (sourceSyncFile.getTypePK() != targetSyncFile.getTypePK()) { _logger.error( "Source type pk {} does not match target {} for {}", sourceSyncFile.getTypePK(), targetSyncFile.getTypePK(), sourceSyncFile.getFilePathName()); } String previousChecksum = sourceSyncFile.getChecksum(); String previousFilePathName = sourceSyncFile.getFilePathName(); long previousParentFolderId = sourceSyncFile.getParentFolderId(); String previousType = sourceSyncFile.getType(); String previousVersion = sourceSyncFile.getVersion(); long previousVersionId = sourceSyncFile.getVersionId(); boolean filePathChanged = processFilePathChange( sourceSyncFile, targetSyncFile); sourceSyncFile.setChangeLog(targetSyncFile.getChangeLog()); sourceSyncFile.setChecksum(targetSyncFile.getChecksum()); sourceSyncFile.setDescription(targetSyncFile.getDescription()); sourceSyncFile.setExtension(targetSyncFile.getExtension()); sourceSyncFile.setExtraSettings(targetSyncFile.getExtraSettings()); sourceSyncFile.setLanTokenKey(targetSyncFile.getLanTokenKey()); sourceSyncFile.setLockExpirationDate( targetSyncFile.getLockExpirationDate()); sourceSyncFile.setLockUserId(targetSyncFile.getLockUserId()); sourceSyncFile.setLockUserName(targetSyncFile.getLockUserName()); sourceSyncFile.setModifiedTime(targetSyncFile.getModifiedTime()); sourceSyncFile.setSize(targetSyncFile.getSize()); sourceSyncFile.setType(targetSyncFile.getType()); sourceSyncFile.setTypePK(targetSyncFile.getTypePK()); sourceSyncFile.setUserId(targetSyncFile.getUserId()); sourceSyncFile.setUserName(targetSyncFile.getUserName()); sourceSyncFile.setVersion(targetSyncFile.getVersion()); sourceSyncFile.setVersionId(targetSyncFile.getVersionId()); SyncFileService.update(sourceSyncFile); if (filePathChanged && !Validator.isBlank(previousChecksum) && previousChecksum.equals(targetSyncFile.getChecksum())) { sourceSyncFile.setState(SyncFile.STATE_SYNCED); if (previousParentFolderId == sourceSyncFile.getParentFolderId()) { sourceSyncFile.setUiEvent(SyncFile.UI_EVENT_RENAMED_REMOTE); } else { sourceSyncFile.setUiEvent(SyncFile.UI_EVENT_MOVED_REMOTE); } SyncFileService.update(sourceSyncFile); return; } Path filePath = Paths.get(targetSyncFile.getFilePathName()); if (!previousType.equals(sourceSyncFile.getType())) { if (previousType.equals(SyncFile.TYPE_FOLDER)) { FileUtils.deleteDirectory(filePath.toFile()); } else { Files.deleteIfExists(filePath); } } if (!FileUtil.exists(filePath)) { if (targetSyncFile.isFolder()) { Path targetFilePath = Paths.get(filePathName); Files.createDirectories(targetFilePath); sourceSyncFile.setState(SyncFile.STATE_SYNCED); sourceSyncFile.setUiEvent(SyncFile.UI_EVENT_UPDATED_REMOTE); SyncFileService.update(sourceSyncFile); FileKeyUtil.writeFileKey( targetFilePath, String.valueOf(sourceSyncFile.getSyncFileId()), false); } else { downloadFile(sourceSyncFile, null, 0, false); } } else if (targetSyncFile.isFile() && FileUtil.isModified(targetSyncFile, filePath)) { downloadFile( sourceSyncFile, previousVersion, previousVersionId, !IODeltaUtil.isIgnoredFilePatchingExtension(targetSyncFile)); } else { sourceSyncFile.setState(SyncFile.STATE_SYNCED); if (previousFilePathName.equals(sourceSyncFile.getFilePathName())) { sourceSyncFile.setUiEvent(SyncFile.UI_EVENT_NONE); } else { sourceSyncFile.setUiEvent(SyncFile.UI_EVENT_RENAMED_REMOTE); } SyncFileService.update(sourceSyncFile); } } protected void updateSettings(Map<String, Long> settingsModifiedTimes) { if (settingsModifiedTimes == null) { return; } for (Map.Entry<String, Long> entry : settingsModifiedTimes.entrySet()) { String setting = entry.getKey(); long modifiedTime = entry.getValue(); if (setting.equals( SyncDLObjectUpdate. PREFERENCE_KEY_SYNC_CONTEXT_MODIFIED_TIME)) { SyncAccount syncAccount = SyncAccountService.fetchSyncAccount( getSyncAccountId()); syncAccount.setSyncContextModifiedTime(modifiedTime); SyncAccountService.update(syncAccount); } } } private static final Logger _logger = LoggerFactory.getLogger( GetSyncDLObjectUpdateHandler.class); private static final Map<String, List<SyncFile>> _dependentSyncFilesMap = new HashMap<>(); private static final ScheduledExecutorService _scheduledExecutorService = Executors.newScheduledThreadPool(5); private static final Comparator<SyncFile> _syncFileComparator = new SyncFileSizeComparator(); private final ScheduledFuture<?> _scheduledFuture; private SyncDLObjectUpdate _syncDLObjectUpdate; }