Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikhail Sennikovsky2005-07-06 13:56:13 -0400
committerMikhail Sennikovsky2005-07-06 13:56:13 -0400
commit3c93caf4c92ac214e6023dd4c39aea37b9a9c7cc (patch)
tree5b15a25277935a65389c4be3184a4a4afe6c023a
parent6783d23fa36a5410d29048234fb88e3ae560d517 (diff)
downloadorg.eclipse.cdt-3c93caf4c92ac214e6023dd4c39aea37b9a9c7cc.tar.gz
org.eclipse.cdt-3c93caf4c92ac214e6023dd4c39aea37b9a9c7cc.tar.xz
org.eclipse.cdt-3c93caf4c92ac214e6023dd4c39aea37b9a9c7cc.zip
Checked in the resouece renaming/deletion handling for MBS. When the resouece is either renamed ore deleted, the project ResourceConfiguration data is updated now.
Also checked in the test for verification resouece renaming/deletion handling.
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ResourceBuildCoreTests.java213
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java2
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuilderCorePlugin.java26
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java3
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties3
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ResourceChangeHandler.java431
6 files changed, 659 insertions, 19 deletions
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ResourceBuildCoreTests.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ResourceBuildCoreTests.java
index 651b11a09c..12d2b8319d 100644
--- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ResourceBuildCoreTests.java
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ResourceBuildCoreTests.java
@@ -11,6 +11,7 @@
package org.eclipse.cdt.managedbuilder.core.tests;
import java.io.ByteArrayInputStream;
+import java.util.HashMap;
import junit.framework.Test;
import junit.framework.TestCase;
@@ -19,19 +20,20 @@ import junit.framework.TestSuite;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.make.core.MakeCorePlugin;
import org.eclipse.cdt.managedbuilder.core.BuildException;
+import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
-import org.eclipse.cdt.managedbuilder.core.IProjectType;
import org.eclipse.cdt.managedbuilder.core.IManagedProject;
-import org.eclipse.cdt.managedbuilder.core.IConfiguration;
-import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration;
-import org.eclipse.cdt.managedbuilder.core.ITool;
import org.eclipse.cdt.managedbuilder.core.IOption;
import org.eclipse.cdt.managedbuilder.core.IOptionCategory;
+import org.eclipse.cdt.managedbuilder.core.IProjectType;
+import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration;
+import org.eclipse.cdt.managedbuilder.core.ITool;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.core.ManagedCProjectNature;
import org.eclipse.cdt.managedbuilder.internal.core.Tool;
import org.eclipse.cdt.managedbuilder.testplugin.ManagedBuildTestHelper;
import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
@@ -44,6 +46,7 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
public class ResourceBuildCoreTests extends TestCase {
@@ -54,8 +57,8 @@ public class ResourceBuildCoreTests extends TestCase {
private static final String projectName = "T1";
-
-
+ private static final String renamedProjectName1 = "T1_1";
+ private static final String renamedProjectName2 = "T1_2";
public ResourceBuildCoreTests(String name) {
super(name);
@@ -66,6 +69,7 @@ public class ResourceBuildCoreTests extends TestCase {
suite.addTest(new ResourceBuildCoreTests("testResourceConfigurations"));
suite.addTest(new ResourceBuildCoreTests("testResourceConfigurationReset"));
suite.addTest(new ResourceBuildCoreTests("testResourceConfigurationBuildInfo"));
+ suite.addTest(new ResourceBuildCoreTests("testResourceRename"));
return suite;
}
@@ -721,4 +725,201 @@ public class ResourceBuildCoreTests extends TestCase {
ManagedBuildManager.removeBuildInfo(project);
}
+ public void testResourceRename() throws Exception {
+ // Create a new project
+ IProject project = null;
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+
+ try {
+ project = createProject(projectName);
+
+ // Now associate the builder with the project
+ ManagedBuildTestHelper.addManagedBuildNature(project);
+ IProjectDescription description = project.getDescription();
+ // Make sure it has a managed nature
+ if (description != null) {
+ assertTrue(description.hasNature(ManagedCProjectNature.MNG_NATURE_ID));
+ }
+
+ } catch (CoreException e) {
+ fail("Test failed on project creation: " + e.getLocalizedMessage());
+ }
+
+ // Find the base project type definition
+ IProjectType[] projTypes = ManagedBuildManager.getDefinedProjectTypes();
+ IProjectType projType = ManagedBuildManager.getProjectType("cdt.managedbuild.target.testgnu21.exe");
+ assertNotNull(projType);
+
+ // Create the managed-project (.cdtbuild) for our project that builds an executable.
+ IManagedProject newProject = ManagedBuildManager.createManagedProject(project, projType);
+ assertEquals(newProject.getName(), projType.getName());
+ assertFalse(newProject.equals(projType));
+ ManagedBuildManager.setNewProjectVersion(project);
+
+ // Create a couple of resources ( 'main.c' & 'bar.c')
+ IFile mainFile = project.getProject().getFile( "main.c" );
+ if( !mainFile.exists() ){
+ mainFile.create( new ByteArrayInputStream( "#include <stdio.h>\n extern void bar(); \n int main() { \nprintf(\"Hello, World!!\"); \n bar();\n return 0; }".getBytes() ), false, null );
+ }
+
+ IFile aFile = project.getProject().getFile( "a.c" );
+ if( !aFile.exists() ){
+ aFile.create( new ByteArrayInputStream( "#include <stdio.h>\n void bar() { \nprintf(\"Hello, bar()!!\");\n return; }".getBytes() ), false, null );
+ }
+
+ IFolder dirFolder = project.getProject().getFolder( "dir" );
+ if(!dirFolder.exists())
+ dirFolder.create(true,true,null);
+ IFile bFile = dirFolder.getFile( "b.c" );
+ if( !bFile.exists() ){
+ bFile.create( new ByteArrayInputStream( "#include <stdio.h>\n void bar1() { \nprintf(\"Hello, bar1()!!\");\n return; }".getBytes() ), false, null );
+ }
+
+ // Get the configurations and make one of them as default configuration.
+ IConfiguration defaultConfig = null;
+ IConfiguration[] configs = projType.getConfigurations();
+ for (int i = 0; i < configs.length; ++i) {
+ // Make the first configuration the default
+ if (i == 0) {
+ defaultConfig = newProject.createConfiguration(configs[i], projType.getId() + "." + i);
+ } else {
+ newProject.createConfiguration(configs[i], projType.getId() + "." + i);
+ }
+ }
+ ManagedBuildManager.setDefaultConfiguration(project, defaultConfig);
+
+ // Create Resource Configurations for files main.c and bar.c
+ IResourceConfiguration resMainConfig = defaultConfig.createResourceConfiguration(mainFile);
+ IResourceConfiguration resAConfig = defaultConfig.createResourceConfiguration(aFile);
+ IResourceConfiguration resBConfig = defaultConfig.createResourceConfiguration(bFile);
+
+ // Check whether defaultConfig has three resource configurations or not.
+ IResourceConfiguration resConfigs[] = defaultConfig.getResourceConfigurations();
+ assertEquals(resMainConfig,defaultConfig.getResourceConfiguration(mainFile.getFullPath().toString()));
+ assertEquals(resAConfig,defaultConfig.getResourceConfiguration(aFile.getFullPath().toString()));
+ assertEquals(resBConfig,defaultConfig.getResourceConfiguration(bFile.getFullPath().toString()));
+ assertEquals(3,resConfigs.length);
+
+
+ mainFile.move(mainFile.getFullPath().removeLastSegments(1).append("main1.c"),true,false,null);
+ mainFile = (IFile)project.findMember("main1.c");
+ assertEquals(resMainConfig,defaultConfig.getResourceConfiguration(mainFile.getFullPath().toString()));
+ assertEquals(resAConfig,defaultConfig.getResourceConfiguration(aFile.getFullPath().toString()));
+ assertEquals(resBConfig,defaultConfig.getResourceConfiguration(bFile.getFullPath().toString()));
+ resConfigs = defaultConfig.getResourceConfigurations();
+ assertEquals(3,resConfigs.length);
+
+ dirFolder.move(dirFolder.getFullPath().removeLastSegments(1).append("dir1"),true,false,null);
+ dirFolder = (IFolder)project.findMember("dir1");
+ bFile = (IFile)dirFolder.findMember("b.c");
+ assertEquals(resMainConfig,defaultConfig.getResourceConfiguration(mainFile.getFullPath().toString()));
+ assertEquals(resAConfig,defaultConfig.getResourceConfiguration(aFile.getFullPath().toString()));
+ assertEquals(resBConfig,defaultConfig.getResourceConfiguration(bFile.getFullPath().toString()));
+ resConfigs = defaultConfig.getResourceConfigurations();
+ assertEquals(3,resConfigs.length);
+
+ bFile.move(bFile.getFullPath().removeLastSegments(1).append("b1.c"),true,false,null);
+ bFile = (IFile)dirFolder.findMember("b1.c");
+ assertEquals(resMainConfig,defaultConfig.getResourceConfiguration(mainFile.getFullPath().toString()));
+ assertEquals(resAConfig,defaultConfig.getResourceConfiguration(aFile.getFullPath().toString()));
+ assertEquals(resBConfig,defaultConfig.getResourceConfiguration(bFile.getFullPath().toString()));
+ resConfigs = defaultConfig.getResourceConfigurations();
+ assertEquals(3,resConfigs.length);
+
+ IProjectDescription des = project.getDescription();
+ des.setName(renamedProjectName1);
+ project.move(des,true,null);
+ project = (IProject)root.findMember(renamedProjectName1);
+ mainFile = (IFile)project.findMember("main1.c");
+ aFile = (IFile)project.findMember("a.c");
+ dirFolder = (IFolder)project.findMember("dir1");
+ bFile = (IFile)dirFolder.findMember("b1.c");
+ assertEquals(resMainConfig,defaultConfig.getResourceConfiguration(mainFile.getFullPath().toString()));
+ assertEquals(resAConfig,defaultConfig.getResourceConfiguration(aFile.getFullPath().toString()));
+ assertEquals(resBConfig,defaultConfig.getResourceConfiguration(bFile.getFullPath().toString()));
+ resConfigs = defaultConfig.getResourceConfigurations();
+ assertEquals(3,resConfigs.length);
+
+ final IResource rcBuf[] = new IResource[5];
+ rcBuf[0] = project;
+ rcBuf[1] = mainFile;
+ rcBuf[2] = aFile;
+ rcBuf[3] = dirFolder;
+ rcBuf[4] = bFile;
+
+ ResourcesPlugin.getWorkspace().run( new IWorkspaceRunnable(){
+
+ public void run(IProgressMonitor monitor) throws CoreException {
+ IProject project = (IProject)rcBuf[0];
+ IFile mainFile = (IFile)rcBuf[1];
+ IFile aFile = (IFile)rcBuf[2];
+ IFolder dirFolder = (IFolder)rcBuf[3];
+ IFile bFile = (IFile)rcBuf[4];
+ // TODO Auto-generated method stub
+ mainFile.move(mainFile.getFullPath().removeLastSegments(1).append("main2.c"),true,false,null);
+ mainFile = (IFile)project.findMember("main2.c");
+
+ dirFolder.move(dirFolder.getFullPath().removeLastSegments(1).append("dir2"),true,false,null);
+ dirFolder = (IFolder)project.findMember("dir2");
+ bFile = (IFile)dirFolder.findMember("b1.c");
+
+ bFile.move(bFile.getFullPath().removeLastSegments(1).append("b2.c"),true,false,null);
+ bFile = (IFile)dirFolder.findMember("b2.c");
+
+// project.move(project.getFullPath().removeLastSegments(1).append(renamedProjectName2),true,null);
+ IProjectDescription des = project.getDescription();
+ des.setName(renamedProjectName2);
+ project.move(des,true,null);
+ project = (IProject)ResourcesPlugin.getWorkspace().getRoot().findMember(renamedProjectName2);
+
+ mainFile = (IFile)project.findMember("main2.c");
+ aFile = (IFile)project.findMember("a.c");
+ dirFolder = (IFolder)project.findMember("dir2");
+ bFile = (IFile)dirFolder.findMember("b2.c");
+
+ rcBuf[0] = project;
+ rcBuf[1] = mainFile;
+ rcBuf[2] = aFile;
+ rcBuf[3] = dirFolder;
+ rcBuf[4] = bFile;
+ }
+
+ },
+ root,
+ IWorkspace.AVOID_UPDATE,
+ null);
+
+ project = (IProject)rcBuf[0];
+ mainFile = (IFile)rcBuf[1];
+ aFile = (IFile)rcBuf[2];
+ dirFolder = (IFolder)rcBuf[3];
+ bFile = (IFile)rcBuf[4];
+
+ assertEquals(resMainConfig,defaultConfig.getResourceConfiguration(mainFile.getFullPath().toString()));
+ assertEquals(resAConfig,defaultConfig.getResourceConfiguration(aFile.getFullPath().toString()));
+ assertEquals(resBConfig,defaultConfig.getResourceConfiguration(bFile.getFullPath().toString()));
+ resConfigs = defaultConfig.getResourceConfigurations();
+ assertEquals(3,resConfigs.length);
+
+ aFile.delete(true,null);
+ // Check whether defaultConfig has two resource configurations or not.
+ assertEquals(resMainConfig,defaultConfig.getResourceConfiguration(mainFile.getFullPath().toString()));
+ assertEquals(null,defaultConfig.getResourceConfiguration(aFile.getFullPath().toString()));
+ assertEquals(resBConfig,defaultConfig.getResourceConfiguration(bFile.getFullPath().toString()));
+ resConfigs = defaultConfig.getResourceConfigurations();
+ assertEquals(2,resConfigs.length);
+
+ dirFolder.delete(true, null);
+ // Check whether defaultConfig has one resource configuration or not.
+ assertEquals(resMainConfig,defaultConfig.getResourceConfiguration(mainFile.getFullPath().toString()));
+ assertEquals(null,defaultConfig.getResourceConfiguration(aFile.getFullPath().toString()));
+ assertEquals(null,defaultConfig.getResourceConfiguration(bFile.getFullPath().toString()));
+ resConfigs = defaultConfig.getResourceConfigurations();
+ assertEquals(1,resConfigs.length);
+
+ // Close and remove project.
+ project.close(null);
+ removeProject(renamedProjectName2);
+ }
+
}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java
index 3e1877f3b5..c27d2405b2 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java
@@ -2133,7 +2133,7 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
jobManager.endRule(rule);
}
- if (!buildInfo.isContainerInited()) {
+ if (buildInfo != null && !buildInfo.isContainerInited()) {
// NOTE: If this is called inside the above rule, then an IllegalArgumentException can
// occur when the CDT project file is saved - it uses the Workspace Root as the scheduling rule.
//
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuilderCorePlugin.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuilderCorePlugin.java
index 7654d771d6..4ae7b62538 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuilderCorePlugin.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuilderCorePlugin.java
@@ -11,8 +11,12 @@
package org.eclipse.cdt.managedbuilder.core;
import org.eclipse.cdt.managedbuilder.internal.core.GeneratedMakefileBuilder;
+import org.eclipse.cdt.managedbuilder.internal.core.ResourceChangeHandler;
import org.eclipse.cdt.managedbuilder.internal.scannerconfig.ManagedBuildCPathEntryContainer;
import org.eclipse.cdt.managedbuilder.internal.scannerconfig.ManagedBuildPathEntryContainerInitializer;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.ISavedState;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.BundleContext;
@@ -35,7 +39,7 @@ public class ManagedBuilderCorePlugin extends Plugin {
// NOTE: The code below is for tracking resource renaming and deleting. This is needed to keep
// ResourceConfiguration elements up to date. It may also be needed by AdditionalInput
// elements
- //private static ResourceChangeHandler listener;
+ private static ResourceChangeHandler listener;
/**
* @param descriptor
@@ -75,14 +79,14 @@ public class ManagedBuilderCorePlugin extends Plugin {
// elements
// Set up a listener for resource change events
- //listener = new ResourceChangeHandler();
- //ResourcesPlugin.getWorkspace().addResourceChangeListener(
- // listener, IResourceChangeEvent.POST_CHANGE /*| IResourceChangeEvent.POST_BUILD*/);
- //ISavedState lastState =
- // ResourcesPlugin.getWorkspace().addSaveParticipant(plugin, listener);
- //if (lastState != null) {
- // lastState.processResourceChangeEvents(listener);
- //}
+ listener = new ResourceChangeHandler();
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(
+ listener, IResourceChangeEvent.POST_CHANGE | IResourceChangeEvent.PRE_DELETE /*| IResourceChangeEvent.POST_BUILD*/);
+ ISavedState lastState =
+ ResourcesPlugin.getWorkspace().addSaveParticipant(this, listener);
+ if (lastState != null) {
+ lastState.processResourceChangeEvents(listener);
+ }
}
@@ -93,7 +97,9 @@ public class ManagedBuilderCorePlugin extends Plugin {
// NOTE: The code below is for tracking resource renaming and deleting. This is needed to keep
// ResourceConfiguration elements up to date. It may also be needed by AdditionalInput
// elements
- //ResourcesPlugin.getWorkspace().removeResourceChangeListener(listener);
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(listener);
+ listener = null;
+ super.stop(context);
}
private static final String PATH_ENTRY = ManagedBuilderCorePlugin.getUniqueIdentifier() + "/debug/pathEntry"; //$NON-NLS-1$
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java
index 8f1897838a..08385ddd04 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java
@@ -852,7 +852,8 @@ public class Configuration extends BuildObject implements IConfiguration {
}
public void removeResourceConfiguration(IResourceConfiguration resConfig) {
- getResourceConfigurationList().remove((ResourceConfiguration)resConfig);
+ getResourceConfigurationList().remove(resConfig);
+ getResourceConfigurationMap().remove(resConfig.getResourcePath());
}
/*
* M O D E L A T T R I B U T E A C C E S S O R S
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties
index b5a4b7ad0d..af6b240fcb 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties
@@ -100,4 +100,5 @@ BuildMacroStatus.status.macro.not.stringlist=Macro {0} is not of String-list typ
BuildMacroStatus.status.error=Error occured
BuildMacroStatus.value.undefined=
-
+#ResourceChangeHandler messages
+ResourceChangeHandler.buildInfoSerializationJob=Build Info Serialization
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ResourceChangeHandler.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ResourceChangeHandler.java
new file mode 100644
index 0000000000..1be5cc97fb
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ResourceChangeHandler.java
@@ -0,0 +1,431 @@
+/*******************************************************************************
+ * Copyright (c) 2005 Intel Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Intel Corporation - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.managedbuilder.internal.core;
+
+import java.util.HashMap;
+import java.util.HashSet;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.managedbuilder.core.IConfiguration;
+import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
+import org.eclipse.cdt.managedbuilder.core.IManagedProject;
+import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration;
+import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
+import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
+import org.eclipse.cdt.managedbuilder.core.ManagedCProjectNature;
+import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IResourceRuleFactory;
+import org.eclipse.core.resources.ISaveContext;
+import org.eclipse.core.resources.ISaveParticipant;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.MultiRule;
+
+public class ResourceChangeHandler implements IResourceChangeListener, ISaveParticipant {
+
+ private class ResourceConfigurationChecker implements IResourceDeltaVisitor{
+ private IResourceDelta fRootDelta;
+ private HashMap fBuildFileGeneratorMap = new HashMap();
+ private HashSet fValidatedFilesSet = new HashSet();
+ private HashSet fModifiedProjects = new HashSet();
+
+ public ResourceConfigurationChecker(IResourceDelta rootDelta){
+ fRootDelta = rootDelta;
+ }
+
+ public IProject[] getModifiedProjects(){
+ return (IProject[])fModifiedProjects.toArray(new IProject[fModifiedProjects.size()]);
+ }
+
+ public boolean visit(IResourceDelta delta) throws CoreException {
+ IResource dResource = delta.getResource();
+ int rcType = dResource.getType();
+
+ if(rcType == IResource.PROJECT || rcType == IResource.FOLDER){
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ IProject project = null;
+ IResource rcToCheck = null;
+ switch (delta.getKind()) {
+ case IResourceDelta.REMOVED :
+ if ((delta.getFlags() & IResourceDelta.MOVED_TO) == 0 && rcType == IResource.PROJECT) {
+ break;
+ }
+ case IResourceDelta.CHANGED :
+ if ((delta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
+ IPath path = delta.getMovedToPath();
+ if(path != null){
+ project = root.findMember(path.segment(0)).getProject();
+ if(project != null && rcType == IResource.FOLDER)
+ rcToCheck = root.getFolder(substituteProject(dResource.getFullPath(),project.getName()));
+ }
+ break;
+ }
+ default:
+ project = dResource.getProject();
+ if(rcType == IResource.FOLDER)
+ rcToCheck = dResource;
+ break;
+ }
+
+ if(project != null) {
+ IManagedBuilderMakefileGenerator makeGen = getInitializedGenerator(project);
+ if(makeGen != null){
+ if(rcToCheck == null || !makeGen.isGeneratedResource(rcToCheck))
+ return true;
+ }
+ }
+ return false;
+ } else if (rcType == IResource.FILE && !dResource.isDerived()) {
+ int flags = delta.getFlags();
+ switch (delta.getKind()) {
+ case IResourceDelta.REMOVED :
+ if ((flags & IResourceDelta.MOVED_TO) == 0) {
+ handleDeleteFile(dResource.getFullPath());
+ break;
+ }
+ case IResourceDelta.ADDED :
+ case IResourceDelta.CHANGED :
+ if ((flags & IResourceDelta.MOVED_TO) != 0) {
+ IPath path = delta.getMovedToPath();
+ if (path != null) {
+ handleRenamedFile(
+ dResource.getFullPath(),
+ path);
+ }
+ } else if ((flags & IResourceDelta.MOVED_FROM) != 0) {
+ IPath path = delta.getMovedFromPath();
+ if (path != null) {
+ handleRenamedFile(
+ path,
+ dResource.getFullPath());
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return false;
+ }
+ return true; // visit the children
+ }
+
+ private IPath substituteProject(IPath path, String projectName){
+ return new Path(projectName).makeAbsolute().append(path.removeFirstSegments(1));
+ }
+
+ private void handleRenamedFile(IPath fromPath, IPath toPath){
+ if(!fValidatedFilesSet.add(fromPath))
+ return;
+
+ IProject fromProject = findModifiedProject(fromPath.segment(0));
+ if(fromProject == null)
+ return;
+ IManagedBuilderMakefileGenerator fromMakeGen = getInitializedGenerator(fromProject);
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ if(fromMakeGen == null || fromMakeGen.isGeneratedResource(root.getFile(substituteProject(fromPath,fromProject.getName()))))
+ return;
+
+ IManagedBuildInfo fromInfo = fromProject != null ?
+ ManagedBuildManager.getBuildInfo(fromProject) :
+ null;
+
+ IProject toProject = root.findMember(toPath.uptoSegment(1)).getProject();
+ IManagedBuildInfo toInfo = toProject != null ?
+ ManagedBuildManager.getBuildInfo(toProject) :
+ null;
+ IManagedBuilderMakefileGenerator toMakeGen = toProject != null ?
+ getInitializedGenerator(toProject) :
+ null;
+ if(toMakeGen != null && toMakeGen.isGeneratedResource(root.getFile(toPath)))
+ toInfo = null;
+
+ if(fromInfo == toInfo){
+ //the resource was moved whithing the project scope
+ if(updateResourceConfigurations(fromInfo,fromPath,toPath) && toProject != null)
+ fModifiedProjects.add(toProject);
+ } else {
+ if(fromInfo != null && toInfo != null){
+ //TODO: this is the case when the resource
+ //is moved from one managed project to another
+ //should we handle this?
+ //e.g. add resource configurations to the destination project?
+ }
+ if(fromInfo != null && removeResourceConfigurations(fromInfo,fromPath) && fromProject != null)
+ fModifiedProjects.add(fromProject);
+ }
+ }
+
+ private void handleDeleteFile(IPath path){
+ IProject project = findModifiedProject(path.segment(0));
+ if(project != null){
+ IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project);
+ if(info != null
+ && removeResourceConfigurations(info,path))
+ fModifiedProjects.add(project);
+ }
+ }
+
+ //finds the project geven the initial project name
+ //That is:
+ // if the project of a given name was renamed returns the renamed project
+ // if the project of a given name was removed returns null
+ // if the project of a given name was neither renamed or removed
+ // returns the project of that name or null if the project does not exist
+ //
+ private IProject findModifiedProject(final String oldProjectName){
+ IResourceDelta projectDelta = fRootDelta.findMember(new Path(oldProjectName));
+ boolean replaced = false;
+ if(projectDelta != null) {
+ switch(projectDelta.getKind()){
+ case IResourceDelta.REMOVED :
+ if ((projectDelta.getFlags() & IResourceDelta.MOVED_TO) == 0) {
+ return null;
+ }
+ case IResourceDelta.CHANGED :
+ if ((projectDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
+ IPath path = projectDelta.getMovedToPath();
+ if(path != null)
+ return ResourcesPlugin.getWorkspace().getRoot().findMember(path).getProject();
+ }
+ break;
+ }
+ }
+
+ final IProject project[] = new IProject[1];
+ try {
+ fRootDelta.accept(new IResourceDeltaVisitor() {
+ public boolean visit(IResourceDelta delta) throws CoreException {
+ IResource dResource = delta.getResource();
+ int rcType = dResource.getType();
+ if(rcType == IResource.ROOT) {
+ return true;
+ } else if(rcType == IResource.PROJECT){
+ switch(delta.getKind()){
+ case IResourceDelta.ADDED :
+ case IResourceDelta.CHANGED :
+ if ((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) {
+ IPath path = delta.getMovedFromPath();
+ if (path != null && path.segment(0).equals(oldProjectName)) {
+ project[0] = dResource.getProject();
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return false;
+ }
+ });
+ } catch (CoreException e) {
+ }
+
+ if(project[0] == null && !replaced)
+ project[0] = ResourcesPlugin.getWorkspace().getRoot().findMember(oldProjectName).getProject();
+ return project[0];
+ }
+
+ private IManagedBuilderMakefileGenerator getInitializedGenerator(IProject project){
+ IManagedBuilderMakefileGenerator makeGen = (IManagedBuilderMakefileGenerator)fBuildFileGeneratorMap.get(project);
+ if(makeGen == null){
+ try{
+ if(project.hasNature(ManagedCProjectNature.MNG_NATURE_ID)){
+ IManagedBuildInfo buildInfo = ManagedBuildManager.getBuildInfo(project);
+ if(buildInfo != null){
+ IConfiguration defaultCfg = buildInfo.getDefaultConfiguration();
+ if(defaultCfg != null){
+ makeGen = ManagedBuildManager.getBuildfileGenerator(defaultCfg);
+ makeGen.initialize(project,buildInfo,new NullProgressMonitor());
+ fBuildFileGeneratorMap.put(project,makeGen);
+ }
+ }
+ }
+ } catch (CoreException e){
+ }
+ }
+ return makeGen;
+ }
+ }
+
+ /*
+ * I R e s o u r c e C h a n g e L i s t e n e r
+ */
+
+ /* (non-Javadoc)
+ *
+ * Handle the renaming and deletion of project resources
+ * This is necessary in order to update ResourceConfigurations and AdditionalInputs
+ *
+ * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
+ */
+ public void resourceChanged(IResourceChangeEvent event) {
+ if (event.getSource() instanceof IWorkspace) {
+
+ switch (event.getType()) {
+ case IResourceChangeEvent.POST_CHANGE :
+ case IResourceChangeEvent.POST_BUILD :
+ case IResourceChangeEvent.PRE_DELETE :
+ IResourceDelta resDelta = event.getDelta();
+ if (resDelta == null) {
+ break;
+ }
+ try {
+ ResourceConfigurationChecker rcChecker = new ResourceConfigurationChecker(resDelta);
+ resDelta.accept(rcChecker);
+
+ //saving info for the modified projects
+ initInfoSerialization(rcChecker.getModifiedProjects());
+
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ }
+ break;
+ default :
+ break;
+ }
+ }
+ }
+
+ private void initInfoSerialization(final IProject projects[]){
+ if(projects.length == 0)
+ return;
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IResourceRuleFactory ruleFactory = workspace.getRuleFactory();
+ ISchedulingRule buildInfoSaveRule;
+ if(projects.length == 1){
+ buildInfoSaveRule = ruleFactory.modifyRule(projects[0]);
+ } else {
+ ISchedulingRule rules[] = new ISchedulingRule[projects.length];
+ for(int i = 0; i < rules.length; i++)
+ rules[i] = ruleFactory.modifyRule(projects[i]);
+ buildInfoSaveRule = MultiRule.combine(rules);
+ }
+
+ Job savingJob = new Job(ManagedMakeMessages.getResourceString("ResourceChangeHandler.buildInfoSerializationJob")){ //$NON-NLS-1$
+ protected IStatus run(IProgressMonitor monitor) {
+ for(int i = 0; i < projects.length; i++){
+ ManagedBuildManager.saveBuildInfo(projects[i],true);
+ }
+ return new Status(
+ IStatus.OK,
+ ManagedBuilderCorePlugin.getUniqueIdentifier(),
+ IStatus.OK,
+ new String(),
+ null);
+ }
+ };
+ savingJob.setRule(buildInfoSaveRule);
+
+ savingJob.schedule();
+ }
+
+ private boolean updateResourceConfigurations(IManagedBuildInfo info, IPath oldPath, IPath newPath){
+ boolean changed = false;
+ if(!oldPath.equals(newPath)){
+ IManagedProject mngProj = info.getManagedProject();
+ if(mngProj != null){
+ IConfiguration configs[] = mngProj.getConfigurations();
+ if(configs != null && configs.length > 0){
+ for(int i = 0; i < configs.length; i++){
+ if(updateResourceConfiguration(configs[i],oldPath,newPath))
+ changed = true;
+ }
+ }
+ }
+ }
+ return changed;
+ }
+
+ private boolean removeResourceConfigurations(IManagedBuildInfo info, IPath path){
+ boolean changed = false;
+ IManagedProject mngProj = info.getManagedProject();
+ if(mngProj != null){
+ IConfiguration configs[] = mngProj.getConfigurations();
+ if(configs != null && configs.length > 0){
+ for(int i = 0; i < configs.length; i++){
+ if(removeResourceConfiguration(configs[i],path))
+ changed = true;
+ }
+ }
+ }
+ return changed;
+ }
+
+ private boolean updateResourceConfiguration(IConfiguration config, IPath oldPath, IPath newPath){
+ IResourceConfiguration rcCfg = config.getResourceConfiguration(oldPath.toString());
+ if(rcCfg != null && !oldPath.equals(newPath)){
+ config.removeResourceConfiguration(rcCfg);
+ rcCfg.setResourcePath(newPath.toString());
+ ((Configuration)config).addResourceConfiguration((ResourceConfiguration)rcCfg);
+ return true;
+ }
+ return false;
+ }
+
+ private boolean removeResourceConfiguration(IConfiguration config, IPath path){
+ IResourceConfiguration rcCfg = config.getResourceConfiguration(path.toString());
+ if(rcCfg != null){
+ config.removeResourceConfiguration(rcCfg);
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * I S a v e P a r t i c i p a n t
+ */
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.ISaveParticipant#saving(org.eclipse.core.resources.ISaveContext)
+ */
+ public void saving(ISaveContext context) throws CoreException {
+ // No state to be saved by the plug-in, but request a
+ // resource delta to be used on next activation.
+ context.needDelta();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.ISaveParticipant#doneSaving(org.eclipse.core.resources.ISaveContext)
+ */
+ public void doneSaving(ISaveContext context) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.ISaveParticipant#prepareToSave(org.eclipse.core.resources.ISaveContext)
+ */
+ public void prepareToSave(ISaveContext context) throws CoreException {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.ISaveParticipant#rollback(org.eclipse.core.resources.ISaveContext)
+ */
+ public void rollback(ISaveContext context) {
+ }
+
+}

Back to the top