From 4eb0f9b0655b4d36998dd2eddac9ca4afc887a3f Mon Sep 17 00:00:00 2001 From: antelder Date: Sat, 14 Feb 2009 08:45:19 +0000 Subject: Start moving the bundle plugin out of the sca build git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@744428 13f79535-47bb-0310-9956-ffa450edef68 --- .../maven/plugin/eclipse/EclipsePlugin.java | 1556 ++++++++++++++++++++ 1 file changed, 1556 insertions(+) create mode 100644 maven-plugins/trunk/maven-bundle-plugin/src/main/java/org/apache/tuscany/maven/plugin/eclipse/EclipsePlugin.java (limited to 'maven-plugins/trunk/maven-bundle-plugin/src/main/java/org/apache/tuscany/maven/plugin/eclipse/EclipsePlugin.java') diff --git a/maven-plugins/trunk/maven-bundle-plugin/src/main/java/org/apache/tuscany/maven/plugin/eclipse/EclipsePlugin.java b/maven-plugins/trunk/maven-bundle-plugin/src/main/java/org/apache/tuscany/maven/plugin/eclipse/EclipsePlugin.java new file mode 100644 index 0000000000..38a906570e --- /dev/null +++ b/maven-plugins/trunk/maven-bundle-plugin/src/main/java/org/apache/tuscany/maven/plugin/eclipse/EclipsePlugin.java @@ -0,0 +1,1556 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.maven.plugin.eclipse; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +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.Map; +import java.util.Set; +import java.util.TreeSet; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.handler.ArtifactHandler; +import org.apache.maven.model.Resource; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.eclipse.BuildCommand; +import org.apache.maven.plugin.eclipse.Constants; +import org.apache.maven.plugin.eclipse.EclipseConfigFile; +import org.apache.maven.plugin.eclipse.EclipseSourceDir; +import org.apache.maven.plugin.eclipse.WorkspaceConfiguration; +import org.apache.maven.plugin.eclipse.reader.ReadWorkspaceLocations; +import org.apache.maven.plugin.eclipse.writers.EclipseManifestWriter; +import org.apache.maven.plugin.eclipse.writers.EclipseSettingsWriter; +import org.apache.maven.plugin.eclipse.writers.EclipseWriterConfig; +import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpApplicationXMLWriter; +import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpComponent15Writer; +import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpComponentWriter; +import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpFacetsWriter; +import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpmodulesWriter; +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.project.MavenProject; +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; + +/** + * 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 641616 2008-03-26 22:42:42Z aheritier $ + * @goal eclipse + * @execute phase="generate-resources" + */ +public class EclipsePlugin + extends AbstractIdeSupportMojo +{ + + 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$ + + protected 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_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_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$ + + protected static final String COMMON_PATH_JDT_LAUNCHING_JRE_CONTAINER = "org.eclipse.jdt.launching.JRE_CONTAINER"; //$NON-NLS-1$ + + protected 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", "2.0", "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 = "artifactId"; //$NON-NLS-1$ + + /** + * Constant for 'groupId' element in POM.xml. + */ + private static final String POM_ELT_GROUP_ID = "groupId"; //$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 artifact to exclude from eclipse classpath, beeing provided by some eclipse classPathContainer + * [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; + + /** + * 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. + * + * @parameter + */ + private List buildcommands; + + /** + * 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.ui.externaltools.ExternalToolBuilder</name>
+     *      <triggers>auto,full,incremental,</triggers>
+     *      <arguments>
+     *        <LaunchConfigHandle>&lt;project&gt;./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. + * + * @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. DEPRECATED - use downloadSources + * + * @parameter expression="${eclipse.downloadSources}" + * @deprecated use downloadSources + */ + private boolean eclipseDownloadSources; + + /** + * Eclipse workspace directory. + * + * @parameter expression="${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 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", "1.0", and "1.5" + * + * @parameter expression="${wtpversion}" default-value="none" + */ + private String wtpversion; + + /** + * JEE context name of the WTP module. ( ex. WEB context name ). + * + * @parameter expression="${wtpContextName}" + */ + private String wtpContextName; + + /** + * 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. + * + *
+     * <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>
+     * 
+ * + * @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 expression="${eclipse.addVersionToProjectName}" default-value="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 expression="${eclipse.addGroupIdToProjectName}" default-value="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 expression="${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 expression="${eclipse.wtpmanifest}" default-value="false" + */ + private boolean wtpmanifest; + + /** + * Must the application files be written for ear projects in a separate directory. + * + * @parameter expression="${eclipse.wtpapplicationxml}" default-value="false" + */ + private boolean wtpapplicationxml; + + /** + * What WTP defined server to use for deployment informations. + * + * @parameter expression="${eclipse.wtpdefaultserver}" + */ + private String wtpdefaultserver; + + private WorkspaceConfiguration workspaceConfiguration; + + /** + * ResourceManager for getting additonalConfig files from resources + * + * @component + * @required + * @readonly + */ + private ResourceManager locator; + + /** + * 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. + * + * @since 2.5 + * @parameter expression="${eclipse.workspace}" + */ + protected String 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 expression="${eclipse.limitProjectReferencesToWorkspace}" default-value="false" + */ + protected boolean limitProjectReferencesToWorkspace; + + protected boolean isJavaProject() + { + return isJavaProject; + } + + protected boolean isPdeProject() + { + return pde; + } + + /** + * Getter for buildcommands. + * + * @return Returns the buildcommands. + */ + public List getBuildcommands() + { + return 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 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 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 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 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 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 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 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 additionalProjectnatures; + } + + /** + * Setter for additionalProjectnatures. + * + * @param additionalProjectnatures The additionalProjectnatures to set. + */ + public void setAdditionalProjectnatures( List additionalProjectnatures ) + { + this.additionalProjectnatures = additionalProjectnatures; + } + + /** + * Getter for addVersionToProjectName. + */ + public boolean isAddVersionToProjectName() + { + return addVersionToProjectName; + } + + /** + * Setter for addVersionToProjectName. + */ + public void setAddVersionToProjectName( boolean addVersionToProjectName ) + { + this.addVersionToProjectName = addVersionToProjectName; + } + + /** + * Getter for addGroupIdToProjectName. + */ + public boolean isAddGroupIdToProjectName() + { + return addGroupIdToProjectName; + } + + /** + * Setter for addGroupIdToProjectName. + */ + public void setAddGroupIdToProjectName( boolean addGroupIdToProjectName ) + { + this.addGroupIdToProjectName = addGroupIdToProjectName; + } + + public String getProjectNameTemplate() + { + return projectNameTemplate; + } + + public void setProjectNameTemplate( String projectNameTemplate ) + { + this.projectNameTemplate = projectNameTemplate; + } + + /** + * @see org.apache.maven.plugin.Mojo#execute() + */ + public boolean setup() + throws MojoExecutionException + { + boolean ready = true; + + checkDeprecations(); + + 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 = + pde || + ( 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(); + } + locator.addSearchPath( FileResourceLoader.ID, project.getFile().getParentFile().getAbsolutePath() ); + locator.setOutputDirectory( new File( project.getBuild().getDirectory() ) ); + + // 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; + } + else if ( "2.0".equalsIgnoreCase( wtpversion ) ) //$NON-NLS-1$ + { + wtpVersionFloat = 2.0f; + } + if ( !"none".equalsIgnoreCase( wtpversion ) ) + { + getLog().info( Messages.getString( "EclipsePlugin.wtpversion", wtpversion ) ); + } + } + + protected void setupExtras() + throws MojoExecutionException + { + // extension point. + } + + protected void verifyClasspathContainerListIsComplete() + { + boolean containsJREContainer = false; + // Check if classpathContainer contains a JRE (default, alternate or + // Execution Environment) + for ( Iterator iter = classpathContainers.iterator(); iter.hasNext(); ) + { + Object classPathContainer = iter.next(); + if ( classPathContainer != null && + classPathContainer.toString().startsWith( COMMON_PATH_JDT_LAUNCHING_JRE_CONTAINER ) ) + { + containsJREContainer = true; + break; + } + } + if ( !containsJREContainer ) + { + 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$ + } + + 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" ) ); //$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; + } + + // [rfeng] Set PDE to false if the project is not a bundle + if(!isOSGiBundle()) { + pde = false; + } + + 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 ); + + if ( wtpmanifest && isJavaProject() ) + { + EclipseManifestWriter.addManifestResource( getLog(), config ); + } + // 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 ( wtpapplicationxml ) + { + new EclipseWtpApplicationXMLWriter().init( getLog(), config ).write(); + } + + // [rfeng] + /* + if ( pde ) + { + this.getLog().info( "The Maven Eclipse plugin runs in 'pde'-mode." ); + new EclipseOSGiManifestWriter().init( getLog(), config ).write(); + } + */ + // [rfeng] + + // 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(); + + writeAdditionalConfig(); + + getLog().info( Messages.getString( "EclipsePlugin.wrote", new Object[] { //$NON-NLS-1$ + config.getEclipseProjectName(), eclipseProjectDir.getAbsolutePath() } ) ); + } + + protected void writeAdditionalConfig() + throws MojoExecutionException + { + if ( additionalConfig != null ) + { + for ( int j = 0; j < additionalConfig.length; j++ ) + { + EclipseConfigFile file = additionalConfig[j]; + File projectRelativeFile = new File( eclipseProjectDir, file.getName() ); + if ( projectRelativeFile.isDirectory() ) + { + // just ignore? + getLog().warn( Messages.getString( "EclipsePlugin.foundadir", //$NON-NLS-1$ + projectRelativeFile.getAbsolutePath() ) ); + } + + try + { + projectRelativeFile.getParentFile().mkdirs(); + if ( file.getContent() == null ) + { + InputStream inStream; + if ( file.getLocation() != null ) + { + inStream = locator.getResourceAsInputStream( file.getLocation() ); + } + else + { + inStream = file.getURL().openConnection().getInputStream(); + } + OutputStream outStream = new FileOutputStream( projectRelativeFile ); + try + { + IOUtil.copy( inStream, outStream ); + } + finally + { + inStream.close(); + outStream.close(); + } + } + else + { + FileUtils.fileWrite( projectRelativeFile.getAbsolutePath(), file.getContent() ); + } + } + catch ( IOException e ) + { + throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantwritetofile", //$NON-NLS-1$ + projectRelativeFile.getAbsolutePath() ) ); + } + catch ( ResourceNotFoundException e ) + { + throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantfindresource", //$NON-NLS-1$ + file.getLocation() ) ); + } + + } + } + } + + 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(); + + config.setWorkspaceConfiguration( getWorkspaceConfiguration() ); + + config.setProjectNameTemplate( calculateProjectNameTemplate() ); + + String projectName = IdeUtils.getProjectName( config.getProjectNameTemplate(), project ); + + config.setEclipseProjectName( projectName ); + + config.setWtpapplicationxml( wtpapplicationxml ); + + config.setWtpVersion( wtpVersionFloat ); + + Set convertedBuildCommands = new LinkedHashSet(); + + if ( buildcommands != null ) + { + for ( Iterator it = buildcommands.iterator(); it.hasNext(); ) + { + Object cmd = it.next(); + + if ( cmd instanceof BuildCommand ) + { + convertedBuildCommands.add( cmd ); + } + else + { + convertedBuildCommands.add( new BuildCommand( (String) cmd ) ); + } + } + } + + config.setBuildCommands( new LinkedList( convertedBuildCommands ) ); + + config.setBuildOutputDirectory( buildOutputDirectory ); + config.setClasspathContainers( classpathContainers ); + config.setDeps( deps ); + config.setEclipseProjectDirectory( eclipseProjectDir ); + config.setLocalRepository( localRepository ); + config.setOSGIManifestFile( manifest ); + config.setPde( pde ); + config.setProject( project ); + config.setProjectBaseDir( projectBaseDir ); + config.setProjectnatures( projectnatures ); + config.setProjectFacets( additionalProjectFacets ); + config.setSourceDirs( sourceDirs ); + config.setAddVersionToProjectName( isAddVersionToProjectName() ); + config.setPackaging( packaging ); + + 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 ( Iterator iter = reactorProjects.iterator(); iter.hasNext(); ) + { + MavenProject reactorProject = (MavenProject) iter.next(); + + if ( Constants.PROJECT_PACKAGING_EAR.equals( reactorProject.getPackaging() ) ) + { + Xpp3Dom[] warDefinitions = + IdeUtils.getPluginConfigurationDom( reactorProject, JeeUtils.ARTIFACT_MAVEN_EAR_PLUGIN, + new String[] { "modules", "webModule" } ); + for ( int index = 0; index < warDefinitions.length; index++ ) + { + Xpp3Dom groupId = warDefinitions[index].getChild( "groupId" ); + Xpp3Dom artifactId = warDefinitions[index].getChild( "artifactId" ); + Xpp3Dom contextRoot = warDefinitions[index].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 " + + warDefinitions[index].toString() ); + } + } + } + } + } + if ( config.getContextName() == null && Constants.PROJECT_PACKAGING_WAR.equals( project.getPackaging() ) ) + { + if ( wtpContextName == null ) + { + config.setContextName( project.getArtifactId() ); + } + 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 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 ) + { + 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(); + + if ( getWorkspaceConfiguration().getDefaultClasspathContainer() != null ) + { + getLog().info( + "Adding default classpath contaigner: " + + getWorkspaceConfiguration().getDefaultClasspathContainer() ); + classpathContainers.add( getWorkspaceConfiguration().getDefaultClasspathContainer() ); + } + 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 ) + { + 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 ) ); + } + + 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 ) + { + getLog().debug( + "testOutput toRelativeAndFixSeparator " + projectBaseDir + " , " + + project.getBuild().getTestOutputDirectory() ); + testOutput = + IdeUtils.toRelativeAndFixSeparator( projectBaseDir, + new File( project.getBuild().getTestOutputDirectory() ), false ); + getLog().debug( "testOutput after toRelative : " + testOutput ); + } + + extractSourceDirs( directories, project.getTestCompileSourceRoots(), basedir, projectBaseDir, true, testOutput ); + + extractResourceDirs( directories, project.getBuild().getTestResources(), project, basedir, projectBaseDir, + true, 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() ); + getLog().debug( "Processing source dir: " + sourceRootFile ); + + 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, final 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 ) ); + 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 ); + } + + getLog().debug( + "Adding eclipse source dir: { " + resourceDir + ", " + thisOutput + ", true, " + test + + ", " + includePattern + ", " + excludePattern + " }." ); + + directories.add( new EclipseSourceDir( resourceDir, thisOutput, true, test, includePattern, excludePattern, + resource.isFiltering() ) ); + } + } + + /** + * Calculate the project name template from the fields {@link #projectNameTemplate}, + * {@link #addVersionToProjectName} and {@link #addGroupIdToProjectName} + * + * @return the project name template that should be used after considering the plugin configuration + */ + private String calculateProjectNameTemplate() + { + if ( getProjectNameTemplate() != null ) + { + if ( isAddVersionToProjectName() || isAddGroupIdToProjectName() ) + { + getLog().warn( + "projectNameTemplate definition overrides " + + "addVersionToProjectName or addGroupIdToProjectName" ); + } + return getProjectNameTemplate(); + } + else if ( isAddVersionToProjectName() && isAddGroupIdToProjectName() ) + { + return IdeUtils.PROJECT_NAME_WITH_GROUP_AND_VERSION_TEMPLATE; + } + else if ( isAddVersionToProjectName() ) + { + return IdeUtils.PROJECT_NAME_WITH_VERSION_TEMPLATE; + } + else if ( isAddGroupIdToProjectName() ) + { + return IdeUtils.PROJECT_NAME_WITH_GROUP_TEMPLATE; + } + return IdeUtils.PROJECT_NAME_DEFAULT_TEMPLATE; + } + + /** + * {@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.getVersion() ) ) + { + return workspaceArtefact.getEclipseProjectName(); + } + } + } + return IdeUtils.getProjectName( calculateProjectNameTemplate(), artifact ); + } + + /** + * {@inheritDoc} + */ + protected IdeDependency[] getWorkspaceArtefacts() + { + return getWorkspaceConfiguration().getWorkspaceArtefacts(); + } + + public WorkspaceConfiguration getWorkspaceConfiguration() + { + if ( workspaceConfiguration == null ) + { + workspaceConfiguration = new WorkspaceConfiguration(); + if ( workspace != null ) + { + workspaceConfiguration.setWorkspaceDirectory( new File( workspace ) ); + } + new ReadWorkspaceLocations().init( getLog(), workspaceConfiguration, project, wtpdefaultserver ); + } + return workspaceConfiguration; + } + + public List getExcludes() + { + return excludes; + } + + /** + * 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.getVersion() ) ) + { + 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.getVersion() + ", found: " + workspaceArtefact.getVersion() ); + } + } + } + return false; + } + + /* + * (non-Javadoc) + * + * @see org.apache.maven.plugin.ide.AbstractIdeSupportMojo#doDependencyResolution() + */ + protected IdeDependency[] doDependencyResolution() + throws MojoExecutionException + { + + return super.doDependencyResolution(); + } + + /** + * Checks if jar has to be resolved for the given artifact + * + * @param art the artifact to check + * @return true if resolution should happen + */ + protected 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 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 + } +} -- cgit v1.2.3