package org.apache.maven.plugin.eclipse; /* * Copyright 2001-2005 The Apache Software Foundation. * * Licensed 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. */ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.Set; import java.util.TreeSet; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.maven.artifact.handler.ArtifactHandler; import org.apache.maven.model.ConfigurationContainer; import org.apache.maven.model.Plugin; import org.apache.maven.model.Resource; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.eclipse.writers.EclipseAjdtWriter; import org.apache.maven.plugin.eclipse.writers.EclipseClasspathWriter; 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.EclipseWtpComponent15Writer; import org.apache.maven.plugin.eclipse.writers.EclipseWtpComponentWriter; import org.apache.maven.plugin.eclipse.writers.EclipseWtpFacetsWriter; import org.apache.maven.plugin.eclipse.writers.EclipseWtpmodulesWriter; import org.apache.maven.plugin.ide.AbstractIdeSupportMojo; import org.apache.maven.plugin.ide.IdeDependency; import org.apache.maven.plugin.ide.IdeUtils; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * Generates the following eclipse configuration files: * * If this goal is run on a multiproject root, dependencies between modules will be configured as direct project * dependencies in Eclipse (unless useProjectReferences is set to false). * * @author Trygve Laugstøl * @author Fabrizio Giustina * @version $Id: EclipsePlugin.java 479356 2006-11-26 13:24:31Z fgiust $ * @goal eclipse * @execute phase="generate-resources" */ public class EclipsePlugin extends AbstractIdeSupportMojo { /** * */ private static final String WEAVE_DEPENDENCY = "weaveDependency"; /** * */ private static final String WEAVE_DEPENDENCIES = "weaveDependencies"; /** * */ private static final String GROUP_ID = "groupId"; /** * */ private static final String ARTIFACT_ID = "artifactId"; /** * */ private static final String ASPECT_LIBRARY = "aspectLibrary"; /** * */ private static final String ASPECT_LIBRARIES = "aspectLibraries"; /** * */ private static final String DEFAULT_TEST_ASPECT_DIRECTORY = "src/test/aspect"; /** * */ private static final String DEFAULT_ASPECT_DIRECTORY = "src/main/aspect"; private static final String ASPECT_DIRECTORY = "aspectDirectory"; private static final String TEST_ASPECT_DIRECTORY = "testAspectDirectory"; private static final String ASPECTJ_MAVEN_PLUGIN = "aspectj-maven-plugin"; private static final String ORG_CODEHAUS_MOJO = "org.codehaus.mojo"; private static final String NATURE_WST_FACET_CORE_NATURE = "org.eclipse.wst.common.project.facet.core.nature"; //$NON-NLS-1$ private static final String BUILDER_WST_COMPONENT_STRUCTURAL_DEPENDENCY_RESOLVER = "org.eclipse.wst.common.modulecore.ComponentStructuralBuilderDependencyResolver"; //$NON-NLS-1$ private static final String BUILDER_WST_VALIDATION = "org.eclipse.wst.validation.validationbuilder"; //$NON-NLS-1$ private static final String BUILDER_JDT_CORE_JAVA = "org.eclipse.jdt.core.javabuilder"; //$NON-NLS-1$ private static final String BUILDER_AJDT_CORE_JAVA = "org.eclipse.ajdt.core.ajbuilder"; //$NON-NLS-1$ private static final String BUILDER_WST_COMPONENT_STRUCTURAL = "org.eclipse.wst.common.modulecore.ComponentStructuralBuilder"; //$NON-NLS-1$ private static final String BUILDER_WST_FACET = "org.eclipse.wst.common.project.facet.core.builder"; //$NON-NLS-1$ private static final String BUILDER_PDE_MANIFEST = "org.eclipse.pde.ManifestBuilder"; //$NON-NLS-1$ private static final String BUILDER_PDE_SCHEMA = "org.eclipse.pde.SchemaBuilder"; //$NON-NLS-1$ private static final String NATURE_WST_MODULE_CORE_NATURE = "org.eclipse.wst.common.modulecore.ModuleCoreNature"; //$NON-NLS-1$ private static final String NATURE_JDT_CORE_JAVA = "org.eclipse.jdt.core.javanature"; //$NON-NLS-1$ private static final String NATURE_AJDT_CORE_JAVA = "org.eclipse.ajdt.ui.ajnature"; //$NON-NLS-1$ private static final String NATURE_JEM_WORKBENCH_JAVA_EMF = "org.eclipse.jem.workbench.JavaEMFNature"; //$NON-NLS-1$ private static final String NATURE_PDE_PLUGIN = "org.eclipse.pde.PluginNature"; //$NON-NLS-1$ private static final String COMMON_PATH_JDT_LAUNCHING_JRE_CONTAINER = "org.eclipse.jdt.launching.JRE_CONTAINER"; //$NON-NLS-1$ private static final String REQUIRED_PLUGINS_CONTAINER = "org.eclipse.pde.core.requiredPlugins"; //$NON-NLS-1$ // warning, order is important for binary search public static final String[] WTP_SUPPORTED_VERSIONS = new String[] { "1.0", "1.5", "R7", "none" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ /** * Constant for 'artifactId' element in POM.xml. */ private static final String POM_ELT_ARTIFACT_ID = ARTIFACT_ID; //$NON-NLS-1$ /** * Constant for 'groupId' element in POM.xml. */ private static final String POM_ELT_GROUP_ID = GROUP_ID; //$NON-NLS-1$ /** * List of eclipse project natures. By default the * org.eclipse.jdt.core.javanature nature plus the needed WTP * natures are added. Natures added using this property replace the default list. * *
     * <projectnatures>
     *    <projectnature>org.eclipse.jdt.core.javanature</projectnature>
     *    <projectnature>org.eclipse.wst.common.modulecore.ModuleCoreNature</projectnature>
     * </projectnatures>
     * 
* * @parameter */ private List projectnatures; /** * List of eclipse project natures to be added to the default ones. * *
     * <additionalProjectnatures>
     *    <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
     * </additionalProjectnatures>
     * 
* * @parameter */ private List additionalProjectnatures; /** * List of eclipse build commands. By default the org.eclipse.jdt.core.javabuilder builder plus the needed * WTP builders are added. Configuration example: * *
     * <buildcommands>
     *    <buildcommand>org.eclipse.wst.common.modulecore.ComponentStructuralBuilder</buildcommand>
     *    <buildcommand>org.eclipse.jdt.core.javabuilder</buildcommand>
     *    <buildcommand>org.eclipse.wst.common.modulecore.ComponentStructuralBuilderDependencyResolver</buildcommand>
     * </buildcommands>
     * 
* * @parameter */ private List buildcommands; /** * List of eclipse build commands to be added to the default ones. * *
     * <additionalBuildcommands>
     *    <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
     * </additionalBuildcommands>
     * 
* * @parameter */ private List additionalBuildcommands; /** * List of container classpath entries. By default the org.eclipse.jdt.launching.JRE_CONTAINER classpath * container is added. Configuration example: *
     * <classpathContainers>
     *    <classpathContainer>org.eclipse.jdt.launching.JRE_CONTAINER</classpathContainer>
     *    <classpathContainer>org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v5.5</classpathContainer>
     *    <classpathContainer>org.eclipse.jst.j2ee.internal.web.container/artifact</classpathContainer>
     * </classpathContainers>
     * 
* * @parameter */ private List classpathContainers; /** * Enables/disables the downloading of source attachments. Defaults to false. * * @parameter expression="${eclipse.downloadSources}" * @deprecated use downloadSources */ private boolean eclipseDownloadSources; /** * Eclipse workspace directory. * * @parameter expression="${eclipse.workspace}" alias="outputDir" */ private File eclipseProjectDir; /** * When set to false, the plugin will not create sub-projects and instead * reference those sub-projects using the installed package in the local * repository * * @parameter expression="${eclipse.useProjectReferences}" default-value="true" * @required */ private boolean useProjectReferences; /** * The default output directory * * @parameter expression="${outputDirectory}" alias="outputDirectory" default-value="${project.build.outputDirectory}" * @required */ private File buildOutputDirectory; /** * The version of WTP for which configuration files will be generated. * The default value is "none" (don't generate WTP configuration), supported versions are "R7" and "1.0" * * @parameter expression="${wtpversion}" default-value="none" */ private String wtpversion; /** * Is it an PDE project? If yes, the plugin adds the necessary natures and build commands to * the .project file. Additionally it copies all libraries to a project local directory and * references them instead of referencing the files in the local Maven repository. It also * ensured that the "Bundle-Classpath" in META-INF/MANIFEST.MF is synchronized. * * @parameter expression="${eclipse.pde}" default-value="false" */ private boolean pde; /** * Is it an AJDT project? If yes, the plugin adds the necessary natures and build commands to * the .project file. * * @parameter expression="${eclipse.ajdt}" default-value="false" */ private boolean ajdt; /** * The relative path of the manifest file * * @parameter expression="${eclipse.manifest}" default-value="${basedir}/META-INF/MANIFEST.MF" */ private File manifest; /** * Allow to configure additional generic configuration files for eclipse that will be written out to disk when * running eclipse:eclipse. FOr each file you can specify the name and the text content. * *
     * <additionalConfig>
     *    <file>
     *      <name>.checkstyle</name>
     *      <content>
     *        <![CDATA[<fileset-config file-format-version="1.2.0" simple-config="true">
     *          <fileset name="all" enabled="true" check-config-name="acme corporate style" local="false">
     *              <file-match-pattern match-pattern="." include-pattern="true"/>
     *          </fileset>
     *          <filter name="NonSrcDirs" enabled="true"/>
     *        </fileset-config>]]>
     *      </content>
     *    </file>
     * </additionalConfig>
     * 
* * @parameter */ private EclipseConfigFile[] additionalConfig; /** * Parsed wtp version. */ private float wtpVersionFloat; /** * Not a plugin parameter. Is this a java project? */ private boolean isJavaProject; protected boolean isJavaProject() { return isJavaProject; } /** * Getter for buildcommands. * @return Returns the buildcommands. */ public List getBuildcommands() { return this.buildcommands; } /** * Setter for buildcommands. * @param buildcommands The buildcommands to set. */ public void setBuildcommands( List buildcommands ) { this.buildcommands = buildcommands; } /** * Getter for buildOutputDirectory. * @return Returns the buildOutputDirectory. */ public File getBuildOutputDirectory() { return this.buildOutputDirectory; } /** * Setter for buildOutputDirectory. * @param buildOutputDirectory The buildOutputDirectory to set. */ public void setBuildOutputDirectory( File buildOutputDirectory ) { this.buildOutputDirectory = buildOutputDirectory; } /** * Getter for classpathContainers. * @return Returns the classpathContainers. */ public List getClasspathContainers() { return this.classpathContainers; } /** * Setter for classpathContainers. * @param classpathContainers The classpathContainers to set. */ public void setClasspathContainers( List classpathContainers ) { this.classpathContainers = classpathContainers; } /** * Getter for eclipseProjectDir. * @return Returns the eclipseProjectDir. */ public File getEclipseProjectDir() { return this.eclipseProjectDir; } /** * Setter for eclipseProjectDir. * @param eclipseProjectDir The eclipseProjectDir to set. */ public void setEclipseProjectDir( File eclipseProjectDir ) { this.eclipseProjectDir = eclipseProjectDir; } /** * Getter for projectnatures. * @return Returns the projectnatures. */ public List getProjectnatures() { return this.projectnatures; } /** * Setter for projectnatures. * @param projectnatures The projectnatures to set. */ public void setProjectnatures( List projectnatures ) { this.projectnatures = projectnatures; } /** * Getter for useProjectReferences. * @return Returns the useProjectReferences. */ public boolean getUseProjectReferences() { return this.useProjectReferences; } /** * Setter for useProjectReferences. * @param useProjectReferences The useProjectReferences to set. */ public void setUseProjectReferences( boolean useProjectReferences ) { this.useProjectReferences = useProjectReferences; } /** * Getter for wtpversion. * @return Returns the wtpversion. */ public String getWtpversion() { return this.wtpversion; } /** * Setter for wtpversion. * @param wtpversion The wtpversion to set. */ public void setWtpversion( String wtpversion ) { this.wtpversion = wtpversion; } /** * Getter for additionalBuildcommands. * @return Returns the additionalBuildcommands. */ public List getAdditionalBuildcommands() { return this.additionalBuildcommands; } /** * Setter for additionalBuildcommands. * @param additionalBuildcommands The additionalBuildcommands to set. */ public void setAdditionalBuildcommands( List additionalBuildcommands ) { this.additionalBuildcommands = additionalBuildcommands; } /** * Getter for additionalProjectnatures. * @return Returns the additionalProjectnatures. */ public List getAdditionalProjectnatures() { return this.additionalProjectnatures; } /** * Setter for additionalProjectnatures. * @param additionalProjectnatures The additionalProjectnatures to set. */ public void setAdditionalProjectnatures( List additionalProjectnatures ) { this.additionalProjectnatures = additionalProjectnatures; } /** * @see org.apache.maven.plugin.Mojo#execute() */ public boolean setup() throws MojoExecutionException { boolean ready = true; checkDeprecations(); ajdt = enableAjdt( executedProject ); ready = validate(); String packaging = executedProject.getPackaging(); // TODO: Why are we using project in some places, and executedProject in others?? ArtifactHandler artifactHandler = this.project.getArtifact().getArtifactHandler(); // ear projects don't contain java sources isJavaProject = Constants.LANGUAGE_JAVA.equals( artifactHandler.getLanguage() ) && !Constants.PROJECT_PACKAGING_EAR.equals( packaging ); setupExtras(); parseConfigurationOptions(); // defaults if ( projectnatures == null ) { fillDefaultNatures( packaging ); } if ( additionalProjectnatures != null ) { projectnatures.addAll( additionalProjectnatures ); } if ( buildcommands == null ) { fillDefaultBuilders( packaging ); } else { convertBuildCommandList( buildcommands ); } if ( additionalBuildcommands != null ) { convertBuildCommandList( additionalBuildcommands ); buildcommands.addAll( additionalBuildcommands ); } if ( classpathContainers == null ) { fillDefaultClasspathContainers( packaging ); } else { verifyClasspathContainerListIsComplete(); } // ready to start return ready; } protected void convertBuildCommandList( List commands ) { if ( commands != null ) { for ( ListIterator i = commands.listIterator(); i.hasNext(); ) { Object command = i.next(); if ( command instanceof String ) { command = new BuildCommand( (String) command ); i.set( command ); } } } } private void parseConfigurationOptions() { if ( "R7".equalsIgnoreCase( wtpversion ) ) //$NON-NLS-1$ { wtpVersionFloat = 0.7f; } else if ( "1.0".equalsIgnoreCase( wtpversion ) ) //$NON-NLS-1$ { wtpVersionFloat = 1.0f; } else if ( "1.5".equalsIgnoreCase( wtpversion ) ) //$NON-NLS-1$ { wtpVersionFloat = 1.5f; } if ( !"none".equalsIgnoreCase( wtpversion ) ) { getLog().info( Messages.getString( "EclipsePlugin.wtpversion", wtpversion ) ); } } protected void setupExtras() throws MojoExecutionException { // extension point. } protected void verifyClasspathContainerListIsComplete() { // this is an extension point. if ( !classpathContainers.contains( COMMON_PATH_JDT_LAUNCHING_JRE_CONTAINER ) ) //$NON-NLS-1$ { getLog().warn( Messages.getString( "EclipsePlugin.missingjrecontainer" ) ); //$NON-NLS-1$ classpathContainers.add( 0, COMMON_PATH_JDT_LAUNCHING_JRE_CONTAINER ); } } private boolean validate() throws MojoExecutionException { // validate sanity of the current m2 project if ( Arrays.binarySearch( WTP_SUPPORTED_VERSIONS, wtpversion ) < 0 ) { throw new MojoExecutionException( Messages .getString( "EclipsePlugin.unsupportedwtp", new Object[] { //$NON-NLS-1$ wtpversion, StringUtils.join( WTP_SUPPORTED_VERSIONS, " " ) } ) ); //$NON-NLS-1$ } String packaging = executedProject.getPackaging(); assertNotEmpty( executedProject.getGroupId(), POM_ELT_GROUP_ID ); //$NON-NLS-1$ assertNotEmpty( executedProject.getArtifactId(), POM_ELT_ARTIFACT_ID ); //$NON-NLS-1$ if ( executedProject.getFile() == null || !executedProject.getFile().exists() ) { throw new MojoExecutionException( Messages.getString( "EclipsePlugin.missingpom" ) ); //$NON-NLS-1$ } if ( "pom".equals( packaging ) && eclipseProjectDir == null ) //$NON-NLS-1$ { getLog().info( Messages.getString( "EclipsePlugin.pompackaging" ) ); //$NON-NLS-1$ return false; } if ( "eclipse-plugin".equals( packaging ) ) { pde = true; } if ( eclipseProjectDir == null ) { eclipseProjectDir = executedProject.getFile().getParentFile(); } if ( !eclipseProjectDir.exists() && !eclipseProjectDir.mkdirs() ) { throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantcreatedir", eclipseProjectDir ) ); //$NON-NLS-1$ } if ( !eclipseProjectDir.equals( executedProject.getFile().getParentFile() ) ) { if ( !eclipseProjectDir.isDirectory() ) { throw new MojoExecutionException( Messages.getString( "EclipsePlugin.notadir", eclipseProjectDir ) ); //$NON-NLS-1$ } eclipseProjectDir = new File( eclipseProjectDir, executedProject.getArtifactId() ); if ( !eclipseProjectDir.isDirectory() && !eclipseProjectDir.mkdirs() ) { throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantcreatedir", eclipseProjectDir ) ); //$NON-NLS-1$ } } validateExtras(); return true; } protected void validateExtras() { // provided for extension. } private void checkDeprecations() { if ( eclipseDownloadSources ) { // deprecated warning getLog().warn( Messages.getString( "EclipsePlugin.deprecatedpar", new Object[] { //$NON-NLS-1$ "eclipse.downloadSources", //$NON-NLS-1$ "downloadSources" } ) ); //$NON-NLS-1$ downloadSources = true; } checkExtraDeprecations(); } protected void checkExtraDeprecations() { // provided for extension. } public void writeConfiguration( IdeDependency[] deps ) throws MojoExecutionException { EclipseWriterConfig config = createEclipseWriterConfig( deps ); // NOTE: This could change the config! writeExtraConfiguration( config ); if ( wtpVersionFloat == 0.7f ) { new EclipseWtpmodulesWriter().init( getLog(), config ).write(); } if ( wtpVersionFloat >= 1.0f ) { new EclipseWtpFacetsWriter().init( getLog(), config ).write(); } if ( wtpVersionFloat == 1.0f ) { new EclipseWtpComponentWriter().init( getLog(), config ).write(); } if ( wtpVersionFloat >= 1.5 ) { new EclipseWtpComponent15Writer().init( getLog(), config ).write(); } new EclipseSettingsWriter().init( getLog(), config ).write(); if ( isJavaProject ) { new EclipseClasspathWriter().init( getLog(), config ).write(); if ( ajdt ) { new EclipseAjdtWriter().init( getLog(), config ).write(); } } if ( pde ) { this.getLog().info( "The Maven Eclipse plugin runs in 'pde'-mode." ); new EclipseOSGiManifestWriter().init( getLog(), config ).write(); } // NOTE: This one MUST be after EclipseClasspathwriter, and possibly others, // since currently EclipseClasspathWriter does some magic to detect nested // output folders and modifies the configuration by adding new (Ant) builders. // So the .project file must be written AFTER those have run! new EclipseProjectWriter().init( getLog(), config ).write(); if ( additionalConfig != null ) { for ( int j = 0; j < additionalConfig.length; j++ ) { EclipseConfigFile file = additionalConfig[j]; File projectRelativeFile = new File( this.eclipseProjectDir, file.getName() ); if ( projectRelativeFile.isDirectory() ) { // just ignore? getLog().warn( Messages.getString( "EclipsePlugin.foundadir", //$NON-NLS-1$ projectRelativeFile.getAbsolutePath() ) ); } try { FileUtils.fileWrite( projectRelativeFile.getAbsolutePath(), file.getContent() ); } catch ( IOException e ) { throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantwritetofile", //$NON-NLS-1$ projectRelativeFile.getAbsolutePath() ) ); } } } getLog().info( Messages.getString( "EclipsePlugin.wrote", new Object[] { //$NON-NLS-1$ project.getArtifactId(), eclipseProjectDir.getAbsolutePath() } ) ); } protected EclipseWriterConfig createEclipseWriterConfig( IdeDependency[] deps ) throws MojoExecutionException { File projectBaseDir = executedProject.getFile().getParentFile(); // build a list of UNIQUE source dirs (both src and resources) to be // used in classpath and wtpmodules EclipseSourceDir[] sourceDirs = buildDirectoryList( executedProject, eclipseProjectDir, buildOutputDirectory ); EclipseWriterConfig config = new EclipseWriterConfig(); // TODO: add mojo param 'addVersionToProjectName' and if set append // -version to the project name. config.setEclipseProjectName( project.getArtifactId() ); Set convertedBuildCommands = new LinkedHashSet(); if ( buildcommands != null ) { for ( Iterator it = buildcommands.iterator(); it.hasNext(); ) { Object cmd = it.next(); if ( cmd instanceof BuildCommand ) { convertedBuildCommands.add( (BuildCommand) cmd ); } else { convertedBuildCommands.add( new BuildCommand( (String) cmd ) ); } } } if( ajdt ) { config.setAjdtWeaveDeps( buildAjdtWeaveDeps( deps ) ); config.setAspectjDeps( buildAspectjDeps( deps ) ); } config.setBuildCommands( new LinkedList( convertedBuildCommands ) ); config.setBuildOutputDirectory( buildOutputDirectory ); config.setClasspathContainers( classpathContainers ); config.setDeps( deps ); config.setEclipseProjectDirectory( eclipseProjectDir ); config.setLocalRepository( localRepository ); config.setManifestFile( manifest ); config.setPde( pde ); config.setProject( project ); config.setProjectBaseDir( projectBaseDir ); config.setProjectnatures( projectnatures ); config.setSourceDirs( sourceDirs ); return config; } /** * Write any extra configuration information for the Eclipse project. This is an extension * point, called before the main configurations are written. *
* * NOTE: This could change the config! * * * @param config * @throws MojoExecutionException */ protected void writeExtraConfiguration( EclipseWriterConfig config ) throws MojoExecutionException { // extension point. } private void assertNotEmpty( String string, String elementName ) throws MojoExecutionException { if ( string == null ) { throw new MojoExecutionException( Messages.getString( "EclipsePlugin.missingelement", elementName ) ); //$NON-NLS-1$ } } protected void fillDefaultNatures( String packaging ) { projectnatures = new ArrayList(); if ( wtpVersionFloat >= 1.0f ) { projectnatures.add( NATURE_WST_FACET_CORE_NATURE ); // WTP 1.0 nature } if ( isJavaProject ) { if ( ajdt ) { projectnatures.add( NATURE_AJDT_CORE_JAVA ); } projectnatures.add( NATURE_JDT_CORE_JAVA ); } if ( wtpVersionFloat >= 0.7f ) { projectnatures.add( NATURE_WST_MODULE_CORE_NATURE ); // WTP 0.7/1.0 nature if ( isJavaProject ) { projectnatures.add( NATURE_JEM_WORKBENCH_JAVA_EMF ); // WTP 0.7/1.0 nature } } if ( pde ) { projectnatures.add( NATURE_PDE_PLUGIN ); } } protected void fillDefaultClasspathContainers( String packaging ) { classpathContainers = new ArrayList(); classpathContainers.add( COMMON_PATH_JDT_LAUNCHING_JRE_CONTAINER ); if ( pde ) { classpathContainers.add( REQUIRED_PLUGINS_CONTAINER ); } } protected void fillDefaultBuilders( String packaging ) { buildcommands = new ArrayList(); if ( wtpVersionFloat == 0.7f ) { buildcommands.add( new BuildCommand( BUILDER_WST_COMPONENT_STRUCTURAL ) ); // WTP 0.7 builder } if ( isJavaProject ) { if ( ajdt ) { buildcommands.add( BUILDER_AJDT_CORE_JAVA ); } else { buildcommands.add( new BuildCommand( BUILDER_JDT_CORE_JAVA ) ); } } if ( wtpVersionFloat >= 1.5f ) { buildcommands.add( new BuildCommand( BUILDER_WST_FACET ) ); // WTP 1.5 builder } if ( wtpVersionFloat >= 0.7f ) { buildcommands.add( new BuildCommand( BUILDER_WST_VALIDATION ) ); // WTP 0.7/1.0 builder } if ( wtpVersionFloat == 0.7f ) { buildcommands.add( new BuildCommand( BUILDER_WST_COMPONENT_STRUCTURAL_DEPENDENCY_RESOLVER ) ); // WTP 0.7 builder } if ( pde ) { buildcommands.add( new BuildCommand( BUILDER_PDE_MANIFEST ) ); buildcommands.add( new BuildCommand( BUILDER_PDE_SCHEMA ) ); } } public EclipseSourceDir[] buildDirectoryList( MavenProject project, File basedir, File buildOutputDirectory ) throws MojoExecutionException { File projectBaseDir = project.getFile().getParentFile(); // avoid duplicated entries Set directories = new TreeSet(); extractSourceDirs( directories, project.getCompileSourceRoots(), basedir, projectBaseDir, false, null ); String relativeOutput = IdeUtils.toRelativeAndFixSeparator( projectBaseDir, buildOutputDirectory, false ); extractResourceDirs( directories, project.getBuild().getResources(), project, basedir, projectBaseDir, false, relativeOutput ); // If using the standard output location, don't mix the test output into it. String testOutput = null; boolean useStandardOutputDir = buildOutputDirectory.equals( new File( project.getBuild().getOutputDirectory() ) ); if ( useStandardOutputDir ) { testOutput = IdeUtils.toRelativeAndFixSeparator( projectBaseDir, new File( project.getBuild() .getTestOutputDirectory() ), false ); } extractSourceDirs( directories, project.getTestCompileSourceRoots(), basedir, projectBaseDir, true, testOutput ); extractResourceDirs( directories, project.getBuild().getTestResources(), project, basedir, projectBaseDir, true, testOutput ); if( ajdt ) { extractAspectDirs( directories, project, basedir, projectBaseDir, testOutput ); } return (EclipseSourceDir[]) directories.toArray( new EclipseSourceDir[directories.size()] ); } private void extractSourceDirs( Set directories, List sourceRoots, File basedir, File projectBaseDir, boolean test, String output ) throws MojoExecutionException { for ( Iterator it = sourceRoots.iterator(); it.hasNext(); ) { File sourceRootFile = new File( (String) it.next() ); if ( sourceRootFile.isDirectory() ) { String sourceRoot = IdeUtils.toRelativeAndFixSeparator( projectBaseDir, sourceRootFile, !projectBaseDir .equals( basedir ) ); directories.add( new EclipseSourceDir( sourceRoot, output, false, test, null, null, false ) ); } } } void extractResourceDirs( Set directories, List resources, MavenProject project, File basedir, File workspaceProjectBaseDir, boolean test, String output ) throws MojoExecutionException { for ( Iterator it = resources.iterator(); it.hasNext(); ) { Resource resource = (Resource) it.next(); getLog().debug( "Processing resource dir: " + resource.getDirectory() ); String includePattern = null; String excludePattern = null; if ( resource.getIncludes().size() != 0 ) { includePattern = StringUtils.join( resource.getIncludes().iterator(), "|" ); } if ( resource.getExcludes().size() != 0 ) { excludePattern = StringUtils.join( resource.getExcludes().iterator(), "|" ); } // TODO: figure out how to merge if the same dir is specified twice // with different in/exclude patterns. File resourceDirectory = new File( /*basedir,*/ resource.getDirectory() ); if ( !resourceDirectory.exists() || !resourceDirectory.isDirectory() ) { getLog().debug( "Resource dir: " + resourceDirectory + " either missing or not a directory." ); continue; } String resourceDir = IdeUtils.toRelativeAndFixSeparator( workspaceProjectBaseDir, resourceDirectory, !workspaceProjectBaseDir .equals( basedir ) ); if ( output != null ) { File outputFile = new File( workspaceProjectBaseDir, output ); // create output dir if it doesn't exist outputFile.mkdirs(); if ( !StringUtils.isEmpty( resource.getTargetPath() ) ) { outputFile = new File( outputFile, resource.getTargetPath() ); // create output dir if it doesn't exist outputFile.mkdirs(); } output = IdeUtils.toRelativeAndFixSeparator( workspaceProjectBaseDir, outputFile, false ); } getLog().debug( "Adding eclipse source dir: { " + resourceDir + ", " + output + ", true, " + test + ", " + includePattern + ", " + excludePattern + " }." ); directories.add( new EclipseSourceDir( resourceDir, output, true, test, includePattern, excludePattern, resource.isFiltering() ) ); } } private void extractAspectDirs( Set directories, MavenProject project, File basedir, File projectBaseDir, String testOutput ) throws MojoExecutionException { Xpp3Dom configuration = getAspectjConfiguration( project ); if( configuration != null ) { String aspectDirectory = DEFAULT_ASPECT_DIRECTORY; Xpp3Dom aspectDirectoryElement = configuration.getChild( ASPECT_DIRECTORY ); if( aspectDirectoryElement != null ) { aspectDirectory = aspectDirectoryElement.getValue(); } File aspectDirectoryFile = new File( basedir, aspectDirectory ); if( aspectDirectoryFile.exists() && aspectDirectoryFile.isDirectory() ) { String sourceRoot = IdeUtils.toRelativeAndFixSeparator( projectBaseDir, aspectDirectoryFile, !projectBaseDir .equals( basedir ) ); directories.add( new EclipseSourceDir( sourceRoot, null, false, false, null, null, false ) ); } String testAspectDirectory = DEFAULT_TEST_ASPECT_DIRECTORY; Xpp3Dom testAspectDirectoryElement = configuration.getChild( TEST_ASPECT_DIRECTORY ); if( testAspectDirectoryElement != null ) { testAspectDirectory = testAspectDirectoryElement.getValue(); } File testAspectDirectoryFile = new File( basedir, testAspectDirectory ); if( testAspectDirectoryFile.exists() && testAspectDirectoryFile.isDirectory() ) { String sourceRoot = IdeUtils.toRelativeAndFixSeparator( projectBaseDir, testAspectDirectoryFile, !projectBaseDir .equals( basedir ) ); directories.add( new EclipseSourceDir( sourceRoot, testOutput, false, true, null, null, false ) ); } } } private boolean enableAjdt(MavenProject project) { boolean enable = false; List buildPlugins = project.getBuildPlugins(); for ( Iterator it = buildPlugins.iterator(); it.hasNext(); ) { Plugin plugin = (Plugin)it.next(); if( plugin.getGroupId().equals( ORG_CODEHAUS_MOJO ) && plugin.getArtifactId().equals( ASPECTJ_MAVEN_PLUGIN ) ) { enable = true; break; } } return enable; } private Xpp3Dom getAspectjConfiguration(MavenProject project) { Xpp3Dom configuration = null; List buildPlugins = project.getBuildPlugins(); for ( Iterator it = buildPlugins.iterator(); it.hasNext(); ) { Plugin plugin = (Plugin)it.next(); if( plugin.getGroupId().equals( ORG_CODEHAUS_MOJO ) && plugin.getArtifactId().equals( ASPECTJ_MAVEN_PLUGIN ) ) { configuration = (Xpp3Dom)plugin.getConfiguration(); break; } } return configuration; } private IdeDependency[] buildAspectjDeps( IdeDependency[] deps ) throws MojoExecutionException { List aspectjDeps = new LinkedList(); Xpp3Dom configuration = getAspectjConfiguration( executedProject ); if( configuration != null ) { Xpp3Dom aspectLibrariesParent = configuration.getChild( ASPECT_LIBRARIES ); if( aspectLibrariesParent != null ) { Xpp3Dom[] aspectLibraries = aspectLibrariesParent.getChildren( ASPECT_LIBRARY ); outerLoop: for( int i = 0 ; i < aspectLibraries.length ; i++ ) { String artifactId = aspectLibraries[ i ].getChild( ARTIFACT_ID ).getValue(); String groupId = aspectLibraries[ i ].getChild( GROUP_ID ).getValue(); for( int j = 0 ; j < deps.length ; j++ ) { if( deps[ j ].getArtifactId().equals( artifactId ) && deps[ j ].getGroupId().equals( groupId ) ) { aspectjDeps.add( deps[ j ] ); continue outerLoop; } } throw new MojoExecutionException( "AspectLibrary is not a dependency of project" ); } } } return (IdeDependency[])aspectjDeps.toArray( new IdeDependency[ aspectjDeps.size() ] ); } private IdeDependency[] buildAjdtWeaveDeps( IdeDependency[] deps ) throws MojoExecutionException { List aspectjDeps = new LinkedList(); Xpp3Dom configuration = getAspectjConfiguration( executedProject ); if( configuration != null ) { Xpp3Dom weaveDependenciesParent = configuration.getChild( WEAVE_DEPENDENCIES ); if( weaveDependenciesParent != null ) { Xpp3Dom[] weaveDependencies = weaveDependenciesParent.getChildren( WEAVE_DEPENDENCY ); outerLoop: for( int i = 0 ; i < weaveDependencies.length ; i++ ) { String artifactId = weaveDependencies[ i ].getChild( ARTIFACT_ID ).getValue(); String groupId = weaveDependencies[ i ].getChild( GROUP_ID ).getValue(); for( int j = 0 ; j < deps.length ; j++ ) { if( deps[ j ].getArtifactId().equals( artifactId ) && deps[ j ].getGroupId().equals( groupId ) ) { aspectjDeps.add( deps[ j ] ); continue outerLoop; } } throw new MojoExecutionException( "WeaveDependency is not a dependency of project" ); } } } return (IdeDependency[])aspectjDeps.toArray( new IdeDependency[ aspectjDeps.size() ] ); } }