summaryrefslogtreecommitdiffstats
path: root/branches/sca-equinox/tools/maven/maven-bundle-plugin
diff options
context:
space:
mode:
Diffstat (limited to 'branches/sca-equinox/tools/maven/maven-bundle-plugin')
-rw-r--r--branches/sca-equinox/tools/maven/maven-bundle-plugin/pom.xml18
-rw-r--r--branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/AbstractIdeSupportMojo.java1114
-rw-r--r--branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseClasspathWriter.java531
-rw-r--r--branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseCleanMojo.java231
-rw-r--r--branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipsePlugin.java1550
-rw-r--r--branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseProjectWriter.java351
-rw-r--r--branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/Messages.java68
-rw-r--r--branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/EclipsePluginMojo.java675
-rw-r--r--branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/maven/plugin/eclipse/messages.properties58
9 files changed, 3914 insertions, 682 deletions
diff --git a/branches/sca-equinox/tools/maven/maven-bundle-plugin/pom.xml b/branches/sca-equinox/tools/maven/maven-bundle-plugin/pom.xml
index 559c7da443..8b8bd996af 100644
--- a/branches/sca-equinox/tools/maven/maven-bundle-plugin/pom.xml
+++ b/branches/sca-equinox/tools/maven/maven-bundle-plugin/pom.xml
@@ -33,31 +33,31 @@
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
- <version>2.0.7</version>
+ <version>2.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
- <version>2.0.7</version>
+ <version>2.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-settings</artifactId>
- <version>2.0.7</version>
+ <version>2.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
- <version>2.0.7</version>
+ <version>2.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-model</artifactId>
- <version>2.0.7</version>
+ <version>2.0.8</version>
</dependency>
<dependency>
@@ -70,8 +70,12 @@
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>1.4.3</version>
- </dependency>
-
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-eclipse-plugin</artifactId>
+ <version>2.5.1</version>
+ </dependency>
</dependencies>
</project>
diff --git a/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/AbstractIdeSupportMojo.java b/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/AbstractIdeSupportMojo.java
new file mode 100644
index 0000000000..d0961ccd9c
--- /dev/null
+++ b/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/AbstractIdeSupportMojo.java
@@ -0,0 +1,1114 @@
+/*
+ * 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.sca.maven.plugin.eclipse;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.zip.ZipFile;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactCollector;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.artifact.resolver.DebugResolutionListener;
+import org.apache.maven.artifact.resolver.ResolutionNode;
+import org.apache.maven.artifact.resolver.WarningResolutionListener;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.Exclusion;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.eclipse.Constants;
+import org.apache.maven.plugin.ide.IdeDependency;
+import org.apache.maven.plugin.ide.IdeUtils;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.logging.LogEnabled;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.IOUtil;
+
+/**
+ * Abstract base plugin which takes care of the common stuff usually needed by maven IDE plugins. A plugin extending
+ * AbstractIdeSupportMojo should implement the <code>setup()</code> and <code>writeConfiguration()</code> methods,
+ * plus the getters needed to get the various configuration flags and required components. The lifecycle:
+ *
+ * <pre>
+ * *** calls setup() where you can configure your specific stuff and stop the mojo from execute if appropriate ***
+ * - manually resolve project dependencies, NOT failing if a dependency is missing
+ * - compute project references (reactor projects) if the getUseProjectReferences() flag is set
+ * - download sources/javadocs if the getDownloadSources() flag is set
+ * *** calls writeConfiguration(), passing the list of resolved referenced dependencies ***
+ * - report the list of missing sources or just tell how to turn this feature on if the flag was disabled
+ * </pre>
+ *
+ * @author Fabrizio Giustina
+ * @version $Id: AbstractIdeSupportMojo.java 628794 2008-02-18 16:09:11Z aheritier $
+ */
+public abstract class AbstractIdeSupportMojo
+ extends AbstractMojo
+ implements LogEnabled
+{
+ /**
+ * Is it an PDE project? If yes, the plugin adds the necessary natures and build commands to the .project file.
+ * Additionally it copies all libraries to a project local directory and references them instead of referencing the
+ * files in the local Maven repository. It also ensured that the "Bundle-Classpath" in META-INF/MANIFEST.MF is
+ * synchronized.
+ *
+ * @parameter expression="${eclipse.pde}" default-value="true"
+ */
+ protected boolean pde;
+
+ /**
+ * The project whose project files to create.
+ *
+ * @parameter expression="${project}"
+ * @required
+ * @readonly
+ */
+ protected MavenProject project;
+
+ // [rfeng] Change it to use the current project
+ /**
+ * The currently executed project (can be a reactor project).
+ *
+ * @parameter expression="${project}"
+ * @readonly
+ */
+ protected MavenProject executedProject;
+
+ /**
+ * The project packaging.
+ *
+ * @parameter expression="${project.packaging}"
+ */
+ protected String packaging;
+
+ /**
+ * Artifact factory, needed to download source jars for inclusion in classpath.
+ *
+ * @component role="org.apache.maven.artifact.factory.ArtifactFactory"
+ * @required
+ * @readonly
+ */
+ protected ArtifactFactory artifactFactory;
+
+ /**
+ * Artifact resolver, needed to download source jars for inclusion in classpath.
+ *
+ * @component role="org.apache.maven.artifact.resolver.ArtifactResolver"
+ * @required
+ * @readonly
+ */
+ protected ArtifactResolver artifactResolver;
+
+ /**
+ * Artifact collector, needed to resolve dependencies.
+ *
+ * @component role="org.apache.maven.artifact.resolver.ArtifactCollector"
+ * @required
+ * @readonly
+ */
+ protected ArtifactCollector artifactCollector;
+
+ /**
+ * @component role="org.apache.maven.artifact.metadata.ArtifactMetadataSource" hint="maven"
+ */
+ protected ArtifactMetadataSource artifactMetadataSource;
+
+ /**
+ * Remote repositories which will be searched for source attachments.
+ *
+ * @parameter expression="${project.remoteArtifactRepositories}"
+ * @required
+ * @readonly
+ */
+ protected List remoteArtifactRepositories;
+
+ /**
+ * Local maven repository.
+ *
+ * @parameter expression="${localRepository}"
+ * @required
+ * @readonly
+ */
+ protected ArtifactRepository localRepository;
+
+ /**
+ * If the executed project is a reactor project, this will contains the full list of projects in the reactor.
+ *
+ * @parameter expression="${reactorProjects}"
+ * @required
+ * @readonly
+ */
+ protected List reactorProjects;
+
+ /**
+ * Skip the operation when true.
+ *
+ * @parameter expression="${eclipse.skip}" default-value="false"
+ */
+ private boolean skip;
+
+ /**
+ * Enables/disables the downloading of source attachments. Defaults to false. When this flag is <code>true</code>
+ * remote repositories are checked for sources: in order to avoid repeated check for unavailable source archives, a
+ * status cache is mantained into the target dir of the root project. Run <code>mvn:clean</code> or delete the
+ * file <code>mvn-eclipse-cache.properties</code> in order to reset this cache.
+ *
+ * @parameter expression="${downloadSources}"
+ */
+ protected boolean downloadSources;
+
+ /**
+ * Enables/disables the downloading of javadoc attachments. Defaults to false. When this flag is <code>true</code>
+ * remote repositories are checked for javadocs: in order to avoid repeated check for unavailable javadoc archives,
+ * a status cache is mantained into the target dir of the root project. Run <code>mvn:clean</code> or delete the
+ * file <code>mvn-eclipse-cache.properties</code> in order to reset this cache.
+ *
+ * @parameter expression="${downloadJavadocs}"
+ */
+ protected boolean downloadJavadocs;
+
+ /**
+ * Plexus logger needed for debugging manual artifact resolution.
+ */
+ protected Logger logger;
+
+ /**
+ * Getter for <code>artifactMetadataSource</code>.
+ *
+ * @return Returns the artifactMetadataSource.
+ */
+ public ArtifactMetadataSource getArtifactMetadataSource()
+ {
+ return artifactMetadataSource;
+ }
+
+ /**
+ * Setter for <code>artifactMetadataSource</code>.
+ *
+ * @param artifactMetadataSource The artifactMetadataSource to set.
+ */
+ public void setArtifactMetadataSource( ArtifactMetadataSource artifactMetadataSource )
+ {
+ this.artifactMetadataSource = artifactMetadataSource;
+ }
+
+ /**
+ * Getter for <code>project</code>.
+ *
+ * @return Returns the project.
+ */
+ public MavenProject getProject()
+ {
+ return project;
+ }
+
+ /**
+ * Setter for <code>project</code>.
+ *
+ * @param project The project to set.
+ */
+ public void setProject( MavenProject project )
+ {
+ this.project = project;
+ }
+
+ /**
+ * Getter for <code>reactorProjects</code>.
+ *
+ * @return Returns the reactorProjects.
+ */
+ public List getReactorProjects()
+ {
+ return reactorProjects;
+ }
+
+ /**
+ * Setter for <code>reactorProjects</code>.
+ *
+ * @param reactorProjects The reactorProjects to set.
+ */
+ public void setReactorProjects( List reactorProjects )
+ {
+ this.reactorProjects = reactorProjects;
+ }
+
+ /**
+ * Getter for <code>remoteArtifactRepositories</code>.
+ *
+ * @return Returns the remoteArtifactRepositories.
+ */
+ public List getRemoteArtifactRepositories()
+ {
+ return remoteArtifactRepositories;
+ }
+
+ /**
+ * Setter for <code>remoteArtifactRepositories</code>.
+ *
+ * @param remoteArtifactRepositories The remoteArtifactRepositories to set.
+ */
+ public void setRemoteArtifactRepositories( List remoteArtifactRepositories )
+ {
+ this.remoteArtifactRepositories = remoteArtifactRepositories;
+ }
+
+ /**
+ * Getter for <code>artifactFactory</code>.
+ *
+ * @return Returns the artifactFactory.
+ */
+ public ArtifactFactory getArtifactFactory()
+ {
+ return artifactFactory;
+ }
+
+ /**
+ * Setter for <code>artifactFactory</code>.
+ *
+ * @param artifactFactory The artifactFactory to set.
+ */
+ public void setArtifactFactory( ArtifactFactory artifactFactory )
+ {
+ this.artifactFactory = artifactFactory;
+ }
+
+ /**
+ * Getter for <code>artifactResolver</code>.
+ *
+ * @return Returns the artifactResolver.
+ */
+ public ArtifactResolver getArtifactResolver()
+ {
+ return artifactResolver;
+ }
+
+ /**
+ * Setter for <code>artifactResolver</code>.
+ *
+ * @param artifactResolver The artifactResolver to set.
+ */
+ public void setArtifactResolver( ArtifactResolver artifactResolver )
+ {
+ this.artifactResolver = artifactResolver;
+ }
+
+ /**
+ * Getter for <code>executedProject</code>.
+ *
+ * @return Returns the executedProject.
+ */
+ public MavenProject getExecutedProject()
+ {
+ return executedProject;
+ }
+
+ /**
+ * Setter for <code>executedProject</code>.
+ *
+ * @param executedProject The executedProject to set.
+ */
+ public void setExecutedProject( MavenProject executedProject )
+ {
+ this.executedProject = executedProject;
+ }
+
+ /**
+ * Getter for <code>localRepository</code>.
+ *
+ * @return Returns the localRepository.
+ */
+ public ArtifactRepository getLocalRepository()
+ {
+ return localRepository;
+ }
+
+ /**
+ * Setter for <code>localRepository</code>.
+ *
+ * @param localRepository The localRepository to set.
+ */
+ public void setLocalRepository( ArtifactRepository localRepository )
+ {
+ this.localRepository = localRepository;
+ }
+
+ /**
+ * Getter for <code>downloadJavadocs</code>.
+ *
+ * @return Returns the downloadJavadocs.
+ */
+ public boolean getDownloadJavadocs()
+ {
+ return downloadJavadocs;
+ }
+
+ /**
+ * Setter for <code>downloadJavadocs</code>.
+ *
+ * @param downloadJavadocs The downloadJavadocs to set.
+ */
+ public void setDownloadJavadocs( boolean downloadJavadoc )
+ {
+ downloadJavadocs = downloadJavadoc;
+ }
+
+ /**
+ * Getter for <code>downloadSources</code>.
+ *
+ * @return Returns the downloadSources.
+ */
+ public boolean getDownloadSources()
+ {
+ return downloadSources;
+ }
+
+ /**
+ * Setter for <code>downloadSources</code>.
+ *
+ * @param downloadSources The downloadSources to set.
+ */
+ public void setDownloadSources( boolean downloadSources )
+ {
+ this.downloadSources = downloadSources;
+ }
+
+ protected void setResolveDependencies( boolean resolveDependencies )
+ {
+ this.resolveDependencies = resolveDependencies;
+ }
+
+ protected boolean isResolveDependencies()
+ {
+ return resolveDependencies;
+ }
+
+ /**
+ * return <code>false</code> if projects available in a reactor build should be considered normal dependencies,
+ * <code>true</code> if referenced project will be linked and not need artifact resolution.
+ *
+ * @return <code>true</code> if referenced project will be linked and not need artifact resolution
+ */
+ protected abstract boolean getUseProjectReferences();
+
+ /**
+ * Hook for preparation steps before the actual plugin execution.
+ *
+ * @return <code>true</code> if execution should continue or <code>false</code> if not.
+ * @throws MojoExecutionException generic mojo exception
+ */
+ protected abstract boolean setup()
+ throws MojoExecutionException;
+
+ /**
+ * Main plugin method where dependencies should be processed in order to generate IDE configuration files.
+ *
+ * @param deps list of <code>IdeDependency</code> objects, with artifacts, sources and javadocs already resolved
+ * @throws MojoExecutionException generic mojo exception
+ */
+ protected abstract void writeConfiguration( IdeDependency[] deps )
+ throws MojoExecutionException;
+
+ /**
+ * Not a plugin parameter. Collect the list of dependencies with a missing source artifact for the final report.
+ */
+ private List missingSourceDependencies = new ArrayList();
+
+ /**
+ * Not a plugin parameter. Collect the list of dependencies with a missing javadoc artifact for the final report.
+ */
+ // TODO merge this with the missingSourceDependencies in a classifier based map?
+ private List missingJavadocDependencies = new ArrayList();
+
+ /**
+ * Cached array of resolved dependencies.
+ */
+ private IdeDependency[] ideDeps;
+
+ /**
+ * Flag for mojo implementations to control whether normal maven dependencies should be resolved. Default value is
+ * true.
+ */
+ private boolean resolveDependencies = true;
+
+ /**
+ * @see org.codehaus.plexus.logging.LogEnabled#enableLogging(org.codehaus.plexus.logging.Logger)
+ */
+ public void enableLogging( Logger logger )
+ {
+ this.logger = logger;
+ }
+
+ /**
+ * @see org.apache.maven.plugin.Mojo#execute()
+ */
+ public final void execute()
+ throws MojoExecutionException, MojoFailureException
+ {
+ if ( skip )
+ {
+ return;
+ }
+
+ boolean processProject = setup();
+ if ( !processProject )
+ {
+ return;
+ }
+
+ // resolve artifacts
+ IdeDependency[] deps = doDependencyResolution();
+
+ resolveSourceAndJavadocArtifacts( deps );
+
+ writeConfiguration( deps );
+
+ reportMissingArtifacts();
+
+ }
+
+ /**
+ * Resolve project dependencies. Manual resolution is needed in order to avoid resolution of multiproject artifacts
+ * (if projects will be linked each other an installed jar is not needed) and to avoid a failure when a jar is
+ * missing.
+ *
+ * @throws MojoExecutionException if dependencies can't be resolved
+ * @return resolved IDE dependencies, with attached jars for non-reactor dependencies
+ */
+ protected IdeDependency[] doDependencyResolution()
+ throws MojoExecutionException
+ {
+ if ( ideDeps == null )
+ {
+ if ( resolveDependencies )
+ {
+ MavenProject project = getProject();
+ ArtifactRepository localRepo = getLocalRepository();
+
+ List deps = getProject().getDependencies();
+
+ // Collect the list of resolved IdeDependencies.
+ List dependencies = new ArrayList();
+
+ if ( deps != null )
+ {
+ Map managedVersions =
+ createManagedVersionMap( getArtifactFactory(), project.getId(),
+ project.getDependencyManagement() );
+
+ ArtifactResolutionResult artifactResolutionResult = null;
+
+ try
+ {
+
+ List listeners = new ArrayList();
+
+ if ( logger.isDebugEnabled() )
+ {
+ listeners.add( new DebugResolutionListener( logger ) );
+ }
+
+ listeners.add( new WarningResolutionListener( logger ) );
+
+ artifactResolutionResult =
+ artifactCollector.collect( getProjectArtifacts(), project.getArtifact(), managedVersions,
+ localRepo, project.getRemoteArtifactRepositories(),
+ getArtifactMetadataSource(), null, listeners );
+ }
+ catch ( ArtifactResolutionException e )
+ {
+ getLog().debug( e.getMessage(), e );
+ getLog().error(
+ Messages.getString( "artifactresolution", new Object[] { //$NON-NLS-1$
+ e.getGroupId(), e.getArtifactId(), e.getVersion(),
+ e.getMessage() } ) );
+
+ // if we are here artifactResolutionResult is null, create a project without dependencies but
+ // don't fail
+ // (this could be a reactor projects, we don't want to fail everything)
+ // Causes MECLIPSE-185. Not sure if it should be handled this way??
+ return new IdeDependency[0];
+ }
+
+ // keep track of added reactor projects in order to avoid duplicates
+ Set emittedReactorProjectId = new HashSet();
+
+ for ( Iterator i = artifactResolutionResult.getArtifactResolutionNodes().iterator(); i.hasNext(); )
+ {
+
+ ResolutionNode node = (ResolutionNode) i.next();
+ int dependencyDepth = node.getDepth();
+ Artifact art = node.getArtifact();
+ // don't resolve jars for reactor projects
+ if ( hasToResolveJar( art ) )
+ {
+ try
+ {
+ artifactResolver.resolve( art, node.getRemoteRepositories(), localRepository );
+ }
+ catch ( ArtifactNotFoundException e )
+ {
+ getLog().debug( e.getMessage(), e );
+ getLog().warn(
+ Messages.getString( "artifactdownload", new Object[] { //$NON-NLS-1$
+ e.getGroupId(), e.getArtifactId(), e.getVersion(),
+ e.getMessage() } ) );
+ }
+ catch ( ArtifactResolutionException e )
+ {
+ getLog().debug( e.getMessage(), e );
+ getLog().warn(
+ Messages.getString( "artifactresolution", new Object[] { //$NON-NLS-1$
+ e.getGroupId(), e.getArtifactId(), e.getVersion(),
+ e.getMessage() } ) );
+ }
+ }
+
+ boolean includeArtifact = true;
+ if ( getExcludes() != null )
+ {
+ String artifactFullId = art.getGroupId() + ":" + art.getArtifactId();
+ if ( getExcludes().contains( artifactFullId ) )
+ {
+ getLog().info( "excluded: " + artifactFullId );
+ includeArtifact = false;
+ }
+ }
+
+ if ( includeArtifact &&
+ ( !( getUseProjectReferences() && isAvailableAsAReactorProject( art ) ) || emittedReactorProjectId.add( art.getGroupId() +
+ '-' + art.getArtifactId() ) ) )
+ {
+
+ // the following doesn't work: art.getArtifactHandler().getPackaging() always returns "jar"
+ // also
+ // if the packaging specified in pom.xml is different.
+
+ // osgi-bundle packaging is provided by the felix osgi plugin
+ // eclipse-plugin packaging is provided by this eclipse plugin
+ // String packaging = art.getArtifactHandler().getPackaging();
+ // boolean isOsgiBundle = "osgi-bundle".equals( packaging ) || "eclipse-plugin".equals(
+ // packaging );
+
+ // we need to check the manifest, if "Bundle-SymbolicName" is there the artifact can be
+ // considered
+ // an osgi bundle
+ boolean isOsgiBundle = false;
+ String osgiSymbolicName = null;
+ if ( art.getFile() != null )
+ {
+ JarFile jarFile = null;
+ try
+ {
+ jarFile = new JarFile( art.getFile(), false, ZipFile.OPEN_READ );
+
+ Manifest manifest = jarFile.getManifest();
+ if ( manifest != null )
+ {
+ osgiSymbolicName =
+ manifest.getMainAttributes().getValue(
+ new Attributes.Name(
+ "Bundle-SymbolicName" ) );
+ }
+ }
+ catch ( IOException e )
+ {
+ getLog().info( "Unable to read jar manifest from " + art.getFile() );
+ }
+ finally
+ {
+ if ( jarFile != null )
+ {
+ try
+ {
+ jarFile.close();
+ }
+ catch ( IOException e )
+ {
+ // ignore
+ }
+ }
+ }
+ }
+
+ isOsgiBundle = osgiSymbolicName != null;
+
+ IdeDependency dep =
+ new IdeDependency( art.getGroupId(), art.getArtifactId(), art.getVersion(),
+ art.getClassifier(), useProjectReference( art ),
+ Artifact.SCOPE_TEST.equals( art.getScope() ),
+ Artifact.SCOPE_SYSTEM.equals( art.getScope() ),
+ Artifact.SCOPE_PROVIDED.equals( art.getScope() ),
+ art.getArtifactHandler().isAddedToClasspath(), art.getFile(),
+ art.getType(), isOsgiBundle, osgiSymbolicName, dependencyDepth,
+ getProjectNameForArifact( art ) );
+ // no duplicate entries allowed. System paths can cause this problem.
+ if ( !dependencies.contains( dep ) )
+ {
+ // [rfeng] Do not add compile/provided dependencies
+ if (!(pde && (Artifact.SCOPE_COMPILE.equals(art.getScope()) || Artifact.SCOPE_PROVIDED
+ .equals(art.getScope())))) {
+ dependencies.add( dep );
+ }
+ }
+ }
+
+ }
+
+ // @todo a final report with the list of
+ // missingArtifacts?
+
+ }
+
+ ideDeps = (IdeDependency[]) dependencies.toArray( new IdeDependency[dependencies.size()] );
+ }
+ else
+ {
+ ideDeps = new IdeDependency[0];
+ }
+ }
+
+ return ideDeps;
+ }
+
+ /**
+ * Find the name of the project as used in eclipse.
+ *
+ * @param artifact The artifact to find the eclipse name for.
+ * @return The name os the eclipse project.
+ */
+ abstract public String getProjectNameForArifact( Artifact artifact );
+
+ /**
+ * Returns the list of project artifacts. Also artifacts generated from referenced projects will be added, but with
+ * the <code>resolved</code> property set to true.
+ *
+ * @return list of projects artifacts
+ * @throws MojoExecutionException if unable to parse dependency versions
+ */
+ private Set getProjectArtifacts()
+ throws MojoExecutionException
+ {
+ // keep it sorted, this should avoid random classpath order in tests
+ Set artifacts = new TreeSet();
+
+ for ( Iterator dependencies = getProject().getDependencies().iterator(); dependencies.hasNext(); )
+ {
+ Dependency dependency = (Dependency) dependencies.next();
+
+ String groupId = dependency.getGroupId();
+ String artifactId = dependency.getArtifactId();
+ VersionRange versionRange;
+ try
+ {
+ versionRange = VersionRange.createFromVersionSpec( dependency.getVersion() );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ throw new MojoExecutionException(
+ Messages.getString(
+ "unabletoparseversion", new Object[] { //$NON-NLS-1$
+ dependency.getArtifactId(),
+ dependency.getVersion(),
+ dependency.getManagementKey(), e.getMessage() } ),
+ e );
+ }
+
+ String type = dependency.getType();
+ if ( type == null )
+ {
+ type = Constants.PROJECT_PACKAGING_JAR;
+ }
+ String classifier = dependency.getClassifier();
+ boolean optional = dependency.isOptional();
+ String scope = dependency.getScope();
+ if ( scope == null )
+ {
+ scope = Artifact.SCOPE_COMPILE;
+ }
+
+ Artifact art =
+ getArtifactFactory().createDependencyArtifact( groupId, artifactId, versionRange, type, classifier,
+ scope, optional );
+
+ if ( scope.equalsIgnoreCase( Artifact.SCOPE_SYSTEM ) )
+ {
+ art.setFile( new File( dependency.getSystemPath() ) );
+ }
+
+ List exclusions = new ArrayList();
+ for ( Iterator j = dependency.getExclusions().iterator(); j.hasNext(); )
+ {
+ Exclusion e = (Exclusion) j.next();
+ exclusions.add( e.getGroupId() + ":" + e.getArtifactId() ); //$NON-NLS-1$
+ }
+
+ ArtifactFilter newFilter = new ExcludesArtifactFilter( exclusions );
+
+ art.setDependencyFilter( newFilter );
+
+ artifacts.add( art );
+ }
+
+ return artifacts;
+ }
+
+ /**
+ * Utility method that locates a project producing the given artifact.
+ *
+ * @param artifact the artifact a project should produce.
+ * @return <code>true</code> if the artifact is produced by a reactor projectart.
+ */
+ protected boolean isAvailableAsAReactorProject( Artifact artifact )
+ {
+ if ( reactorProjects != null )
+ {
+ for ( Iterator iter = reactorProjects.iterator(); iter.hasNext(); )
+ {
+ MavenProject reactorProject = (MavenProject) iter.next();
+
+ if ( reactorProject.getGroupId().equals( artifact.getGroupId() ) &&
+ reactorProject.getArtifactId().equals( artifact.getArtifactId() ) )
+ {
+ if ( reactorProject.getVersion().equals( artifact.getVersion() ) )
+ {
+ return true;
+ }
+ else
+ {
+ getLog().info(
+ "Artifact " +
+ artifact.getId() +
+ " already available as a reactor project, but with different version. Expected: " +
+ artifact.getVersion() + ", found: " + reactorProject.getVersion() );
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @return an array with all dependencies avalaible in the workspace, to be implemented by the subclasses.
+ */
+ protected IdeDependency[] getWorkspaceArtefacts()
+ {
+ return new IdeDependency[0];
+ }
+
+ private Map createManagedVersionMap( ArtifactFactory artifactFactory, String projectId,
+ DependencyManagement dependencyManagement )
+ throws MojoExecutionException
+ {
+ Map map;
+ if ( dependencyManagement != null && dependencyManagement.getDependencies() != null )
+ {
+ map = new HashMap();
+ for ( Iterator i = dependencyManagement.getDependencies().iterator(); i.hasNext(); )
+ {
+ Dependency d = (Dependency) i.next();
+
+ try
+ {
+ VersionRange versionRange = VersionRange.createFromVersionSpec( d.getVersion() );
+ Artifact artifact =
+ artifactFactory.createDependencyArtifact( d.getGroupId(), d.getArtifactId(), versionRange,
+ d.getType(), d.getClassifier(), d.getScope(),
+ d.isOptional() );
+ map.put( d.getManagementKey(), artifact );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ throw new MojoExecutionException( Messages.getString( "unabletoparseversion", new Object[] { //$NON-NLS-1$
+ projectId, d.getVersion(),
+ d.getManagementKey(), e.getMessage() } ),
+ e );
+ }
+ }
+ }
+ else
+ {
+ map = Collections.EMPTY_MAP;
+ }
+ return map;
+ }
+
+ /**
+ * Find the reactor target dir. executedProject doesn't have the multiproject root dir set, and the only way to
+ * extract it is iterating on parent projects.
+ *
+ * @param prj current project
+ * @return the parent target dir.
+ */
+ private File getReactorTargetDir( MavenProject prj )
+ {
+ if ( prj.getParent() != null )
+ {
+ if ( prj.getParent().getBasedir() != null && prj.getParent().getBasedir().exists() )
+ {
+ return getReactorTargetDir( prj.getParent() );
+ }
+ }
+ return new File( prj.getBuild().getDirectory() );
+ }
+
+ /**
+ * Resolve source artifacts and download them if <code>downloadSources</code> is <code>true</code>. Source and
+ * javadocs artifacts will be attached to the <code>IdeDependency</code> Resolve source and javadoc artifacts. The
+ * resolved artifacts will be downloaded based on the <code>downloadSources</code> and
+ * <code>downloadJavadocs</code> attributes. Source and
+ *
+ * @param deps resolved dependencies
+ */
+ private void resolveSourceAndJavadocArtifacts( IdeDependency[] deps )
+ {
+
+ File reactorTargetDir = getReactorTargetDir( project );
+ File unavailableArtifactsTmpFile = new File( reactorTargetDir, "mvn-eclipse-cache.properties" );
+
+ getLog().info( "Using source status cache: " + unavailableArtifactsTmpFile.getAbsolutePath() );
+
+ // create target dir if missing
+ if ( !unavailableArtifactsTmpFile.getParentFile().exists() )
+ {
+ unavailableArtifactsTmpFile.getParentFile().mkdirs();
+ }
+
+ Properties unavailableArtifactsCache = new Properties();
+ if ( unavailableArtifactsTmpFile.exists() )
+ {
+ InputStream is = null;
+ try
+ {
+ is = new FileInputStream( unavailableArtifactsTmpFile );
+ unavailableArtifactsCache.load( is );
+ }
+ catch ( IOException e )
+ {
+ getLog().warn( "Unable to read source status for reactor projects" );
+ }
+ finally
+ {
+ IOUtil.close( is );
+ }
+
+ }
+
+ final List missingSources =
+ resolveDependenciesWithClassifier( deps, "sources", getDownloadSources(), unavailableArtifactsCache );
+ missingSourceDependencies.addAll( missingSources );
+
+ final List missingJavadocs =
+ resolveDependenciesWithClassifier( deps, "javadoc", getDownloadJavadocs(), unavailableArtifactsCache );
+ missingJavadocDependencies.addAll( missingJavadocs );
+
+ FileOutputStream fos = null;
+ try
+ {
+ fos = new FileOutputStream( unavailableArtifactsTmpFile );
+ unavailableArtifactsCache.store( fos, "Temporary index for unavailable sources and javadocs" );
+ }
+ catch ( IOException e )
+ {
+ getLog().warn( "Unable to cache source status for reactor projects" );
+ }
+ finally
+ {
+ IOUtil.close( fos );
+ }
+
+ }
+
+ /**
+ * Resolve the required artifacts for each of the dependency. <code>sources</code> or <code>javadoc</code>
+ * artifacts (depending on the <code>classifier</code>) are attached to the dependency.
+ *
+ * @param deps resolved dependencies
+ * @param inClassifier the classifier we are looking for (either <code>sources</code> or <code>javadoc</code>)
+ * @param includeRemoteRepositories flag whether we should search remote repositories for the artifacts or not
+ * @param unavailableArtifactsCache cache of unavailable artifacts
+ * @return the list of dependencies for which the required artifact was not found
+ */
+ private List resolveDependenciesWithClassifier( IdeDependency[] deps, String inClassifier,
+ boolean includeRemoteRepositories,
+ Properties unavailableArtifactsCache )
+ {
+ List missingClassifierDependencies = new ArrayList();
+
+ // if downloadSources is off, just check
+ // local repository for reporting missing source jars
+ List remoteRepos = includeRemoteRepositories ? getRemoteArtifactRepositories() : Collections.EMPTY_LIST;
+
+ for ( int j = 0; j < deps.length; j++ )
+ {
+ IdeDependency dependency = deps[j];
+
+ if ( dependency.isReferencedProject() || dependency.isSystemScoped() )
+ {
+ // artifact not needed
+ continue;
+ }
+
+ if ( getLog().isDebugEnabled() )
+ {
+ getLog().debug(
+ "Searching for sources for " + dependency.getId() + ":" + dependency.getClassifier() +
+ " at " + dependency.getId() + ":" + inClassifier );
+ }
+
+ String key =
+ dependency.getClassifier() == null ? dependency.getId() + ":" + inClassifier : dependency.getId() +
+ ":" + inClassifier + ":" + dependency.getClassifier();
+
+ if ( !unavailableArtifactsCache.containsKey( key ) )
+ {
+ Artifact artifact =
+ IdeUtils.resolveArtifactWithClassifier( dependency.getGroupId(), dependency.getArtifactId(),
+ dependency.getVersion(), dependency.getClassifier(),
+ inClassifier, localRepository, artifactResolver,
+ artifactFactory, remoteRepos, getLog() );
+ if ( artifact.isResolved() )
+ {
+ if ( "sources".equals( inClassifier ) )
+ {
+ dependency.setSourceAttachment( artifact.getFile() );
+ }
+ else if ( "javadoc".equals( inClassifier ) )
+ {
+ dependency.setJavadocAttachment( artifact.getFile() );
+ }
+ }
+ else
+ {
+ unavailableArtifactsCache.put( key, Boolean.TRUE.toString() );
+ // add the dependencies to the list
+ // of those lacking the required
+ // artifact
+ missingClassifierDependencies.add( dependency );
+ }
+ }
+ }
+
+ // return the list of dependencies missing the
+ // required artifact
+ return missingClassifierDependencies;
+
+ }
+
+ /**
+ * Output a message with the list of missing dependencies and info on how turn download on if it was disabled.
+ */
+ private void reportMissingArtifacts()
+ {
+ StringBuffer msg = new StringBuffer();
+
+ if ( !missingSourceDependencies.isEmpty() )
+ {
+ if ( getDownloadSources() )
+ {
+ msg.append( Messages.getString( "sourcesnotavailable" ) ); //$NON-NLS-1$
+ }
+ else
+ {
+ msg.append( Messages.getString( "sourcesnotdownloaded" ) ); //$NON-NLS-1$
+ }
+
+ for ( Iterator it = missingSourceDependencies.iterator(); it.hasNext(); )
+ {
+ IdeDependency art = (IdeDependency) it.next();
+ msg.append( Messages.getString( "sourcesmissingitem", art.getId() ) ); //$NON-NLS-1$
+ }
+ msg.append( "\n" ); //$NON-NLS-1$
+ }
+
+ if ( !missingJavadocDependencies.isEmpty() )
+ {
+ if ( getDownloadJavadocs() )
+ {
+ msg.append( Messages.getString( "javadocnotavailable" ) ); //$NON-NLS-1$
+ }
+ else
+ {
+ msg.append( Messages.getString( "javadocnotdownloaded" ) ); //$NON-NLS-1$
+ }
+
+ for ( Iterator it = missingJavadocDependencies.iterator(); it.hasNext(); )
+ {
+ IdeDependency art = (IdeDependency) it.next();
+ msg.append( Messages.getString( "javadocmissingitem", art.getId() ) ); //$NON-NLS-1$
+ }
+ msg.append( "\n" ); //$NON-NLS-1$
+ }
+ getLog().info( msg );
+ }
+
+ /**
+ * @return List of dependencies to exclude from eclipse classpath.
+ * @since 2.5
+ */
+ public abstract List getExcludes();
+
+ /**
+ * 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 ) );
+ }
+
+ /**
+ * 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 )
+ {
+ return getUseProjectReferences() && isAvailableAsAReactorProject( art );
+ }
+}
diff --git a/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseClasspathWriter.java b/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseClasspathWriter.java
new file mode 100644
index 0000000000..2813eb5388
--- /dev/null
+++ b/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseClasspathWriter.java
@@ -0,0 +1,531 @@
+/*
+ * 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.sca.maven.plugin.eclipse;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+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.EclipseSourceDir;
+import org.apache.maven.plugin.eclipse.writers.AbstractEclipseWriter;
+import org.apache.maven.plugin.eclipse.writers.EclipseAntExternalLaunchConfigurationWriter;
+import org.apache.maven.plugin.eclipse.writers.EclipseLaunchConfigurationWriter;
+import org.apache.maven.plugin.ide.IdeDependency;
+import org.apache.maven.plugin.ide.IdeUtils;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * Writes eclipse .classpath file.
+ *
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @author <a href="mailto:kenney@neonics.com">Kenney Westerhof</a>
+ * @author <a href="mailto:fgiust@apache.org">Fabrizio Giustina</a>
+ * @version $Id: EclipseClasspathWriter.java 636955 2008-03-14 02:10:42Z aheritier $
+ */
+public class EclipseClasspathWriter
+ extends AbstractEclipseWriter
+{
+
+ /**
+ * Eclipse build path variable M2_REPO
+ */
+ private static final String M2_REPO = "M2_REPO"; //$NON-NLS-1$
+
+ /**
+ * Attribute for sourcepath.
+ */
+ private static final String ATTR_SOURCEPATH = "sourcepath"; //$NON-NLS-1$
+
+ /**
+ * Attribute for output.
+ */
+ private static final String ATTR_OUTPUT = "output"; //$NON-NLS-1$
+
+ /**
+ * Attribute for path.
+ */
+ private static final String ATTR_PATH = "path"; //$NON-NLS-1$
+
+ /**
+ * Attribute for kind - Container (con), Variable (var)..etc.
+ */
+ private static final String ATTR_KIND = "kind"; //$NON-NLS-1$
+
+ /**
+ * Attribute value for kind: var
+ */
+ private static final String ATTR_VAR = "var"; //$NON-NLS-1$
+
+ /**
+ * Attribute value for kind: lib
+ */
+ private static final String ATTR_LIB = "lib"; //$NON-NLS-1$
+
+ /**
+ * Attribute value for kind: src
+ */
+ private static final String ATTR_SRC = "src"; //$NON-NLS-1$
+
+ /**
+ * Attribute name for source file includes in a path.
+ */
+ private static final String ATTR_INCLUDING = "including";
+
+ /**
+ * Attribute name for source file excludes in a path.
+ */
+ private static final String ATTR_EXCLUDING = "excluding";
+
+ /**
+ * Element for classpathentry.
+ */
+ private static final String ELT_CLASSPATHENTRY = "classpathentry"; //$NON-NLS-1$
+
+ /**
+ * Element for classpath.
+ */
+ private static final String ELT_CLASSPATH = "classpath"; //$NON-NLS-1$
+
+ /**
+ * File name that stores project classpath settings.
+ */
+ private static final String FILE_DOT_CLASSPATH = ".classpath"; //$NON-NLS-1$
+
+ /**
+ * @see org.apache.tuscany.sca.maven.plugin.eclipse.writers.EclipseWriter#write()
+ */
+ public void write()
+ throws MojoExecutionException
+ {
+
+ Writer w;
+
+ try
+ {
+ w =
+ new OutputStreamWriter( new FileOutputStream( new File( config.getEclipseProjectDirectory(),
+ FILE_DOT_CLASSPATH ) ), "UTF-8" );
+ }
+ catch ( IOException ex )
+ {
+ throw new MojoExecutionException( Messages.getString( "EclipsePlugin.erroropeningfile" ), ex ); //$NON-NLS-1$
+ }
+
+ XMLWriter writer = new PrettyPrintXMLWriter( w );
+
+ writer.startElement( ELT_CLASSPATH );
+
+ String defaultOutput =
+ IdeUtils.toRelativeAndFixSeparator( config.getProjectBaseDir(), config.getBuildOutputDirectory(), false );
+
+ // ----------------------------------------------------------------------
+ // Source roots and resources
+ // ----------------------------------------------------------------------
+
+ // List<EclipseSourceDir>
+ List specialSources = new ArrayList();
+
+ // Map<String,List<EclipseSourceDir>>
+ Map byOutputDir = new HashMap();
+
+ for ( int j = 0; j < config.getSourceDirs().length; j++ )
+ {
+ EclipseSourceDir dir = config.getSourceDirs()[j];
+
+ // List<EclipseSourceDir>
+ List byOutputDirs = (List) byOutputDir.get( dir.getOutput() );
+ if ( byOutputDirs == null )
+ {
+ // ArrayList<EclipseSourceDir>
+ byOutputDir.put( dir.getOutput() == null ? defaultOutput : dir.getOutput(), byOutputDirs =
+ new ArrayList() );
+ }
+ byOutputDirs.add( dir );
+ }
+
+ for ( int j = 0; j < config.getSourceDirs().length; j++ )
+ {
+ EclipseSourceDir dir = config.getSourceDirs()[j];
+
+ log.debug( "Processing " + ( dir.isResource() ? "re" : "" ) + "source " + dir.getPath() + ": output=" +
+ dir.getOutput() + "; default output=" + defaultOutput );
+
+ boolean isSpecial = false;
+
+ // handle resource with nested output folders
+ if ( dir.isResource() )
+ {
+ // Check if the output is a subdirectory of the default output,
+ // and if the default output has any sources that copy there.
+
+ if ( dir.getOutput() != null // resource output dir is set
+ &&
+ !dir.getOutput().equals( defaultOutput ) // output dir is not default target/classes
+ && dir.getOutput().startsWith( defaultOutput ) // ... but is nested
+ && byOutputDir.get( defaultOutput ) != null // ???
+ && !( (List) byOutputDir.get( defaultOutput ) ).isEmpty() // ???
+ )
+ {
+ // do not specify as source since the output will be nested. Instead, mark
+ // it as a todo, and handle it with a custom build.xml file later.
+
+ log.debug( "Marking as special to prevent output folder nesting: " + dir.getPath() + " (output=" +
+ dir.getOutput() + ")" );
+
+ isSpecial = true;
+ specialSources.add( dir );
+ }
+ }
+
+ writer.startElement( ELT_CLASSPATHENTRY );
+
+ writer.addAttribute( ATTR_KIND, "src" ); //$NON-NLS-1$
+ writer.addAttribute( ATTR_PATH, dir.getPath() );
+
+ if ( !isSpecial && dir.getOutput() != null && !defaultOutput.equals( dir.getOutput() ) )
+ {
+ writer.addAttribute( ATTR_OUTPUT, dir.getOutput() );
+ }
+
+ if ( StringUtils.isNotEmpty( dir.getInclude() ) )
+ {
+ writer.addAttribute( ATTR_INCLUDING, dir.getInclude() );
+ }
+
+ String excludes = dir.getExclude();
+
+ if ( dir.isResource() )
+ {
+ // 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 = StringUtils.isEmpty( excludes ) ? "**/*.java" : excludes + "|**/*.java";
+ }
+
+ if ( StringUtils.isNotEmpty( excludes ) )
+ {
+ writer.addAttribute( ATTR_EXCLUDING, excludes );
+ }
+
+ writer.endElement();
+
+ }
+
+ // handle the special sources.
+ if ( !specialSources.isEmpty() )
+ {
+ log.info( "Creating maven-eclipse.xml Ant file to handle resources" );
+
+ try
+ {
+ Writer buildXmlWriter =
+ new OutputStreamWriter( new FileOutputStream( new File( config.getEclipseProjectDirectory(),
+ "maven-eclipse.xml" ) ), "UTF-8" );
+ PrettyPrintXMLWriter buildXmlPrinter = new PrettyPrintXMLWriter( buildXmlWriter );
+
+ buildXmlPrinter.startElement( "project" );
+ buildXmlPrinter.addAttribute( "default", "copy-resources" );
+
+ buildXmlPrinter.startElement( "target" );
+ buildXmlPrinter.addAttribute( "name", "init" );
+ // initialize filtering tokens here
+ buildXmlPrinter.endElement();
+
+ buildXmlPrinter.startElement( "target" );
+ buildXmlPrinter.addAttribute( "name", "copy-resources" );
+ buildXmlPrinter.addAttribute( "depends", "init" );
+
+ for ( Iterator it = specialSources.iterator(); it.hasNext(); )
+ {
+ // TODO: merge source dirs on output path+filtering to reduce
+ // <copy> tags for speed.
+ EclipseSourceDir dir = (EclipseSourceDir) it.next();
+ buildXmlPrinter.startElement( "copy" );
+ buildXmlPrinter.addAttribute( "todir", dir.getOutput() );
+ buildXmlPrinter.addAttribute( "filtering", "" + dir.isFiltering() );
+
+ buildXmlPrinter.startElement( "fileset" );
+ buildXmlPrinter.addAttribute( "dir", dir.getPath() );
+ if ( dir.getInclude() != null )
+ {
+ buildXmlPrinter.addAttribute( "includes", dir.getInclude() );
+ }
+ if ( dir.getExclude() != null )
+ {
+ buildXmlPrinter.addAttribute( "excludes", dir.getExclude() );
+ }
+ buildXmlPrinter.endElement();
+
+ buildXmlPrinter.endElement();
+ }
+
+ buildXmlPrinter.endElement();
+
+ buildXmlPrinter.endElement();
+
+ IOUtil.close( buildXmlWriter );
+ }
+ catch ( IOException e )
+ {
+ throw new MojoExecutionException( "Cannot create " + config.getEclipseProjectDirectory() +
+ "/maven-eclipse.xml", e );
+ }
+
+ log.info( "Creating external launcher file" );
+ // now create the launcher
+ new EclipseAntExternalLaunchConfigurationWriter().init( log, config, "Maven_Ant_Builder.launch",
+ "maven-eclipse.xml" ).write();
+
+ // finally add it to the project writer.
+
+ config.getBuildCommands().add(
+ new BuildCommand(
+ "org.eclipse.ui.externaltools.ExternalToolBuilder",
+ "LaunchConfigHandle",
+ "<project>/" +
+ EclipseLaunchConfigurationWriter.FILE_DOT_EXTERNAL_TOOL_BUILDERS +
+ "Maven_Ant_Builder.launch" ) );
+ }
+
+ // ----------------------------------------------------------------------
+ // The default output
+ // ----------------------------------------------------------------------
+
+ writer.startElement( ELT_CLASSPATHENTRY );
+ writer.addAttribute( ATTR_KIND, ATTR_OUTPUT );
+ writer.addAttribute( ATTR_PATH, defaultOutput );
+ writer.endElement();
+
+ // ----------------------------------------------------------------------
+ // Container classpath entries
+ // ----------------------------------------------------------------------
+
+ for ( Iterator it = config.getClasspathContainers().iterator(); it.hasNext(); )
+ {
+ writer.startElement( ELT_CLASSPATHENTRY );
+ writer.addAttribute( ATTR_KIND, "con" ); //$NON-NLS-1$
+ writer.addAttribute( ATTR_PATH, (String) it.next() );
+ writer.endElement(); // name
+ }
+
+ // ----------------------------------------------------------------------
+ // The dependencies
+ // ----------------------------------------------------------------------
+ Set addedDependencies = new HashSet();
+ // TODO if (..magic property equals orderDependencies..)
+ IdeDependency[] depsToWrite = config.getDepsOrdered();
+ for ( int j = 0; j < depsToWrite.length; j++ )
+ {
+ IdeDependency dep = depsToWrite[j];
+
+ if ( dep.isAddedToClasspath() )
+ {
+ String depId =
+ dep.getGroupId() + ":" + dep.getArtifactId() + ":" + dep.getClassifier() + ":" + dep.getVersion();
+ /* avoid duplicates in the classpath for artifacts with different types (like ejbs) */
+ if ( !addedDependencies.contains( depId ) )
+ {
+ addDependency( writer, dep );
+ addedDependencies.add( depId );
+ }
+ }
+ }
+
+ writer.endElement();
+
+ IOUtil.close( w );
+
+ }
+
+ protected void addDependency( XMLWriter writer, IdeDependency dep )
+ throws MojoExecutionException
+ {
+
+ String path;
+ String kind;
+ String sourcepath = null;
+ String javadocpath = null;
+ // [rfeng] Force to non-PDE mode
+ boolean pdeMode = false;
+
+ if ( dep.isReferencedProject() && !pdeMode )
+ {
+ path = "/" + dep.getEclipseProjectName(); //$NON-NLS-1$
+ kind = ATTR_SRC;
+ }
+ else if ( dep.isReferencedProject() && pdeMode )
+ {
+ // don't do anything, referenced projects are automatically handled by eclipse in PDE builds
+ return;
+ }
+ else
+ {
+ File artifactPath = dep.getFile();
+
+ if ( artifactPath == null )
+ {
+ log.error( Messages.getString( "EclipsePlugin.artifactpathisnull", dep.getId() ) ); //$NON-NLS-1$
+ return;
+ }
+
+ if ( dep.isSystemScoped() )
+ {
+ path = IdeUtils.toRelativeAndFixSeparator( config.getEclipseProjectDirectory(), artifactPath, false );
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( Messages.getString( "EclipsePlugin.artifactissystemscoped", //$NON-NLS-1$
+ new Object[] { dep.getArtifactId(), path } ) );
+ }
+
+ kind = ATTR_LIB;
+ }
+ else
+ {
+ File localRepositoryFile = new File( config.getLocalRepository().getBasedir() );
+
+ // if the dependency is not provided and the plugin runs in "pde mode", the dependency is
+ // added to the Bundle-Classpath:
+ if ( pdeMode && ( dep.isProvided() || dep.isOsgiBundle() ) )
+ {
+ return;
+ }
+ else if ( pdeMode && !dep.isProvided() && !dep.isTestDependency() )
+ {
+ // path for link created in .project, not to the actual file
+ path = dep.getFile().getName();
+
+ kind = ATTR_LIB;
+ }
+ // running in PDE mode and the dependency is provided means, that it is provided by
+ // the target platform. This case is covered by adding the plugin container
+ else
+ {
+ String fullPath = artifactPath.getPath();
+ String relativePath =
+ IdeUtils.toRelativeAndFixSeparator( localRepositoryFile, new File( fullPath ), false );
+
+ if ( !new File( relativePath ).isAbsolute() )
+ {
+ path = M2_REPO + "/" //$NON-NLS-1$
+ + relativePath;
+ kind = ATTR_VAR; //$NON-NLS-1$
+ }
+ else
+ {
+ path = relativePath;
+ kind = ATTR_LIB;
+ }
+ }
+
+ if ( dep.getSourceAttachment() != null )
+ {
+ if ( ATTR_VAR.equals( kind ) )
+ {
+ sourcepath =
+ M2_REPO +
+ "/" //$NON-NLS-1$
+ +
+ IdeUtils.toRelativeAndFixSeparator( localRepositoryFile, dep.getSourceAttachment(),
+ false );
+ }
+ else
+ {
+ // source archive must be referenced with the full path, we can't mix a lib with a variable
+ sourcepath = IdeUtils.getCanonicalPath( dep.getSourceAttachment() );
+ }
+ }
+
+ if ( dep.getJavadocAttachment() != null )
+ {
+ // NB eclipse (3.1) doesn't support variables in javadoc paths, so we need to add the
+ // full path for the maven repo
+ javadocpath =
+ StringUtils.replace( IdeUtils.getCanonicalPath( dep.getJavadocAttachment() ), "\\", "/" ); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ }
+
+ }
+
+ writer.startElement( ELT_CLASSPATHENTRY );
+ writer.addAttribute( ATTR_KIND, kind );
+ writer.addAttribute( ATTR_PATH, path );
+
+ if ( sourcepath != null )
+ {
+ writer.addAttribute( ATTR_SOURCEPATH, sourcepath );
+ }
+
+ boolean attributeElemOpen = false;
+
+ if ( javadocpath != null )
+ {
+ if ( !attributeElemOpen )
+ {
+ writer.startElement( "attributes" ); //$NON-NLS-1$
+ attributeElemOpen = true;
+ }
+
+ writer.startElement( "attribute" ); //$NON-NLS-1$
+ writer.addAttribute( "value", "jar:" + new File( javadocpath ).toURI() + "!/" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ writer.addAttribute( "name", "javadoc_location" ); //$NON-NLS-1$ //$NON-NLS-2$
+ writer.endElement();
+
+ }
+
+ if ( Constants.PROJECT_PACKAGING_WAR.equals( this.config.getPackaging() ) && config.getWtpapplicationxml() &&
+ kind.equals( ATTR_VAR ) && !dep.isTestDependency() && !dep.isProvided() &&
+ !dep.isSystemScopedOutsideProject( this.config.getProject() ) )
+ {
+ if ( !attributeElemOpen )
+ {
+ writer.startElement( "attributes" ); //$NON-NLS-1$
+ attributeElemOpen = true;
+ }
+
+ writer.startElement( "attribute" ); //$NON-NLS-1$
+ writer.addAttribute( "value", "/WEB-INF/lib" ); //$NON-NLS-1$ //$NON-NLS-2$
+ writer.addAttribute( "name", "org.eclipse.jst.component.dependency" ); //$NON-NLS-1$ //$NON-NLS-2$
+ writer.endElement();
+
+ }
+
+ if ( attributeElemOpen )
+ {
+ writer.endElement();
+ }
+ writer.endElement();
+
+ }
+}
diff --git a/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseCleanMojo.java b/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseCleanMojo.java
new file mode 100644
index 0000000000..ac770c743c
--- /dev/null
+++ b/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseCleanMojo.java
@@ -0,0 +1,231 @@
+/*
+ * 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.sca.maven.plugin.eclipse;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.eclipse.Constants;
+import org.apache.maven.plugin.eclipse.EclipseConfigFile;
+import org.codehaus.plexus.util.FileUtils;
+
+/**
+ * Deletes the .project, .classpath, .wtpmodules files and .settings folder used by Eclipse.
+ *
+ * @goal clean
+ */
+public class EclipseCleanMojo
+ extends AbstractMojo
+{
+
+ /**
+ * Definition file for Eclipse Web Tools project.
+ */
+ private static final String FILE_DOT_WTPMODULES = ".wtpmodules"; //$NON-NLS-1$
+
+ /**
+ * Classpath definition file for an Eclipse Java project.
+ */
+ private static final String FILE_DOT_CLASSPATH = ".classpath"; //$NON-NLS-1$
+
+ /**
+ * Project definition file for an Eclipse Project.
+ */
+ private static final String FILE_DOT_PROJECT = ".project"; //$NON-NLS-1$
+
+ /**
+ * Web Project definition file for Eclipse Web Tools Project (Release 1.0x).
+ */
+ private static final String DIR_DOT_SETTINGS = ".settings"; //$NON-NLS-1$
+
+ /**
+ * File name where the WTP component settings will be stored - WTP 1.0 name.
+ */
+ private static final String FILE_DOT_COMPONENT = ".settings/.component"; //$NON-NLS-1$
+
+ /**
+ * File name where the WTP component settings will be stored - WTP 1.5 name.
+ */
+ private static final String FILE_DOT_COMPONENT_15 = ".settings/org.eclipse.wst.common.component"; //$NON-NLS-1$
+
+ /**
+ * File name where Eclipse Project's Facet configuration will be stored.
+ */
+ private static final String FILE_FACET_CORE_XML = ".settings/org.eclipse.wst.common.project.facet.core.xml"; //$NON-NLS-1$
+
+ /**
+ * General project preferences.
+ */
+ private static final String FILE_ECLIPSE_JDT_CORE_PREFS = ".settings/org.eclipse.jdt.core.prefs"; //$NON-NLS-1$
+
+ /**
+ * Packaging for the current project.
+ *
+ * @parameter expression="${project.packaging}"
+ */
+ private String packaging;
+
+ /**
+ * The root directory of the project
+ *
+ * @parameter expression="${basedir}"
+ */
+ private File basedir;
+
+ /**
+ * Skip the operation when true.
+ *
+ * @parameter expression="${eclipse.skip}" default-value="false"
+ */
+ private boolean skip;
+
+ /**
+ * additional generic configuration files for eclipse
+ *
+ * @parameter
+ */
+ private EclipseConfigFile[] additionalConfig;
+
+ /**
+ * @see org.apache.maven.plugin.AbstractMojo#execute()
+ */
+ public void execute()
+ throws MojoExecutionException
+ {
+ if ( skip )
+ {
+ return;
+ }
+
+ if ( Constants.PROJECT_PACKAGING_POM.equals( this.packaging ) )
+ {
+ return;
+ }
+
+ delete( new File( basedir, FILE_DOT_PROJECT ) );
+ delete( new File( basedir, FILE_DOT_CLASSPATH ) );
+ delete( new File( basedir, FILE_DOT_WTPMODULES ) );
+
+ delete( new File( basedir, FILE_DOT_COMPONENT ) );
+ delete( new File( basedir, FILE_DOT_COMPONENT_15 ) );
+ delete( new File( basedir, FILE_FACET_CORE_XML ) );
+ delete( new File( basedir, FILE_ECLIPSE_JDT_CORE_PREFS ) );
+
+ File settingsDir = new File( basedir, DIR_DOT_SETTINGS );
+ if ( settingsDir.exists() && settingsDir.isDirectory() && settingsDir.list().length == 0 )
+ {
+ delete( settingsDir );
+ }
+
+ if ( additionalConfig != null )
+ {
+ for ( int i = 0; i < additionalConfig.length; i++ )
+ {
+ delete( new File( basedir, additionalConfig[i].getName() ) );
+ }
+ }
+
+ cleanExtras();
+ }
+
+ protected void cleanExtras()
+ throws MojoExecutionException
+ {
+ // extension point.
+ }
+
+ /**
+ * Delete a file, handling log messages and exceptions
+ *
+ * @param f File to be deleted
+ * @throws MojoExecutionException only if a file exists and can't be deleted
+ */
+ protected void delete( File f )
+ throws MojoExecutionException
+ {
+ if ( f.isDirectory() )
+ {
+ getLog().info( Messages.getString( "EclipseCleanMojo.deletingDirectory", f.getName() ) ); //$NON-NLS-1$
+ }
+ else
+ {
+ getLog().info( Messages.getString( "EclipseCleanMojo.deletingFile", f.getName() ) ); //$NON-NLS-1$
+ }
+
+ if ( f.exists() )
+ {
+ if ( !f.delete() )
+ {
+ try
+ {
+ FileUtils.forceDelete( f );
+ }
+ catch ( IOException e )
+ {
+ throw new MojoExecutionException( Messages.getString( "EclipseCleanMojo.failedtodelete", //$NON-NLS-1$
+ new Object[] { f.getName(),
+ f.getAbsolutePath() } ) );
+ }
+ }
+ }
+ else
+ {
+ getLog().debug( Messages.getString( "EclipseCleanMojo.nofilefound", f.getName() ) ); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Getter for <code>basedir</code>.
+ *
+ * @return Returns the basedir.
+ */
+ public File getBasedir()
+ {
+ return this.basedir;
+ }
+
+ /**
+ * Setter for <code>basedir</code>.
+ *
+ * @param basedir The basedir to set.
+ */
+ public void setBasedir( File basedir )
+ {
+ this.basedir = basedir;
+ }
+
+ /**
+ * @return the packaging
+ */
+ public String getPackaging()
+ {
+ return this.packaging;
+ }
+
+ /**
+ * @param packaging the packaging to set
+ */
+ public void setPackaging( String packaging )
+ {
+ this.packaging = packaging;
+ }
+
+}
diff --git a/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipsePlugin.java b/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipsePlugin.java
new file mode 100644
index 0000000000..f2049c2cde
--- /dev/null
+++ b/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipsePlugin.java
@@ -0,0 +1,1550 @@
+/*
+ * 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.sca.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:
+ * <ul>
+ * <li><code>.project</code> and <code>.classpath</code> files</li>
+ * <li><code>.setting/org.eclipse.jdt.core.prefs</code> with project specific compiler settings</li>
+ * <li>various configuration files for WTP (Web Tools Project), if the parameter <code>wtpversion</code> is set to a
+ * valid version (WTP configuration is not generated by default)</li>
+ * </ul>
+ * If this goal is run on a multiproject root, dependencies between modules will be configured as direct project
+ * dependencies in Eclipse (unless <code>useProjectReferences</code> is set to <code>false</code>).
+ *
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @author <a href="mailto:fgiust@apache.org">Fabrizio Giustina</a>
+ * @version $Id: EclipsePlugin.java 641616 2008-03-26 22:42:42Z aheritier $
+ * @goal eclipse
+ * @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 <code>org.eclipse.jdt.core.javanature</code> nature plus the
+ * needed WTP natures are added. Natures added using this property <strong>replace</strong> the default list.
+ *
+ * <pre>
+ * &lt;projectnatures&gt;
+ * &lt;projectnature&gt;org.eclipse.jdt.core.javanature&lt;/projectnature&gt;
+ * &lt;projectnature&gt;org.eclipse.wst.common.modulecore.ModuleCoreNature&lt;/projectnature&gt;
+ * &lt;/projectnatures&gt;
+ * </pre>
+ *
+ * @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.
+ *
+ * <pre>
+ * &lt;additionalProjectnatures&gt;
+ * &lt;projectnature&gt;org.springframework.ide.eclipse.core.springnature&lt;/projectnature&gt;
+ * &lt;/additionalProjectnatures&gt;
+ * </pre>
+ *
+ * @parameter
+ */
+ private List additionalProjectnatures;
+
+ /**
+ * List of eclipse project facets to be added to the default ones.
+ *
+ * <pre>
+ * &lt;additionalProjectFacets&gt;
+ * &lt;jst.jsf&gt;1.1&lt;jst.jsf/&gt;
+ * &lt;/additionalProjectFacets&gt;
+ * </pre>
+ *
+ * @parameter
+ */
+ private Map additionalProjectFacets;
+
+ /**
+ * List of eclipse build commands. By default the <code>org.eclipse.jdt.core.javabuilder</code> 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 <code>additionalBuildCommands</code> parameter for
+ * that. Configuration example: Old style:
+ *
+ * <pre>
+ * &lt;buildcommands&gt;
+ * &lt;buildcommand&gt;org.eclipse.wst.common.modulecore.ComponentStructuralBuilder&lt;/buildcommand&gt;
+ * &lt;buildcommand&gt;org.eclipse.jdt.core.javabuilder&lt;/buildcommand&gt;
+ * &lt;buildcommand&gt;org.eclipse.wst.common.modulecore.ComponentStructuralBuilderDependencyResolver&lt;/buildcommand&gt;
+ * &lt;/buildcommands&gt;
+ * </pre>
+ *
+ * For new style, see <code>additionalBuildCommands</code>.
+ *
+ * @parameter
+ */
+ private List buildcommands;
+
+ /**
+ * List of eclipse build commands to be added to the default ones. Old style:
+ *
+ * <pre>
+ * &lt;additionalBuildcommands&gt;
+ * &lt;buildcommand&gt;org.springframework.ide.eclipse.core.springbuilder&lt;/buildcommand&gt;
+ * &lt;/additionalBuildcommands&gt;
+ * </pre>
+ *
+ * New style:
+ *
+ * <pre>
+ * &lt;additionalBuildcommands&gt;
+ * &lt;buildCommand&gt;
+ * &lt;name&gt;org.ui.externaltools.ExternalToolBuilder&lt;/name&gt;
+ * &lt;triggers&gt;auto,full,incremental,&lt;/triggers&gt;
+ * &lt;arguments&gt;
+ * &lt;LaunchConfigHandle&gt;&amp;lt;project&amp;gt;./externalToolBuilders/MavenBuilder.launch&lt;/LaunchConfighandle&gt;
+ * &lt;/arguments&gt;
+ * &lt;/buildCommand&gt;
+ * &lt;/additionalBuildcommands&gt;
+ * </pre>
+ *
+ * Note the difference between <code>build<strong>c</strong>ommand</code> and
+ * <code>build<strong>C</strong>ommand</code>. You can mix and match old and new-style configuration entries.
+ *
+ * @parameter
+ */
+ private List additionalBuildcommands;
+
+ /**
+ * List of container classpath entries. By default the <code>org.eclipse.jdt.launching.JRE_CONTAINER</code>
+ * classpath container is added. Configuration example:
+ *
+ * <pre>
+ * &lt;classpathContainers&gt;
+ * &lt;classpathContainer&gt;org.eclipse.jdt.launching.JRE_CONTAINER&lt;/classpathContainer&gt;
+ * &lt;classpathContainer&gt;org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v5.5&lt;/classpathContainer&gt;
+ * &lt;classpathContainer&gt;org.eclipse.jst.j2ee.internal.web.container/artifact&lt;/classpathContainer&gt;
+ * &lt;/classpathContainers&gt;
+ * </pre>
+ *
+ * @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.
+ *
+ * <pre>
+ * &lt;plugin&gt;
+ * &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
+ * &lt;artifactId&gt;maven-eclipse-plugin&lt;/artifactId&gt;
+ * &lt;configuration&gt;
+ * &lt;additionalConfig&gt;
+ * &lt;file&gt;
+ * &lt;name&gt;.checkstyle&lt;/name&gt;
+ * &lt;content&gt;
+ * &lt;![CDATA[&lt;fileset-config file-format-version=&quot;1.2.0&quot; simple-config=&quot;true&quot;&gt;
+ * &lt;fileset name=&quot;all&quot; enabled=&quot;true&quot; check-config-name=&quot;acme corporate style&quot; local=&quot;false&quot;&gt;
+ * &lt;file-match-pattern match-pattern=&quot;.&quot; include-pattern=&quot;true&quot;/&gt;
+ * &lt;/fileset&gt;
+ * &lt;filter name=&quot;NonSrcDirs&quot; enabled=&quot;true&quot;/&gt;
+ * &lt;/fileset-config&gt;]]&gt;
+ * &lt;/content&gt;
+ * &lt;/file&gt;
+ * &lt;/additionalConfig&gt;
+ * &lt;/configuration&gt;
+ * &lt;/plugin&gt;
+ * </pre>
+ *
+ * Instead of the content you can also define (from version 2.5) an url to download the file :
+ *
+ * <pre>
+ * &lt;plugin&gt;
+ * &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
+ * &lt;artifactId&gt;maven-eclipse-plugin&lt;/artifactId&gt;
+ * &lt;configuration&gt;
+ * &lt;additionalConfig&gt;
+ * &lt;file&gt;
+ * &lt;name&gt;.checkstyle&lt;/name&gt;
+ * &lt;url&gt;http://some.place.org/path/to/file&lt;/url&gt;
+ * &lt;/file&gt;
+ * &lt;/additionalConfig&gt;
+ * &lt;/configuration&gt;
+ * </pre>
+ *
+ * or a location :
+ *
+ * <pre>
+ * &lt;plugin&gt;
+ * &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
+ * &lt;artifactId&gt;maven-eclipse-plugin&lt;/artifactId&gt;
+ * &lt;configuration&gt;
+ * &lt;additionalConfig&gt;
+ * &lt;file&gt;
+ * &lt;name&gt;.checkstyle&lt;/name&gt;
+ * &lt;location&gt;/checkstyle-config.xml&lt;/location&gt;
+ * &lt;/file&gt;
+ * &lt;/additionalConfig&gt;
+ * &lt;/configuration&gt;
+ * &lt;dependencies&gt;
+ * &lt;!-- The file defined in the location is stored in this dependency --&gt;
+ * &lt;dependency&gt;
+ * &lt;groupId&gt;eclipsetest&lt;/groupId&gt;
+ * &lt;artifactId&gt;checkstyle-config&lt;/artifactId&gt;
+ * &lt;version&gt;1.0&lt;/version&gt;
+ * &lt;/dependency&gt;
+ * &lt;/dependencies&gt;
+ * &lt;/plugin&gt;
+ * </pre>
+ *
+ * @parameter
+ */
+ private EclipseConfigFile[] additionalConfig;
+
+ /**
+ * If set to <code>true</code>, 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 <code>true</code>, 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 <code>[groupId]</code>, <code>[artifactId]</code> and
+ * <code>[version]</code> variables. eg. <code>[groupId].[artifactId]-[version]</code>
+ *
+ * @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 <code>buildcommands</code>.
+ *
+ * @return Returns the buildcommands.
+ */
+ public List getBuildcommands()
+ {
+ return buildcommands;
+ }
+
+ /**
+ * Setter for <code>buildcommands</code>.
+ *
+ * @param buildcommands The buildcommands to set.
+ */
+ public void setBuildcommands( List buildcommands )
+ {
+ this.buildcommands = buildcommands;
+ }
+
+ /**
+ * Getter for <code>buildOutputDirectory</code>.
+ *
+ * @return Returns the buildOutputDirectory.
+ */
+ public File getBuildOutputDirectory()
+ {
+ return buildOutputDirectory;
+ }
+
+ /**
+ * Setter for <code>buildOutputDirectory</code>.
+ *
+ * @param buildOutputDirectory The buildOutputDirectory to set.
+ */
+ public void setBuildOutputDirectory( File buildOutputDirectory )
+ {
+ this.buildOutputDirectory = buildOutputDirectory;
+ }
+
+ /**
+ * Getter for <code>classpathContainers</code>.
+ *
+ * @return Returns the classpathContainers.
+ */
+ public List getClasspathContainers()
+ {
+ return classpathContainers;
+ }
+
+ /**
+ * Setter for <code>classpathContainers</code>.
+ *
+ * @param classpathContainers The classpathContainers to set.
+ */
+ public void setClasspathContainers( List classpathContainers )
+ {
+ this.classpathContainers = classpathContainers;
+ }
+
+ /**
+ * Getter for <code>eclipseProjectDir</code>.
+ *
+ * @return Returns the eclipseProjectDir.
+ */
+ public File getEclipseProjectDir()
+ {
+ return eclipseProjectDir;
+ }
+
+ /**
+ * Setter for <code>eclipseProjectDir</code>.
+ *
+ * @param eclipseProjectDir The eclipseProjectDir to set.
+ */
+ public void setEclipseProjectDir( File eclipseProjectDir )
+ {
+ this.eclipseProjectDir = eclipseProjectDir;
+ }
+
+ /**
+ * Getter for <code>projectnatures</code>.
+ *
+ * @return Returns the projectnatures.
+ */
+ public List getProjectnatures()
+ {
+ return projectnatures;
+ }
+
+ /**
+ * Setter for <code>projectnatures</code>.
+ *
+ * @param projectnatures The projectnatures to set.
+ */
+ public void setProjectnatures( List projectnatures )
+ {
+ this.projectnatures = projectnatures;
+ }
+
+ /**
+ * Getter for <code>useProjectReferences</code>.
+ *
+ * @return Returns the useProjectReferences.
+ */
+ public boolean getUseProjectReferences()
+ {
+ return useProjectReferences;
+ }
+
+ /**
+ * Setter for <code>useProjectReferences</code>.
+ *
+ * @param useProjectReferences The useProjectReferences to set.
+ */
+ public void setUseProjectReferences( boolean useProjectReferences )
+ {
+ this.useProjectReferences = useProjectReferences;
+ }
+
+ /**
+ * Getter for <code>wtpversion</code>.
+ *
+ * @return Returns the wtpversion.
+ */
+ public String getWtpversion()
+ {
+ return wtpversion;
+ }
+
+ /**
+ * Setter for <code>wtpversion</code>.
+ *
+ * @param wtpversion The wtpversion to set.
+ */
+ public void setWtpversion( String wtpversion )
+ {
+ this.wtpversion = wtpversion;
+ }
+
+ /**
+ * Getter for <code>additionalBuildcommands</code>.
+ *
+ * @return Returns the additionalBuildcommands.
+ */
+ public List getAdditionalBuildcommands()
+ {
+ return additionalBuildcommands;
+ }
+
+ /**
+ * Setter for <code>additionalBuildcommands</code>.
+ *
+ * @param additionalBuildcommands The additionalBuildcommands to set.
+ */
+ public void setAdditionalBuildcommands( List additionalBuildcommands )
+ {
+ this.additionalBuildcommands = additionalBuildcommands;
+ }
+
+ /**
+ * Getter for <code>additionalProjectnatures</code>.
+ *
+ * @return Returns the additionalProjectnatures.
+ */
+ public List getAdditionalProjectnatures()
+ {
+ return additionalProjectnatures;
+ }
+
+ /**
+ * Setter for <code>additionalProjectnatures</code>.
+ *
+ * @param additionalProjectnatures The additionalProjectnatures to set.
+ */
+ public void setAdditionalProjectnatures( List additionalProjectnatures )
+ {
+ this.additionalProjectnatures = additionalProjectnatures;
+ }
+
+ /**
+ * Getter for <code>addVersionToProjectName</code>.
+ */
+ public boolean isAddVersionToProjectName()
+ {
+ return addVersionToProjectName;
+ }
+
+ /**
+ * Setter for <code>addVersionToProjectName</code>.
+ */
+ public void setAddVersionToProjectName( boolean addVersionToProjectName )
+ {
+ this.addVersionToProjectName = addVersionToProjectName;
+ }
+
+ /**
+ * Getter for <code>addGroupIdToProjectName</code>.
+ */
+ public boolean isAddGroupIdToProjectName()
+ {
+ return addGroupIdToProjectName;
+ }
+
+ /**
+ * Setter for <code>addGroupIdToProjectName</code>.
+ */
+ 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;
+ }
+
+ 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. <br/> <b> NOTE: This could change the config! </b>
+ *
+ * @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() );
+
+ 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 <code>true</code> 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
+ }
+}
diff --git a/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseProjectWriter.java b/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseProjectWriter.java
new file mode 100644
index 0000000000..070b9b3e8b
--- /dev/null
+++ b/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseProjectWriter.java
@@ -0,0 +1,351 @@
+/*
+ * 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.sca.maven.plugin.eclipse;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+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.writers.AbstractEclipseWriter;
+import org.apache.maven.plugin.ide.IdeDependency;
+import org.apache.maven.plugin.ide.IdeUtils;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
+import org.codehaus.plexus.util.xml.XMLWriter;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * Writes eclipse .project file.
+ *
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @author <a href="mailto:kenney@neonics.com">Kenney Westerhof</a>
+ * @author <a href="mailto:fgiust@apache.org">Fabrizio Giustina</a>
+ * @version $Id: EclipseProjectWriter.java 616816 2008-01-30 17:23:08Z aheritier $
+ */
+public class EclipseProjectWriter
+ extends AbstractEclipseWriter
+{
+ private static final String ELT_NAME = "name"; //$NON-NLS-1$
+
+ private static final String ELT_BUILD_COMMAND = "buildCommand"; //$NON-NLS-1$
+
+ private static final String ELT_BUILD_SPEC = "buildSpec"; //$NON-NLS-1$
+
+ private static final String ELT_NATURE = "nature"; //$NON-NLS-1$
+
+ private static final String ELT_NATURES = "natures"; //$NON-NLS-1$
+
+ private static final String FILE_DOT_PROJECT = ".project"; //$NON-NLS-1$
+
+ /**
+ * Constant for links to files.
+ */
+ private static final int LINK_TYPE_FILE = 1;
+
+ /**
+ * Constant for links to directories.
+ */
+ private static final int LINK_TYPE_DIRECTORY = 2;
+
+ /**
+ * @see org.apache.tuscany.sca.maven.plugin.eclipse.writers.EclipseWriter#write()
+ */
+ public void write()
+ throws MojoExecutionException
+ {
+
+ Set projectnatures = new LinkedHashSet();
+ Set buildCommands = new LinkedHashSet();
+
+ File dotProject = new File( config.getEclipseProjectDirectory(), FILE_DOT_PROJECT );
+
+ if ( dotProject.exists() )
+ {
+
+ log.info( Messages.getString( "EclipsePlugin.keepexisting", dotProject.getAbsolutePath() ) ); //$NON-NLS-1$
+
+ // parse existing file in order to keep manually-added entries
+ Reader reader = null;
+ try
+ {
+ reader = new InputStreamReader( new FileInputStream( dotProject ), "UTF-8" );
+ Xpp3Dom dom = Xpp3DomBuilder.build( reader );
+
+ Xpp3Dom naturesElement = dom.getChild( ELT_NATURES );
+ if ( naturesElement != null )
+ {
+ Xpp3Dom[] existingNatures = naturesElement.getChildren( ELT_NATURE );
+ for ( int j = 0; j < existingNatures.length; j++ )
+ {
+ // adds all the existing natures
+ projectnatures.add( existingNatures[j].getValue() );
+ }
+ }
+
+ Xpp3Dom buildSpec = dom.getChild( ELT_BUILD_SPEC );
+ if ( buildSpec != null )
+ {
+ Xpp3Dom[] existingBuildCommands = buildSpec.getChildren( ELT_BUILD_COMMAND );
+ for ( int j = 0; j < existingBuildCommands.length; j++ )
+ {
+ Xpp3Dom buildCommandName = existingBuildCommands[j].getChild( ELT_NAME );
+ if ( buildCommandName != null )
+ {
+ buildCommands.add( new BuildCommand( existingBuildCommands[j] ) );
+ }
+ }
+ }
+ }
+ catch ( XmlPullParserException e )
+ {
+ log.warn( Messages.getString( "EclipsePlugin.cantparseexisting", dotProject.getAbsolutePath() ) ); //$NON-NLS-1$
+ }
+ catch ( IOException e )
+ {
+ log.warn( Messages.getString( "EclipsePlugin.cantparseexisting", dotProject.getAbsolutePath() ) ); //$NON-NLS-1$
+ }
+ finally
+ {
+ IOUtil.close( reader );
+ }
+ }
+
+ // adds new entries after the existing ones
+ for ( Iterator iter = config.getProjectnatures().iterator(); iter.hasNext(); )
+ {
+ projectnatures.add( iter.next() );
+ }
+
+ for ( Iterator iter = config.getBuildCommands().iterator(); iter.hasNext(); )
+ {
+ buildCommands.add( (BuildCommand) iter.next() );
+ }
+
+ Writer w;
+
+ try
+ {
+ w = new OutputStreamWriter( new FileOutputStream( dotProject ), "UTF-8" );
+ }
+ catch ( IOException ex )
+ {
+ throw new MojoExecutionException( Messages.getString( "EclipsePlugin.erroropeningfile" ), ex ); //$NON-NLS-1$
+ }
+
+ XMLWriter writer = new PrettyPrintXMLWriter( w );
+
+ writer.startElement( "projectDescription" ); //$NON-NLS-1$
+
+ writer.startElement( ELT_NAME );
+ writer.writeText( config.getEclipseProjectName() );
+ writer.endElement();
+
+ // TODO: this entire element might be dropped if the comment is null.
+ // but as the maven1 eclipse plugin does it, it's better to be safe than sorry
+ // A eclipse developer might want to look at this.
+ writer.startElement( "comment" ); //$NON-NLS-1$
+
+ if ( config.getProject().getDescription() != null )
+ {
+ writer.writeText( config.getProject().getDescription() );
+ }
+
+ writer.endElement();
+
+ writer.startElement( "projects" ); //$NON-NLS-1$
+
+ // referenced projects should not be added for plugins
+ if ( !config.isPde() )
+ {
+ for ( int j = 0; j < config.getDepsOrdered().length; j++ )
+ {
+ IdeDependency dep = config.getDepsOrdered()[j];
+ if ( dep.isReferencedProject() )
+ {
+ writer.startElement( "project" ); //$NON-NLS-1$
+ writer.writeText( dep.getEclipseProjectName() );
+ writer.endElement();
+ }
+ }
+ }
+
+ writer.endElement(); // projects
+
+ writer.startElement( ELT_BUILD_SPEC );
+
+ for ( Iterator it = buildCommands.iterator(); it.hasNext(); )
+ {
+ ( (BuildCommand) it.next() ).print( writer );
+ }
+
+ writer.endElement(); // buildSpec
+
+ writer.startElement( ELT_NATURES );
+
+ for ( Iterator it = projectnatures.iterator(); it.hasNext(); )
+ {
+ writer.startElement( ELT_NATURE );
+ writer.writeText( (String) it.next() );
+ writer.endElement(); // name
+ }
+
+ writer.endElement(); // natures
+
+ /*
+ boolean addLinks = !config.getProjectBaseDir().equals( config.getEclipseProjectDirectory() );
+
+ if ( addLinks || ( config.isPde() && config.getDepsOrdered().length > 0 ) )
+ {
+ writer.startElement( "linkedResources" ); //$NON-NLS-1$
+
+ if ( addLinks )
+ {
+
+ addFileLink( writer, config.getProjectBaseDir(), config.getEclipseProjectDirectory(),
+ config.getProject().getFile() );
+
+ addSourceLinks( writer, config.getProjectBaseDir(), config.getEclipseProjectDirectory(),
+ config.getProject().getCompileSourceRoots() );
+ addResourceLinks( writer, config.getProjectBaseDir(), config.getEclipseProjectDirectory(),
+ config.getProject().getBuild().getResources() );
+
+ addSourceLinks( writer, config.getProjectBaseDir(), config.getEclipseProjectDirectory(),
+ config.getProject().getTestCompileSourceRoots() );
+ addResourceLinks( writer, config.getProjectBaseDir(), config.getEclipseProjectDirectory(),
+ config.getProject().getBuild().getTestResources() );
+
+ }
+
+ if ( config.isPde() )
+ {
+ for ( int j = 0; j < config.getDepsOrdered().length; j++ )
+ {
+ IdeDependency dep = config.getDepsOrdered()[j];
+
+ if ( dep.isAddedToClasspath() && !dep.isProvided() && !dep.isReferencedProject() &&
+ !dep.isTestDependency() && !dep.isOsgiBundle() )
+ {
+ String name = dep.getFile().getName();
+ addLink( writer, name, StringUtils.replace( IdeUtils.getCanonicalPath( dep.getFile() ), "\\",
+ "/" ), LINK_TYPE_FILE );
+ }
+ }
+ }
+
+ writer.endElement(); // linkedResources
+ }
+ */
+
+ writer.endElement(); // projectDescription
+
+ IOUtil.close( w );
+ }
+
+ private void addFileLink( XMLWriter writer, File projectBaseDir, File basedir, File file )
+ throws MojoExecutionException
+ {
+ if ( file.isFile() )
+ {
+ String name = IdeUtils.toRelativeAndFixSeparator( projectBaseDir, file, true );
+ String location = IdeUtils.getCanonicalPath( file ).replaceAll( "\\\\", "/" ); //$NON-NLS-1$ //$NON-NLS-2$
+
+ addLink( writer, name, location, LINK_TYPE_FILE );
+ }
+ else
+ {
+ log.warn( Messages.getString( "EclipseProjectWriter.notafile", file ) ); //$NON-NLS-1$
+ }
+ }
+
+ private void addSourceLinks( XMLWriter writer, File projectBaseDir, File basedir, List sourceRoots )
+ throws MojoExecutionException
+ {
+ for ( Iterator it = sourceRoots.iterator(); it.hasNext(); )
+ {
+ String sourceRootString = (String) it.next();
+ File sourceRoot = new File( sourceRootString );
+
+ if ( sourceRoot.isDirectory() )
+ {
+ String name = IdeUtils.toRelativeAndFixSeparator( projectBaseDir, sourceRoot, true );
+ String location = IdeUtils.getCanonicalPath( sourceRoot ).replaceAll( "\\\\", "/" ); //$NON-NLS-1$ //$NON-NLS-2$
+
+ addLink( writer, name, location, LINK_TYPE_DIRECTORY );
+ }
+ }
+ }
+
+ private void addResourceLinks( XMLWriter writer, File projectBaseDir, File basedir, List sourceRoots )
+ throws MojoExecutionException
+ {
+ for ( Iterator it = sourceRoots.iterator(); it.hasNext(); )
+ {
+ String resourceDirString = ( (Resource) it.next() ).getDirectory();
+ File resourceDir = new File( resourceDirString );
+
+ if ( resourceDir.isDirectory() )
+ {
+ String name = IdeUtils.toRelativeAndFixSeparator( projectBaseDir, resourceDir, true );
+ String location = IdeUtils.getCanonicalPath( resourceDir ).replaceAll( "\\\\", "/" ); //$NON-NLS-1$ //$NON-NLS-2$
+
+ addLink( writer, name, location, LINK_TYPE_DIRECTORY );
+ }
+ }
+ }
+
+ /**
+ * @param writer
+ * @param name
+ * @param location
+ */
+ private void addLink( XMLWriter writer, String name, String location, int type )
+ {
+ writer.startElement( "link" ); //$NON-NLS-1$
+
+ writer.startElement( ELT_NAME );
+ writer.writeText( name );
+ writer.endElement(); // name
+
+ writer.startElement( "type" ); //$NON-NLS-1$
+ writer.writeText( Integer.toString( type ) );
+ writer.endElement(); // type
+
+ writer.startElement( "location" ); //$NON-NLS-1$
+
+ writer.writeText( location );
+
+ writer.endElement(); // location
+
+ writer.endElement(); // link
+ }
+}
diff --git a/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/Messages.java b/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/Messages.java
new file mode 100644
index 0000000000..553cae6256
--- /dev/null
+++ b/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/Messages.java
@@ -0,0 +1,68 @@
+/*
+ * 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.sca.maven.plugin.eclipse;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * @author <a href="mailto:fgiust@users.sourceforge.net">Fabrizio Giustina</a>
+ * @version $Id: Messages.java 485864 2006-12-11 20:41:36Z fgiust $
+ */
+public class Messages
+{
+
+ private static final String BUNDLE_NAME = "org.apache.tuscany.sca.maven.plugin.eclipse.messages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle( BUNDLE_NAME );
+
+ private Messages()
+ {
+ }
+
+ public static String getString( String key )
+ {
+ try
+ {
+ return RESOURCE_BUNDLE.getString( key );
+ }
+ catch ( MissingResourceException e )
+ {
+ return '!' + key + '!';
+ }
+ }
+
+ public static String getString( String key, Object[] params )
+ {
+ try
+ {
+ return MessageFormat.format( RESOURCE_BUNDLE.getString( key ), params );
+ }
+ catch ( MissingResourceException e )
+ {
+ return '!' + key + '!';
+ }
+ }
+
+ public static String getString( String key, Object param )
+ {
+ return getString( key, new Object[] { param } );
+ }
+}
diff --git a/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/EclipsePluginMojo.java b/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/EclipsePluginMojo.java
deleted file mode 100644
index c40020aee8..0000000000
--- a/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/EclipsePluginMojo.java
+++ /dev/null
@@ -1,675 +0,0 @@
-/*
- * 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.sca.tools.bundle.plugin;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.model.Resource;
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.project.MavenProject;
-import org.codehaus.plexus.util.StringUtils;
-
-/**
- * A maven plugin that generates Generate .classpath and .project
- *
- * @version $Rev$ $Date$
- * @goal generate-pde
- * @phase generate-resources
- * @requiresDependencyResolution test
- * @description Generate .classpath and .project
- */
-public class EclipsePluginMojo extends AbstractMojo {
-
- public static class EclipseSourceDir implements Comparable {
- private String exclude;
-
- private boolean filtering;
-
- private String include;
-
- private boolean isResource;
-
- private String output;
-
- private String path;
-
- private boolean test;
-
- public EclipseSourceDir(String path,
- String output,
- boolean isResource,
- boolean test,
- String include,
- String exclude,
- boolean filtering) {
- this.path = path;
- this.output = output;
- this.isResource = isResource;
- this.test = test;
- this.include = include;
- this.exclude = exclude;
- this.filtering = filtering;
- }
-
- /**
- * @see java.lang.Comparable#compareTo(java.lang.Object)
- */
- public int compareTo(Object obj) {
- return this.path.compareTo(((EclipseSourceDir)obj).path);
- }
-
- /**
- * @see java.lang.Object#equals(java.lang.Object)
- */
- public boolean equals(Object obj) {
- return (obj != null) && (obj instanceof EclipseSourceDir) && this.path.equals(((EclipseSourceDir)obj).path);
- }
-
- /**
- * Getter for <code>exclude</code>.
- *
- * @return Returns the exclude.
- */
- public String getExclude() {
- return this.exclude;
- }
-
- /**
- * Getter for <code>include</code>.
- *
- * @return Returns the include.
- */
- public String getInclude() {
- return this.include;
- }
-
- /**
- * Getter for <code>output</code>.
- *
- * @return Returns the output.
- */
- public String getOutput() {
- return this.output;
- }
-
- /**
- * Getter for <code>path</code>.
- *
- * @return Returns the path.
- */
- public String getPath() {
- return this.path;
- }
-
- /**
- * @see java.lang.Object#hashCode()
- */
- public int hashCode() {
- return this.path.hashCode();
- }
-
- /**
- * Wheter this resource should be copied with filtering.
- */
- public boolean isFiltering() {
- return filtering;
- }
-
- /**
- * Getter for <code>isResource</code>.
- *
- * @return Returns the isResource.
- */
- public boolean isResource() {
- return this.isResource;
- }
-
- /**
- * Getter for <code>test</code>.
- *
- * @return Returns the test.
- */
- public boolean isTest() {
- return this.test;
- }
-
- /**
- * Setter for <code>exclude</code>.
- *
- * @param exclude The exclude to set.
- */
- public void setExclude(String exclude) {
- this.exclude = exclude;
- }
-
- /**
- * Setter for <code>include</code>.
- *
- * @param include The include to set.
- */
- public void setInclude(String include) {
- this.include = include;
- }
-
- /**
- * Setter for <code>output</code>.
- *
- * @param output The output to set.
- */
- public void setOutput(String output) {
- this.output = output;
- }
-
- /**
- * Setter for <code>path</code>.
- *
- * @param path The path to set.
- */
- public void setPath(String path) {
- this.path = path;
- }
-
- /**
- * Setter for <code>test</code>.
- *
- * @param test The test to set.
- */
- public void setTest(boolean test) {
- this.test = test;
- }
- }
-
- /**
- * Attribute name for source file excludes in a path.
- */
- private static final String ATTR_EXCLUDING = "excluding";
-
- /**
- * Attribute name for source file includes in a path.
- */
- private static final String ATTR_INCLUDING = "including";
-
- /**
- * Attribute for kind - Container (con), Variable (var)..etc.
- */
- private static final String ATTR_KIND = "kind";
-
- /**
- * Attribute for output.
- */
- private static final String ATTR_OUTPUT = "output";
-
- /**
- * Attribute for path.
- */
- private static final String ATTR_PATH = "path";
-
- /**
- * Attribute value for kind: src
- */
- private static final String ATTR_SRC = "src";
-
- /**
- * Attribute value for kind: var
- */
- private static final String ATTR_VAR = "var";
-
- /**
- * Attribute value for kind: lib
- */
- private static final String ATTR_LIB = "lib";
-
- /**
- * Eclipse build path variable M2_REPO
- */
- private static final String M2_REPO = "M2_REPO";
-
- /**
- * Element for classpathentry.
- */
- private static final String ELT_CLASSPATHENTRY = "classpathentry";
- private static final String ELT_CLASSPATH = "classpath";
-
- /**
- * @parameter expression="${localRepository}"
- * @required
- * @readonly
- */
- private ArtifactRepository localRepository;
-
- /**
- * If the executed project is a reactor project, this will contains the full list of projects in the reactor.
- *
- * @parameter expression="${reactorProjects}"
- * @required
- * @readonly
- */
- protected List reactorProjects;
-
- /**
- * Utility method that locates a project producing the given artifact.
- *
- * @param artifact the artifact a project should produce.
- * @return <code>true</code> if the artifact is produced by a reactor project.
- */
- private boolean isAvailableAsAReactorProject(Artifact artifact) {
- if (reactorProjects != null) {
- for (Iterator iter = reactorProjects.iterator(); iter.hasNext();) {
- MavenProject reactorProject = (MavenProject)iter.next();
-
- if (reactorProject.getGroupId().equals(artifact.getGroupId()) && reactorProject.getArtifactId()
- .equals(artifact.getArtifactId())) {
- if (reactorProject.getVersion().equals(artifact.getVersion())) {
- return true;
- } else {
- getLog().info("Artifact " + artifact.getId()
- + " already available as a reactor project, but with different version. Expected: "
- + artifact.getVersion()
- + ", found: "
- + reactorProject.getVersion());
- }
- }
- }
- }
- return false;
- }
-
- private static String getCanonicalPath(File file) throws MojoExecutionException {
- try {
- return file.getCanonicalPath();
- } catch (IOException e) {
- throw new MojoExecutionException(e.getMessage(), e);
- }
- }
-
- private static String toRelativeAndFixSeparator(File basedir, File fileToAdd, boolean replaceSlashesWithDashes)
- throws MojoExecutionException {
- if (!fileToAdd.isAbsolute()) {
- fileToAdd = new File(basedir, fileToAdd.getPath());
- }
-
- String basedirpath;
- String absolutePath;
-
- basedirpath = getCanonicalPath(basedir);
- absolutePath = getCanonicalPath(fileToAdd);
-
- String relative;
-
- if (absolutePath.equals(basedirpath)) {
- relative = ".";
- } else if (absolutePath.startsWith(basedirpath)) {
- relative = absolutePath.substring(basedirpath.length() + 1);
- } else {
- relative = absolutePath;
- }
-
- relative = StringUtils.replace(relative, '\\', '/');
-
- if (replaceSlashesWithDashes) {
- relative = StringUtils.replace(relative, '/', '-');
- relative = StringUtils.replace(relative, ':', '-'); // remove ":" for absolute paths in windows
- }
-
- return relative;
- }
-
- /**
- * The project to create a distribution for.
- *
- * @parameter expression="${project}"
- * @required
- * @readonly
- */
- private MavenProject project;
-
- /**
- * Skip the operation when true.
- *
- * @parameter expression="${eclipse.skip}" default-value="false"
- */
- private boolean skip;
-
- private EclipseSourceDir[] buildDirectoryList() throws MojoExecutionException {
- File buildOutputDirectory = new File(project.getBuild().getOutputDirectory());
- File basedir = project.getBasedir();
- File projectBaseDir = project.getFile().getParentFile();
-
- // avoid duplicated entries
- Set<EclipseSourceDir> directories = new TreeSet<EclipseSourceDir>();
-
- extractSourceDirs(directories, project.getCompileSourceRoots(), basedir, projectBaseDir, false, null);
-
- String relativeOutput = 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 =
- 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()]);
- }
-
- public void execute() throws MojoExecutionException {
-
- try {
- if (skip || "pom".equals(project.getPackaging())) {
- return;
- }
-
- EclipseSourceDir[] dirs = buildDirectoryList();
- File classPathFile = new File(project.getBasedir(), ".classpath");
- writeClassPath(new PrintWriter(classPathFile, "UTF-8"), dirs);
-
- File projectFile = new File(project.getBasedir(), ".project");
- writeProject(new PrintWriter(projectFile, "UTF-8"));
-
- } catch (Exception e) {
- throw new MojoExecutionException(e.getMessage(), e);
- }
-
- }
-
- void extractResourceDirs(Set<EclipseSourceDir> directories,
- List<Resource> resources,
- MavenProject project,
- File basedir,
- File workspaceProjectBaseDir,
- boolean test,
- final String output) throws MojoExecutionException {
- for (Iterator<Resource> it = resources.iterator(); it.hasNext();) {
- 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 =
- 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 = 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()));
- }
- }
-
- private void extractSourceDirs(Set<EclipseSourceDir> directories,
- List<String> sourceRoots,
- File basedir,
- File projectBaseDir,
- boolean test,
- String output) throws MojoExecutionException {
- for (Iterator<String> it = sourceRoots.iterator(); it.hasNext();) {
-
- File sourceRootFile = new File(it.next());
-
- if (sourceRootFile.isDirectory()) {
- String sourceRoot =
- toRelativeAndFixSeparator(projectBaseDir, sourceRootFile, !projectBaseDir.equals(basedir));
-
- directories.add(new EclipseSourceDir(sourceRoot, output, false, test, null, null, false));
- }
- }
- }
-
- private void writeClassPath(PrintWriter writer, EclipseSourceDir[] dirs) throws MojoExecutionException {
- String defaultOutput =
- toRelativeAndFixSeparator(project.getBasedir(), new File(project.getBuild().getOutputDirectory()), false);
-
- // ----------------------------------------------------------------------
- // Source roots and resources
- // ----------------------------------------------------------------------
-
- // List<EclipseSourceDir>
- List<EclipseSourceDir> specialSources = new ArrayList<EclipseSourceDir>();
-
- // Map<String,List<EclipseSourceDir>>
- Map<String, List<EclipseSourceDir>> byOutputDir = new HashMap<String, List<EclipseSourceDir>>();
-
- for (int j = 0; j < dirs.length; j++) {
- EclipseSourceDir dir = dirs[j];
-
- // List<EclipseSourceDir>
- List<EclipseSourceDir> byOutputDirs = byOutputDir.get(dir.getOutput());
- if (byOutputDirs == null) {
- // ArrayList<EclipseSourceDir>
- byOutputDir.put(dir.getOutput() == null ? defaultOutput : dir.getOutput(), byOutputDirs =
- new ArrayList<EclipseSourceDir>());
- }
- byOutputDirs.add(dir);
- }
-
- writer.println("<" + ELT_CLASSPATH + ">");
- writer.println(" <classpathentry kind=\"con\" path=\"org.eclipse.jdt.launching.JRE_CONTAINER\"/>");
- writer.println(" <classpathentry kind=\"con\" path=\"org.eclipse.pde.core.requiredPlugins\"/>");
- for (int j = 0; j < dirs.length; j++) {
- EclipseSourceDir dir = dirs[j];
-
- getLog().debug("Processing " + (dir.isResource() ? "re" : "")
- + "source "
- + dir.getPath()
- + ": output="
- + dir.getOutput()
- + "; default output="
- + defaultOutput);
-
- boolean isSpecial = false;
-
- // handle resource with nested output folders
- if (dir.isResource()) {
- // Check if the output is a subdirectory of the default output,
- // and if the default output has any sources that copy there.
-
- if (dir.getOutput() != null // resource output dir is set
- && !dir.getOutput().equals(defaultOutput) // output dir is not default target/classes
- && dir.getOutput().startsWith(defaultOutput) // ... but is nested
- && byOutputDir.get(defaultOutput) != null // ???
- && !(byOutputDir.get(defaultOutput)).isEmpty() // ???
- ) {
- // do not specify as source since the output will be nested. Instead, mark
- // it as a todo, and handle it with a custom build.xml file later.
-
- getLog().debug("Marking as special to prevent output folder nesting: " + dir.getPath()
- + " (output="
- + dir.getOutput()
- + ")");
-
- isSpecial = true;
- specialSources.add(dir);
- }
- }
-
- writer.print(" <" + ELT_CLASSPATHENTRY);
-
- writer.print(" " + ATTR_KIND + "=\"" + ATTR_SRC + "\"");
- writer.print(" " + ATTR_PATH + "=\"" + dir.getPath() + "\"");
-
- if (!isSpecial && dir.getOutput() != null && !defaultOutput.equals(dir.getOutput())) {
- writer.print(" " + ATTR_OUTPUT + "=\"" + dir.getOutput() + "\"");
- }
-
- if (StringUtils.isNotEmpty(dir.getInclude())) {
- writer.print(" " + ATTR_INCLUDING + "=\"" + dir.getInclude() + "\"");
- }
-
- String excludes = dir.getExclude();
-
- if (dir.isResource()) {
- // 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 = StringUtils.isEmpty(excludes) ? "**/*.java" : excludes + "|**/*.java";
- }
-
- if (StringUtils.isNotEmpty(excludes)) {
- writer.print(" " + ATTR_EXCLUDING + "=\"" + excludes + "\"");
- }
-
- writer.println("/>");
- }
-
- for (Object a : project.getArtifacts()) {
- Artifact artifact = (Artifact)a;
- if (Artifact.SCOPE_TEST.equals(artifact.getScope()) || Artifact.SCOPE_RUNTIME.equals(artifact.getScope())) {
- if (getLog().isDebugEnabled()) {
- getLog().debug("Adding explict classpath entry: " + artifact.toString());
- }
-
- String path = "", kind = "";
- if (isAvailableAsAReactorProject(artifact)) {
- path = "/" + artifact.getArtifactId();
- kind = ATTR_SRC;
- } else {
- String fullPath = artifact.getFile().getPath();
- String relativePath =
- toRelativeAndFixSeparator(new File(localRepository.getBasedir()), new File(fullPath), false);
-
- if (!new File(relativePath).isAbsolute()) {
- path = M2_REPO + "/" + relativePath;
- kind = ATTR_VAR;
- } else {
- path = relativePath;
- kind = ATTR_LIB;
- }
- }
- writer.print(" <" + ELT_CLASSPATHENTRY);
-
- writer.print(" " + ATTR_KIND + "=\"" + kind + "\"");
- writer.print(" " + ATTR_PATH + "=\"" + path + "\"");
- writer.println("/>");
- }
- }
- writer.println(" <classpathentry kind=\"" + ATTR_OUTPUT + "\" path=\"" + defaultOutput + "\"/>");
- writer.println("</" + ELT_CLASSPATH + ">");
- writer.close();
- }
-
- private void writeProject(PrintWriter ps) {
- ps.println("<projectDescription>");
- ps.println(" <name>" + project.getArtifactId() + "</name>");
- ps.println(" <projects/>");
- ps.println(" <buildSpec>");
- ps.println(" <buildCommand>");
- ps.println(" <name>org.eclipse.jdt.core.javabuilder</name>");
- ps.println(" </buildCommand>");
- ps.println(" <buildCommand>");
- ps.println(" <name>org.eclipse.pde.ManifestBuilder</name>");
- ps.println(" </buildCommand>");
- ps.println(" <buildCommand>");
- ps.println(" <name>org.eclipse.pde.SchemaBuilder</name>");
- ps.println(" </buildCommand>");
- ps.println(" </buildSpec>");
- ps.println(" <natures>");
- ps.println(" <nature>org.eclipse.jdt.core.javanature</nature>");
- ps.println(" <nature>org.eclipse.pde.PluginNature</nature>");
- ps.println(" </natures>");
- ps.println(" <linkedResources/>");
- ps.println("</projectDescription>");
- ps.close();
- }
-
-}
diff --git a/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/maven/plugin/eclipse/messages.properties b/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/maven/plugin/eclipse/messages.properties
new file mode 100644
index 0000000000..11de16d7a8
--- /dev/null
+++ b/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/maven/plugin/eclipse/messages.properties
@@ -0,0 +1,58 @@
+EclipsePlugin.missingpom=There must be a POM in the current working directory for the Eclipse plugin to work.
+EclipsePlugin.pompackaging=Not running eclipse plugin goal for pom project
+EclipsePlugin.notadir=Not a directory: "{0}"
+EclipsePlugin.cantcreatedir=Can''t create directory "{0}"
+EclipsePlugin.erroropeningfile=Exception while opening file.
+EclipsePlugin.cantwritetofile=Unable to write to file: {0}
+EclipsePlugin.cantfindresource=Unable to resolve resource location: {0}
+EclipsePlugin.cantreadfile=Unable to read file: {0}
+EclipsePlugin.keepexisting=File {0} already exists.\n Additional settings will be preserved, run mvn eclipse:clean if you want old settings to be removed.
+EclipsePlugin.cantparseexisting=Unable to parse existing file: {0}. Settings will not be preserved.
+EclipsePlugin.cantresolvesources=Cannot resolve source artifact. Artifact id: {0} (Message: {1})
+EclipsePlugin.wrote=Wrote Eclipse project for "{0}" to {1}.
+EclipsePlugin.missingelement=Missing element from the project descriptor: "{0}"
+EclipsePlugin.includenotsupported=This plugin currently doesn't support include patterns for resources. Adding the entire directory.
+EclipsePlugin.excludenotsupported=This plugin currently doesn't support exclude patterns for resources. Adding the entire directory.
+EclipsePlugin.artifactpathisnull=The artifact path was null. Artifact id: {0}
+EclipsePlugin.artifactissystemscoped=The artifact has scope ''system''. Artifact id: {0}. System path: {1}
+EclipsePlugin.unsupportedwtp=Unsupported WTP version: {0}. This plugin currently supports only the following versions: {1}.
+EclipsePlugin.wtpversion=Adding support for WTP version {0}.
+EclipsePlugin.missingjrecontainer=You did specify a list of classpath containers without the base org.eclipse.jdt.launching.JRE_CONTAINER.\n If you specify custom classpath containers you should also add org.eclipse.jdt.launching.JRE_CONTAINER to the list
+EclipsePlugin.deprecatedpar=Plugin parameter "{0}" is deprecated, please use "{1}"
+EclipsePlugin.cantcopyartifact=Can''t copy artifact "{0}".
+EclipsePlugin.foundadir={0} is a directory, ignoring.
+
+EclipseSettingsWriter.wrotesettings=Wrote settings to {0}
+EclipseSettingsWriter.cannotcreatesettings=Cannot create settings file
+EclipseSettingsWriter.errorwritingsettings=Error writing settings file
+EclipseSettingsWriter.usingdefaults=Not writing settings - defaults suffice
+
+EclipseClasspathWriter.lookingforsources=Looking for source archive for artifact {0}
+EclipseClasspathWriter.sourcesavailable=Sources attachment for artifact {0} set to {1}
+
+EclipseProjectWriter.notafile=Not adding a file link to {0}; it is not a file
+
+EclipseCleanMojo.failedtodelete=Failed to delete {0} file: {0}
+EclipseCleanMojo.nofilefound=No {0} file found
+EclipseCleanMojo.deletingFile=Deleting file: {0}
+EclipseCleanMojo.deletingDirectory=Deleting directory: {0}
+
+EclipseOSGiManifestWriter.nomanifestfile=The references manifest file doesn''t exist, plugin dependencies will not be updated: {0}
+
+IdeDependency.cantreadfile=Unable to read file: {0}
+
+Rad6LibCopier.cantdeletefile=Failed to delete file: {0}
+
+MyEclipseSpringBeansWriter.springVersionNotFound=Spring must be declared in the project's dependencies to generate .springBeans file.
+
+AbstractIdeSupportMojo.sourcesnotavailable=\n Sources for some artifacts are not available.\n List of artifacts without a source archive:
+AbstractIdeSupportMojo.sourcesnotdownloaded=\n Sources for some artifacts are not available.\n Please run the same goal with the -DdownloadSources=true parameter in order to check remote repositories for sources.\n List of artifacts without a source archive:
+AbstractIdeSupportMojo.sourcesmissingitem=\n o {0}
+AbstractIdeSupportMojo.javadocnotavailable=\n Javadoc for some artifacts is not available.\n List of artifacts without a javadoc archive:
+AbstractIdeSupportMojo.javadocnotdownloaded=\n Javadoc for some artifacts is not available.\n Please run the same goal with the -DdownloadJavadocs=true parameter in order to check remote repositories for javadoc.\n List of artifacts without a javadoc archive:
+AbstractIdeSupportMojo.javadocmissingitem=\n o {0}
+AbstractIdeSupportMojo.errorresolving=Error resolving {0} artifact. Artifact id: {1} (Message: {2})
+AbstractIdeSupportMojo.artifactresolution=An error occurred during dependency resolution of the following artifact:\n {0}:{1}:{2}\nCaused by: {3}
+AbstractIdeSupportMojo.artifactdownload=An error occurred during dependency resolution.\n Failed to retrieve {0}:{1}-{2}\nCaused by: {3}
+AbstractIdeSupportMojo.cantcanonicalize=Can''t canonicalize system path: {0}
+AbstractIdeSupportMojo.unabletoparseversion={0}: unable to parse version ''{1}'' for dependency ''{2}'': {3}