org.apache.maven.plugin.eclipse.EclipsePlugin Maven / Gradle / Ivy
package org.apache.maven.plugin.eclipse;
/*
* 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.
*/
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.manager.WagonManager;
import org.apache.maven.model.Build;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.eclipse.reader.ReadWorkspaceLocations;
import org.apache.maven.plugin.eclipse.writers.EclipseAjdtWriter;
import org.apache.maven.plugin.eclipse.writers.EclipseClasspathWriter;
import org.apache.maven.plugin.eclipse.writers.EclipseManifestWriter;
import org.apache.maven.plugin.eclipse.writers.EclipseProjectWriter;
import org.apache.maven.plugin.eclipse.writers.EclipseWriterConfig;
import org.apache.maven.plugin.eclipse.writers.workspace.EclipseSettingsWriter;
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;
import org.apache.maven.plugin.eclipse.writers.wtp.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.plugin.ide.JeeUtils;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.MavenSettingsBuilder;
import org.apache.maven.settings.Proxy;
import org.apache.maven.settings.Settings;
import org.apache.maven.wagon.Wagon;
import org.apache.maven.wagon.WagonException;
import org.apache.maven.wagon.observers.Debug;
import org.apache.maven.wagon.proxy.ProxyInfo;
import org.apache.maven.wagon.repository.Repository;
import org.codehaus.plexus.resource.ResourceManager;
import org.codehaus.plexus.resource.loader.FileResourceLoader;
import org.codehaus.plexus.resource.loader.ResourceNotFoundException;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
/**
* Generates the following eclipse configuration files:
*
* .project
and .classpath
files
* .setting/org.eclipse.jdt.core.prefs
with project specific compiler settings
* - various configuration files for WTP (Web Tools Project), if the parameter
wtpversion
is set to a
* valid version (WTP configuration is not generated by default)
*
* 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$
*/
@Mojo( name = "eclipse" )
@Execute( phase = LifecyclePhase.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 ASPECT_LIBRARY = "aspectLibrary";
private static final String ASPECT_LIBRARIES = "aspectLibraries";
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 DEFAULT_TEST_ASPECT_DIRECTORY = "src/test/aspect";
private static final String DEFAULT_ASPECT_DIRECTORY = "src/main/aspect";
private static final String NATURE_WST_FACET_CORE_NATURE =
"org.eclipse.wst.common.project.facet.core.nature";
private static final String BUILDER_WST_COMPONENT_STRUCTURAL_DEPENDENCY_RESOLVER =
"org.eclipse.wst.common.modulecore.ComponentStructuralBuilderDependencyResolver";
protected static final String BUILDER_WST_VALIDATION = "org.eclipse.wst.validation.validationbuilder";
private static final String BUILDER_JDT_CORE_JAVA = "org.eclipse.jdt.core.javabuilder";
private static final String BUILDER_WST_COMPONENT_STRUCTURAL =
"org.eclipse.wst.common.modulecore.ComponentStructuralBuilder";
private static final String BUILDER_WST_FACET = "org.eclipse.wst.common.project.facet.core.builder";
private static final String BUILDER_AJDT_CORE_JAVA = "org.eclipse.ajdt.core.ajbuilder";
private static final String NATURE_WST_MODULE_CORE_NATURE = "org.eclipse.wst.common.modulecore.ModuleCoreNature";
private static final String NATURE_JDT_CORE_JAVA = "org.eclipse.jdt.core.javanature";
private static final String NATURE_JEM_WORKBENCH_JAVA_EMF = "org.eclipse.jem.workbench.JavaEMFNature";
private static final String NATURE_AJDT_CORE_JAVA = "org.eclipse.ajdt.ui.ajnature";
protected static final String COMMON_PATH_JDT_LAUNCHING_JRE_CONTAINER = "org.eclipse.jdt.launching.JRE_CONTAINER";
protected static final String ASPECTJ_RT_CONTAINER = "org.eclipse.ajdt.core.ASPECTJRT_CONTAINER";
// warning, order is important for binary search
public static final String[] WTP_SUPPORTED_VERSIONS = new String[] { "1.0", "1.5", "2.0", "R7", "none" };
public static final String ASPECTJ_FILE_PATTERN = "**/*.aj";
public static final String JAVA_FILE_PATTERN = "**/*.java";
/**
* Constant for 'artifactId' element in POM.xml.
*/
private static final String POM_ELT_ARTIFACT_ID = "artifactId";
/**
* Constant for 'groupId' element in POM.xml.
*/
private static final String POM_ELT_GROUP_ID = "groupId";
/**
* 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 artifacts, represented as groupId:artifactId
, to exclude from the eclipse classpath, being
* provided by some eclipse classPathContainer.
*
* @see http://jira.codehaus.org/browse/MECLIPSE-79
* @since 2.5
*/
@Parameter
private List excludes;
/**
* 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 project facets to be added to the default ones.
*
*
* <additionalProjectFacets>
* <jst.jsf>1.1<jst.jsf/>
* </additionalProjectFacets>
*
*/
@Parameter
private Map additionalProjectFacets;
// CHECKSTYLE_OFF: LineLength
/**
* List of eclipse build commands. By default the org.eclipse.jdt.core.javabuilder
builder plus the
* needed WTP builders are added. If you specify any configuration for this parameter, only those buildcommands
* specified will be used; the defaults won't be added. Use the additionalBuildCommands
parameter for
* that. Configuration example: Old style:
*
*
* <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>
*
*
* For new style, see additionalBuildCommands
.
*/
// CHECKSTYLE_ON: LineLength
@Parameter
private List buildcommands;
// CHECKSTYLE_OFF: LineLength
/**
* List of eclipse build commands to be added to the default ones. Old style:
*
*
* <additionalBuildcommands>
* <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
* </additionalBuildcommands>
*
*
* New style:
*
*
* <additionalBuildcommands>
* <buildCommand>
* <name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
* <triggers>auto,full,incremental,</triggers>
* <arguments>
* <LaunchConfigHandle><project>./externalToolBuilders/MavenBuilder.launch</LaunchConfighandle>
* </arguments>
* </buildCommand>
* </additionalBuildcommands>
*
*
* Note the difference between buildcommand
and
* buildCommand
. You can mix and match old and new-style configuration entries.
*/
// CHECKSTYLE_ON: LineLength
@Parameter
private List additionalBuildcommands;
// CHECKSTYLE_OFF: LineLength
/**
* 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>
*
*/
// CHECKSTYLE_ON: LineLength
@Parameter
private List classpathContainers;
/**
* Enables/disables the downloading of source attachments. Defaults to false. DEPRECATED - use downloadSources
*
* @deprecated use downloadSources
*/
@Parameter( property = "eclipse.downloadSources" )
private boolean eclipseDownloadSources;
/**
* Eclipse workspace directory.
*/
@Parameter( property = "eclipse.projectDir", 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( property = "eclipse.useProjectReferences", defaultValue = "true", required = true )
private boolean useProjectReferences;
/**
* The default output directory
*/
@Parameter( property = "outputDirectory", alias = "outputDirectory",
defaultValue = "${project.build.outputDirectory}", required = true )
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", "1.0", "1.5" and "2.0"
*/
@Parameter( property = "wtpversion", defaultValue = "none" )
private String wtpversion;
/**
* JEE context name of the WTP module. ( ex. WEB context name ). You can use "ROOT" if you want to map the webapp to
* the root context.
*/
@Parameter( property = "wtpContextName" )
private String wtpContextName;
/**
* Is it an AJDT project? If yes, the plugin adds the necessary natures and build commands to the .project file.
*/
private boolean ajdt;
/**
* The relative path of the manifest file
*/
@Parameter( property = "eclipse.manifest", defaultValue = "${basedir}/META-INF/MANIFEST.MF" )
private File manifest;
// CHECKSTYLE_OFF: LineLength
/**
* 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.
*
*
* <plugin>
* <groupId>org.apache.maven.plugins</groupId>
* <artifactId>maven-eclipse-plugin</artifactId>
* <configuration>
* <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>
* </configuration>
* </plugin>
*
*
* Instead of the content you can also define (from version 2.5) an url to download the file :
*
*
* <plugin>
* <groupId>org.apache.maven.plugins</groupId>
* <artifactId>maven-eclipse-plugin</artifactId>
* <configuration>
* <additionalConfig>
* <file>
* <name>.checkstyle</name>
* <url>http://some.place.org/path/to/file</url>
* </file>
* </additionalConfig>
* </configuration>
*
*
* or a location :
*
*
* <plugin>
* <groupId>org.apache.maven.plugins</groupId>
* <artifactId>maven-eclipse-plugin</artifactId>
* <configuration>
* <additionalConfig>
* <file>
* <name>.checkstyle</name>
* <location>/checkstyle-config.xml</location>
* </file>
* </additionalConfig>
* </configuration>
* <dependencies>
* <!-- The file defined in the location is stored in this dependency -->
* <dependency>
* <groupId>eclipsetest</groupId>
* <artifactId>checkstyle-config</artifactId>
* <version>1.0</version>
* </dependency>
* </dependencies>
* </plugin>
*
*/
// CHECKSTYLE_ON: LineLength
@Parameter
private EclipseConfigFile[] additionalConfig;
/**
* If set to true
, the version number of the artifact is appended to the name of the generated Eclipse
* project. See projectNameTemplate for other options.
*/
@Parameter( property = "eclipse.addVersionToProjectName", defaultValue = "false" )
private boolean addVersionToProjectName;
/**
* If set to true
, the groupId of the artifact is appended to the name of the generated Eclipse
* project. See projectNameTemplate for other options.
*/
@Parameter( property = "eclipse.addGroupIdToProjectName", defaultValue = "false" )
private boolean addGroupIdToProjectName;
/**
* Allows configuring the name of the eclipse projects. This property if set wins over addVersionToProjectName and
* addGroupIdToProjectName You can use [groupId]
, [artifactId]
and [version]
* variables. eg. [groupId].[artifactId]-[version]
*/
@Parameter( property = "eclipse.projectNameTemplate" )
private String projectNameTemplate;
/**
* Parsed wtp version.
*/
private float wtpVersionFloat;
/**
* Not a plugin parameter. Is this a java project?
*/
private boolean isJavaProject;
/**
* Must the manifest files be written for java projects so that that the jee classpath for wtp is correct.
*/
@Parameter( property = "eclipse.wtpmanifest", defaultValue = "false" )
private boolean wtpmanifest;
/**
* Must the application files be written for ear projects in a separate directory.
*/
@Parameter( property = "eclipse.wtpapplicationxml", defaultValue = "false" )
private boolean wtpapplicationxml;
/**
* What WTP defined server to use for deployment informations.
*/
@Parameter( property = "eclipse.wtpdefaultserver" )
private String wtpdefaultserver;
/**
* If set to true
, the standard execution environment matching the compiler settings is set as JRE. If
* set to false
, the JRE matching the configured compiler-plugin executable or JAVA_HOME is selected
* by name, if it is configured in the workspace.
*
* @since 2.10
*/
@Parameter( property = "eclipse.preferStandardClasspathContainer", defaultValue = "false" )
private boolean preferStandardClasspathContainer;
private WorkspaceConfiguration workspaceConfiguration;
/**
* ResourceManager for getting additonalConfig files from resources
*/
@Component
private ResourceManager locator;
/**
* WagonManager for accessing internet resources.
*/
@Component
private WagonManager wagonManager;
/**
* MavenSettingsBuilder for accessing settings.xml.
*/
@Component
private MavenSettingsBuilder mavenSettingsBuilder;
/**
* This eclipse workspace is read and all artifacts detected there will be connected as eclipse projects and will
* not be linked to the jars in the local repository. Requirement is that it was created with the similar wtp
* settings as the reactor projects, but the project name template my differ. The pom's in the workspace projects
* may not contain variables in the artefactId, groupId and version tags. If workspace is not defined, then an
* attempt to locate it by checking up the directory hierarchy will be made.
*
* @since 2.5
*/
@Parameter( property = "eclipse.workspace" )
protected File workspace;
/**
* Limit the use of project references to the current workspace. No project references will be created to projects
* in the reactor when they are not available in the workspace.
*/
@Parameter( property = "eclipse.limitProjectReferencesToWorkspace", defaultValue = "false" )
protected boolean limitProjectReferencesToWorkspace;
/**
* The version of AJDT for which configuration files will be generated. The default value is "1.5", supported
* versions are "none" (AJDT support disabled), "1.4", and "1.5".
*/
@Parameter( property = "eclipse.ajdtVersion", defaultValue = "none" )
private String ajdtVersion;
/**
* List of exclusions to add to the source directories on the classpath. Adds excluding="" to the classpathentry of
* the eclipse .classpath file. [MECLIPSE-104]
*
* @since 2.6.1
*/
@Parameter
private List sourceExcludes;
/**
* List of inclusions to add to the source directories on the classpath. Adds including="" to the classpathentry of
* the eclipse .classpath file.
*
* Java projects will always include "**/*.java"
*
* Ajdt projects will always include "**/*.aj"
*
* [MECLIPSE-104]
*
* @since 2.6.1
*/
@Parameter
private List sourceIncludes;
/**
* A list of links to local files in the system. A configuration like this one in the pom :
*
*
* <plugin>
* <groupId>org.apache.maven.plugins</groupId>
* <artifactId>maven-eclipse-plugin</artifactId>
* <configuration>
* <linkedResources>
* <linkedResource>
* <name>src/test/resources/oracle-ds.xml</name>
* <type>1</type>
* <location>C://jboss/server/default/deploy/oracle-ds.xml</location>
* </linkedResource>
* </linkedResources>
* </configuration>
* </plugin>
*
*
* will produce in the .project :
*
*
* <linkedResources>
* <link>
* <name>src/test/resources/oracle-ds.xml</name>
* <type>1</type>
* <location>C://jboss/server/default/deploy/oracle-ds.xml</location>
* </link>
* </linkedResources>
*
*
* @since 2.8
*/
@Parameter
private List linkedResources;
/**
* Put classpath container entries last in eclipse classpath configuration. Note that this behaviour, although
* useful in situations were you want to override resources found in classpath containers, will made JRE classes
* loaded after 3rd party jars, so enabling it is not suggested.
*
* @since 2.9
*/
@Parameter( property = "eclipse.classpathContainersLast", defaultValue = "false" )
protected boolean classpathContainersLast;
/**
* Whether to place test resources after main resources. Note that the default behavior of Maven version 2.0.8 or
* later is to have test dirs before main dirs in classpath so this is discouraged if you need to reproduce the
* maven behavior during tests. The default behavior is also changed in eclipse plugin version 2.6 in order to
* better match the maven one. Switching to "test source last" can anyway be useful if you need to run your
* application in eclipse, since there is no concept in eclipse of "phases" with different set of source dirs and
* dependencies like we have in maven.
*
* @since 2.9
*/
@Parameter( property = "eclipse.testSourcesLast", defaultValue = "false" )
protected boolean testSourcesLast;
/**
* The plugin is often capable in predicting the required jee version based on the dependencies of the project. By
* setting this parameter to one of the {@code jeeversion} options the version will be locked.
*
*
*
* jeeversion
* EJB version
* Servlet version
* JSP version
*
*
*
* 6.0
* 3.1
* 3.0
* 2.2
*
*
* 5.0
* 3.0
* 2.5
* 2.1
*
*
* 1.4
* 2.1
* 2.4
* 2.0
*
*
* 1.3
* 2.0
* 2.3
* 1.2
*
*
* 1.2
* 1.1
* 2.2
* 1.1
*
*
*
*
* @since 2.9
*/
@Parameter( property = "eclipse.jeeversion" )
protected String jeeversion;
protected final boolean isJavaProject()
{
return isJavaProject;
}
/**
* Getter for buildcommands
.
*
* @return Returns the buildcommands.
*/
public final List getBuildcommands()
{
return buildcommands;
}
/**
* Setter for buildcommands
.
*
* @param buildcommands The buildcommands to set.
*/
public final void setBuildcommands( List buildcommands )
{
this.buildcommands = buildcommands;
}
/**
* Getter for buildOutputDirectory
.
*
* @return Returns the buildOutputDirectory.
*/
public final File getBuildOutputDirectory()
{
return buildOutputDirectory;
}
/**
* Setter for buildOutputDirectory
.
*
* @param buildOutputDirectory The buildOutputDirectory to set.
*/
public final void setBuildOutputDirectory( File buildOutputDirectory )
{
this.buildOutputDirectory = buildOutputDirectory;
}
/**
* Getter for classpathContainers
.
*
* @return Returns the classpathContainers.
*/
public final List getClasspathContainers()
{
return classpathContainers;
}
/**
* Setter for classpathContainers
.
*
* @param classpathContainers The classpathContainers to set.
*/
public final void setClasspathContainers( List classpathContainers )
{
this.classpathContainers = classpathContainers;
}
/**
* Getter for eclipseProjectDir
.
*
* @return Returns the eclipseProjectDir.
*/
public final File getEclipseProjectDir()
{
return eclipseProjectDir;
}
/**
* Setter for eclipseProjectDir
.
*
* @param eclipseProjectDir The eclipseProjectDir to set.
*/
public final void setEclipseProjectDir( File eclipseProjectDir )
{
this.eclipseProjectDir = eclipseProjectDir;
}
/**
* Getter for projectnatures
.
*
* @return Returns the projectnatures.
*/
public final List getProjectnatures()
{
return projectnatures;
}
/**
* Setter for projectnatures
.
*
* @param projectnatures The projectnatures to set.
*/
public final void setProjectnatures( List projectnatures )
{
this.projectnatures = projectnatures;
}
/**
* Getter for useProjectReferences
.
*
* @return Returns the useProjectReferences.
*/
public final boolean getUseProjectReferences()
{
return useProjectReferences;
}
/**
* Setter for useProjectReferences
.
*
* @param useProjectReferences The useProjectReferences to set.
*/
public final void setUseProjectReferences( boolean useProjectReferences )
{
this.useProjectReferences = useProjectReferences;
}
/**
* Getter for wtpversion
.
*
* @return Returns the wtpversion.
*/
public final String getWtpversion()
{
return wtpversion;
}
/**
* Setter for wtpversion
.
*
* @param wtpversion The wtpversion to set.
*/
public final void setWtpversion( String wtpversion )
{
this.wtpversion = wtpversion;
}
/**
* Getter for additionalBuildcommands
.
*
* @return Returns the additionalBuildcommands.
*/
public final List getAdditionalBuildcommands()
{
return additionalBuildcommands;
}
/**
* Setter for additionalBuildcommands
.
*
* @param additionalBuildcommands The additionalBuildcommands to set.
*/
public final void setAdditionalBuildcommands( List additionalBuildcommands )
{
this.additionalBuildcommands = additionalBuildcommands;
}
/**
* Getter for additionalProjectnatures
.
*
* @return Returns the additionalProjectnatures.
*/
public final List getAdditionalProjectnatures()
{
return additionalProjectnatures;
}
/**
* Setter for additionalProjectnatures
.
*
* @param additionalProjectnatures The additionalProjectnatures to set.
*/
public final void setAdditionalProjectnatures( List additionalProjectnatures )
{
this.additionalProjectnatures = additionalProjectnatures;
}
/**
* Getter for addVersionToProjectName
.
*/
public final boolean isAddVersionToProjectName()
{
return addVersionToProjectName;
}
/**
* Setter for addVersionToProjectName
.
*/
public final void setAddVersionToProjectName( boolean addVersionToProjectName )
{
this.addVersionToProjectName = addVersionToProjectName;
}
/**
* Getter for addGroupIdToProjectName
.
*/
public final boolean isAddGroupIdToProjectName()
{
return addGroupIdToProjectName;
}
/**
* Setter for addGroupIdToProjectName
.
*/
public final void setAddGroupIdToProjectName( boolean addGroupIdToProjectName )
{
this.addGroupIdToProjectName = addGroupIdToProjectName;
}
/**
* Getter for projectNameTemplate
*
* @return projectNameTemplate
*/
public final String getProjectNameTemplate()
{
return projectNameTemplate;
}
/**
* Setter for projectNameTemplate
.
*
* @param projectNameTemplate projectNameTemplate
*/
public final void setProjectNameTemplate( String projectNameTemplate )
{
this.projectNameTemplate = projectNameTemplate;
}
/**
* @return the linkedResources
*/
public List getLinkedResources()
{
return linkedResources;
}
/**
* @param linkedResources the linkedResources to set
*/
public void setLinkedResources( List linkedResources )
{
this.linkedResources = linkedResources;
}
/**
* @see org.apache.maven.plugin.Mojo#execute()
*/
public final boolean setup()
throws MojoExecutionException
{
boolean ready;
checkDeprecations();
setProjectNameTemplate( IdeUtils.calculateProjectNameTemplate( getProjectNameTemplate(),
isAddVersionToProjectName(),
isAddGroupIdToProjectName(), getLog() ) );
ajdt = enableAjdt( executedProject ) && !ajdtVersion.equals( "none" );
ready = validate();
// TODO: Why are we using project in some places, and executedProject in others??
ArtifactHandler artifactHandler = project.getArtifact().getArtifactHandler();
// ear projects don't contain java sources
// pde projects are always java projects
isJavaProject =
( Constants.LANGUAGE_JAVA.equals( artifactHandler.getLanguage() )
&& !Constants.PROJECT_PACKAGING_EAR.equals( packaging ) );
if ( sourceIncludes == null )
{
sourceIncludes = new ArrayList();
}
if ( isJavaProject )
{
sourceIncludes.add( JAVA_FILE_PATTERN );
}
if ( ajdt )
{
sourceIncludes.add( ASPECTJ_FILE_PATTERN );
}
if ( sourceExcludes == null )
{
sourceExcludes = new ArrayList();
}
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();
}
if ( linkedResources == null )
{
linkedResources = new ArrayList();
}
locator.addSearchPath( FileResourceLoader.ID, project.getFile().getParentFile().getAbsolutePath() );
locator.setOutputDirectory( new File( project.getBuild().getDirectory() ) );
// ready to start
return ready;
}
/**
* Convert any Strings in the commands
List to BuildCommand
s. The conversion happens in
* situ.
*
* @param commands a list of commands to convert into BuildCommand
*/
protected final 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 );
}
}
}
}
// CHECKSTYLE_OFF: MagicNumber
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;
}
else if ( "2.0".equalsIgnoreCase( wtpversion ) ) //$NON-NLS-1$
{
wtpVersionFloat = 2.0f;
}
if ( !"none".equalsIgnoreCase( wtpversion ) )
{
getLog().info( Messages.getString( "EclipsePlugin.wtpversion", wtpversion ) );
}
}
// CHECKSTYLE_ON: MagicNumber
/**
* Extension point for subclasses.
*
* Called during setup
.
*
* @throws MojoExecutionException mojo failures.
*/
protected void setupExtras()
throws MojoExecutionException
{
// extension point.
}
private void verifyClasspathContainerListIsComplete()
{
boolean containsJREContainer = false;
// Check if classpathContainer contains a JRE (default, alternate or
// Execution Environment)
for ( Object classPathContainer : classpathContainers )
{
if ( classPathContainer != null
&& classPathContainer.toString().startsWith( COMMON_PATH_JDT_LAUNCHING_JRE_CONTAINER ) )
{
containsJREContainer = true;
break;
}
}
if ( !containsJREContainer )
{
getLog().warn( Messages.getString( "EclipsePlugin.missingjrecontainer" ) );
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[] {
wtpversion, StringUtils.join( WTP_SUPPORTED_VERSIONS, " " ) } ) );
}
assertNotEmpty( executedProject.getGroupId(), POM_ELT_GROUP_ID );
assertNotEmpty( executedProject.getArtifactId(), POM_ELT_ARTIFACT_ID );
if ( executedProject.getFile() == null || !executedProject.getFile().exists() )
{
throw new MojoExecutionException( Messages.getString( "EclipsePlugin.missingpom" ) );
}
if ( "pom".equals( packaging ) && eclipseProjectDir == null )
{
getLog().info( Messages.getString( "EclipsePlugin.pompackaging" ) );
return false;
}
if ( "eclipse-plugin".equals( packaging ) )
{
getLog().info( Messages.getString( "EclipsePlugin.pdepackaging" ) );
return false;
}
if ( eclipseProjectDir == null )
{
eclipseProjectDir = executedProject.getFile().getParentFile();
}
if ( !eclipseProjectDir.exists() && !eclipseProjectDir.mkdirs() )
{
throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantcreatedir", eclipseProjectDir ) );
}
if ( !eclipseProjectDir.equals( executedProject.getFile().getParentFile() ) )
{
if ( !eclipseProjectDir.isDirectory() )
{
throw new MojoExecutionException( Messages.getString( "EclipsePlugin.notadir", eclipseProjectDir ) );
}
eclipseProjectDir = new File( eclipseProjectDir, executedProject.getArtifactId() );
if ( !eclipseProjectDir.isDirectory() && !eclipseProjectDir.mkdirs() )
{
throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantcreatedir",
eclipseProjectDir ) );
}
}
validateExtras();
return true;
}
/**
* Extension point for subclasses.
*
* Called during setup
and used to validate that the configuration is sane.
*
* @throws MojoExecutionException mojo failures.
*/
protected void validateExtras()
throws MojoExecutionException
{
// provided for extension.
}
private void checkDeprecations()
{
if ( eclipseDownloadSources )
{
// deprecated warning
getLog().warn( Messages.getString( "EclipsePlugin.deprecatedpar", new Object[] {
"eclipse.downloadSources",
"downloadSources" } ) );
downloadSources = true;
}
checkDeprecationsExtras();
}
/**
* Extension point for subclasses.
*
* Check for any extra deprecations and log warnings. Called during setup
*/
protected void checkDeprecationsExtras()
{
// provided for extension.
}
public final void writeConfiguration( IdeDependency[] deps )
throws MojoExecutionException
{
// write additional configuration files first to allow merging with eclipse
// settings generated by other steps (MECLIPSE-641)
writeAdditionalConfig();
EclipseWriterConfig config = createEclipseWriterConfig( deps );
if ( wtpmanifest && isJavaProject() )
{
// NOTE: This could change the config!
EclipseManifestWriter.addManifestResource( getLog(), config );
}
// NOTE: This could change the config!
writeConfigurationExtras( config );
// CHECKSTYLE_OFF: MagicNumber
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();
}
// CHECKSTYLE_ON: MagicNumber
new EclipseSettingsWriter().init( getLog(), config ).write();
if ( isJavaProject )
{
new EclipseClasspathWriter().init( getLog(), config ).write();
if ( ajdt && ajdtVersion.equals( "1.4" ) )
{
new EclipseAjdtWriter().init( getLog(), config ).write();
}
}
if ( wtpapplicationxml )
{
new EclipseWtpApplicationXMLWriter().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();
getLog().info( Messages.getString( "EclipsePlugin.wrote", new Object[] {
config.getEclipseProjectName(), eclipseProjectDir.getAbsolutePath() } ) );
}
private void writeAdditionalConfig()
throws MojoExecutionException
{
if ( additionalConfig != null )
{
for ( EclipseConfigFile file : additionalConfig )
{
File projectRelativeFile = new File( eclipseProjectDir, file.getName() );
if ( projectRelativeFile.isDirectory() )
{
// just ignore?
getLog().warn( Messages.getString( "EclipsePlugin.foundadir",
projectRelativeFile.getAbsolutePath() ) );
}
try
{
projectRelativeFile.getParentFile().mkdirs();
if ( file.getContent() == null )
{
if ( file.getLocation() != null )
{
InputStream inStream = locator.getResourceAsInputStream( file.getLocation() );
OutputStream outStream = new FileOutputStream( projectRelativeFile );
try
{
IOUtil.copy( inStream, outStream );
}
finally
{
IOUtil.close( inStream );
IOUtil.close( outStream );
}
}
else
{
URL url = file.getURL();
String endPointUrl = url.getProtocol() + "://" + url.getAuthority();
// Repository Id should be ignored by Wagon ...
Repository repository = new Repository( "additonal-configs", endPointUrl );
Wagon wagon = wagonManager.getWagon( repository );
if ( logger.isDebugEnabled() )
{
Debug debug = new Debug();
wagon.addSessionListener( debug );
wagon.addTransferListener( debug );
}
wagon.setTimeout( 1000 );
Settings settings = mavenSettingsBuilder.buildSettings();
ProxyInfo proxyInfo = null;
if ( settings != null && settings.getActiveProxy() != null )
{
Proxy settingsProxy = settings.getActiveProxy();
proxyInfo = new ProxyInfo();
proxyInfo.setHost( settingsProxy.getHost() );
proxyInfo.setType( settingsProxy.getProtocol() );
proxyInfo.setPort( settingsProxy.getPort() );
proxyInfo.setNonProxyHosts( settingsProxy.getNonProxyHosts() );
proxyInfo.setUserName( settingsProxy.getUsername() );
proxyInfo.setPassword( settingsProxy.getPassword() );
}
if ( proxyInfo != null )
{
wagon.connect( repository, wagonManager.getAuthenticationInfo( repository.getId() ),
proxyInfo );
}
else
{
wagon.connect( repository, wagonManager.getAuthenticationInfo( repository.getId() ) );
}
wagon.get( url.getPath(), projectRelativeFile );
}
}
else
{
FileUtils.fileWrite( projectRelativeFile.getAbsolutePath(), file.getContent() );
}
}
catch ( WagonException e )
{
throw new MojoExecutionException( Messages.getString( "EclipsePlugin.remoteexception",
new Object[] { file.getURL(), e.getMessage() } ) );
}
catch ( IOException e )
{
throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantwritetofile",
projectRelativeFile.getAbsolutePath() ) );
}
catch ( ResourceNotFoundException e )
{
throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantfindresource",
file.getLocation() ) );
}
catch ( XmlPullParserException e )
{
throw new MojoExecutionException( Messages.getString( "EclipsePlugin.settingsxmlfailure",
e.getMessage() ) );
}
}
}
}
/**
* Create the EclipseWriterConfig
for the specified dependencies.
*
* @param deps the project dependencies
* @return a configured EclipseWriterConfig
* @throws MojoExecutionException mojo failures.
*/
protected final 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();
config.setWorkspaceConfiguration( getWorkspaceConfiguration() );
config.setProjectNameTemplate( getProjectNameTemplate() );
String projectName = IdeUtils.getProjectName( config.getProjectNameTemplate(), project );
config.setEclipseProjectName( projectName );
config.setWtpapplicationxml( wtpapplicationxml );
config.setWtpVersion( wtpVersionFloat );
float ajdtVersionFloat;
try
{
ajdtVersionFloat = Float.parseFloat( ajdtVersion );
}
catch ( NumberFormatException e )
{
ajdtVersionFloat = 0.0f;
}
config.setAjdtVersion( ajdtVersionFloat );
Set convertedBuildCommands = new LinkedHashSet();
if ( buildcommands != null )
{
for ( Object cmd : buildcommands )
{
if ( cmd instanceof BuildCommand )
{
convertedBuildCommands.add( cmd );
}
else
{
convertedBuildCommands.add( new BuildCommand( (String) cmd ) );
}
}
}
if ( ajdt )
{
buildAjdtWeaveDeps( deps );
buildAspectjDeps( deps );
}
config.setBuildCommands( new LinkedList( convertedBuildCommands ) );
config.setBuildOutputDirectory( buildOutputDirectory );
config.setClasspathContainers( classpathContainers );
config.setDeps( deps );
config.setEclipseProjectDirectory( eclipseProjectDir );
config.setLocalRepository( localRepository );
config.setOSGIManifestFile( manifest );
config.setProject( project );
config.setProjectBaseDir( projectBaseDir );
config.setProjectnatures( projectnatures );
config.setProjectFacets( additionalProjectFacets );
config.setSourceDirs( sourceDirs );
config.setPackaging( packaging );
config.setLinkedResources( linkedResources );
config.setClasspathContainersLast( classpathContainersLast );
config.setJeeVersion( jeeversion );
collectWarContextRootsFromReactorEarConfiguration( config );
return config;
}
/**
* If this is a war module peek into the reactor an search for an ear module that defines the context root of this
* module.
*
* @param config config to save the context root.
*/
private void collectWarContextRootsFromReactorEarConfiguration( EclipseWriterConfig config )
{
if ( reactorProjects != null && wtpContextName == null
&& Constants.PROJECT_PACKAGING_WAR.equals( project.getPackaging() ) )
{
for ( Object reactorProject1 : reactorProjects )
{
MavenProject reactorProject = (MavenProject) reactorProject1;
if ( Constants.PROJECT_PACKAGING_EAR.equals( reactorProject.getPackaging() ) )
{
Xpp3Dom[] warDefinitions =
IdeUtils.getPluginConfigurationDom( reactorProject, JeeUtils.ARTIFACT_MAVEN_EAR_PLUGIN,
new String[] { "modules", "webModule" } );
for ( Xpp3Dom warDefinition : warDefinitions )
{
Xpp3Dom groupId = warDefinition.getChild( "groupId" );
Xpp3Dom artifactId = warDefinition.getChild( "artifactId" );
Xpp3Dom contextRoot = warDefinition.getChild( "contextRoot" );
if ( groupId != null && artifactId != null && contextRoot != null && groupId.getValue() != null
&& artifactId.getValue() != null && contextRoot.getValue() != null )
{
getLog().info( "Found context root definition for " + groupId.getValue() + ":"
+ artifactId.getValue() + " " + contextRoot.getValue() );
if ( project.getArtifactId().equals( artifactId.getValue() )
&& project.getGroupId().equals( groupId.getValue() ) )
{
config.setContextName( contextRoot.getValue() );
}
}
else
{
getLog().info( "Found incomplete ear configuration in " + reactorProject.getGroupId() + ":"
+ reactorProject.getGroupId() + " found " + warDefinition.toString() );
}
}
}
}
}
if ( config.getContextName() == null && Constants.PROJECT_PACKAGING_WAR.equals( project.getPackaging() ) )
{
if ( wtpContextName == null )
{
config.setContextName( project.getArtifactId() );
}
else if ( "ROOT".equals( wtpContextName ) )
{
config.setContextName( "" );
}
else
{
config.setContextName( wtpContextName );
}
}
}
/**
* 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 writeConfigurationExtras( 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 ) );
}
}
/**
* Fill getProjectnatures() with values.
*
* Subclasses should call super and then calculate their own additions and insert them via
* getProjectnatures().addAll()
.
*
* @param packaging the pom's packaging
*/
protected void fillDefaultNatures( String packaging )
{
projectnatures = new ArrayList();
// CHECKSTYLE_OFF: MagicNumber
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
}
}
// CHECKSTYLE_ON: MagicNumber
}
/**
* Fill getClasspathContainers() with values.
*
* Subclasses should call super and then calculate their own additions and insert them via
* getClasspathContainers().addAll()
.
*
* @param packaging the pom's packaging
*/
protected void fillDefaultClasspathContainers( String packaging )
{
classpathContainers = new ArrayList();
if ( getWorkspaceConfiguration().getDefaultClasspathContainer() != null )
{
getLog().info( "Adding default classpath container: "
+ getWorkspaceConfiguration().getDefaultClasspathContainer() );
classpathContainers.add( getWorkspaceConfiguration().getDefaultClasspathContainer() );
}
if ( ajdt )
{
classpathContainers.add( ASPECTJ_RT_CONTAINER );
}
}
/**
* Fill getBuildcommands() with values.
*
* Subclasses should call super and then calculate their own additions and insert them via
* getBuildcommands().addAll()
.
*
* @param packaging the pom's packaging
*/
protected void fillDefaultBuilders( String packaging )
{
buildcommands = new ArrayList();
// CHECKSTYLE_OFF: MagicNumber
if ( wtpVersionFloat == 0.7f )
{
buildcommands.add( new BuildCommand( BUILDER_WST_COMPONENT_STRUCTURAL ) ); // WTP 0.7 builder
}
if ( isJavaProject )
{
if ( ajdt )
{
buildcommands.add( new BuildCommand( 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 )
{
// WTP 0.7 builder
buildcommands.add( new BuildCommand( BUILDER_WST_COMPONENT_STRUCTURAL_DEPENDENCY_RESOLVER ) );
}
// CHECKSTYLE_ON: MagicNumber
}
public final EclipseSourceDir[] buildDirectoryList( MavenProject project, File basedir, File buildOutputDirectory )
throws MojoExecutionException
{
File projectBaseDir = project.getFile().getParentFile();
String mainOutput = IdeUtils.toRelativeAndFixSeparator( projectBaseDir, buildOutputDirectory, false );
// 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 )
{
getLog().debug( "testOutput toRelativeAndFixSeparator " + projectBaseDir + " , "
+ project.getBuild().getTestOutputDirectory() );
testOutput =
IdeUtils.toRelativeAndFixSeparator( projectBaseDir,
new File( project.getBuild().getTestOutputDirectory() ), false );
getLog().debug( "testOutput after toRelative : " + testOutput );
}
Set mainDirectories = new LinkedHashSet();
extractSourceDirs( mainDirectories, project.getCompileSourceRoots(), basedir, projectBaseDir, false, null );
extractResourceDirs( mainDirectories, project.getBuild().getResources(), basedir, projectBaseDir, false,
mainOutput );
Set testDirectories = new LinkedHashSet();
extractSourceDirs( testDirectories, project.getTestCompileSourceRoots(), basedir, projectBaseDir, true,
testOutput );
extractResourceDirs( testDirectories, project.getBuild().getTestResources(), basedir, projectBaseDir, true,
testOutput );
// avoid duplicated entries
Set directories = new LinkedHashSet();
// NOTE: Since MNG-3118, test classes come before main classes
boolean testBeforeMain = isMavenVersion( "[2.0.8,)" );
// let users override this if needed, they need to simulate more than the test phase in eclipse
if ( testSourcesLast )
{
testBeforeMain = false;
}
if ( testBeforeMain )
{
directories.addAll( testDirectories );
directories.removeAll( mainDirectories );
directories.addAll( mainDirectories );
}
else
{
directories.addAll( mainDirectories );
directories.addAll( testDirectories );
}
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 ( Object sourceRoot1 : sourceRoots )
{
File sourceRootFile = new File( (String) sourceRoot1 );
if ( sourceRootFile.isDirectory() )
{
String sourceRoot =
IdeUtils.toRelativeAndFixSeparator( projectBaseDir, sourceRootFile,
!projectBaseDir.equals( basedir ) );
directories.add( new EclipseSourceDir( sourceRoot, output, false, test, sourceIncludes, sourceExcludes,
false ) );
}
}
}
final void extractResourceDirs( Set directories, List resources, File basedir, File workspaceProjectBaseDir,
boolean test, final String output )
throws MojoExecutionException
{
for ( Object resource1 : resources )
{
Resource resource = (Resource) resource1;
getLog().debug( "Processing resource dir: " + resource.getDirectory() );
List excludes = new ArrayList( resource.getExcludes() );
// automatically exclude java files: eclipse doesn't have the concept of resource directory so it will
// try to compile any java file found in maven resource dirs
excludes.add( JAVA_FILE_PATTERN );
// 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 resourcePath =
IdeUtils.toRelativeAndFixSeparator( workspaceProjectBaseDir, resourceDirectory,
!workspaceProjectBaseDir.equals( basedir ) );
String thisOutput = output;
if ( thisOutput != null )
{
// sometimes thisOutput is already an absolute path
File outputFile = new File( thisOutput );
if ( !outputFile.isAbsolute() )
{
outputFile = new File( workspaceProjectBaseDir, thisOutput );
}
// 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();
}
getLog().debug( "Making relative and fixing separator: { " + workspaceProjectBaseDir + ", "
+ outputFile + ", false }." );
thisOutput = IdeUtils.toRelativeAndFixSeparator( workspaceProjectBaseDir, outputFile, false );
}
EclipseSourceDir resourceDir =
new EclipseSourceDir( resourcePath, thisOutput, true, test, resource.getIncludes(), excludes,
resource.isFiltering() );
if ( !directories.add( resourceDir ) )
{
EclipseSourceDir originalDir = (EclipseSourceDir) get( directories, resourceDir );
boolean merged = originalDir.merge( resourceDir );
if ( merged )
{
getLog().info( "Resource directory's path matches an existing source directory. "
+ "Resources have been merged with the source directory "
+ originalDir.getPath() );
}
else
{
getLog().info( "Resource directory's path matches an existing source directory but \"test\", "
+ "\"filtering\" or \"output\" were different. The resulting eclipse configuration "
+ "may not accurately reflect the project configuration for " + originalDir.getPath() );
}
}
}
}
/**
* java.util.Set doesn't have a get() method that returns the matching object. Since we use objects that are
* different by conceptually "equal" based on the path we need to locate the original object out of the Set.
*
* @param set the set to iterate over looking for the specified object
* @param o the object to locate in the set
* @return the object from the set, or null if not found in the set
*/
private Object get( Set set, Object o )
{
for ( Object item : set )
{
if ( o.equals( item ) )
{
return item;
}
}
return null;
}
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, sourceIncludes, sourceExcludes,
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, sourceIncludes,
sourceExcludes, false ) );
}
}
}
private boolean enableAjdt( MavenProject project )
{
boolean enable = false;
List buildPlugins = project.getBuildPlugins();
for ( Object buildPlugin : buildPlugins )
{
Plugin plugin = (Plugin) buildPlugin;
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 ( Object buildPlugin : buildPlugins )
{
Plugin plugin = (Plugin) buildPlugin;
if ( plugin.getGroupId().equals( ORG_CODEHAUS_MOJO )
&& plugin.getArtifactId().equals( ASPECTJ_MAVEN_PLUGIN ) )
{
configuration = (Xpp3Dom) plugin.getConfiguration();
break;
}
}
return configuration;
}
private void buildAspectjDeps( IdeDependency[] deps )
throws MojoExecutionException
{
Xpp3Dom configuration = getAspectjConfiguration( executedProject );
if ( configuration != null )
{
Xpp3Dom aspectLibrariesParent = configuration.getChild( ASPECT_LIBRARIES );
if ( aspectLibrariesParent != null )
{
Xpp3Dom[] aspectLibraries = aspectLibrariesParent.getChildren( ASPECT_LIBRARY );
outerLoop: for ( Xpp3Dom aspectLibrary : aspectLibraries )
{
String artifactId = aspectLibrary.getChild( POM_ELT_ARTIFACT_ID ).getValue();
String groupId = aspectLibrary.getChild( POM_ELT_GROUP_ID ).getValue();
for ( IdeDependency dep : deps )
{
if ( dep.getArtifactId().equals( artifactId ) && dep.getGroupId().equals( groupId ) )
{
dep.setAjdtDependency( true );
continue outerLoop;
}
}
throw new MojoExecutionException( "AspectLibrary is not a dependency of project" );
}
}
}
}
private void buildAjdtWeaveDeps( IdeDependency[] deps )
throws MojoExecutionException
{
Xpp3Dom configuration = getAspectjConfiguration( executedProject );
if ( configuration != null )
{
Xpp3Dom weaveDependenciesParent = configuration.getChild( WEAVE_DEPENDENCIES );
if ( weaveDependenciesParent != null )
{
Xpp3Dom[] weaveDependencies = weaveDependenciesParent.getChildren( WEAVE_DEPENDENCY );
outerLoop: for ( Xpp3Dom weaveDependency : weaveDependencies )
{
String artifactId = weaveDependency.getChild( POM_ELT_ARTIFACT_ID ).getValue();
String groupId = weaveDependency.getChild( POM_ELT_GROUP_ID ).getValue();
for ( IdeDependency dep : deps )
{
if ( dep.getArtifactId().equals( artifactId ) && dep.getGroupId().equals( groupId ) )
{
dep.setAjdtWeaveDependency( true );
continue outerLoop;
}
}
throw new MojoExecutionException( "WeaveDependency is not a dependency of project" );
}
}
}
}
/**
* {@inheritDoc}
*/
public String getProjectNameForArifact( Artifact artifact )
{
IdeDependency[] workspaceArtefacts = getWorkspaceArtefacts();
for ( int index = 0; workspaceArtefacts != null && index < workspaceArtefacts.length; index++ )
{
IdeDependency workspaceArtefact = workspaceArtefacts[index];
if ( workspaceArtefact.isAddedToClasspath()
&& workspaceArtefact.getGroupId().equals( artifact.getGroupId() )
&& workspaceArtefact.getArtifactId().equals( artifact.getArtifactId() ) )
{
if ( workspaceArtefact.getVersion().equals( artifact.getBaseVersion() ) )
{
return workspaceArtefact.getEclipseProjectName();
}
}
}
MavenProject reactorProject = getReactorProject( artifact );
if ( reactorProject != null )
{
return IdeUtils.getProjectName( getProjectNameTemplateForMavenProject( reactorProject ), artifact );
}
return IdeUtils.getProjectName( getProjectNameTemplate(), artifact );
}
/**
* @param mavenProject the project to get the projectNameTemplate configuration from
* @return the projectNameTemplate configuration from the specified MavenProject
*/
private String getProjectNameTemplateForMavenProject( MavenProject mavenProject )
{
String projectNameTemplate = null;
boolean addVersionToProjectName = false;
boolean addGroupIdToProjectName = false;
Build build = mavenProject.getBuild();
if ( build != null )
{
String eclipsePlugin = "org.apache.maven.plugins:maven-eclipse-plugin";
Plugin plugin = (Plugin) build.getPluginsAsMap().get( eclipsePlugin );
if ( plugin == null && build.getPluginManagement() != null )
{
plugin = (Plugin) build.getPluginManagement().getPluginsAsMap().get( eclipsePlugin );
}
if ( plugin != null )
{
Xpp3Dom config = (Xpp3Dom) plugin.getConfiguration();
if ( config != null )
{
Xpp3Dom projectNameTemplateNode = config.getChild( "projectNameTemplate" );
if ( projectNameTemplateNode != null )
{
projectNameTemplate = projectNameTemplateNode.getValue();
}
Xpp3Dom addVersionToProjectNameNode = config.getChild( "addVersionToProjectName" );
addVersionToProjectName = addVersionToProjectNameNode != null;
Xpp3Dom addGroupIdToProjectNameNode = config.getChild( "addGroupIdToProjectName" );
addGroupIdToProjectName = addGroupIdToProjectNameNode != null;
}
}
}
return IdeUtils.calculateProjectNameTemplate( projectNameTemplate, addVersionToProjectName,
addGroupIdToProjectName, getLog() );
}
/**
* {@inheritDoc}
*/
protected final IdeDependency[] getWorkspaceArtefacts()
{
return getWorkspaceConfiguration().getWorkspaceArtefacts();
}
public final WorkspaceConfiguration getWorkspaceConfiguration()
{
if ( workspaceConfiguration == null )
{
workspaceConfiguration = new WorkspaceConfiguration();
locateWorkspace();
getLog().info( Messages.getString( "EclipsePlugin.workspace", workspace ) );
workspaceConfiguration.setWorkspaceDirectory( workspace );
new ReadWorkspaceLocations().init( getLog(), workspaceConfiguration, project, wtpdefaultserver,
preferStandardClasspathContainer );
}
return workspaceConfiguration;
}
/**
* If workspace is not defined, then attempt to locate it by checking up the directory hierarchy.
*/
private void locateWorkspace()
{
if ( workspace == null )
{
File currentWorkingDirectory = new File( "." ).getAbsoluteFile();
while ( currentWorkingDirectory != null )
{
File metadataDirectory = new File( currentWorkingDirectory, ".metadata" );
logger.debug( "Checking for eclipse workspace at " + currentWorkingDirectory );
if ( metadataDirectory.exists() && metadataDirectory.isDirectory() )
{
logger.debug( " Found workspace at " + currentWorkingDirectory );
workspace = currentWorkingDirectory;
return;
}
currentWorkingDirectory = currentWorkingDirectory.getParentFile();
}
}
}
public final List getExcludes()
{
return excludes;
}
/**
* Utility method that locates a project producing the given artifact and verifies if it's a valid Eclipse project.
*
* @param artifact the artifact a project should produce.
* @return true
if the artifact is produced by a reactor projectart.
*/
protected boolean isAvailableAsAReactorProject( Artifact artifact )
{
MavenProject project = getReactorProject( artifact );
return ( project != null && new File( project.getBasedir(), ".project" ).exists() );
}
/**
* Utility method that locates a project in the workspace for the given artifact.
*
* @param artifact the artifact a project should produce.
* @return true
if the artifact is produced by a reactor projectart.
*/
private boolean isAvailableAsAWorkspaceProject( Artifact artifact )
{
IdeDependency[] workspaceArtefacts = getWorkspaceArtefacts();
for ( int index = 0; workspaceArtefacts != null && index < workspaceArtefacts.length; index++ )
{
IdeDependency workspaceArtefact = workspaceArtefacts[index];
if ( workspaceArtefact.getGroupId().equals( artifact.getGroupId() )
&& workspaceArtefact.getArtifactId().equals( artifact.getArtifactId() ) )
{
if ( workspaceArtefact.getVersion().equals( artifact.getBaseVersion() ) )
{
workspaceArtefact.setAddedToClasspath( true );
getLog().debug( "Using workspace project: " + workspaceArtefact.getEclipseProjectName() );
return true;
}
else
{
getLog().info( "Artifact "
+ artifact.getId()
+ " already available as a workspace project, but with different version. "
+ "Expected: " + artifact.getBaseVersion() + ", found: "
+ workspaceArtefact.getVersion() );
}
}
}
return false;
}
/**
* Checks if jar has to be resolved for the given artifact
*
* @param art the artifact to check
* @return true if resolution should happen
*/
protected final boolean hasToResolveJar( Artifact art )
{
return !( getUseProjectReferences() && isAvailableAsAReactorProject( art ) )
|| ( limitProjectReferencesToWorkspace
&& !( getUseProjectReferences() && isAvailableAsAWorkspaceProject( art ) ) );
}
/**
* Checks if a projects reference has to be used for the given artifact
*
* @param art the artifact to check
* @return true if a project reference has to be used.
*/
protected final boolean useProjectReference( Artifact art )
{
boolean isReactorProject = getUseProjectReferences() && isAvailableAsAReactorProject( art );
boolean isWorkspaceProject = getUseProjectReferences() && isAvailableAsAWorkspaceProject( art );
return ( isReactorProject && !limitProjectReferencesToWorkspace ) || // default
( limitProjectReferencesToWorkspace && isWorkspaceProject ) || // limitProjectReferencesToWorkspace
( !isReactorProject && isWorkspaceProject ); // default + workspace projects
}
}