merged in patch from meclipse-213
git-svn-id: https://svn.apache.org/repos/asf/maven/plugins/trunk/maven-eclipse-plugin@574764 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/maven/plugin/eclipse/EclipsePlugin.java b/src/main/java/org/apache/maven/plugin/eclipse/EclipsePlugin.java
index 2bb5e82..2f1fa3a 100644
--- a/src/main/java/org/apache/maven/plugin/eclipse/EclipsePlugin.java
+++ b/src/main/java/org/apache/maven/plugin/eclipse/EclipsePlugin.java
@@ -31,14 +31,17 @@
import java.util.Set;
import java.util.TreeSet;
+import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.eclipse.writers.EclipseClasspathWriter;
+import org.apache.maven.plugin.eclipse.writers.EclipseManifestWriter;
import org.apache.maven.plugin.eclipse.writers.EclipseOSGiManifestWriter;
import org.apache.maven.plugin.eclipse.writers.EclipseProjectWriter;
import org.apache.maven.plugin.eclipse.writers.EclipseSettingsWriter;
import org.apache.maven.plugin.eclipse.writers.EclipseWriterConfig;
+import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpApplicationXMLWriter;
import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpComponent15Writer;
import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpComponentWriter;
import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpFacetsWriter;
@@ -354,6 +357,20 @@
*/
private boolean isJavaProject;
+ /**
+ * Must the manifest files be written for java projects so that that the jee classpath for wtp is correct.
+ *
+ * @parameter expression="${eclipse.wtpmanifest}" default-value="false"
+ */
+ private boolean wtpmanifest;
+
+ /**
+ * Must the application files be written for ear projects in a separate directory.
+ *
+ * @parameter expression="${eclipse.wtpapplicationxml}" default-value="false"
+ */
+ private boolean wtpapplicationxml;
+
protected boolean isJavaProject()
{
return isJavaProject;
@@ -776,6 +793,10 @@
{
EclipseWriterConfig config = createEclipseWriterConfig( deps );
+ if (wtpmanifest && isJavaProject())
+ {
+ EclipseManifestWriter.addManifestResource(getLog(), config);
+ }
// NOTE: This could change the config!
writeExtraConfiguration( config );
@@ -803,7 +824,12 @@
{
new EclipseClasspathWriter().init( getLog(), config ).write();
}
-
+
+ if (wtpapplicationxml)
+ {
+ new EclipseWtpApplicationXMLWriter().init(getLog(), config).write();
+ }
+
if ( pde )
{
this.getLog().info( "The Maven Eclipse plugin runs in 'pde'-mode." );
@@ -862,6 +888,8 @@
String projectName = IdeUtils.getProjectName( config.getProjectNameTemplate(), project );
config.setEclipseProjectName( projectName );
+
+ config.setWtpapplicationxml(wtpapplicationxml);
Set convertedBuildCommands = new LinkedHashSet();
@@ -1162,4 +1190,11 @@
}
return IdeUtils.PROJECT_NAME_DEFAULT_TEMPLATE;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getProjectNameForArifact(Artifact artifact) {
+ return IdeUtils.getProjectName(calculateProjectNameTemplate(), artifact);
+ }
}
diff --git a/src/main/java/org/apache/maven/plugin/eclipse/writers/EclipseManifestWriter.java b/src/main/java/org/apache/maven/plugin/eclipse/writers/EclipseManifestWriter.java
new file mode 100644
index 0000000..0e73841
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugin/eclipse/writers/EclipseManifestWriter.java
@@ -0,0 +1,393 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
+ * or agreed to in writing, software distributed under the License is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package org.apache.maven.plugin.eclipse.writers;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.apache.maven.archiver.ManifestConfiguration;
+import org.apache.maven.archiver.MavenArchiver;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.eclipse.Constants;
+import org.apache.maven.plugin.eclipse.EclipseSourceDir;
+import org.apache.maven.plugin.eclipse.Messages;
+import org.apache.maven.plugin.eclipse.writers.wtp.AbstractWtpResourceWriter;
+import org.apache.maven.plugin.ide.IdeDependency;
+import org.apache.maven.plugin.ide.IdeUtils;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Create or adapt the manifest files for the RAD6 runtime dependencys.
+ * attention these will not be used for the real ear these are just to get the
+ * runtime enviorment using the maven dependencies. WARNING: The manifest
+ * resources added here will not have the benefit of the dependencies of the
+ * project, since that's not provided in the setup() apis, one of the locations
+ * from which this writer is used in the RadPlugin.
+ *
+ * @author <a href="mailto:nir@cfc.at">Richard van Nieuwenhoven </a>
+ */
+public class EclipseManifestWriter extends AbstractEclipseWriter {
+
+ private static final String MANIFEST_MF_FILENAME = "MANIFEST.MF";
+
+ private static final String META_INF_DIRECTORY = "META-INF";
+
+ private static final String GENERATED_RESOURCE_DIRNAME = "target" + File.separatorChar + "generated-resources" + File.separatorChar + "eclipse";
+
+ private static final String WEBAPP_RESOURCE_DIR = "src" + File.separatorChar + "main" + File.separatorChar + "webapp";
+
+ /**
+ * Search the project for the existing META-INF directory where the manifest
+ * should be located.
+ *
+ * @return the apsolute path to the META-INF directory
+ */
+ public String getMetaInfBaseDirectory(MavenProject project) {
+ String metaInfBaseDirectory = null;
+
+ if (this.config.getProject().getPackaging().equals(Constants.PROJECT_PACKAGING_WAR)) {
+ metaInfBaseDirectory = this.config.getProject().getBasedir().getAbsolutePath() + File.separatorChar + EclipseManifestWriter.WEBAPP_RESOURCE_DIR;
+
+ this.log.debug("Attempting to use: " + metaInfBaseDirectory + " for location of META-INF in war project.");
+
+ File metaInfDirectoryFile = new File(metaInfBaseDirectory + File.separatorChar + EclipseManifestWriter.META_INF_DIRECTORY);
+
+ if (metaInfDirectoryFile.exists() && !metaInfDirectoryFile.isDirectory()) {
+ metaInfBaseDirectory = null;
+ }
+ }
+
+ for (int index = this.config.getSourceDirs().length - 1; metaInfBaseDirectory == null && index >= 0; index--) {
+
+ File manifestFile =
+ new File(this.config.getEclipseProjectDirectory(), this.config.getSourceDirs()[index].getPath() + File.separatorChar + EclipseManifestWriter.META_INF_DIRECTORY + File.separatorChar
+ + EclipseManifestWriter.MANIFEST_MF_FILENAME);
+
+ this.log.debug("Checking for existence of META-INF/MANIFEST.MF file: " + manifestFile);
+
+ if (manifestFile.exists()) {
+ metaInfBaseDirectory = manifestFile.getParentFile().getParent();
+ }
+ }
+
+ return metaInfBaseDirectory;
+ }
+
+ /**
+ * Write the manifest files use an existing one it it exists (it will be
+ * overwritten!! in a war use webapp/META-INF else use the generated rad6
+ * sourcefolder
+ *
+ * @see AbstractWtpResourceWriter#write(EclipseSourceDir[],
+ * ArtifactRepository, File)
+ * @param sourceDirs
+ * all eclipse source directorys
+ * @param localRepository
+ * the local reposetory
+ * @param buildOutputDirectory
+ * build output directory (target)
+ * @throws MojoExecutionException
+ * when writing the config files was not possible
+ */
+ public void write() throws MojoExecutionException {
+ String metaInfBaseDirectory = getMetaInfBaseDirectory(this.config.getProject());
+
+ if (metaInfBaseDirectory == null) {
+ // TODO: if this really is an error, shouldn't we stop the build??
+ throw new MojoExecutionException(Messages.getString("EclipseCleanMojo.nofilefound", new Object[]{
+ EclipseManifestWriter.META_INF_DIRECTORY
+ }));
+ }
+// if (this.config.getEclipseProjectName().equals(IdeUtils.getProjectName(IdeUtils.PROJECT_NAME_WITH_VERSION_TEMPLATE, this.config.getProject()))) {
+// MavenArchiver mavenArchiver = new MavenArchiver();
+// ManifestConfiguration configuration = new ManifestConfiguration() {
+//
+// public boolean isAddClasspath() {
+// return true;
+// }
+// };
+//
+// File manifestFile = new File(metaInfBaseDirectory + File.separatorChar + EclipseManifestWriter.META_INF_DIRECTORY + File.separatorChar + EclipseManifestWriter.MANIFEST_MF_FILENAME);
+// manifestFile.getParentFile().mkdirs();
+//
+// try {
+// PrintWriter printwriter = new PrintWriter(manifestFile);
+// mavenArchiver.getManifest(this.config.getProject(), configuration).write(printwriter);
+// printwriter.close();
+// } catch (Exception e) {
+// this.log.error(Messages.getString("EclipsePlugin.cantwritetofile", new Object[]{
+// metaInfBaseDirectory + File.separatorChar + EclipseManifestWriter.MANIFEST_MF_FILENAME
+// }));
+// }
+// } else {
+ Manifest manifest = createNewManifest();
+
+ File manifestFile = new File(metaInfBaseDirectory + File.separatorChar + EclipseManifestWriter.META_INF_DIRECTORY + File.separatorChar + EclipseManifestWriter.MANIFEST_MF_FILENAME);
+
+ System.out.println("MANIFEST LOCATION: " + manifestFile);
+
+ if (shouldNewManifestFileBeWritten(manifest, manifestFile)) {
+ System.out.println("Writing manifest...");
+
+ manifestFile.getParentFile().mkdirs();
+
+ try {
+ FileOutputStream stream = new FileOutputStream(manifestFile);
+
+ manifest.write(stream);
+
+ stream.close();
+
+ } catch (Exception e) {
+ this.log.error(Messages.getString("EclipsePlugin.cantwritetofile", new Object[]{
+ metaInfBaseDirectory + File.separatorChar + EclipseManifestWriter.MANIFEST_MF_FILENAME
+ }));
+ }
+
+// }
+ }
+ }
+
+ /**
+ * make room for a Manifest file. use a generated resource for JARS and for
+ * WARS use the manifest in the webapp/META-INF directory.
+ *
+ * @throws MojoExecutionException
+ */
+ public static void addManifestResource(Log log, EclipseWriterConfig config) throws MojoExecutionException {
+
+ EclipseManifestWriter manifestWriter = new EclipseManifestWriter();
+ manifestWriter.init(log, config);
+
+ String packaging = config.getProject().getPackaging();
+
+ String manifestDirectory = manifestWriter.getMetaInfBaseDirectory(config.getProject());
+
+
+ if (!Constants.PROJECT_PACKAGING_EAR.equals(packaging) && !Constants.PROJECT_PACKAGING_WAR.equals(packaging) && manifestDirectory == null) {
+
+ String generatedResourceDir = config.getProject().getBasedir().getAbsolutePath() + File.separatorChar + EclipseManifestWriter.GENERATED_RESOURCE_DIRNAME;
+
+ manifestDirectory = generatedResourceDir + File.separatorChar + "META-INF";
+
+ try {
+ new File(manifestDirectory).mkdirs();
+ File manifestFile = new File(manifestDirectory + File.separatorChar + "MANIFEST.MF");
+ if (manifestFile.exists()) {
+ manifestFile.delete();
+ }
+ manifestFile.createNewFile();
+ } catch (IOException e) {
+ log.error(Messages.getString("EclipsePlugin.cantwritetofile", new Object[]{
+ manifestDirectory + File.separatorChar + "META-INF" + File.separatorChar + "MANIFEST.MF"
+ }));
+ }
+
+ log.debug("Adding " + EclipseManifestWriter.GENERATED_RESOURCE_DIRNAME + " to eclipse sources ");
+
+ EclipseSourceDir[] sourceDirs = config.getSourceDirs();
+ EclipseSourceDir[] newSourceDirs = new EclipseSourceDir[sourceDirs.length + 1];
+ System.arraycopy(sourceDirs, 0, newSourceDirs, 0, sourceDirs.length);
+ newSourceDirs[sourceDirs.length] = new EclipseSourceDir(EclipseManifestWriter.GENERATED_RESOURCE_DIRNAME, null, true, false, null, null, false);
+ config.setSourceDirs(newSourceDirs);
+ }
+
+ if (Constants.PROJECT_PACKAGING_WAR.equals(packaging)) {
+ new File(config.getProject().getBasedir().getAbsolutePath() + File.separatorChar + "src" + File.separatorChar + "main" + File.separatorChar + "webapp"
+ + File.separatorChar + "META-INF").mkdirs();
+ }
+
+ // special case must be done first because it can add stuff to the
+ // classpath that will be
+ // written by the superclass
+ manifestWriter.write();
+ }
+
+ /**
+ * Add one dependency to the black separated classpath stringbuffer. When
+ * the project is available in the reactor (current build) then the project
+ * is used else the jar representing the artifact. System dependencies will
+ * only be included if they are in this project.
+ *
+ * @param classpath
+ * existing classpath to append
+ * @param dependency
+ * dependency to append as jar or as project
+ */
+ private void addDependencyToClassPath(StringBuffer classpath, IdeDependency dependency) {
+ if (!dependency.isTestDependency() && !dependency.isProvided() && !dependency.isSystemScopedOutsideProject(this.config.getProject())) {
+
+ // blank is the separator in manifest classpath's
+ if (classpath.length() != 0) {
+ classpath.append(' ');
+ }
+ // if the dependency is a workspace project add the project and not
+ // the jar
+ if (!dependency.isReferencedProject()) {
+ classpath.append(dependency.getFile().getName());
+ } else {
+ classpath.append(dependency.getEclipseProjectName() + ".jar");
+ }
+ }
+ }
+
+ /**
+ * Check if the two manifests are equal. Manifest.equal can not be used
+ * because of the special case the Classpath entr, witch must be comaired
+ * sorted so that a different oder in the classpath does not result in "not
+ * equal". This not not realy correct but in this case it is more important
+ * to reduce the number of version-controll files.
+ *
+ * @param manifest
+ * the new manifest
+ * @param existingManifest
+ * to compaire the new one with
+ * @return are the manifests equal
+ */
+ private boolean areManifestsEqual(Manifest manifest, Manifest existingManifest) {
+ if (existingManifest == null) {
+ return false;
+ }
+
+ Set keys = new HashSet();
+ Attributes existingMap = existingManifest.getMainAttributes();
+ Attributes newMap = manifest.getMainAttributes();
+ keys.addAll(existingMap.keySet());
+ keys.addAll(newMap.keySet());
+ Iterator iterator = keys.iterator();
+ while (iterator.hasNext()) {
+ Attributes.Name key = (Attributes.Name) iterator.next();
+ String newValue = (String) newMap.get(key);
+ String existingValue = (String) existingMap.get(key);
+ // special case classpath... they are qual when there entries
+ // are equal
+ if (Attributes.Name.CLASS_PATH.equals(key)) {
+ newValue = orderClasspath(newValue);
+ existingValue = orderClasspath(existingValue);
+ }
+ if ((newValue == null || !newValue.equals(existingValue)) && (existingValue == null || !existingValue.equals(newValue))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Convert all dependencies in a blank seperated list of jars and projects
+ * representing the classpath.
+ *
+ * @return the blank separeted classpath string
+ */
+ private String constructManifestClasspath() {
+ StringBuffer stringBuffer = new StringBuffer();
+ IdeDependency[] deps = this.config.getDeps();
+
+ for (int index = 0; index < deps.length; index++) {
+ addDependencyToClassPath(stringBuffer, deps[index]);
+ }
+
+ return stringBuffer.toString();
+ }
+
+ /**
+ * Create a manifest contaigning the required classpath.
+ *
+ * @return the newly created manifest
+ */
+ private Manifest createNewManifest() {
+ Manifest manifest = new Manifest();
+ manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
+ manifest.getMainAttributes().put(Attributes.Name.CLASS_PATH, constructManifestClasspath());
+ return manifest;
+ }
+
+ /**
+ * Aphabeticaly sort the classpath. Do this by splitting it up, sort the
+ * entries and gleue them together again.
+ *
+ * @param newValue
+ * classpath to sort
+ * @return the sorted classpath
+ */
+ private String orderClasspath(String newValue) {
+ if (newValue == null) {
+ return null;
+ }
+ String[] entries = newValue.split(" ");
+ Arrays.sort(entries);
+ StringBuffer buffer = new StringBuffer(newValue.length());
+ for (int index = 0; index < entries.length; index++) {
+ buffer.append(entries[index]);
+ buffer.append(' ');
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * Read and parse the existing manifest file.
+ *
+ * @param manifestFile
+ * file
+ * @return the read manifest
+ * @throws IOException
+ * if the file could not be read
+ */
+ private Manifest readExistingManifest(File manifestFile) throws IOException {
+ if (!manifestFile.exists()) {
+ return null;
+ }
+
+ Manifest existingManifest = new Manifest();
+ FileInputStream inputStream = new FileInputStream(manifestFile);
+ existingManifest.read(inputStream);
+ inputStream.close();
+ return existingManifest;
+ }
+
+ /**
+ * Verify is the manifest sould be overwritten this sould take in account
+ * that the manifest should only be written if the contents of the classpath
+ * was changed not the order. The classpath sorting oder should be ignored.
+ *
+ * @param manifest
+ * the newly created classpath
+ * @param manifestFile
+ * the file where the manifest
+ * @return if the new manifest file must be written
+ * @throws MojoExecutionException
+ */
+ private boolean shouldNewManifestFileBeWritten(Manifest manifest, File manifestFile) throws MojoExecutionException {
+ try {
+ Manifest existingManifest = readExistingManifest(manifestFile);
+ if (areManifestsEqual(manifest, existingManifest)) {
+ this.log.info(Messages.getString("EclipseCleanMojo.unchanged", manifestFile.getAbsolutePath()));
+ return false;
+ }
+ } catch (Exception e) {
+ throw new MojoExecutionException(Messages.getString("EclipseCleanMojo.nofilefound", manifestFile.getAbsolutePath()), e);
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/org/apache/maven/plugin/eclipse/writers/EclipseWriterConfig.java b/src/main/java/org/apache/maven/plugin/eclipse/writers/EclipseWriterConfig.java
index 1db9438..8784811 100644
--- a/src/main/java/org/apache/maven/plugin/eclipse/writers/EclipseWriterConfig.java
+++ b/src/main/java/org/apache/maven/plugin/eclipse/writers/EclipseWriterConfig.java
@@ -123,6 +123,10 @@
private String contextName;
+ /**
+ * @see EclipsePlugin#wtpapplicationxml()
+ */
+ private boolean wtpapplicationxml;
/**
* Getter for <code>deps</code>.
@@ -416,4 +420,13 @@
this.contextName = deployName;
}
+ public boolean getWtpapplicationxml()
+ {
+ return this.wtpapplicationxml;
+ }
+
+ public void setWtpapplicationxml( boolean wtpapplicationxml )
+ {
+ this.wtpapplicationxml = wtpapplicationxml;
+ }
}
diff --git a/src/main/java/org/apache/maven/plugin/eclipse/writers/wtp/AbstractWtpResourceWriter.java b/src/main/java/org/apache/maven/plugin/eclipse/writers/wtp/AbstractWtpResourceWriter.java
index cced0fa..1034a3e 100644
--- a/src/main/java/org/apache/maven/plugin/eclipse/writers/wtp/AbstractWtpResourceWriter.java
+++ b/src/main/java/org/apache/maven/plugin/eclipse/writers/wtp/AbstractWtpResourceWriter.java
@@ -19,6 +19,7 @@
package org.apache.maven.plugin.eclipse.writers.wtp;
import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.eclipse.Messages;
import org.apache.maven.plugin.eclipse.writers.AbstractEclipseWriter;
@@ -27,8 +28,11 @@
import org.apache.maven.plugin.ide.JeeUtils;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.xml.XMLWriter;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
import java.io.File;
+import java.util.Iterator;
+import java.util.List;
/**
* Base class to hold common constants used by extending classes.
@@ -149,7 +153,7 @@
* @param basedir
* @throws MojoExecutionException
*/
- protected void addDependency( XMLWriter writer, IdeDependency dep, ArtifactRepository localRepository, File basedir )
+ protected void addDependency( XMLWriter writer, IdeDependency dep, ArtifactRepository localRepository, File basedir, String deployPath )
throws MojoExecutionException
{
String handle;
@@ -161,7 +165,7 @@
// <dependency-type>uses</dependency-type>
// </dependent-module>
- handle = "module:/resource/" + dep.getArtifactId() + "/" + dep.getArtifactId(); //$NON-NLS-1$ //$NON-NLS-2$
+ handle = "module:/resource/" + dep.getEclipseProjectName() + "/" + dep.getEclipseProjectName(); //$NON-NLS-1$ //$NON-NLS-2$
}
else
{
@@ -199,7 +203,9 @@
writer.startElement( ELT_DEPENDENT_MODULE );
- writer.addAttribute( ATTR_DEPLOY_PATH, "/WEB-INF/lib" ); //$NON-NLS-1$
+ writer.addAttribute( "archiveName",dep.getEclipseProjectName()+"."+dep.getType());
+
+ writer.addAttribute( ATTR_DEPLOY_PATH, deployPath ); //$NON-NLS-1$
writer.addAttribute( ATTR_HANDLE, handle );
writer.startElement( ELT_DEPENDENCY_TYPE );
@@ -212,7 +218,15 @@
protected void writeWarOrEarResources( XMLWriter writer, MavenProject project, ArtifactRepository localRepository )
throws MojoExecutionException
{
-
+ // use /WEB-INF/lib for war projects and / or the configured defaultLibBundleDir for ear projects
+ String deployDir = IdeUtils.getPluginSetting( config.getProject(), ARTIFACT_MAVEN_EAR_PLUGIN,
+ "defaultLibBundleDir",
+ "/" );
+
+ if (project.getPackaging().equals("war"))
+ {
+ deployDir = "/WEB-INF/lib";
+ }
// dependencies
for ( int j = 0; j < config.getDeps().length; j++ )
{
@@ -220,11 +234,11 @@
String type = dep.getType();
// NB war is needed for ear projects, we suppose nobody adds a war dependency to a war/jar project
- // exclude test and provided deps
- if ( ( !dep.isTestDependency() && !dep.isProvided() )
+ // exclude test and provided and system dependencies outside the project
+ if ( ( !dep.isTestDependency() && !dep.isProvided() && !dep.isSystemScopedOutsideProject(project))
&& ( "jar".equals( type ) || "ejb".equals( type ) || "ejb-client".equals( type ) || "war".equals( type ) ) ) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
{
- addDependency( writer, dep, localRepository, config.getProject().getBasedir() );
+ addDependency( writer, dep, localRepository, config.getProject().getBasedir(), deployDir );
}
}
}
diff --git a/src/main/java/org/apache/maven/plugin/eclipse/writers/wtp/EclipseWtpApplicationXMLWriter.java b/src/main/java/org/apache/maven/plugin/eclipse/writers/wtp/EclipseWtpApplicationXMLWriter.java
new file mode 100644
index 0000000..b883cb4
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugin/eclipse/writers/wtp/EclipseWtpApplicationXMLWriter.java
@@ -0,0 +1,514 @@
+package org.apache.maven.plugin.eclipse.writers.wtp;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.eclipse.EclipseSourceDir;
+import org.apache.maven.plugin.ide.IdeDependency;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
+import org.codehaus.plexus.util.xml.XMLWriter;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
+import org.codehaus.plexus.util.xml.Xpp3DomWriter;
+
+/**
+ * This writer creates the application.xml and the .modulemaps files for RAD6
+ * the the META-INF directory in the project root. this is where RAD6 requires
+ * the files to be. These will be independent of the real application.xml witch
+ * will be generated the stad. maven way.
+ *
+ * @author <a href="mailto:nir@cfc.at">Richard van Nieuwenhoven</a>
+ */
+public class EclipseWtpApplicationXMLWriter extends AbstractWtpResourceWriter {
+ private static final String APPLICATION_XML_APPLICATION = "application";
+
+ private static final String APPLICATION_XML_CONTEXT_ROOT = "context-root";
+
+ private static final String APPLICATION_XML_DESCRIPTION = "description";
+
+ private static final String APPLICATION_XML_DISPLAY_NAME = "display-name";
+
+ private static final String APPLICATION_XML_FILENAME = "application.xml";
+
+ private static final String APPLICATION_XML_MODULE = "module";
+
+ private static final String APPLICATION_XML_WEB = "web";
+
+ private static final String APPLICATION_XML_WEB_URI = "web-uri";
+
+ private static final String HREF = "href";
+
+ private static final String ID = "id";
+
+ private static final String MODULEMAP_EARPROJECT_MAP = "modulemap:EARProjectMap";
+
+ private static final String MODULEMAPS_APPLICATION_EJB_MODULE = "application:EjbModule";
+
+ private static final String MODULEMAPS_APPLICATION_WEB_MODULE = "application:WebModule";
+
+ private static final String MODULEMAPS_FILENAME = ".modulemaps";
+
+ private static final String MODULEMAPS_MAPPINGS = "mappings";
+
+ private static final String MODULEMAPS_PROJECT_NAME = "projectName";
+
+ private static final String MODULEMAPS_UTILITY_JARMAPPINGS = "utilityJARMappings";
+
+ private static final String URI = "uri";
+
+ private static final String VERSION = "version";
+
+ private static final String XMI_ID = "xmi:id";
+
+ private static final String XMI_TYPE = "xmi:type";
+
+ private static final String XMI_VERSION = "xmi:version";
+
+ private static final String XMLNS = "xmlns";
+
+ private static final String XMLNS_APPLICATION = "xmlns:application";
+
+ private static final String XMLNS_MODULEMAP = "xmlns:modulemap";
+
+ private static final String XMLNS_SCHEMA_LOCATION = "xmlns:schemaLocation";
+
+ private static final String XMLNS_XMI = "xmlns:xmi";
+
+ private static final String XMLNS_XSI = "xmlns:xsi";
+
+ private Xpp3Dom[] applicationXmlDomChildren;
+
+ private Xpp3Dom[] modulemapsXmlDomChildren;
+
+ private Xpp3Dom[] webModulesFromPoms;
+
+ /**
+ * write the application.xml and the .modulemaps file to the META-INF
+ * directory.
+ *
+ * @see AbstractWtpResourceWriter#write(EclipseSourceDir[],
+ * ArtifactRepository, File)
+ * @throws MojoExecutionException
+ * when writing the config files was not possible
+ */
+ public void write() throws MojoExecutionException {
+ String packaging = this.config.getProject().getPackaging();
+ if ("ear".equalsIgnoreCase(packaging)) {
+ File applicationXmlFile = new File(this.config.getEclipseProjectDirectory(), "target" + File.separator + "eclipseEar" + File.separator + "META-INF" + File.separator
+ + EclipseWtpApplicationXMLWriter.APPLICATION_XML_FILENAME);
+ // create the directory structiure for eclipse deployment
+ applicationXmlFile.getParentFile().mkdirs();
+ // copy all deployment files to the eclipse deployment
+ copyApplicationFiles();
+ // delete any existing application.xml so that it will be
+ // overwritten.
+ applicationXmlFile.delete();
+
+ Xpp3Dom applicationXmlDom = readXMLFile(applicationXmlFile);
+ if (applicationXmlDom == null) {
+ applicationXmlDom = createNewApplicationXml();
+ }
+ this.applicationXmlDomChildren = applicationXmlDom.getChildren(EclipseWtpApplicationXMLWriter.APPLICATION_XML_MODULE);
+
+ File modulemapsXmlFile = new File(this.config.getEclipseProjectDirectory(), "target" + File.separator + "eclipseEar" + File.separator + "META-INF" + File.separator
+ + EclipseWtpApplicationXMLWriter.MODULEMAPS_FILENAME);
+ Xpp3Dom modulemapsXmlDom = readXMLFile(modulemapsXmlFile);
+ if (modulemapsXmlDom == null) {
+ modulemapsXmlDom = createNewModulemaps();
+ }
+ this.modulemapsXmlDomChildren = modulemapsXmlDom.getChildren();
+
+ this.webModulesFromPoms = ((Xpp3Dom) ((org.apache.maven.model.Plugin) this.config.getProject().getBuild().getPluginsAsMap().get("org.apache.maven.plugins:maven-ear-plugin"))
+ .getConfiguration()).getChild("modules").getChildren("webModule");
+
+ IdeDependency[] deps = this.config.getDeps();
+ for (int index = 0; index < deps.length; index++) {
+ updateApplicationXml(applicationXmlDom, modulemapsXmlDom, deps[index]);
+ }
+
+ removeUnusedEntries(applicationXmlDom, modulemapsXmlDom);
+
+ writePrettyXmlFile(applicationXmlFile, applicationXmlDom);
+ writePrettyXmlFile(modulemapsXmlFile, modulemapsXmlDom);
+ }
+ }
+
+ /**
+ * Copy all files from application directory to the target eclipseEar
+ * directory.
+ *
+ * @throws MojoExecutionException
+ * wenn an error occures during file copieing
+ */
+ private void copyApplicationFiles() throws MojoExecutionException {
+ try {
+ File applicationDirectory = new File(this.config.getEclipseProjectDirectory(), "src" + File.separator + "main" + File.separator + "application");
+ File eclipseApplicationDirectory = new File(this.config.getEclipseProjectDirectory(), "target" + File.separator + "eclipseEar");
+ copyDirectoryStructure(applicationDirectory, eclipseApplicationDirectory);
+ } catch (IOException e) {
+ throw new MojoExecutionException("could not copy files the the eclipseEar directory", e);
+ }
+ }
+
+ /**
+ * Copies a entire directory structure without scm files.
+ *
+ * Note:
+ * <ul>
+ * <li>It will include empty directories.
+ * <li>The <code>sourceDirectory</code> must exists.
+ * </ul>
+ *
+ * @param sourceDirectory
+ * @param destinationDirectory
+ * @throws IOException
+ */
+ public static void copyDirectoryStructure(File sourceDirectory, File destinationDirectory) throws IOException {
+ if (!sourceDirectory.exists()) {
+ return;
+ }
+
+ File[] files = sourceDirectory.listFiles();
+
+ String sourcePath = sourceDirectory.getAbsolutePath();
+
+ for (int i = 0; i < files.length; i++) {
+ File file = files[i];
+
+ String dest = file.getAbsolutePath();
+
+ dest = dest.substring(sourcePath.length() + 1);
+
+ File destination = new File(destinationDirectory, dest);
+
+ if (file.isFile()) {
+ destination = destination.getParentFile();
+
+ FileUtils.copyFileToDirectory(file, destination);
+ } else if (file.isDirectory() && !file.getName().equals(".svn") && !file.getName().equals("CVS")) {
+ if (!destination.exists() && !destination.mkdirs()) {
+ throw new IOException("Could not create destination directory '" + destination.getAbsolutePath() + "'.");
+ }
+
+ copyDirectoryStructure(file, destination);
+ }
+ }
+ }
+
+ /**
+ * there is no existing application.xml file so create a new one.
+ *
+ * @return the domtree representing the contents of application.xml
+ */
+ private Xpp3Dom createNewApplicationXml() {
+ Xpp3Dom result = new Xpp3Dom(EclipseWtpApplicationXMLWriter.APPLICATION_XML_APPLICATION);
+ result.setAttribute(EclipseWtpApplicationXMLWriter.ID, "Application_ID");
+ result.setAttribute(EclipseWtpApplicationXMLWriter.VERSION, "1.4");
+ result.setAttribute(EclipseWtpApplicationXMLWriter.XMLNS, "http://java.sun.com/xml/ns/j2ee");
+ result.setAttribute(EclipseWtpApplicationXMLWriter.XMLNS_XSI, "http://www.w3.org/2001/XMLSchema-instance");
+ result.setAttribute(EclipseWtpApplicationXMLWriter.XMLNS_SCHEMA_LOCATION, "http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application_1_4.xsd");
+ result.addChild(new Xpp3Dom(EclipseWtpApplicationXMLWriter.APPLICATION_XML_DESCRIPTION));
+ Xpp3Dom name = new Xpp3Dom(EclipseWtpApplicationXMLWriter.APPLICATION_XML_DISPLAY_NAME);
+ name.setValue(this.config.getEclipseProjectName());
+ result.addChild(name);
+ return result;
+ }
+
+ /**
+ * there is no existing .modulemaps file so create a new one.
+ *
+ * @return the domtree representing the contents of the .modulemaps file
+ */
+ private Xpp3Dom createNewModulemaps() {
+ Xpp3Dom result = new Xpp3Dom(EclipseWtpApplicationXMLWriter.MODULEMAP_EARPROJECT_MAP);
+ result.setAttribute(EclipseWtpApplicationXMLWriter.XMI_VERSION, "2.0");
+ result.setAttribute(EclipseWtpApplicationXMLWriter.XMLNS_XMI, "http://www.omg.org/XMI");
+ result.setAttribute(EclipseWtpApplicationXMLWriter.XMLNS_APPLICATION, "application.xmi");
+ result.setAttribute(EclipseWtpApplicationXMLWriter.XMLNS_MODULEMAP, "modulemap.xmi");
+ result.setAttribute(EclipseWtpApplicationXMLWriter.XMI_ID, "EARProjectMap_" + System.identityHashCode(this));
+ return result;
+ }
+
+ /**
+ * find an existing module entry in the application.xml file by looking up
+ * the id in the modulemaps file and then using that to locate the entry in
+ * the application.xml file.
+ *
+ * @param applicationXmlDom
+ * application.xml dom tree
+ * @param mapping
+ * .modulemaps dom tree
+ * @return dom tree representing the module
+ */
+ private Xpp3Dom findModuleInApplicationXml(Xpp3Dom applicationXmlDom, Xpp3Dom mapping) {
+ String id = getIdFromMapping(mapping);
+ Xpp3Dom[] children = applicationXmlDom.getChildren();
+ for (int index = 0; index < children.length; index++) {
+ String childId = children[index].getAttribute(EclipseWtpApplicationXMLWriter.ID);
+ if (childId != null && childId.equals(id)) {
+ return children[index];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * find an artifact in the modulemaps dom tree, if it is missing create a
+ * new entry in the modulemaps dom tree.
+ *
+ * @param dependency
+ * dependency to find
+ * @param modulemapXmlDom
+ * dom-tree of modulemaps
+ * @return dom-tree representing the artifact
+ */
+ private Xpp3Dom findOrCreateArtifact(IdeDependency dependency, Xpp3Dom modulemapXmlDom) {
+ // first try to find it
+ Xpp3Dom[] children = modulemapXmlDom.getChildren();
+ for (int index = 0; index < children.length; index++) {
+ if (children[index].getAttribute(EclipseWtpApplicationXMLWriter.MODULEMAPS_PROJECT_NAME).equals(dependency.getEclipseProjectName())) {
+ if ((dependency.getType().equals("ejb") || dependency.getType().equals("ejb3")) && children[index].getName().equals(EclipseWtpApplicationXMLWriter.MODULEMAPS_MAPPINGS)
+ && children[index].getChild(EclipseWtpApplicationXMLWriter.APPLICATION_XML_MODULE).getAttribute(EclipseWtpApplicationXMLWriter.XMI_TYPE).equals(EclipseWtpApplicationXMLWriter.MODULEMAPS_APPLICATION_EJB_MODULE)) {
+ return children[index];
+ } else if (dependency.getType().equals("war") && children[index].getName().equals(EclipseWtpApplicationXMLWriter.MODULEMAPS_MAPPINGS)
+ && children[index].getChild(EclipseWtpApplicationXMLWriter.APPLICATION_XML_MODULE).getAttribute(EclipseWtpApplicationXMLWriter.XMI_TYPE).equals(EclipseWtpApplicationXMLWriter.MODULEMAPS_APPLICATION_WEB_MODULE)) {
+ return children[index];
+ } else if (dependency.getType().equals("jar") && children[index].getName().equals(EclipseWtpApplicationXMLWriter.MODULEMAPS_UTILITY_JARMAPPINGS)) {
+ return children[index];
+ } else {
+ modulemapXmlDom.removeChild(index);
+ break;
+ }
+ }
+ }
+ // ok, its missing (or it changed type). create a new one based on its
+ // type
+ long id = System.identityHashCode(dependency);
+ if (dependency.getType().equals("ejb") || dependency.getType().equals("ejb3")) {
+ Xpp3Dom mapping = new Xpp3Dom(EclipseWtpApplicationXMLWriter.MODULEMAPS_MAPPINGS);
+ mapping.setAttribute(EclipseWtpApplicationXMLWriter.XMI_ID, "ModuleMapping_" + id);
+ mapping.setAttribute(EclipseWtpApplicationXMLWriter.MODULEMAPS_PROJECT_NAME, dependency.getEclipseProjectName());
+ Xpp3Dom module = new Xpp3Dom(EclipseWtpApplicationXMLWriter.APPLICATION_XML_MODULE);
+ module.setAttribute(EclipseWtpApplicationXMLWriter.XMI_TYPE, EclipseWtpApplicationXMLWriter.MODULEMAPS_APPLICATION_EJB_MODULE);
+ module.setAttribute(EclipseWtpApplicationXMLWriter.HREF, "META-INF/application.xml#EjbModule_" + id);
+ mapping.addChild(module);
+ modulemapXmlDom.addChild(mapping);
+ return mapping;
+ } else if (dependency.getType().equals("war")) {
+ Xpp3Dom mapping = new Xpp3Dom(EclipseWtpApplicationXMLWriter.MODULEMAPS_MAPPINGS);
+ mapping.setAttribute(EclipseWtpApplicationXMLWriter.XMI_ID, "ModuleMapping_" + id);
+ mapping.setAttribute(EclipseWtpApplicationXMLWriter.MODULEMAPS_PROJECT_NAME, dependency.getEclipseProjectName());
+ Xpp3Dom module = new Xpp3Dom(EclipseWtpApplicationXMLWriter.APPLICATION_XML_MODULE);
+ module.setAttribute(EclipseWtpApplicationXMLWriter.XMI_TYPE, EclipseWtpApplicationXMLWriter.MODULEMAPS_APPLICATION_WEB_MODULE);
+ module.setAttribute(EclipseWtpApplicationXMLWriter.HREF, "META-INF/application.xml#WebModule_" + id);
+ mapping.addChild(module);
+ modulemapXmlDom.addChild(mapping);
+ return mapping;
+ } else {
+ Xpp3Dom utilityJARMapping = new Xpp3Dom(EclipseWtpApplicationXMLWriter.MODULEMAPS_UTILITY_JARMAPPINGS);
+ utilityJARMapping.setAttribute(EclipseWtpApplicationXMLWriter.XMI_ID, "UtilityJARMapping_" + id);
+ utilityJARMapping.setAttribute(EclipseWtpApplicationXMLWriter.MODULEMAPS_PROJECT_NAME, dependency.getEclipseProjectName());
+ utilityJARMapping.setAttribute(EclipseWtpApplicationXMLWriter.URI, dependency.getEclipseProjectName() + ".jar");
+ modulemapXmlDom.addChild(utilityJARMapping);
+ return utilityJARMapping;
+ }
+ }
+
+ /**
+ * get the id from the href of a modulemap.
+ *
+ * @param mapping
+ * the dom-tree of modulemaps
+ * @return module identifier
+ */
+ private String getIdFromMapping(Xpp3Dom mapping) {
+ if (mapping.getChildCount() < 1) {
+ return "";
+ }
+ String href = mapping.getChild(0).getAttribute(EclipseWtpApplicationXMLWriter.HREF);
+ String id = href.substring(href.indexOf('#') + 1);
+ return id;
+ }
+
+ /**
+ * mark the domtree entry as handled (all not handled ones will be deleted).
+ *
+ * @param xpp3Dom
+ * dom element to mark handled
+ */
+ private void handled(Xpp3Dom xpp3Dom) {
+ for (int index = 0; index < this.applicationXmlDomChildren.length; index++) {
+ if (this.applicationXmlDomChildren[index] == xpp3Dom) {
+ this.applicationXmlDomChildren[index] = null;
+ }
+ }
+ for (int index = 0; index < this.modulemapsXmlDomChildren.length; index++) {
+ if (this.modulemapsXmlDomChildren[index] == xpp3Dom) {
+ this.modulemapsXmlDomChildren[index] = null;
+ }
+ }
+ }
+
+ /**
+ * read an xml file (application.xml or .modulemaps).
+ *
+ * @param xmlFile
+ * an xmlfile
+ * @return dom-tree representing the file contents
+ */
+ private Xpp3Dom readXMLFile(File xmlFile) {
+ try {
+ FileReader reader1 = new FileReader(xmlFile);
+ Xpp3Dom applicationXmlDom = Xpp3DomBuilder.build(reader1);
+ return applicationXmlDom;
+ } catch (FileNotFoundException e) {
+ return null;
+ } catch (Exception e) {
+ this.log.error("cantreadfile" + xmlFile.getAbsolutePath());
+ // this will trigger creating a new file
+ return null;
+ }
+ }
+
+ /**
+ * delete all unused entries from the dom-trees.
+ *
+ * @param applicationXmlDom
+ * dom-tree of application.xml
+ * @param modulemapsXmlDom
+ * dom-tree of modulemaps
+ */
+ private void removeUnusedEntries(Xpp3Dom applicationXmlDom, Xpp3Dom modulemapsXmlDom) {
+ for (int index = 0; index < this.modulemapsXmlDomChildren.length; index++) {
+ if (this.modulemapsXmlDomChildren[index] != null) {
+ Xpp3Dom[] newModulemapsXmlDomChildren = modulemapsXmlDom.getChildren();
+ for (int newIndex = 0; newIndex < newModulemapsXmlDomChildren.length; newIndex++) {
+ if (newModulemapsXmlDomChildren[newIndex] == this.modulemapsXmlDomChildren[index]) {
+ modulemapsXmlDom.removeChild(newIndex);
+ break;
+ }
+ }
+ }
+ }
+ for (int index = 0; index < this.applicationXmlDomChildren.length; index++) {
+ if (this.applicationXmlDomChildren[index] != null) {
+ Xpp3Dom[] newApplicationXmlDomChildren = applicationXmlDom.getChildren();
+ for (int newIndex = 0; newIndex < newApplicationXmlDomChildren.length; newIndex++) {
+ if (newApplicationXmlDomChildren[newIndex] == this.applicationXmlDomChildren[index]) {
+ applicationXmlDom.removeChild(newIndex);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * update the application.xml and the .modulemaps file for a specified
+ * dependency.all WAR an EJB dependencies will go in both files all others
+ * only in the modulemaps files. Webapplications contextroots are corrected
+ * to the contextRoot specified in the pom.
+ *
+ * @param applicationXmlDom
+ * dom-tree of application.xml
+ * @param modulemapXmlDom
+ * dom-tree of modulemaps
+ * @param dependency
+ * the eclipse dependency to handle
+ */
+ private void updateApplicationXml(Xpp3Dom applicationXmlDom, Xpp3Dom modulemapXmlDom, IdeDependency dependency) {
+ if (dependency.isTestDependency() || dependency.isProvided() || dependency.isSystemScopedOutsideProject(this.config.getProject()))
+ {
+ return;
+ }
+ Xpp3Dom mapping = findOrCreateArtifact(dependency, modulemapXmlDom);
+ handled(mapping);
+ if (dependency.getType().equals("ejb") || dependency.getType().equals("ejb3") ) {
+ Xpp3Dom module = findModuleInApplicationXml(applicationXmlDom, mapping);
+ if (module == null) {
+ module = new Xpp3Dom(EclipseWtpApplicationXMLWriter.APPLICATION_XML_MODULE);
+ module.setAttribute(EclipseWtpApplicationXMLWriter.ID, getIdFromMapping(mapping));
+ Xpp3Dom ejb = new Xpp3Dom("ejb");
+ ejb.setValue(dependency.getEclipseProjectName() + ".jar");
+ module.addChild(ejb);
+ applicationXmlDom.addChild(module);
+ } else {
+ handled(module);
+ module.getChild("ejb").setValue(dependency.getEclipseProjectName() + ".jar");
+ }
+ } else if (dependency.getType().equals("war")) {
+ String contextRootInPom = getContextRootFor(dependency.getEclipseProjectName());
+ Xpp3Dom module = findModuleInApplicationXml(applicationXmlDom, mapping);
+ if (module == null) {
+ module = new Xpp3Dom(EclipseWtpApplicationXMLWriter.APPLICATION_XML_MODULE);
+ module.setAttribute(EclipseWtpApplicationXMLWriter.ID, getIdFromMapping(mapping));
+ Xpp3Dom web = new Xpp3Dom(EclipseWtpApplicationXMLWriter.APPLICATION_XML_WEB);
+ Xpp3Dom webUri = new Xpp3Dom(EclipseWtpApplicationXMLWriter.APPLICATION_XML_WEB_URI);
+ webUri.setValue(dependency.getEclipseProjectName() + ".war");
+ Xpp3Dom contextRoot = new Xpp3Dom(EclipseWtpApplicationXMLWriter.APPLICATION_XML_CONTEXT_ROOT);
+ contextRoot.setValue(contextRootInPom);
+ web.addChild(webUri);
+ web.addChild(contextRoot);
+ module.addChild(web);
+ applicationXmlDom.addChild(module);
+ } else {
+ handled(module);
+ module.getChild(EclipseWtpApplicationXMLWriter.APPLICATION_XML_WEB).getChild(EclipseWtpApplicationXMLWriter.APPLICATION_XML_WEB_URI).setValue(dependency.getEclipseProjectName() + ".war");
+ module.getChild(EclipseWtpApplicationXMLWriter.APPLICATION_XML_WEB).getChild(EclipseWtpApplicationXMLWriter.APPLICATION_XML_CONTEXT_ROOT).setValue(contextRootInPom);
+ }
+ }
+ }
+
+ /**
+ * Find the contextRoot specified in the pom and convert it into contectroot
+ * for the application.xml.
+ *
+ * @param artifactId
+ * the artifactid to search
+ * @return string with the context root
+ */
+ private String getContextRootFor(String artifactId) {
+ for (int index = 0; index < this.webModulesFromPoms.length; index++) {
+ if (this.webModulesFromPoms[index].getChild("artifactId").getValue().equals(artifactId)) {
+ return new File(this.webModulesFromPoms[index].getChild("contextRoot").getValue()).getName();
+ }
+ }
+ return artifactId;
+ }
+
+ /**
+ * write back a domtree to a xmlfile and use the pretty print for it so that
+ * it is human readable.
+ *
+ * @param xmlFile
+ * file to write to
+ * @param xmlDomTree
+ * dom-tree to write
+ * @throws MojoExecutionException
+ * if the file could not be written
+ */
+ private void writePrettyXmlFile(File xmlFile, Xpp3Dom xmlDomTree) throws MojoExecutionException {
+ Xpp3Dom original = readXMLFile(xmlFile);
+ if (original != null && original.equals(xmlDomTree)) {
+ this.log.info("Rad6CleanMojo.unchanged" + xmlFile.getAbsolutePath());
+ return;
+ }
+ FileWriter w = null;
+ xmlFile.getParentFile().mkdirs();
+ try {
+ w = new FileWriter(xmlFile);
+ } catch (IOException ex) {
+ throw new MojoExecutionException("Rad6Plugin.erroropeningfile", ex); //$NON-NLS-1$
+ }
+ XMLWriter writer = new PrettyPrintXMLWriter(w, "UTF-8", null);
+ Xpp3DomWriter.write(writer, xmlDomTree);
+ IOUtil.close(w);
+ }
+}
diff --git a/src/main/java/org/apache/maven/plugin/eclipse/writers/wtp/EclipseWtpComponentWriter.java b/src/main/java/org/apache/maven/plugin/eclipse/writers/wtp/EclipseWtpComponentWriter.java
index 074d009..265ed5c 100644
--- a/src/main/java/org/apache/maven/plugin/eclipse/writers/wtp/EclipseWtpComponentWriter.java
+++ b/src/main/java/org/apache/maven/plugin/eclipse/writers/wtp/EclipseWtpComponentWriter.java
@@ -122,7 +122,8 @@
}
writer.startElement( ELT_WB_MODULE );
- writer.addAttribute( ATTR_DEPLOY_NAME, config.getProject().getArtifactId() );
+ //we should use the eclipse project name as the deploy name.
+ writer.addAttribute( ATTR_DEPLOY_NAME, this.config.getEclipseProjectName() );
// deploy-path is "/" for utility and ejb projects, "/WEB-INF/classes" for webapps
String target = "/"; //$NON-NLS-1$
@@ -153,9 +154,12 @@
}
else if ( "ear".equalsIgnoreCase( packaging ) ) //$NON-NLS-1$
{
+
+ String defaultApplicationXML = config.getWtpapplicationxml()?"/target/eclipseEar":"/src/main/application";
+
String earSourceDirectory = IdeUtils.getPluginSetting( config.getProject(), ARTIFACT_MAVEN_EAR_PLUGIN,
"earSourceDirectory", //$NON-NLS-1$
- config.getProject().getBasedir()+"/src/main/application" ); //$NON-NLS-1$
+ config.getProject().getBasedir()+defaultApplicationXML); //$NON-NLS-1$
writer.startElement( ELT_WB_RESOURCE );
writer.addAttribute( ATTR_DEPLOY_PATH, "/" ); //$NON-NLS-1$
writer.addAttribute( ATTR_SOURCE_PATH, IdeUtils
diff --git a/src/main/java/org/apache/maven/plugin/eclipse/writers/wtp/EclipseWtpmodulesWriter.java b/src/main/java/org/apache/maven/plugin/eclipse/writers/wtp/EclipseWtpmodulesWriter.java
index 88cc867..c978a25 100644
--- a/src/main/java/org/apache/maven/plugin/eclipse/writers/wtp/EclipseWtpmodulesWriter.java
+++ b/src/main/java/org/apache/maven/plugin/eclipse/writers/wtp/EclipseWtpmodulesWriter.java
@@ -64,7 +64,8 @@
writer.addAttribute( ATTR_MODULE_ID, "moduleCoreId" ); //$NON-NLS-1$
writer.startElement( ELT_WB_MODULE );
- writer.addAttribute( ATTR_DEPLOY_NAME, config.getProject().getArtifactId() );
+ // we should use the configured eclipse project name.
+ writer.addAttribute( ATTR_DEPLOY_NAME, this.config.getEclipseProjectName() );
writer.startElement( ELT_MODULE_TYPE );
writeModuleTypeAccordingToPackaging( config.getProject(), writer, config.getBuildOutputDirectory() );
diff --git a/src/main/java/org/apache/maven/plugin/ide/AbstractIdeSupportMojo.java b/src/main/java/org/apache/maven/plugin/ide/AbstractIdeSupportMojo.java
index 7800bc8..561252e 100644
--- a/src/main/java/org/apache/maven/plugin/ide/AbstractIdeSupportMojo.java
+++ b/src/main/java/org/apache/maven/plugin/ide/AbstractIdeSupportMojo.java
@@ -633,10 +633,13 @@
.getVersion(), art.getClassifier(), isReactorProject, Artifact.SCOPE_TEST.equals( art
.getScope() ), Artifact.SCOPE_SYSTEM.equals( art.getScope() ), Artifact.SCOPE_PROVIDED
.equals( art.getScope() ), art.getArtifactHandler().isAddedToClasspath(),
- art.getFile(), art.getType(), isOsgiBundle,
- osgiSymbolicName, dependencyDepth );
-
- dependencies.add( dep );
+ art.getFile(), art.getType(), isOsgiBundle, osgiSymbolicName, dependencyDepth,
+ getProjectNameForArifact(art));
+ //no duplicate entries allowed. System paths can cause this problem.
+ if ( !dependencies.contains(dep) )
+ {
+ dependencies.add( dep );
+ }
}
}
@@ -656,7 +659,14 @@
return ideDeps;
}
-
+
+ /**
+ * Find the name of the project as used in eclipse.
+ * @param artifact The artifact to find the eclipse name for.
+ * @return The name os the eclipse project.
+ */
+ abstract public String getProjectNameForArifact(Artifact artifact) ;
+
/**
* Returns the list of project artifacts. Also artifacts
* generated from referenced projects will be added, but
diff --git a/src/main/java/org/apache/maven/plugin/ide/IdeDependency.java b/src/main/java/org/apache/maven/plugin/ide/IdeDependency.java
index 01d0fff..d39484c 100644
--- a/src/main/java/org/apache/maven/plugin/ide/IdeDependency.java
+++ b/src/main/java/org/apache/maven/plugin/ide/IdeDependency.java
@@ -20,6 +20,8 @@
import java.io.File;
+import org.apache.maven.project.MavenProject;
+
/**
* @author Fabrizio Giustina
* @version $Id$
@@ -98,6 +100,11 @@
private boolean osgiBundle;
/**
+ * How is this dependency called when it is an eclipse project.
+ */
+ private String eclipseProjectName;
+
+ /**
* Creates an uninitialized instance
*/
public IdeDependency()
@@ -120,10 +127,12 @@
* @param osgiBundle Does this artifact contains a OSGI Manifest?
* @param osgiSymbolicName Bundle-SymbolicName from the Manifest (if available)
* @param dependencyDepth Depth of this dependency in the transitive dependency trail.
+ * @param eclipseProjectName The name of the project in eclipse
*/
public IdeDependency( String groupId, String artifactId, String version, String classifier, boolean referencedProject,
boolean testDependency, boolean systemScoped, boolean provided, boolean addedToClasspath,
- File file, String type, boolean osgiBundle, String osgiSymbolicName, int dependencyDepth )
+ File file, String type, boolean osgiBundle, String osgiSymbolicName, int dependencyDepth,
+ String eclipseProjectName)
{
// group:artifact:version
this.groupId = groupId;
@@ -143,6 +152,7 @@
// file and type
this.file = file;
this.type = type;
+ this.eclipseProjectName = eclipseProjectName;
}
/**
@@ -398,6 +408,22 @@
}
/**
+ * Getter for <code>eclipseProjectName</code>.
+ * @return Returns the eclipseProjectName.
+ */
+ public String getEclipseProjectName() {
+ return this.eclipseProjectName;
+ }
+
+ /**
+ * Setter for <code>eclipseProjectName</code>.
+ * @param eclipseProjectName The eclipseProjectName to set.
+ */
+ public void setEclipseProjectName(String eclipseProjectName) {
+ this.eclipseProjectName = eclipseProjectName;
+ }
+
+ /**
* @see java.lang.Object#toString()
*/
public String toString()
@@ -412,6 +438,11 @@
public int compareTo( Object o )
{
IdeDependency dep = (IdeDependency) o;
+ //in case of system scoped dependencies the files must be compared.
+ if (isSystemScoped() && dep.isSystemScoped() && getFile().equals(dep.getFile()))
+ {
+ return 0;
+ }
int equals = this.getGroupId().compareTo( dep.getGroupId() );
if ( equals != 0 )
{
@@ -427,8 +458,44 @@
{
return equals;
}
-
return 0;
}
+ /**
+ * Is this dependency System scoped outside the eclipse project. This is
+ * NOT complete because in reality the check should mean that any module
+ * in the reactor contains the system scope locally!
+ * @return Returns this dependency is systemScoped outside the project.
+ */
+ public boolean isSystemScopedOutsideProject( MavenProject project )
+ {
+ File modulesTop = project.getBasedir();
+ while (new File(modulesTop.getParentFile(), "pom.xml").exists())
+ {
+ modulesTop = modulesTop.getParentFile();
+ }
+ return isSystemScoped() && !getFile().getAbsolutePath().startsWith(modulesTop.getAbsolutePath());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean equals(Object obj)
+ {
+ return compareTo(obj) == 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int hashCode() {
+ if (isSystemScoped())
+ {
+ return getFile().hashCode();
+ }
+ else
+ {
+ return this.getGroupId().hashCode() ^ this.getArtifactId().hashCode() ^ this.getType().hashCode();
+ }
+ }
}
diff --git a/src/main/java/org/apache/maven/plugin/ide/IdeUtils.java b/src/main/java/org/apache/maven/plugin/ide/IdeUtils.java
index f9a68dd..45b180e 100644
--- a/src/main/java/org/apache/maven/plugin/ide/IdeUtils.java
+++ b/src/main/java/org/apache/maven/plugin/ide/IdeUtils.java
@@ -195,6 +195,18 @@
return getProjectName( template, dep.getGroupId(), dep.getArtifactId(), dep.getVersion() );
}
+ /**
+ * Use the project name template to create an eclipse project.
+ *
+ * @param template Template for the project name
+ * @param artifact the artifact to create the project name for
+ * @return the created ide project name
+ */
+ public static String getProjectName( String template, Artifact artifact )
+ {
+ return getProjectName( template, artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() );
+ }
+
public static String getProjectName( String template, MavenProject project )
{
return getProjectName( template, project.getGroupId(), project.getArtifactId(), project.getVersion() );
diff --git a/src/test/java/org/apache/maven/plugin/eclipse/EclipsePluginTest.java b/src/test/java/org/apache/maven/plugin/eclipse/EclipsePluginTest.java
index e870f9b..729eb78 100644
--- a/src/test/java/org/apache/maven/plugin/eclipse/EclipsePluginTest.java
+++ b/src/test/java/org/apache/maven/plugin/eclipse/EclipsePluginTest.java
@@ -342,6 +342,10 @@
testProject( "project-32" );
}
+ public void testProject34() throws Exception
+ {
+ testProject( "project-34" );
+ }
/**
* MECLIPSE-287 : dependencies with and without classifiers
diff --git a/src/test/resources/m2repo/eclipsetest/multymodule-1/1.0/multymodule-1-1.0.jar b/src/test/resources/m2repo/eclipsetest/multymodule-1/1.0/multymodule-1-1.0.jar
new file mode 100644
index 0000000..e51013e
--- /dev/null
+++ b/src/test/resources/m2repo/eclipsetest/multymodule-1/1.0/multymodule-1-1.0.jar
@@ -0,0 +1 @@
+-testfile-not a valid jar-
\ No newline at end of file
diff --git a/src/test/resources/m2repo/eclipsetest/multymodule-1/1.0/multymodule-1-1.0.pom b/src/test/resources/m2repo/eclipsetest/multymodule-1/1.0/multymodule-1-1.0.pom
new file mode 100644
index 0000000..0e4e900
--- /dev/null
+++ b/src/test/resources/m2repo/eclipsetest/multymodule-1/1.0/multymodule-1-1.0.pom
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>eclipsetest</groupId>
+ <artifactId>master-test</artifactId>
+ <version>1.0</version>
+ </parent>
+ <packaging>jar</packaging>
+ <groupId>eclipsetest</groupId>
+ <artifactId>multymodule-1</artifactId>
+ <version>1.0</version>
+ <name>multymodule-1</name>
+ <dependencies>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>multymodule-4</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>refproject-compile</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>refproject-test</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>refproject-provided</artifactId>
+ <version>1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>refproject-optional</artifactId>
+ <version>1.0</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>refproject-sysdep</artifactId>
+ <version>1.0</version>
+ <scope>system</scope>
+ <systemPath>${basedir}/refproject-sysdep.jar</systemPath>
+ </dependency>
+ </dependencies>
+ <distributionManagement>
+ <status>verified</status>
+ </distributionManagement>
+</project>
diff --git a/src/test/resources/m2repo/eclipsetest/multymodule-2/1.0/multymodule-2-1.0.pom b/src/test/resources/m2repo/eclipsetest/multymodule-2/1.0/multymodule-2-1.0.pom
new file mode 100644
index 0000000..6679876
--- /dev/null
+++ b/src/test/resources/m2repo/eclipsetest/multymodule-2/1.0/multymodule-2-1.0.pom
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>eclipsetest</groupId>
+ <artifactId>master-test</artifactId>
+ <version>1.0</version>
+ </parent>
+ <packaging>war</packaging>
+ <groupId>eclipsetest</groupId>
+ <artifactId>module-2</artifactId>
+ <version>1.0</version>
+ <name>module-2</name>
+ <dependencies>
+ <dependency>
+ <!-- module -->
+ <groupId>eclipsetest</groupId>
+ <artifactId>module-1</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <!-- module -->
+ <groupId>eclipsetest</groupId>
+ <artifactId>module-1</artifactId>
+ <version>1.0</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>direct-compile</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>direct-test</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>direct-provided</artifactId>
+ <version>1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>direct-optional</artifactId>
+ <version>1.0</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>direct-sysdep</artifactId>
+ <version>1.0</version>
+ <scope>system</scope>
+ <systemPath>${basedir}/direct-sysdep.jar</systemPath>
+ </dependency>
+ </dependencies>
+ <distributionManagement>
+ <status>verified</status>
+ </distributionManagement>
+</project>
diff --git a/src/test/resources/m2repo/eclipsetest/multymodule-2/1.0/multymodule-2-1.0.war b/src/test/resources/m2repo/eclipsetest/multymodule-2/1.0/multymodule-2-1.0.war
new file mode 100644
index 0000000..e51013e
--- /dev/null
+++ b/src/test/resources/m2repo/eclipsetest/multymodule-2/1.0/multymodule-2-1.0.war
@@ -0,0 +1 @@
+-testfile-not a valid jar-
\ No newline at end of file
diff --git a/src/test/resources/m2repo/eclipsetest/multymodule-4/1.0/multymodule-4-1.0.jar b/src/test/resources/m2repo/eclipsetest/multymodule-4/1.0/multymodule-4-1.0.jar
new file mode 100644
index 0000000..e51013e
--- /dev/null
+++ b/src/test/resources/m2repo/eclipsetest/multymodule-4/1.0/multymodule-4-1.0.jar
@@ -0,0 +1 @@
+-testfile-not a valid jar-
\ No newline at end of file
diff --git a/src/test/resources/m2repo/eclipsetest/multymodule-4/1.0/multymodule-4-1.0.pom b/src/test/resources/m2repo/eclipsetest/multymodule-4/1.0/multymodule-4-1.0.pom
new file mode 100644
index 0000000..405fbd1
--- /dev/null
+++ b/src/test/resources/m2repo/eclipsetest/multymodule-4/1.0/multymodule-4-1.0.pom
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>eclipsetest</groupId>
+ <artifactId>master-test</artifactId>
+ <version>1.0</version>
+ </parent>
+ <packaging>jar</packaging>
+ <groupId>eclipsetest</groupId>
+ <artifactId>multymodule-4</artifactId>
+ <version>1.0</version>
+ <name>multymodule-4</name>
+ <dependencies>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>refproject-compile</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+ <distributionManagement>
+ <status>verified</status>
+ </distributionManagement>
+</project>
diff --git a/src/test/resources/projects/project-05/expected/.wtpmodules b/src/test/resources/projects/project-05/expected/.wtpmodules
index 374ff8f..580db97 100644
--- a/src/test/resources/projects/project-05/expected/.wtpmodules
+++ b/src/test/resources/projects/project-05/expected/.wtpmodules
@@ -5,7 +5,7 @@
<property name="context-root" value="contextName"/>
</module-type>
<wb-resource deploy-path="/" source-path="/src/main/webapp"/>
- <dependent-module deploy-path="/WEB-INF/lib" handle="module:/classpath/var/M2_REPO/maven/maven-core/98.0/maven-core-98.0.jar">
+ <dependent-module archiveName="maven-core.jar" deploy-path="/WEB-INF/lib" handle="module:/classpath/var/M2_REPO/maven/maven-core/98.0/maven-core-98.0.jar">
<dependency-type>uses</dependency-type>
</dependent-module>
<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/java"/>
diff --git a/src/test/resources/projects/project-08/expected/.wtpmodules b/src/test/resources/projects/project-08/expected/.wtpmodules
index f389d9f..ebe44e9 100644
--- a/src/test/resources/projects/project-08/expected/.wtpmodules
+++ b/src/test/resources/projects/project-08/expected/.wtpmodules
@@ -5,8 +5,8 @@
<property name="context-root" value="maven-eclipse-plugin-test-project-8"/>
</module-type>
<wb-resource deploy-path="/" source-path="/src/main/webapp"/>
- <dependent-module deploy-path="/WEB-INF/lib" handle="module:/classpath/lib/sysdep.jar">
+ <dependent-module archiveName="sysdep.jar" deploy-path="/WEB-INF/lib" handle="module:/classpath/lib/sysdep.jar">
<dependency-type>uses</dependency-type>
</dependent-module>
</wb-module>
-</project-modules>
\ No newline at end of file
+</project-modules>
diff --git a/src/test/resources/projects/project-34/multymodule-1/expected/.project b/src/test/resources/projects/project-34/multymodule-1/expected/.project
new file mode 100644
index 0000000..a155912
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-1/expected/.project
@@ -0,0 +1,15 @@
+<projectDescription>
+ <name>multymodule-1-1.0</name>
+ <comment/>
+ <projects>
+ <project>multymodule-4-1.0</project>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
\ No newline at end of file
diff --git a/src/test/resources/projects/project-34/multymodule-1/expected/target/generated-resources/eclipse/META-INF/MANIFEST.MF b/src/test/resources/projects/project-34/multymodule-1/expected/target/generated-resources/eclipse/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e202401
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-1/expected/target/generated-resources/eclipse/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Class-Path: refproject-compile-1.0.jar refproject-sysdep.jar multymodu
+ le-4-1.0.jar refproject-optional-1.0.jar deps-refproject-compile-1.0.
+ jar
+
diff --git a/src/test/resources/projects/project-34/multymodule-1/pom.xml b/src/test/resources/projects/project-34/multymodule-1/pom.xml
new file mode 100644
index 0000000..9b69ffa
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-1/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>eclipsetest</groupId>
+ <artifactId>master-test</artifactId>
+ <version>1.0</version>
+ </parent>
+ <packaging>jar</packaging>
+ <groupId>eclipsetest</groupId>
+ <artifactId>multymodule-1</artifactId>
+ <version>1.0</version>
+ <name>multymodule-1</name>
+ <dependencies>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>multymodule-4</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>refproject-compile</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>refproject-test</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>refproject-provided</artifactId>
+ <version>1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>refproject-optional</artifactId>
+ <version>1.0</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>refproject-sysdep</artifactId>
+ <version>1.0</version>
+ <scope>system</scope>
+ <systemPath>${basedir}/refproject-sysdep.jar</systemPath>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/src/test/resources/projects/project-34/multymodule-1/src/main/java/DummyClass.txt b/src/test/resources/projects/project-34/multymodule-1/src/main/java/DummyClass.txt
new file mode 100644
index 0000000..9ade9c1
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-1/src/main/java/DummyClass.txt
@@ -0,0 +1,7 @@
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id: DummyClass.txt 359507 2005-12-28 13:14:19Z fgiust $
+ */
+public class DummyClass
+{
+}
diff --git a/src/test/resources/projects/project-34/multymodule-2/expected/.classpath b/src/test/resources/projects/project-34/multymodule-2/expected/.classpath
new file mode 100644
index 0000000..dc23684
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-2/expected/.classpath
@@ -0,0 +1,16 @@
+<classpath>
+ <classpathentry kind="src" path="src/main/java"/>
+ <classpathentry kind="output" path="target/classes"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="var" path="M2_REPO/eclipsetest/direct-optional/1.0/direct-optional-1.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/eclipsetest/deps-direct-compile/1.0/deps-direct-compile-1.0.jar"/>
+ <classpathentry kind="src" path="/multymodule-4-1.0"/>
+ <classpathentry kind="var" path="M2_REPO/eclipsetest/direct-test/1.0/direct-test-1.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/eclipsetest/refproject-compile/1.0/refproject-compile-1.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/eclipsetest/deps-refproject-compile/1.0/deps-refproject-compile-1.0.jar"/>
+ <classpathentry kind="lib" path="/tmp/maven-eclipse-plugin-trunk/target/test-classes/projects/project-34/multymodule-1/refproject-sysdep.jar"/>
+ <classpathentry kind="src" path="/multymodule-1-1.0"/>
+ <classpathentry kind="lib" path="direct-sysdep.jar"/>
+ <classpathentry kind="var" path="M2_REPO/eclipsetest/direct-provided/1.0/direct-provided-1.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/eclipsetest/direct-compile/1.0/direct-compile-1.0.jar"/>
+</classpath>
\ No newline at end of file
diff --git a/src/test/resources/projects/project-34/multymodule-2/expected/.project b/src/test/resources/projects/project-34/multymodule-2/expected/.project
new file mode 100644
index 0000000..242e307
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-2/expected/.project
@@ -0,0 +1,16 @@
+<projectDescription>
+ <name>multymodule-2-1.0</name>
+ <comment/>
+ <projects>
+ <project>multymodule-4-1.0</project>
+ <project>multymodule-1-1.0</project>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
\ No newline at end of file
diff --git a/src/test/resources/projects/project-34/multymodule-2/expected/pom.xml b/src/test/resources/projects/project-34/multymodule-2/expected/pom.xml
new file mode 100644
index 0000000..99c6109
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-2/expected/pom.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>eclipsetest</groupId>
+ <artifactId>master-test</artifactId>
+ <version>1.0</version>
+ </parent>
+ <packaging>war</packaging>
+ <groupId>eclipsetest</groupId>
+ <artifactId>multymodule-2</artifactId>
+ <version>1.0</version>
+ <name>multymodule-2</name>
+ <dependencies>
+ <dependency>
+ <!-- module -->
+ <groupId>eclipsetest</groupId>
+ <artifactId>multymodule-1</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <!-- module -->
+ <groupId>eclipsetest</groupId>
+ <artifactId>multymodule-1</artifactId>
+ <version>1.0</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>direct-compile</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>direct-test</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>direct-provided</artifactId>
+ <version>1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>direct-optional</artifactId>
+ <version>1.0</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>direct-sysdep</artifactId>
+ <version>1.0</version>
+ <scope>system</scope>
+ <systemPath>${basedir}/direct-sysdep.jar</systemPath>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/src/test/resources/projects/project-34/multymodule-2/expected/src/main/webapp/META-INF/MANIFEST.MF b/src/test/resources/projects/project-34/multymodule-2/expected/src/main/webapp/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..d2448ea
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-2/expected/src/main/webapp/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Class-Path: direct-optional-1.0.jar deps-direct-compile-1.0.jar multym
+ odule-4-1.0.jar refproject-compile-1.0.jar deps-refproject-compile-1.
+ 0.jar refproject-sysdep.jar direct-sysdep.jar direct-compile-1.0.jar
+
diff --git a/src/test/resources/projects/project-34/multymodule-2/pom.xml b/src/test/resources/projects/project-34/multymodule-2/pom.xml
new file mode 100644
index 0000000..99c6109
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-2/pom.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>eclipsetest</groupId>
+ <artifactId>master-test</artifactId>
+ <version>1.0</version>
+ </parent>
+ <packaging>war</packaging>
+ <groupId>eclipsetest</groupId>
+ <artifactId>multymodule-2</artifactId>
+ <version>1.0</version>
+ <name>multymodule-2</name>
+ <dependencies>
+ <dependency>
+ <!-- module -->
+ <groupId>eclipsetest</groupId>
+ <artifactId>multymodule-1</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <!-- module -->
+ <groupId>eclipsetest</groupId>
+ <artifactId>multymodule-1</artifactId>
+ <version>1.0</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>direct-compile</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>direct-test</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>direct-provided</artifactId>
+ <version>1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>direct-optional</artifactId>
+ <version>1.0</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>direct-sysdep</artifactId>
+ <version>1.0</version>
+ <scope>system</scope>
+ <systemPath>${basedir}/direct-sysdep.jar</systemPath>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/src/test/resources/projects/project-34/multymodule-2/src/main/java/DummyClass.txt b/src/test/resources/projects/project-34/multymodule-2/src/main/java/DummyClass.txt
new file mode 100644
index 0000000..9ade9c1
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-2/src/main/java/DummyClass.txt
@@ -0,0 +1,7 @@
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id: DummyClass.txt 359507 2005-12-28 13:14:19Z fgiust $
+ */
+public class DummyClass
+{
+}
diff --git a/src/test/resources/projects/project-34/multymodule-3/expected/.project b/src/test/resources/projects/project-34/multymodule-3/expected/.project
new file mode 100644
index 0000000..7944b14
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-3/expected/.project
@@ -0,0 +1,9 @@
+<projectDescription>
+ <name>multymodule-3-1.0</name>
+ <comment/>
+ <projects>
+ <project>multymodule-2-1.0</project>
+ </projects>
+ <buildSpec/>
+ <natures/>
+</projectDescription>
\ No newline at end of file
diff --git a/src/test/resources/projects/project-34/multymodule-3/expected/target/application.xml b/src/test/resources/projects/project-34/multymodule-3/expected/target/application.xml
new file mode 100644
index 0000000..a80e711
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-3/expected/target/application.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE application PUBLIC
+ "-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN"
+ "http://java.sun.com/dtd/application_1_3.dtd">
+<application>
+ <display-name>multymodule-3</display-name>
+ <module>
+ <web>
+ <web-uri>multymodule-2-1.0.war</web-uri>
+ <context-root>/multymodule-2-1.0</context-root>
+ </web>
+ </module>
+</application>
\ No newline at end of file
diff --git a/src/test/resources/projects/project-34/multymodule-3/expected/target/eclipseEar/META-INF/.modulemaps b/src/test/resources/projects/project-34/multymodule-3/expected/target/eclipseEar/META-INF/.modulemaps
new file mode 100644
index 0000000..e4b502a
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-3/expected/target/eclipseEar/META-INF/.modulemaps
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<modulemap:EARProjectMap xmlns:xmi="http://www.omg.org/XMI" xmlns:application="application.xmi" xmi:version="2.0" xmlns:modulemap="modulemap.xmi" xmi:id="EARProjectMap_24763620">
+ <mappings projectName="multymodule-2-1.0" xmi:id="ModuleMapping_26542488">
+ <module xmi:type="application:WebModule" href="META-INF/application.xml#WebModule_26542488"/>
+ </mappings>
+</modulemap:EARProjectMap>
\ No newline at end of file
diff --git a/src/test/resources/projects/project-34/multymodule-3/expected/target/eclipseEar/META-INF/application.xml b/src/test/resources/projects/project-34/multymodule-3/expected/target/eclipseEar/META-INF/application.xml
new file mode 100644
index 0000000..8833430
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-3/expected/target/eclipseEar/META-INF/application.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<application xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application_1_4.xsd" id="Application_ID" version="1.4">
+ <description/>
+ <display-name>multymodule-3-1.0</display-name>
+ <module id="WebModule_26542488">
+ <web>
+ <web-uri>multymodule-2-1.0.war</web-uri>
+ <context-root>multymodule-2-1.0</context-root>
+ </web>
+ </module>
+</application>
\ No newline at end of file
diff --git a/src/test/resources/projects/project-34/multymodule-3/expected/target/eclipseEar/META-INF/test-file.txt b/src/test/resources/projects/project-34/multymodule-3/expected/target/eclipseEar/META-INF/test-file.txt
new file mode 100644
index 0000000..ea3ff8c
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-3/expected/target/eclipseEar/META-INF/test-file.txt
@@ -0,0 +1 @@
+empty test file
\ No newline at end of file
diff --git a/src/test/resources/projects/project-34/multymodule-3/pom.xml b/src/test/resources/projects/project-34/multymodule-3/pom.xml
new file mode 100644
index 0000000..61c7cda
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-3/pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>eclipsetest</groupId>
+ <artifactId>master-test</artifactId>
+ <version>1.0</version>
+ </parent>
+ <packaging>ear</packaging>
+ <groupId>eclipsetest</groupId>
+ <artifactId>multymodule-3</artifactId>
+ <version>1.0</version>
+ <name>multymodule-3</name>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-ear-plugin</artifactId>
+ <configuration>
+ <defaultLibBundleDir>lib</defaultLibBundleDir>
+ <modules>
+ <webModule>
+ <groupId>${groupId}</groupId>
+ <artifactId>multymodule-2</artifactId>
+ <contextRoot>/multymodule-2-${project.version}</contextRoot>
+ </webModule>
+ </modules>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>multymodule-2</artifactId>
+ <version>1.0</version>
+ <type>war</type>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/src/test/resources/projects/project-34/multymodule-3/src/main/application/META-INF/test-file.txt b/src/test/resources/projects/project-34/multymodule-3/src/main/application/META-INF/test-file.txt
new file mode 100644
index 0000000..ea3ff8c
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-3/src/main/application/META-INF/test-file.txt
@@ -0,0 +1 @@
+empty test file
\ No newline at end of file
diff --git a/src/test/resources/projects/project-34/multymodule-4/expected/.project b/src/test/resources/projects/project-34/multymodule-4/expected/.project
new file mode 100644
index 0000000..863a276
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-4/expected/.project
@@ -0,0 +1,13 @@
+<projectDescription>
+ <name>multymodule-4-1.0</name>
+ <comment/>
+ <projects/>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
\ No newline at end of file
diff --git a/src/test/resources/projects/project-34/multymodule-4/pom.xml b/src/test/resources/projects/project-34/multymodule-4/pom.xml
new file mode 100644
index 0000000..1caca09
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-4/pom.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>eclipsetest</groupId>
+ <artifactId>master-test</artifactId>
+ <version>1.0</version>
+ </parent>
+ <packaging>jar</packaging>
+ <groupId>eclipsetest</groupId>
+ <artifactId>multymodule-4</artifactId>
+ <version>1.0</version>
+ <name>multymodule-4</name>
+ <dependencies>
+ <dependency>
+ <groupId>eclipsetest</groupId>
+ <artifactId>refproject-compile</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/src/test/resources/projects/project-34/multymodule-4/src/main/java/DummyClass.txt b/src/test/resources/projects/project-34/multymodule-4/src/main/java/DummyClass.txt
new file mode 100644
index 0000000..9ade9c1
--- /dev/null
+++ b/src/test/resources/projects/project-34/multymodule-4/src/main/java/DummyClass.txt
@@ -0,0 +1,7 @@
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id: DummyClass.txt 359507 2005-12-28 13:14:19Z fgiust $
+ */
+public class DummyClass
+{
+}
diff --git a/src/test/resources/projects/project-34/pom.xml b/src/test/resources/projects/project-34/pom.xml
new file mode 100644
index 0000000..23c9054
--- /dev/null
+++ b/src/test/resources/projects/project-34/pom.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <packaging>pom</packaging>
+ <groupId>eclipsetest</groupId>
+ <artifactId>master-test</artifactId>
+ <version>1.0</version>
+ <name>master</name>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-eclipse-plugin</artifactId>
+ <version>test</version>
+ <configuration>
+ <workspace>${basedir}</workspace>
+ <projectNameTemplate>[artifactId]-[version]</projectNameTemplate>
+ <wtpContextName>${artifactId}-${version}</wtpContextName>
+ <wtpmanifest>true</wtpmanifest>
+ <wtpapplicationxml>true</wtpapplicationxml>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <modules>
+ <module>multymodule-1</module>
+ <module>multymodule-2</module>
+ <module>multymodule-3</module>
+ </modules>
+</project>