SYNC: Asks user about synchronization include & debug files between 58/20358/1
authordonghyuk.yang <donghyuk.yang@samsung.com>
Mon, 5 May 2014 10:14:23 +0000 (19:14 +0900)
committerdonghyuk.yang <donghyuk.yang@samsung.com>
Mon, 5 May 2014 10:14:23 +0000 (19:14 +0900)
remote server and local.

- If include files are changed after building a project, IDE asks user
to synchronize include files. If debug files are changed before
debugging, IDE also asks user to synchronize debug files.
- Exclude "include/boost" directory when synchronizing include files
because the directory has so many files.

Change-Id: Ia515f7814fd8062c263a38029721cda760ce05bd
Signed-off-by: donghyuk.yang <donghyuk.yang@samsung.com>
org.tizen.nativeplatform/src/org/tizen/nativeplatform/build/PlatformBuildCommandLauncher.java
org.tizen.nativeplatform/src/org/tizen/nativeplatform/build/PlatformExternalBuildRunner.java
org.tizen.nativeplatform/src/org/tizen/nativeplatform/launch/PlatformLaunchDelegate.java
org.tizen.nativeplatform/src/org/tizen/nativeplatform/launch/wizard/pages/PlatformLaunchSettingPage.java
org.tizen.nativeplatform/src/org/tizen/nativeplatform/remote/connection/RootstrapSynchronizer.java [moved from org.tizen.nativeplatform/src/org/tizen/nativeplatform/remote/connection/RootstrapSyncronizer.java with 76% similarity]
org.tizen.nativeplatform/src/org/tizen/nativeplatform/remote/connection/RsyncProcessor.java
org.tizen.nativeplatform/src/org/tizen/nativeplatform/remote/connection/WorkspaceSynchronizer.java [moved from org.tizen.nativeplatform/src/org/tizen/nativeplatform/remote/connection/WorkspaceSyncronizer.java with 96% similarity]
org.tizen.nativeplatform/src/org/tizen/nativeplatform/views/ui/RootstrapUIMessages.properties
org.tizen.nativeplatform/src/org/tizen/nativeplatform/views/ui/RootstrapView.java

index 36fea9d..30b6394 100644 (file)
@@ -31,7 +31,6 @@ import org.eclipse.cdt.core.CommandLauncher;
 import org.eclipse.cdt.managedbuilder.core.IConfiguration;
 import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
 import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResourceDelta;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -45,9 +44,6 @@ import org.tizen.nativecommon.build.ProjectTypeManager;
 import org.tizen.nativecommon.build.SmartBuildInterface;
 import org.tizen.nativeplatform.Activator;
 import org.tizen.nativeplatform.remote.connection.RemoteConnectionManager;
-import org.tizen.nativeplatform.remote.connection.WorkspaceDeltaManager;
-import org.tizen.nativeplatform.remote.connection.WorkspaceResourceDelta;
-import org.tizen.nativeplatform.remote.connection.WorkspaceSyncronizer;
 import org.tizen.nativeplatform.rootstrap.RootstrapManager;
 import org.tizen.nativeplatform.util.RootstrapUtil;
 
index 0e2b67f..345b884 100644 (file)
@@ -40,7 +40,6 @@ import org.eclipse.cdt.core.CCorePlugin;
 import org.eclipse.cdt.core.ErrorParserManager;
 import org.eclipse.cdt.core.ICommandLauncher;
 import org.eclipse.cdt.core.IMarkerGenerator;
-import org.eclipse.cdt.core.index.IIndexManager;
 import org.eclipse.cdt.core.model.CoreModel;
 import org.eclipse.cdt.core.model.ICModelMarker;
 import org.eclipse.cdt.core.resources.IConsole;
@@ -92,7 +91,9 @@ import org.eclipse.ptp.remotetools.exception.CancelException;
 import org.eclipse.ptp.remotetools.exception.RemoteConnectionException;
 import org.eclipse.ptp.remotetools.exception.RemoteExecutionException;
 import org.eclipse.ptp.remotetools.exception.RemoteOperationException;
+import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Display;
+import org.tizen.common.util.DialogUtil;
 import org.tizen.common.util.OSChecker;
 import org.tizen.common.util.log.UserInteraction;
 import org.tizen.common.util.log.UserLogger;
@@ -100,10 +101,10 @@ import org.tizen.nativecommon.build.SmartBuildInterface;
 import org.tizen.nativeplatform.Activator;
 import org.tizen.nativeplatform.build.IBuildCommandProvider.BUILDTOOL;
 import org.tizen.nativeplatform.remote.connection.RemoteConnectionManager;
-import org.tizen.nativeplatform.remote.connection.RootstrapSyncronizer;
+import org.tizen.nativeplatform.remote.connection.RootstrapSynchronizer;
 import org.tizen.nativeplatform.remote.connection.WorkspaceDeltaManager;
 import org.tizen.nativeplatform.remote.connection.WorkspaceResourceDelta;
-import org.tizen.nativeplatform.remote.connection.WorkspaceSyncronizer;
+import org.tizen.nativeplatform.remote.connection.WorkspaceSynchronizer;
 import org.tizen.nativeplatform.rootstrap.RootstrapManager;
 import org.tizen.nativeplatform.util.IPackageUtil;
 import org.tizen.nativeplatform.util.PkgUtilFactory;
@@ -150,13 +151,9 @@ public class PlatformExternalBuildRunner extends ExternalBuildRunner {
         }
         
         if (needRemoteSync) {
-            /*
-            Display.getDefault().asyncExec(new Runnable() {
-                public void run() {
-                    syncRootstrap(rootstrap);
-                }
-            });
-            */
+            if (RootstrapSynchronizer.isChangedIncludes(rootstrap)) {
+                syncIncludes(rootstrap, new SubProgressMonitor(monitor, 1));
+            }
         } else {
             CCorePlugin.getIndexManager().reindex(CoreModel.getDefault().create(project));
         }
@@ -164,14 +161,23 @@ public class PlatformExternalBuildRunner extends ExternalBuildRunner {
         return isClean;
     }
     
-    private void readySyncRootstrap(PlatformRootstrap rootstrap) {
-        RootstrapSyncronizer.cacheModificationTime(rootstrap);
+    public void syncIncludes(final PlatformRootstrap rootstrap, IProgressMonitor monitor) {
+        if (!RemoteConnectionManager.connected()) {
+            return;
+        }
+        String msg = "There are changes for includes in remote rootstrap.\n" +
+                "Do you want to synchronize the changes?\n\n" +
+                "(Recommend \"YES\". This may take a few moments.)";
+        int result = DialogUtil.openQuestionDialog(msg);
+        if (result == SWT.YES) {
+            RootstrapSynchronizer.syncronize(rootstrap, true, false, monitor);            
+        }
     }
     
-    private void syncRootstrap(PlatformRootstrap rootstrap) {
-        RootstrapSyncronizer.syncronizeIfChanges(rootstrap, new NullProgressMonitor());
+    private void readySyncRootstrap(PlatformRootstrap rootstrap) {
+        RootstrapSynchronizer.cacheModificationTime(rootstrap);
     }
-    
+
     private void syncWorkspace(IProject project, IConfiguration config, IProgressMonitor monitor) 
             throws CoreException {
         WorkspaceResourceDelta resourceDelta = WorkspaceDeltaManager.getDelta(project);
@@ -207,7 +213,7 @@ public class PlatformExternalBuildRunner extends ExternalBuildRunner {
             }
         }
         if (needSync) {
-            if(!WorkspaceSyncronizer.syncronize(project, new SubProgressMonitor(monitor, 1))) {
+            if(!WorkspaceSynchronizer.syncronize(project, new SubProgressMonitor(monitor, 1))) {
                 Status status = new Status(Status.ERROR, Activator.PLUGIN_ID,
                         "Failed to syncronized workspace", null);
                 throw new CoreException(status);
index 656fbb7..2e2bcf8 100644 (file)
@@ -31,6 +31,7 @@ import static org.tizen.sdblib.util.DeviceUtil.isOnline;
 
 import java.io.File;
 import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.List;
@@ -70,10 +71,13 @@ import org.eclipse.debug.core.ILaunchConfiguration;
 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
 import org.eclipse.debug.core.ILaunchManager;
 import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.viewers.ILabelProvider;
 import org.eclipse.jface.viewers.LabelProvider;
 import org.eclipse.jface.window.Window;
 import org.eclipse.ptp.remotetools.core.IRemoteCopyTools;
+import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.PartInitException;
@@ -110,6 +114,7 @@ import org.tizen.nativeplatform.pkg.commander.factory.PkgFilterFactory;
 import org.tizen.nativeplatform.pkg.model.IPackage;
 import org.tizen.nativeplatform.pkg.model.PkgStatus;
 import org.tizen.nativeplatform.remote.connection.RemoteConnectionManager;
+import org.tizen.nativeplatform.remote.connection.RootstrapSynchronizer;
 import org.tizen.nativeplatform.rootstrap.RootstrapManager;
 import org.tizen.nativeplatform.types.CmdTargetTypes;
 import org.tizen.nativeplatform.util.IPackageUtil;
@@ -178,6 +183,9 @@ public class PlatformLaunchDelegate extends AbstractCLaunchDelegate {
             verifyBuildConfiguration(config, mode, new SubProgressMonitor(monitor, 1));
             setPkgCommandTarget();
             tizenCommand = new TizenLaunchCommand(currentDevice, null);
+            if (mode.equals(ILaunchManager.DEBUG_MODE) && OSChecker.isWindows()) {
+                checkDebugsourceSync();
+            }
 
             ILaunchConfigurationProcessor processor = getConfigurationProcessor(shell, config,
                     project, mode, target, new SubProgressMonitor(monitor, 1));
@@ -216,6 +224,53 @@ public class PlatformLaunchDelegate extends AbstractCLaunchDelegate {
             UserLogger.end(UserInteraction.CATE_PLATFORM_LAUNCH);
         }
     }
+    
+    protected void checkDebugsourceSync() {
+        if (!RemoteConnectionManager.connected()) {
+            return;
+        }
+        final PlatformRootstrap rootstrap = target.getRootstrap();
+        String rootstrapPath = RootstrapUtil.getUserSyncRootstrapPath(rootstrap.getId());
+        String defaultPath = new Path(rootstrapPath).append("usr").append("src").append("debug").toString();
+        File debugSrcPath = new File(defaultPath);
+        if (!debugSrcPath.exists()) {
+            return;
+        }
+        long dstTime = debugSrcPath.lastModified();
+        long srcTime = RootstrapSynchronizer.getDebugsrcPathLastmodifiedTime(rootstrap);
+        if (srcTime != dstTime) {
+            String msg = "There are changes for debug source in remote rootstrap.\n" +
+                    "Do you want to synchronize the changes?\n\n" +
+                    "(Click \"Yes\" if you want to debug other platform source together.)";
+            int result = DialogUtil.openQuestionDialog(shell, "Do you want to synchronize?", msg);
+            if (result == SWT.YES) {
+                SWTUtil.syncExec(new Runnable() {
+                    public void run() {
+                        ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell);
+                        try {
+                            dialog.run(true, true, new IRunnableWithProgress() {
+                                @Override
+                                public void run(IProgressMonitor monitor)
+                                        throws InvocationTargetException, InterruptedException {
+                                    monitor.beginTask("Synchronize debug sources...", -1);
+                                    try {
+                                        RootstrapSynchronizer.syncronize(rootstrap, false, true, monitor);
+                                    } finally {
+                                        monitor.done();
+                                    }
+                                }
+                            });
+                        } catch (Exception e) {
+                            logger.error("Failed to syncronize debug sources", e);
+                            DialogUtil.openErrorDialog(String.format("%s\n * %s",
+                                    "Failed to syncronize debug sources", e.toString()));
+                            return;
+                        }
+                    }
+                });
+            }
+        }
+    }
 
     protected ILaunchConfigurationProcessor getConfigurationProcessor(Shell shell,
             ILaunchConfiguration launchConfig, IProject project, String mode,
index a9ce339..45b8ea1 100644 (file)
@@ -337,7 +337,11 @@ public class PlatformLaunchSettingPage extends PlatformLaunchCommonPage {
     }
     
     public boolean loadSharedLibAutomatically() {
-       return autoLibButton.getSelection();
+        if (autoLibButton == null) {
+            return false;
+        } else {
+            return autoLibButton.getSelection();
+        }
     }
     
     public String getSelectedApp() {
@@ -29,56 +29,94 @@ import org.tizen.nativeplatform.util.PlatformUserInteraction;
 import org.tizen.nativeplatform.util.RootstrapUtil;\r
 import org.tizen.nativeplatform.views.model.PlatformRootstrap;\r
 \r
-public class RootstrapSyncronizer {\r
+public class RootstrapSynchronizer {\r
+    \r
+    public static String[] EXCLUDES = {"boost/"};\r
     \r
     private static long includeDirModificationTime = 0;\r
     private static long debugsrcDirModificationTime = 0;\r
     \r
     public static void cacheModificationTime(PlatformRootstrap rootstrap) {\r
+        long time = getIncludePathLastmodifiedTime(rootstrap);\r
+        if (time > 0) {\r
+            includeDirModificationTime = time;\r
+        }\r
+        time = getDebugsrcPathLastmodifiedTime(rootstrap);\r
+        if (time > 0) {\r
+            debugsrcDirModificationTime = time;\r
+        }\r
+    }\r
+    \r
+    public static long getIncludePathLastmodifiedTime(PlatformRootstrap rootstrap) {\r
         String remoteIncludePath = getRemoteIncludePath(rootstrap);\r
-        String remoteDebugsrcPath = getRemoteDebugsrcPath(rootstrap);\r
         IRemoteFileTools filetool = RemoteConnectionManager.getRemoteTools().getFileTool();\r
         try {\r
             boolean exists = filetool.hasDirectory(remoteIncludePath, new NullProgressMonitor());\r
             if (exists) {\r
                 IRemoteItem item = filetool.getDirectory(remoteIncludePath, new NullProgressMonitor());\r
-                includeDirModificationTime = item.getModificationTime();\r
+                return item.getModificationTime();\r
             }\r
-            exists = filetool.hasDirectory(remoteDebugsrcPath, new NullProgressMonitor());\r
+        }  catch (RemoteOperationException e) {\r
+            e.printStackTrace();\r
+        } catch (RemoteConnectionException e) {\r
+            e.printStackTrace();\r
+        } catch (CancelException e) {\r
+            e.printStackTrace();\r
+        }\r
+        return -1;\r
+    }\r
+    \r
+    public static long getDebugsrcPathLastmodifiedTime(PlatformRootstrap rootstrap) {\r
+        String remoteDebugsrcPath = getRemoteDebugsrcPath(rootstrap);\r
+        IRemoteFileTools filetool = RemoteConnectionManager.getRemoteTools().getFileTool();\r
+        try {\r
+            boolean exists = filetool.hasDirectory(remoteDebugsrcPath, new NullProgressMonitor());\r
             if (exists) {\r
                 IRemoteItem item = filetool.getDirectory(remoteDebugsrcPath, new NullProgressMonitor());\r
-                debugsrcDirModificationTime = item.getModificationTime();\r
+                return item.getModificationTime();\r
             }\r
-        } catch (RemoteOperationException e) {\r
+        }  catch (RemoteOperationException e) {\r
             e.printStackTrace();\r
         } catch (RemoteConnectionException e) {\r
             e.printStackTrace();\r
         } catch (CancelException e) {\r
             e.printStackTrace();\r
         }\r
+        return -1;\r
     }\r
     \r
-    public static void syncronizeIfChanges(PlatformRootstrap rootstrap, IProgressMonitor monitor) {\r
+    public static boolean isChangedIncludes(PlatformRootstrap rootstrap) {\r
         String remoteIncludePath = getRemoteIncludePath(rootstrap);\r
-        String remoteDebugsrcPath = getRemoteDebugsrcPath(rootstrap);\r
         IRemoteFileTools filetool = RemoteConnectionManager.getRemoteTools().getFileTool();\r
-        boolean syncInclude = false;\r
-        boolean syncDebugsrc = false;\r
         try {\r
             boolean exists = filetool.hasDirectory(remoteIncludePath, new NullProgressMonitor());\r
             if (exists) {\r
                 IRemoteItem item = filetool.getDirectory(remoteIncludePath, new NullProgressMonitor());\r
                 long currentModificationTime = item.getModificationTime();\r
                 if (includeDirModificationTime != currentModificationTime) {\r
-                    syncInclude = true;\r
+                    return true;\r
                 }\r
             }\r
-            exists = filetool.hasDirectory(remoteDebugsrcPath, new NullProgressMonitor());\r
+        } catch (RemoteOperationException e) {\r
+            e.printStackTrace();\r
+        } catch (RemoteConnectionException e) {\r
+            e.printStackTrace();\r
+        } catch (CancelException e) {\r
+            e.printStackTrace();\r
+        } \r
+        return false;\r
+    }\r
+    \r
+    public static boolean isChangedDebugsrc(PlatformRootstrap rootstrap) {\r
+        String remoteDebugsrcPath = getRemoteDebugsrcPath(rootstrap);\r
+        IRemoteFileTools filetool = RemoteConnectionManager.getRemoteTools().getFileTool();\r
+        try {\r
+            boolean exists = filetool.hasDirectory(remoteDebugsrcPath, new NullProgressMonitor());\r
             if (exists) {\r
                 IRemoteItem item = filetool.getDirectory(remoteDebugsrcPath, new NullProgressMonitor());\r
                 long currentModificationTime = item.getModificationTime();\r
                 if (debugsrcDirModificationTime != currentModificationTime) {\r
-                    syncDebugsrc = true;\r
+                    return true;\r
                 }\r
             }\r
         } catch (RemoteOperationException e) {\r
@@ -87,7 +125,13 @@ public class RootstrapSyncronizer {
             e.printStackTrace();\r
         } catch (CancelException e) {\r
             e.printStackTrace();\r
-        }\r
+        } \r
+        return false;\r
+    }\r
+    \r
+    public static void syncronizeIfChanges(PlatformRootstrap rootstrap, IProgressMonitor monitor) {\r
+        boolean syncInclude = isChangedIncludes(rootstrap);\r
+        boolean syncDebugsrc = isChangedDebugsrc(rootstrap);\r
         syncronize(rootstrap, syncInclude, syncDebugsrc, monitor);\r
     }\r
     \r
@@ -121,7 +165,7 @@ public class RootstrapSyncronizer {
         final String host = RemoteConnectionManager.getRemoteTools().getHost();\r
         final String user = RemoteConnectionManager.getRemoteTools().getUser();\r
         final String sshKeyPath = RemoteConnectionManager.getRemoteTools().getPrivateKey();\r
-        monitor.beginTask("Syncronize includes...", list.size() * 2);\r
+        monitor.beginTask("Synchronize includes... (This may take a few moments)", list.size() * 2);\r
         for (PlatformRootstrap rootstrap : list) {\r
             final String remoteIncludePath = getRemoteIncludePath(rootstrap);\r
             final String remoteDebugsrcPath = getRemoteDebugsrcPath(rootstrap);            \r
@@ -135,17 +179,16 @@ public class RootstrapSyncronizer {
             try {\r
                 UserLogger.start(PlatformUserInteraction.CATE_SYNCRONIZE, PlatformUserInteraction.SYNC_INCLUDES);\r
                 if (syncIncludes) {\r
-                    monitor.subTask(String.format("Syncronize includes... [%s]", rootstrap.getId()));\r
-                    processor.downloadSync(remoteIncludePath, usrDir.toString(), monitor);\r
+                    monitor.subTask(String.format("Synchronize includes... [%s]", rootstrap.getId()));\r
+                    processor.downloadSync(remoteIncludePath, usrDir.toString(), EXCLUDES, monitor);\r
                 }\r
                 monitor.worked(1);\r
                 if (syncDebugsrc) {\r
                        if (!debugDir.exists()) {\r
                         FileUtil.createDirectory(debugDir);\r
                     }\r
-                    monitor.subTask(String.format("Syncronize debug source... [%s]", rootstrap.getId()));\r
-                    \r
-                    processor.downloadSync(remoteDebugsrcPath, debugDir.toString(), monitor);\r
+                    monitor.subTask(String.format("Synchronize debug source... [%s]", rootstrap.getId()));\r
+                    processor.downloadSync(remoteDebugsrcPath, debugDir.toString(), null, monitor);\r
                 }\r
                 monitor.worked(1);\r
                 UserLogger.end(PlatformUserInteraction.CATE_SYNCRONIZE, PlatformUserInteraction.SYNC_INCLUDES);\r
index 1f7c58a..e69c3f7 100644 (file)
@@ -22,7 +22,7 @@ public class RsyncProcessor {
         this.sshPrivateKey = sshPrivateKey;\r
     }\r
     \r
-    public boolean downloadSync(String remotePath, String localPath, IProgressMonitor monitor) throws InterruptedException {\r
+    public boolean downloadSync(String remotePath, String localPath, String[] excludes, IProgressMonitor monitor) throws InterruptedException {\r
         SmartBuildInterface sbi = SmartBuildInterface.getInstance();\r
         String[] envs = sbi.getEnvironmentVariables();\r
         Map<String, String> envMap = new HashMap<String, String>();\r
@@ -34,6 +34,13 @@ public class RsyncProcessor {
                 envMap.put(key, value);\r
             }\r
         }\r
+        String excludeCmd = "";\r
+        if (excludes != null) {\r
+            for (String exclude : excludes) {\r
+                excludeCmd += String.format("--exclude=%s ", exclude);\r
+            }\r
+        }\r
+        \r
         String msysBinPath = sbi.getMsysBinPath();\r
         StringBuffer cmd = new StringBuffer();\r
         cmd.append(new Path(msysBinPath).append("sh.exe").toOSString());\r
@@ -43,6 +50,9 @@ public class RsyncProcessor {
         cmd.append(sshPrivateKey);\r
         cmd.append(" -o StrictHostKeyChecking=no");\r
         cmd.append("' ");\r
+        if (!excludeCmd.isEmpty()) {\r
+            cmd.append(excludeCmd);\r
+        }\r
         cmd.append(user);\r
         cmd.append("@");\r
         cmd.append(host);\r
@@ -17,7 +17,7 @@ import org.tizen.common.util.log.UserLogger;
 import org.tizen.nativeplatform.util.PlatformUserInteraction;\r
 import org.tizen.nativeplatform.util.RootstrapUtil;\r
 \r
-public class WorkspaceSyncronizer {\r
+public class WorkspaceSynchronizer {\r
     \r
     public static String[] EXCLUDES = {".git/", "Debug/", "Release/", ".cproject", ".project", ".tproject",\r
         ".gitignore"};\r
index d416dca..8f8acd7 100644 (file)
@@ -14,7 +14,7 @@ View.Contextmenu.Change.ConfFile = Change Configuration File
 View.Contextmenu.Manage = Manage Packages
 View.Contextmenu.Remove = Remove
 View.Contextmenu.Export = Export
-View.Contextmenu.Sync = Sync Includes
+View.Contextmenu.Sync = Sync Include && Debug files
 View.Contextmenu.OpenDbgsrc = Open Debug Source
 
 View.Desc.Arch = * Architecture: %s(%s)
index 6efad7b..093c9ee 100644 (file)
@@ -39,7 +39,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.ResourceBundle;
 
-import org.eclipse.ui.ide.IDE;
 import org.eclipse.cdt.core.model.CoreModel;
 import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent;
 import org.eclipse.cdt.core.settings.model.ICProjectDescriptionListener;
@@ -54,6 +53,7 @@ import org.eclipse.core.resources.IWorkspace;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.jface.action.Action;
@@ -96,7 +96,6 @@ import org.eclipse.swt.widgets.TableItem;
 import org.eclipse.swt.widgets.Text;
 import org.eclipse.swt.widgets.ToolBar;
 import org.eclipse.swt.widgets.ToolItem;
-import org.eclipse.ui.IEditorDescriptor;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.ISelectionListener;
 import org.eclipse.ui.ISizeProvider;
@@ -105,6 +104,7 @@ import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.contexts.IContextService;
+import org.eclipse.ui.ide.IDE;
 import org.eclipse.ui.part.ViewPart;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -126,7 +126,7 @@ import org.tizen.nativeplatform.pkg.commander.PkgCommandTarget;
 import org.tizen.nativeplatform.pkgmgr.PkgMgrInitializer;
 import org.tizen.nativeplatform.pkgmgr.ui.RPMPackageDialog;
 import org.tizen.nativeplatform.remote.connection.RemoteConnectionManager;
-import org.tizen.nativeplatform.remote.connection.RootstrapSyncronizer;
+import org.tizen.nativeplatform.remote.connection.RootstrapSynchronizer;
 import org.tizen.nativeplatform.remote.connection.RsyncProcessor;
 import org.tizen.nativeplatform.repo.commander.LocalRepoMounter;
 import org.tizen.nativeplatform.repo.commander.RepoManager;
@@ -790,6 +790,42 @@ public class RootstrapView extends ViewPart {
                 final PlatformRootstrap selected = (PlatformRootstrap) item[0].getData();
                 String rootstrapPath = RootstrapUtil.getUserSyncRootstrapPath(selected.getId());
                 String defaultPath = new Path(rootstrapPath).append("usr").append("src").append("debug").toString();
+                File debugSrcPath = new File(defaultPath);
+                if (!debugSrcPath.exists()) {
+                    String msg = String.format("There is no any debug source in \"%s\" rootstrap.\n" +
+                               "Try it again after installing debug packages using \"Manage Packages\" menu.", selected.getId());
+                    DialogUtil.openMessageDialog(shell, msg);
+                    return;
+                }
+                long dstTime = debugSrcPath.lastModified();
+                long srcTime = RootstrapSynchronizer.getDebugsrcPathLastmodifiedTime(selected);
+                if (srcTime != dstTime) {
+                    String msg = "There are changes for debug source in remote rootstrap.\n" +
+                               "Do you want to synchronize the changes?";
+                    int result = DialogUtil.openQuestionDialog(shell, "Do you want to synchronize?", msg);
+                    if (result == SWT.YES) {
+                        ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell);
+                        try {
+                            dialog.run(true, true, new IRunnableWithProgress() {
+                                @Override
+                                public void run(IProgressMonitor monitor)
+                                        throws InvocationTargetException, InterruptedException {
+                                    monitor.beginTask("Synchronize debug sources...", -1);
+                                    try {
+                                        RootstrapSynchronizer.syncronize(selected, false, true, monitor);
+                                    } finally {
+                                        monitor.done();
+                                    }
+                                }
+                            });
+                        } catch (Exception e) {
+                            logger.error("Failed to syncronize debug sources", e);
+                            DialogUtil.openErrorDialog(String.format("%s\n * %s",
+                                    "Failed to syncronize debug sources", e.toString()));
+                            return;
+                        }
+                    }
+                }
                FileDialog fd = new FileDialog(shell, SWT.OPEN | SWT.SINGLE);
                 fd.setText("Select debug source file");
                 fd.setFilterPath(defaultPath);
@@ -828,9 +864,9 @@ public class RootstrapView extends ViewPart {
                         @Override
                         public void run(IProgressMonitor monitor)
                                 throws InvocationTargetException, InterruptedException {
-                            monitor.beginTask("Syncronize includes...", -1);
+                            monitor.beginTask("Synchronize includes...", -1);
                             try {
-                                RootstrapSyncronizer.syncronize(selected, monitor);
+                                RootstrapSynchronizer.syncronize(selected, monitor);
                             } finally {
                                 monitor.done();
                             }
@@ -929,7 +965,7 @@ public class RootstrapView extends ViewPart {
                         throw new InterruptedException();
                     }
                     if (OSChecker.isWindows()) {
-                        RootstrapSyncronizer.syncronize(generatedRootstrap, monitor);
+                        RootstrapSynchronizer.syncronize(generatedRootstrap, monitor);
                     }
                 }
             });
@@ -1105,7 +1141,7 @@ public class RootstrapView extends ViewPart {
                 }
                 final boolean needRemoteSync = OSChecker.isWindows();
                 if (needRemoteSync) {
-                    RootstrapSyncronizer.cacheModificationTime(selected);
+                    RootstrapSynchronizer.cacheModificationTime(selected);
                 }
                 // launch package manager
                 IDevice device = ConnectionPlugin.getDefault().getCurrentDevice();
@@ -1165,7 +1201,7 @@ public class RootstrapView extends ViewPart {
                                 RootstrapManager.updateRootstrap(selected);
                                 monitor.worked(1);
                                 if (needRemoteSync) {
-                                    RootstrapSyncronizer.syncronizeIfChanges(selected, new SubProgressMonitor(monitor, 1));
+                                    RootstrapSynchronizer.syncronizeIfChanges(selected, new SubProgressMonitor(monitor, 1));
                                 }
                                 monitor.worked(1);
                             } finally {