tuscany-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rf...@apache.org
Subject svn commit: r714199 [1/2] - in /tuscany/branches/sca-equinox: modules/ tools/maven/maven-bundle-plugin/ tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/ tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/mav...
Date Sat, 15 Nov 2008 00:33:33 GMT
Author: rfeng
Date: Fri Nov 14 16:33:33 2008
New Revision: 714199

URL: http://svn.apache.org/viewvc?rev=714199&view=rev
Log:
Leverage code from maven eclipse plugin to handle .classpath/.project generation for tuscany modules

Added:
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/AbstractIdeSupportMojo.java   (with props)
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseClasspathWriter.java   (with props)
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseCleanMojo.java   (with props)
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipsePlugin.java   (with props)
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseProjectWriter.java   (with props)
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/Messages.java   (with props)
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/resources/
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/resources/org/
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/maven/
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/maven/plugin/
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/maven/plugin/eclipse/
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/maven/plugin/eclipse/messages.properties   (with props)
Removed:
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/EclipsePluginMojo.java
Modified:
    tuscany/branches/sca-equinox/modules/pom.xml
    tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/pom.xml

Modified: tuscany/branches/sca-equinox/modules/pom.xml
URL: http://svn.apache.org/viewvc/tuscany/branches/sca-equinox/modules/pom.xml?rev=714199&r1=714198&r2=714199&view=diff
==============================================================================
--- tuscany/branches/sca-equinox/modules/pom.xml (original)
+++ tuscany/branches/sca-equinox/modules/pom.xml Fri Nov 14 16:33:33 2008
@@ -159,7 +159,7 @@
                                <id>generate-pde</id> 
                                <phase>generate-resources</phase> 
                                <goals> 
-                                   <goal>generate-pde</goal> 
+                                   <goal>eclipse</goal> 
                                </goals> 
                                <configuration> 
                                </configuration> 

Modified: tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/pom.xml
URL: http://svn.apache.org/viewvc/tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/pom.xml?rev=714199&r1=714198&r2=714199&view=diff
==============================================================================
--- tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/pom.xml (original)
+++ tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/pom.xml Fri Nov 14 16:33:33 2008
@@ -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>

Added: tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/AbstractIdeSupportMojo.java
URL: http://svn.apache.org/viewvc/tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/AbstractIdeSupportMojo.java?rev=714199&view=auto
==============================================================================
--- tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/AbstractIdeSupportMojo.java (added)
+++ tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/AbstractIdeSupportMojo.java Fri Nov 14 16:33:33 2008
@@ -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 );
+    }
+}

Propchange: tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/AbstractIdeSupportMojo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/AbstractIdeSupportMojo.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseClasspathWriter.java
URL: http://svn.apache.org/viewvc/tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseClasspathWriter.java?rev=714199&view=auto
==============================================================================
--- tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseClasspathWriter.java (added)
+++ tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseClasspathWriter.java Fri Nov 14 16:33:33 2008
@@ -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();
+
+    }
+}

Propchange: tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseClasspathWriter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseClasspathWriter.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseCleanMojo.java
URL: http://svn.apache.org/viewvc/tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseCleanMojo.java?rev=714199&view=auto
==============================================================================
--- tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseCleanMojo.java (added)
+++ tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseCleanMojo.java Fri Nov 14 16:33:33 2008
@@ -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;
+    }
+
+}

Propchange: tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseCleanMojo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tuscany/branches/sca-equinox/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseCleanMojo.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date



Mime
View raw message