Index: /Users/amuino/dev/workspaces/m2eclipse/org.maven.ide.eclipse/META-INF/MANIFEST.MF
===================================================================
--- /Users/amuino/dev/workspaces/m2eclipse/org.maven.ide.eclipse/META-INF/MANIFEST.MF (revision 250)
+++ /Users/amuino/dev/workspaces/m2eclipse/org.maven.ide.eclipse/META-INF/MANIFEST.MF (working copy)
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: Maven 2.0 integration
Bundle-SymbolicName: org.maven.ide.eclipse; singleton:=true
-Bundle-Version: 0.0.11.20070603-1200
+Bundle-Version: 0.0.11.20070731-0000
Bundle-Activator: org.maven.ide.eclipse.Maven2Plugin
Bundle-Vendor: maven.org
Bundle-Localization: plugin
Index: /Users/amuino/dev/workspaces/m2eclipse/org.maven.ide.eclipse/src/org/maven/ide/eclipse/embedder/BuildPathManager.java
===================================================================
--- /Users/amuino/dev/workspaces/m2eclipse/org.maven.ide.eclipse/src/org/maven/ide/eclipse/embedder/BuildPathManager.java (revision 250)
+++ /Users/amuino/dev/workspaces/m2eclipse/org.maven.ide.eclipse/src/org/maven/ide/eclipse/embedder/BuildPathManager.java (working copy)
@@ -58,8 +58,11 @@
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IProjectNature;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IBundleGroup;
+import org.eclipse.core.runtime.IBundleGroupProvider;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
@@ -64,6 +67,7 @@
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IClasspathAttribute;
@@ -85,7 +89,11 @@
import org.maven.ide.eclipse.preferences.Maven2PreferenceConstants;
import org.maven.ide.eclipse.util.Util;
-
+/**
+ * TODO: Document me
+ *
+ * @author amuino (MNGECLIPSE-105)
+ */
public class BuildPathManager {
private final MavenEmbedderManager embedderManager;
private final Maven2Console console;
@@ -92,6 +100,14 @@
private final MavenModelManager mavenModelManager;
private final MavenRepositoryIndexManager indexManager;
private final IPreferenceStore preferenceStore;
+
+ public static final String CLASSPATH_COMPONENT_NON_DEPENDENCY = "org.eclipse.jst.component.nondependency";
+ public static final String CLASSPATH_COMPONENT_DEPENDENCY = "org.eclipse.jst.component.dependency";
+
+ public static final String JST_IDENTIFER = "org.eclipse.jst";
+
+ public static final String PACKAGING_EAR = "ear";
+ public static final String PACKAGING_WAR = "war";
public BuildPathManager(MavenEmbedderManager embedderManager, Maven2Console console,
@@ -126,7 +142,8 @@
public void updateClasspathContainer(IProject project, boolean recursive, IProgressMonitor monitor) throws CoreException {
- IClasspathEntry containerEntry = getMavenContainerEntry(JavaCore.create(project));
+ IJavaProject javaProject = JavaCore.create(project);
+ IClasspathEntry containerEntry = getMavenContainerEntry(javaProject);
boolean resolveWorkspaceProjects = isResolvingWorkspaceProjects(containerEntry);
boolean includeModules = isIncludingModules(containerEntry);
@@ -151,9 +168,14 @@
Maven2ClasspathContainer container = new Maven2ClasspathContainer(containerEntry.getPath(), entries);
- JavaCore.setClasspathContainer(container.getPath(), new IJavaProject[] {JavaCore.create(project)},
+ JavaCore.setClasspathContainer(container.getPath(), new IJavaProject[] {javaProject},
new IClasspathContainer[] {container}, monitor);
+ String runtimePath = getRuntimePath(pomFile);
+ if (runtimePath != null) {
+ setWTPDependencyAttribute(javaProject, container, runtimePath);
+ }
+
for(Iterator it = dependentProjects.iterator(); it.hasNext();) {
IProject p = (IProject) it.next();
updateClasspathContainer(p, recursive, monitor);
@@ -180,7 +202,9 @@
boolean downloadSources = !offline & preferenceStore.getBoolean(Maven2PreferenceConstants.P_DOWNLOAD_SOURCES);
boolean downloadJavadoc = !offline & preferenceStore.getBoolean(Maven2PreferenceConstants.P_DOWNLOAD_JAVADOC);
boolean debug = preferenceStore.getBoolean(Maven2PreferenceConstants.P_DEBUG_OUTPUT);
-
+ // TODO: Should be done only once and when bundles are reinstalled
+ boolean wtpAvailable = isWTPAvailable();
+
MavenExecutionResult result = mavenModelManager.readMavenProject(pomFile, monitor, offline, debug, resolveWorkspaceProjects);
MavenProject mavenProject = getMavenProject(pomFile, result);
if(mavenProject == null) {
@@ -217,6 +241,7 @@
}
moduleArtifacts.put(artifactLocation, a);
+ List attributes = new ArrayList();
if(resolveWorkspaceProjects) {
mavenModelManager.addProjectArtifact(pomFile, a);
// this is needed to projects with have modules (either inner or external)
@@ -222,6 +247,14 @@
// this is needed to projects with have modules (either inner or external)
mavenModelManager.addProjectArtifact(rootPomFile, a);
+ // Check the scope & set WTP non-dependency as appropriate
+ String scope = a.getScope();
+ if (Artifact.SCOPE_PROVIDED.equals(scope)
+ || Artifact.SCOPE_TEST.equals(scope)
+ || Artifact.SCOPE_SYSTEM.equals(scope)) {
+ attributes.add(JavaCore.newClasspathAttribute(CLASSPATH_COMPONENT_NON_DEPENDENCY, ""));
+ }
+
IFile artifactPomFile = mavenModelManager.getArtifactFile(a);
if(artifactPomFile != null) {
IProject artifactProject = artifactPomFile.getProject();
@@ -230,6 +263,14 @@
// add our own project to ourself
continue;
}
+
+// if (wtpAvailable
+// && PACKAGING_WAR.equals(mavenProject.getPackaging())
+// && hasDynamicWebProjectNature(currentProject)) {
+// // Leave it out so that the user can handle it the WTP way
+// continue;
+// }
+
libraryEntries.add(JavaCore.newProjectEntry(artifactProject.getFullPath(), false));
continue;
@@ -238,7 +279,6 @@
Path srcPath = materializeArtifactPath(embedder, mavenProject, a, "java-source", "sources", downloadSources, monitor);
- ArrayList attributes = new ArrayList();
attributes.add(JavaCore.newClasspathAttribute(Maven2ClasspathContainer.GROUP_ID_ATTRIBUTE, a.getGroupId()));
attributes.add(JavaCore.newClasspathAttribute(Maven2ClasspathContainer.ARTIFACT_ID_ATTRIBUTE, a.getArtifactId()));
attributes.add(JavaCore.newClasspathAttribute(Maven2ClasspathContainer.VERSION_ATTRIBUTE, a.getVersion()));
@@ -302,7 +342,40 @@
}
}
-
+
+ // TODO work out how to listen for changes in the installed bundles and only run this then
+ private boolean isWTPAvailable() {
+ IBundleGroupProvider[] bundleGroupProviders = Platform.getBundleGroupProviders();
+ for(int i = 0; i < bundleGroupProviders.length; i++ ) {
+ IBundleGroupProvider bundleGroupProvider = bundleGroupProviders[i];
+ IBundleGroup[] bundleGroups = bundleGroupProvider.getBundleGroups();
+ for(int j = 0; j < bundleGroups.length; j++ ) {
+ IBundleGroup bundleGroup = bundleGroups[j];
+ if (JST_IDENTIFER.equals(bundleGroup.getIdentifier())) {
+ String version = bundleGroup.getVersion();
+ int majorVersion = Integer.parseInt(version.substring(0, version.indexOf('.')));
+ if (majorVersion >= 2) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean hasDynamicWebProjectNature(IProject project) {
+ try {
+ IProjectNature nature1 = project.getNature("org.eclipse.wst.common.modulecore.ModuleCoreNature");
+ IProjectNature nature2 = project.getNature("org.eclipse.wst.common.project.facet.core.nature");
+ if (nature1 != null && nature2 != null) {
+ return true;
+ }
+ } catch (Exception e) {
+ console.logError("Unable to inspect nature: " + e);
+ }
+ return false;
+ }
+
private MavenProject getMavenProject(IFile pomFile, MavenExecutionResult result) {
deleteMarkers(pomFile);
@@ -799,6 +872,100 @@
Maven2Plugin.log(ex);
}
}
+
+ /**
+ * Returns the path where this container dependencies will be located at runtime
+ * (like /WEB-INF/lib for war packaging).
+ * If the project packaging does not know about deployment, it will be null.
+ * @param pomFile
+ * @return the path to the runtime folder, or null.
+ */
+ private String getRuntimePath(IFile pomFile) {
+ Model model = mavenModelManager.getMavenModel(pomFile);
+ String packaging = model.getPackaging();
+ String runtimePath = null;
+ if (PACKAGING_WAR.equalsIgnoreCase(packaging)) {
+ runtimePath = "/WEB-INF/lib";
+ }
+ return runtimePath;
+ }
+
+ /**
+ * Updates the specified Java project so that the Maven Classpath Container has
+ * the WTP component dependency attribute.
+ * @param javaProject Target Java project.
+ * @param entries Classpath entries that should have the component dependency attribute. Map from IClasspathEntry
+ * to the IClasspathAttribute for the WTP classpath component dependency.
+ * @throws CoreException Thrown if an error is encountered.
+ */
+ private void setWTPDependencyAttribute(final IJavaProject javaProject, IClasspathContainer container, String runtimePath) throws CoreException {
+ if (javaProject == null || !javaProject.getProject().isAccessible()) {
+ return;
+ }
+ final List updatedClasspath = new ArrayList();
+ final IClasspathEntry[] rawClasspath = javaProject.getRawClasspath();
+ boolean found = false;
+ for (int i = 0; i < rawClasspath.length; i++) {
+ IClasspathEntry entry = rawClasspath[i];
+ if (found == false && entry.getPath().equals(container.getPath())) {
+ found = true;
+ if (hasComponentDependencyAttribute(entry)) {
+ // No work to do
+ return;
+ }
+ // should have the attribute and currently missing it
+ IClasspathAttribute attrib = JavaCore.newClasspathAttribute(CLASSPATH_COMPONENT_DEPENDENCY, runtimePath);
+ IClasspathAttribute[] updatedAttributes = updateAttributes(entry.getExtraAttributes(), attrib, true);
+ entry = JavaCore.newContainerEntry(entry.getPath(), entry.getAccessRules(), updatedAttributes, entry.isExported());
+ }
+
+ updatedClasspath.add(entry);
+ }
+ final IClasspathEntry[] updatedCPArray = (IClasspathEntry[]) updatedClasspath.toArray(new IClasspathEntry[updatedClasspath.size()]);
+ javaProject.setRawClasspath(updatedCPArray, null);
+ }
+
+ private IClasspathAttribute[] updateAttributes(final IClasspathAttribute[] currentAttribs, final IClasspathAttribute targetAttrib, final boolean add) {
+ final List updatedAttribs = new ArrayList();
+ boolean hasAttrib = false;
+ for (int i = 0; i < currentAttribs.length; i++) {
+ if (currentAttribs[i].getName().equals(targetAttrib.getName())) {
+ hasAttrib = true;
+ if (!add) {
+ continue;
+ }
+ }
+ updatedAttribs.add(currentAttribs[i]);
+ }
+ if (add && !hasAttrib) {
+ updatedAttribs.add(targetAttrib);
+ }
+ return (IClasspathAttribute[]) updatedAttribs.toArray(new IClasspathAttribute[updatedAttribs.size()]);
+ }
+
+ /**
+ * Checks if the specified IClasspathEntry has one of the special WTP component dependency
+ * attribute (org.eclipse.jst.component.dependency) that indicates it should be mapped into the virtual component for the associated project.
+ *
+ * @param entry The IClasspathEntry.
+ * @return true if the classpath entry will be mapped, false if it lacks the attribute.
+ */
+ private static boolean hasComponentDependencyAttribute(final IClasspathEntry entry) {
+ if (entry == null) {
+ throw new IllegalArgumentException("Parameter 'entry' can't be null");
+ }
+ final IClasspathAttribute[] attributes = entry.getExtraAttributes();
+ for (int i = 0; i < attributes.length; i++) {
+ final IClasspathAttribute attribute = attributes[i];
+ if (CLASSPATH_COMPONENT_DEPENDENCY.equals(attribute.getName())) {
+ // Attribute found
+ return true;
+ }
+ }
+ // Attribute not found
+ return false;
+ }
+
public static boolean isMaven2ClasspathContainer( IPath containerPath) {
return containerPath!=null && containerPath.segmentCount()>0