Index: C:/usr/src/maven-plugins/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/ide/AbstractIdeSupportMojo.java =================================================================== --- C:/usr/src/maven-plugins/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/ide/AbstractIdeSupportMojo.java (revision 475757) +++ C:/usr/src/maven-plugins/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/ide/AbstractIdeSupportMojo.java (working copy) @@ -19,6 +19,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; +import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -55,6 +56,8 @@ import org.apache.maven.model.Dependency; import org.apache.maven.model.DependencyManagement; import org.apache.maven.model.Exclusion; +import org.apache.maven.model.Model; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -345,6 +348,13 @@ * @return true if referenced project will be linked and not need artifact resolution */ protected abstract boolean getUseProjectReferences(); + + /** + * Return true if an attempt should be made to directly reference dependee projects + * instead of considering them as normal dependencies. + * @return Returns the referenceDependeeProjects. + */ + protected abstract boolean getReferenceDependeeProjects(); /** * Hook for preparation steps before the actual plugin execution. @@ -470,9 +480,11 @@ int dependencyDepth = node.getDepth(); Artifact art = node.getArtifact(); boolean isReactorProject = getUseProjectReferences() && isAvailableAsAReactorProject( art ); - - // don't resolve jars for reactor projects - if ( !isReactorProject ) + boolean isResolvedDependeeProject = getReferenceDependeeProjects() && dependeeProjectExists( art, true, logger ); + boolean isProjectReference = isReactorProject || isResolvedDependeeProject; + + // don't resolve jars for reactor projects or resolved dependee projects + if ( !isProjectReference ) { try { @@ -500,7 +512,7 @@ } } - if ( !isReactorProject || emittedReactorProjectId.add( art.getGroupId() + '-' + art.getArtifactId() ) ) + if ( !isProjectReference || emittedReactorProjectId.add( art.getGroupId() + '-' + art.getArtifactId() ) ) { // the following doesn't work: art.getArtifactHandler().getPackaging() always returns "jar" also @@ -552,7 +564,7 @@ isOsgiBundle = osgiSymbolicName != null; IdeDependency dep = new IdeDependency( art.getGroupId(), art.getArtifactId(), art.getVersion(), - isReactorProject, Artifact.SCOPE_TEST + isProjectReference, Artifact.SCOPE_TEST .equals( art.getScope() ), Artifact.SCOPE_SYSTEM .equals( art.getScope() ), Artifact.SCOPE_PROVIDED .equals( art.getScope() ), art.getArtifactHandler() @@ -883,5 +895,62 @@ getLog().info( msg ); //$NON-NLS-1$ } + + /** + * Checks for the existence of a dependee project in the same directory as the current one.

+ * @param dependency the dependency corresponding to the dependee project + * @param considerSnapshot if true, snapshot versions are canditate projects + * @return true, if a dependee project is found + */ + static public boolean dependeeProjectExists( Artifact dependency, boolean considerSnapshot, Logger log ) { + if ( dependeeProjectExists( dependency.getArtifactId(), dependency.getVersion(), log ) ) { + return true; + } else { + if ( considerSnapshot ) { + if ( ! dependency.getVersion().endsWith( "-SNAPSHOT" ) ) { + if ( dependeeProjectExists( dependency.getArtifactId(), dependency.getVersion() + "-SNAPSHOT", log ) ) { + return true; + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + } + } + + /** + * Checks for the existence of a dependee project in the same directory as the current one.

+ * @param artifactId artifact identifier of the dependency corresponding to the dependee project + * @param version version of the dependency corresponding to the dependee project + * @param log log object + * @return true, if a dependee project is found + */ + static public boolean dependeeProjectExists( String artifactId, String version, Logger log ) { + // Look for the dependency project in the same directory as the current project + File dependentProjectPOMFile = new File( ".." + File.separator + artifactId + File.separator + "pom.xml" ); + + if ( dependentProjectPOMFile.exists() ) { + try { + FileReader reader = new FileReader( dependentProjectPOMFile ); + MavenXpp3Reader modelReader = new MavenXpp3Reader(); + Model dependencyModel = modelReader.read( reader ); + if ( dependencyModel.getVersion().equals( version ) ) { + log.info( Messages.getString( "EclipsePlugin.foundDependeeProject", + new Object[] { artifactId, version, dependentProjectPOMFile.getParent() } ) ); + return true; + } + } catch ( Exception e ) { + log.debug( Messages.getString( "EclipsePlugin.exceptionWhileLookingForDependeeProject", + new Object[] { artifactId, version, dependentProjectPOMFile.getParent() } ), e ); + } + } + + return false; + } + } Index: C:/usr/src/maven-plugins/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/writers/EclipseClasspathWriter.java =================================================================== --- C:/usr/src/maven-plugins/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/writers/EclipseClasspathWriter.java (revision 475757) +++ C:/usr/src/maven-plugins/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/writers/EclipseClasspathWriter.java (working copy) @@ -20,12 +20,10 @@ import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; -import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.TreeMap; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.eclipse.BuildCommand; @@ -169,9 +167,8 @@ if ( byOutputDirs == null ) { // ArrayList - byOutputDir.put( - dir.getOutput() == null ? defaultOutput : dir.getOutput(), - byOutputDirs = new ArrayList() ); + byOutputDir.put( dir.getOutput() == null ? defaultOutput : dir.getOutput(), + byOutputDirs = new ArrayList() ); } byOutputDirs.add( dir ); } @@ -184,21 +181,25 @@ + dir.getOutput() + "; default output=" + defaultOutput ); boolean isSpecial = false; - + // handle resource with nested output folders if ( dir.isResource() ) { // Check if the output is a subdirectory of the default output, // and if the default output has any sources that copy there. - if ( dir.getOutput() != null && !dir.getOutput().equals( defaultOutput ) - && dir.getOutput().startsWith( defaultOutput ) && byOutputDir.get( defaultOutput ) != null - && !( (List) byOutputDir.get( defaultOutput ) ).isEmpty() ) + if ( dir.getOutput() != null // resource output dir is set + && !dir.getOutput().equals( defaultOutput ) // output dir is not default target/classes + && dir.getOutput().startsWith( defaultOutput ) // ... but is nested + && byOutputDir.get( defaultOutput ) != null // ??? + && !( (List) byOutputDir.get( defaultOutput ) ).isEmpty() // ??? + ) { // do not specify as source since the output will be nested. Instead, mark // it as a todo, and handle it with a custom build.xml file later. - log.debug( "Marking as special to prevent output folder nesting: " + dir.getPath() + " (output=" + dir.getOutput() +")"); + log.debug( "Marking as special to prevent output folder nesting: " + dir.getPath() + " (output=" + + dir.getOutput() + ")" ); isSpecial = true; specialSources.add( dir ); @@ -245,9 +246,8 @@ try { - FileWriter buildXmlWriter = new FileWriter( new File( - config.getEclipseProjectDirectory(), - "maven-eclipse.xml" ) ); + FileWriter buildXmlWriter = new FileWriter( new File( config.getEclipseProjectDirectory(), + "maven-eclipse.xml" ) ); PrettyPrintXMLWriter buildXmlPrinter = new PrettyPrintXMLWriter( buildXmlWriter ); buildXmlPrinter.startElement( "project" ); @@ -267,7 +267,7 @@ // TODO: merge source dirs on output path+filtering to reduce // tags for speed. EclipseSourceDir dir = (EclipseSourceDir) it.next(); - buildXmlPrinter.startElement( "copy"); + buildXmlPrinter.startElement( "copy" ); buildXmlPrinter.addAttribute( "todir", dir.getOutput() ); buildXmlPrinter.addAttribute( "filtering", "" + dir.isFiltering() ); @@ -300,16 +300,16 @@ log.info( "Creating external launcher file" ); // now create the launcher - new EclipseAntExternalLaunchConfigurationWriter().init( log, config, "Maven_Ant_Builder.launch", "maven-eclipse.xml").write(); + new EclipseAntExternalLaunchConfigurationWriter().init( log, config, "Maven_Ant_Builder.launch", + "maven-eclipse.xml" ).write(); // finally add it to the project writer. - config.getBuildCommands().add( - new BuildCommand( - "org.eclipse.ui.externaltools.ExternalToolBuilder", - "LaunchConfigHandle", - "/" + EclipseLaunchConfigurationWriter.FILE_DOT_EXTERNAL_TOOL_BUILDERS - + "Maven_Ant_Builder.launch" ) ); + config.getBuildCommands() + .add( + new BuildCommand( "org.eclipse.ui.externaltools.ExternalToolBuilder", "LaunchConfigHandle", + "/" + EclipseLaunchConfigurationWriter.FILE_DOT_EXTERNAL_TOOL_BUILDERS + + "Maven_Ant_Builder.launch" ) ); } // ---------------------------------------------------------------------- @@ -367,6 +367,11 @@ path = "/" + dep.getArtifactId(); //$NON-NLS-1$ kind = ATTR_SRC; } + else if ( dep.isReferencedProject() && config.isPde() ) + { + // don't do anything, referenced projects are automatically handled by eclipse in PDE builds + return; + } else { File artifactPath = dep.getFile(); Index: C:/usr/src/maven-plugins/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/EclipsePlugin.java =================================================================== --- C:/usr/src/maven-plugins/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/EclipsePlugin.java (revision 475757) +++ C:/usr/src/maven-plugins/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/EclipsePlugin.java (working copy) @@ -208,6 +208,15 @@ private boolean useProjectReferences; /** + * When set to true, the plugin will try to reference dependee modules as + * project references as opposed to installed artifacts + * + * @parameter expression="${eclipse.referenceDependeeProjects}" default-value="false" + * @required + */ + private boolean referenceDependeeProjects; + + /** * The default output directory * * @parameter expression="${outputDirectory}" alias="outputDirectory" default-value="${project.build.outputDirectory}" @@ -388,6 +397,24 @@ } /** + * Getter for referenceDependeeProjects. + * @return Returns the referenceDependeeProjects. + */ + public boolean getReferenceDependeeProjects() + { + return this.referenceDependeeProjects; + } + + /** + * Setter for referenceDependeeProjects. + * @param referenceDependeeProjects The referenceDependeeProjects to set. + */ + public void setReferenceDependeeProjects( boolean referenceDependeeProjects ) + { + this.referenceDependeeProjects = referenceDependeeProjects; + } + + /** * Getter for wtpversion. * @return Returns the wtpversion. */