Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgor Fedorenko2011-09-22 02:51:17 +0000
committerIgor Fedorenko2011-09-28 00:17:06 +0000
commit42a58b2be70f958a1789099a45eadb00a558abf1 (patch)
tree4430c4f037c0cfe2ef0b0a8834bdf7775a90e387
parente4a326c95d2776d20809a6a0ce41e517da7d18ec (diff)
downloadm2e-core-42a58b2be70f958a1789099a45eadb00a558abf1.tar.gz
m2e-core-42a58b2be70f958a1789099a45eadb00a558abf1.tar.xz
m2e-core-42a58b2be70f958a1789099a45eadb00a558abf1.zip
353266 preserve custom .classpath entries
Introduced new IClasspathEntryDescriptor pomDerived attribute. If false, the entry is preserved during project import and configuration update. Internally, pomDerived is implemented as IClasspathAttribute and thus is stored in .classpath file. All new classpath entries created through IClasspathDescriptor API are considered pomDerived by default and will be automatically removed from classpath during project configurtion update unless recreated. Clients of this API that prefer to manage stale classpath entry cleaup need to pomDerived to false explicitly. Signed-off-by: Igor Fedorenko <igor@ifedorenko.com>
-rw-r--r--org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/IClasspathEntryDescriptor.java28
-rw-r--r--org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/IClasspathManager.java6
-rw-r--r--org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/AbstractJavaProjectConfigurator.java15
-rw-r--r--org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/BuildPathManager.java4
-rw-r--r--org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/ClasspathDescriptor.java60
-rw-r--r--org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/ClasspathEntryDescriptor.java12
6 files changed, 105 insertions, 20 deletions
diff --git a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/IClasspathEntryDescriptor.java b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/IClasspathEntryDescriptor.java
index 0b797bf8..c3710db7 100644
--- a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/IClasspathEntryDescriptor.java
+++ b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/IClasspathEntryDescriptor.java
@@ -54,7 +54,7 @@ public interface IClasspathEntryDescriptor {
public void addInclusionPattern(IPath pattern);
public void setInclusionPatterns(IPath[] inclusionPatterns);
-
+
public IPath[] getInclusionPatterns();
public void addExclusionPattern(IPath pattern);
@@ -115,4 +115,30 @@ public interface IClasspathEntryDescriptor {
*/
public IClasspathEntry toClasspathEntry();
+ /**
+ * Returns <code>true</code> if this classpath entry was derived from pom.xml and <code>false</code> otherwise. <br/>
+ * Stale derived entries are automatically removed when workspace project configuration is synchronized with pom.xml.
+ *
+ * @see #setPomDerived(boolean)
+ * @since 1.1
+ */
+ public boolean isPomDerived();
+
+ /**
+ * Marks classpath entry as derived from pom.xml (<code>true</code>) or not (<code>false</code>).
+ * <p>
+ * Not-derived (or custom) entries are preserved during project configuration update, while derived entries are
+ * automatically removed whenever their corresponding pom.xml configuration is changed or removed.
+ * <p>
+ * All new classpath entries are marked as derived by default, however value of this flag is preserved when entry
+ * descriptor is read from .classpath file. The intend is to make sure that custom classpath entries are not removed
+ * automatically. Clients of IClasspathDescriptor API who prefer to manage cleanup of stale class classpath entries
+ * explicitly may set derived flag to <code>false</code>.
+ * <p>
+ * Although not enforced, derived flag only applies to project 'raw' classpath entries. The flag is silently ignored
+ * for classpath container entries.
+ *
+ * @since 1.1
+ */
+ public void setPomDerived(boolean derived);
}
diff --git a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/IClasspathManager.java b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/IClasspathManager.java
index 1f0d8df7..fd6062c0 100644
--- a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/IClasspathManager.java
+++ b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/IClasspathManager.java
@@ -55,6 +55,12 @@ public interface IClasspathManager {
public static final String SCOPE_ATTRIBUTE = "maven.scope"; //$NON-NLS-1$
/**
+ * @see IClasspathEntryDescriptor#setPomDerived(boolean)
+ * @since 1.1
+ */
+ public static final String POMDERIVED_ATTRIBUTE = "maven.pomderived"; //$NON-NLS-1$
+
+ /**
* Maven dependency resolution scope constant indicating test scope.
*/
public static final int CLASSPATH_TEST = 0;
diff --git a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/AbstractJavaProjectConfigurator.java b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/AbstractJavaProjectConfigurator.java
index d3d4a814..e642c5e8 100644
--- a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/AbstractJavaProjectConfigurator.java
+++ b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/AbstractJavaProjectConfigurator.java
@@ -340,13 +340,13 @@ public abstract class AbstractJavaProjectConfigurator extends AbstractProjectCon
for(String sourceRoot : sourceRoots) {
IFolder sourceFolder = getFolder(project, sourceRoot);
if(sourceFolder != null && sourceFolder.exists() && sourceFolder.getProject().equals(project)) {
- IClasspathEntryDescriptor cped = getEnclosingEntryDescriptor(classpath, sourceFolder.getFullPath());
- if(cped == null) {
+ IClasspathEntryDescriptor enclosing = getEnclosingEntryDescriptor(classpath, sourceFolder.getFullPath());
+ if(enclosing == null || getEntryDescriptor(classpath, sourceFolder.getFullPath()) != null) {
log.info("Adding source folder " + sourceFolder.getFullPath());
classpath.addSourceEntry(sourceFolder.getFullPath(), outputPath, inclusion, exclusion, false);
} else {
log.info("Not adding source folder " + sourceFolder.getFullPath() + " because it overlaps with "
- + cped.getPath());
+ + enclosing.getPath());
}
// Set folder encoding (null = platform/container default)
@@ -368,6 +368,15 @@ public abstract class AbstractJavaProjectConfigurator extends AbstractProjectCon
return null;
}
+ private IClasspathEntryDescriptor getEntryDescriptor(IClasspathDescriptor classpath, IPath fullPath) {
+ for(IClasspathEntryDescriptor cped : classpath.getEntryDescriptors()) {
+ if(cped.getPath().equals(fullPath)) {
+ return cped;
+ }
+ }
+ return null;
+ }
+
private void addResourceDirs(IClasspathDescriptor classpath, IProject project, List<Resource> resources,
IPath outputPath, String resourceEncoding, IProgressMonitor monitor) throws CoreException {
diff --git a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/BuildPathManager.java b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/BuildPathManager.java
index f3b51557..289dc19a 100644
--- a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/BuildPathManager.java
+++ b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/BuildPathManager.java
@@ -287,9 +287,7 @@ public class BuildPathManager implements IMavenProjectChangedListener, IResource
private IClasspathEntry[] getClasspath(IMavenProjectFacade projectFacade, final int kind,
final Properties sourceAttachment, boolean uniquePaths, final IProgressMonitor monitor) throws CoreException {
- IJavaProject javaProject = JavaCore.create(projectFacade.getProject());
-
- final ClasspathDescriptor classpath = new ClasspathDescriptor(javaProject);
+ final ClasspathDescriptor classpath = new ClasspathDescriptor(uniquePaths);
getDelegate(projectFacade, monitor).populateClasspath(classpath, projectFacade, kind, monitor);
diff --git a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/ClasspathDescriptor.java b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/ClasspathDescriptor.java
index 470a2c9d..c866cf06 100644
--- a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/ClasspathDescriptor.java
+++ b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/ClasspathDescriptor.java
@@ -13,13 +13,17 @@ package org.eclipse.m2e.jdt.internal;
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaModelException;
import org.apache.maven.artifact.Artifact;
@@ -40,7 +44,23 @@ public class ClasspathDescriptor implements IClasspathDescriptor {
private final ArrayList<IClasspathEntryDescriptor> entries = new ArrayList<IClasspathEntryDescriptor>();
- public ClasspathDescriptor(IJavaProject project) {
+ private final Map<IPath, IClasspathEntryDescriptor> staleEntries = new LinkedHashMap<IPath, IClasspathEntryDescriptor>();
+
+ private final boolean uniquePaths;
+
+ public ClasspathDescriptor(boolean uniquePaths) {
+ this.uniquePaths = uniquePaths;
+ }
+
+ public ClasspathDescriptor(IJavaProject javaProject) throws JavaModelException {
+ this(true);
+ for(IClasspathEntry cpe : javaProject.getRawClasspath()) {
+ if(!javaProject.getProject().getFullPath().equals(cpe.getPath())) {
+ ClasspathEntryDescriptor entry = new ClasspathEntryDescriptor(cpe);
+ entries.add(entry);
+ staleEntries.put(entry.getPath(), entry);
+ }
+ }
}
/**
@@ -78,6 +98,7 @@ public class ClasspathDescriptor implements IClasspathDescriptor {
while(iter.hasNext()) {
IClasspathEntryDescriptor descriptor = iter.next();
if(filter.accept(descriptor)) {
+ staleEntries.remove(descriptor.getPath());
result.add(descriptor);
iter.remove();
}
@@ -100,19 +121,21 @@ public class ClasspathDescriptor implements IClasspathDescriptor {
descriptor.setClasspathAttribute(IClasspathAttribute.OPTIONAL, "true"); //$NON-NLS-1$
}
- entries.add(descriptor);
+ addEntryDescriptor(descriptor);
return descriptor;
}
public IClasspathEntry[] getEntries() {
- IClasspathEntry[] result = new IClasspathEntry[entries.size()];
+ List<IClasspathEntry> result = new ArrayList<IClasspathEntry>();
- for(int i = 0; i < entries.size(); i++ ) {
- result[i] = entries.get(i).toClasspathEntry();
+ for(IClasspathEntryDescriptor entry : entries) {
+ if(!entry.isPomDerived() || !staleEntries.containsKey(entry.getPath())) {
+ result.add(entry.toClasspathEntry());
+ }
}
- return result;
+ return result.toArray(new IClasspathEntry[result.size()]);
}
public List<IClasspathEntryDescriptor> getEntryDescriptors() {
@@ -121,7 +144,7 @@ public class ClasspathDescriptor implements IClasspathDescriptor {
public ClasspathEntryDescriptor addEntry(IClasspathEntry cpe) {
ClasspathEntryDescriptor entry = new ClasspathEntryDescriptor(cpe);
- entries.add(entry);
+ addEntryDescriptor(entry);
return entry;
}
@@ -136,9 +159,7 @@ public class ClasspathDescriptor implements IClasspathDescriptor {
public ClasspathEntryDescriptor addProjectEntry(IPath entryPath) {
ClasspathEntryDescriptor entry = new ClasspathEntryDescriptor(IClasspathEntry.CPE_PROJECT, entryPath);
-
- entries.add(entry);
-
+ addEntryDescriptor(entry);
return entry;
}
@@ -159,9 +180,22 @@ public class ClasspathDescriptor implements IClasspathDescriptor {
public ClasspathEntryDescriptor addLibraryEntry(IPath entryPath) {
ClasspathEntryDescriptor entry = new ClasspathEntryDescriptor(IClasspathEntry.CPE_LIBRARY, entryPath);
-
- entries.add(entry);
-
+ addEntryDescriptor(entry);
return entry;
}
+
+ private void addEntryDescriptor(ClasspathEntryDescriptor descriptor) {
+ staleEntries.remove(descriptor.getPath());
+ descriptor.setPomDerived(true);
+ ListIterator<IClasspathEntryDescriptor> iter = entries.listIterator();
+ if(uniquePaths) {
+ while(iter.hasNext()) {
+ if(iter.next().getPath().equals(descriptor.getPath())) {
+ iter.set(descriptor);
+ return; // PAY ATTENTION to this early return. Ain't pretty, but works.
+ }
+ }
+ }
+ entries.add(descriptor);
+ }
}
diff --git a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/ClasspathEntryDescriptor.java b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/ClasspathEntryDescriptor.java
index 5673bcb7..ff33c691 100644
--- a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/ClasspathEntryDescriptor.java
+++ b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/ClasspathEntryDescriptor.java
@@ -315,4 +315,16 @@ public class ClasspathEntryDescriptor implements IClasspathEntryDescriptor {
public boolean combineAccessRules() {
return combineAccessRules;
}
+
+ public boolean isPomDerived() {
+ return Boolean.parseBoolean(attributes.get(IClasspathManager.POMDERIVED_ATTRIBUTE));
+ }
+
+ public void setPomDerived(boolean derived) {
+ if(derived) {
+ attributes.put(IClasspathManager.POMDERIVED_ATTRIBUTE, Boolean.toString(true));
+ } else {
+ attributes.remove(IClasspathManager.POMDERIVED_ATTRIBUTE);
+ }
+ }
}

Back to the top