Author: agudian Date: Sun May 24 17:25:06 2015 New Revision: 1681500 URL: http://svn.apache.org/r1681500 Log: [MECLIPSE-759] Add goal resolve-workspace-dependencies to resolve the M2_REPO classpath references of all projects contained in a workspace
Added: maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/WorkspaceDependencyResolveMojo.java Modified: maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/EclipsePlugin.java maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/reader/ReadWorkspaceLocations.java maven/plugins/trunk/maven-eclipse-plugin/src/site/apt/index.apt.vm Modified: maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/EclipsePlugin.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/EclipsePlugin.java?rev=1681500&r1=1681499&r2=1681500&view=diff ============================================================================== --- maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/EclipsePlugin.java (original) +++ maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/EclipsePlugin.java Sun May 24 17:25:06 2015 @@ -451,6 +451,8 @@ public class EclipsePlugin * If set to <code>true</code>, the standard execution environment matching the compiler settings is set as JRE. If * set to <code>false</code>, the JRE matching the configured compiler-plugin executable or JAVA_HOME is selected by * name, if it is configured in the workspace. + * + * @since 2.10 */ @Parameter( property = "eclipse.preferStandardClasspathContainer", defaultValue = "false" ) private boolean preferStandardClasspathContainer; Added: maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/WorkspaceDependencyResolveMojo.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/WorkspaceDependencyResolveMojo.java?rev=1681500&view=auto ============================================================================== --- maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/WorkspaceDependencyResolveMojo.java (added) +++ maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/WorkspaceDependencyResolveMojo.java Sun May 24 17:25:06 2015 @@ -0,0 +1,182 @@ +package org.apache.maven.plugin.eclipse; + +import java.io.File; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.List; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.factory.ArtifactFactory; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.resolver.ArtifactNotFoundException; +import org.apache.maven.artifact.resolver.ArtifactResolutionException; +import org.apache.maven.artifact.resolver.ArtifactResolver; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.eclipse.reader.ReadWorkspaceLocations; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.codehaus.plexus.util.StringUtils; +import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.codehaus.plexus.util.xml.Xpp3DomBuilder; + +/** + * For all projects currently part of the workspace, all references to the <code>M2_REPO</code> classpath variable are + * resolved. + * <p> + * Note: not the projects of the <em>reactor</em> are inspected for unresolved artifacts, but the projects that are part + * of the <em>workspace</em>. + * + * @since 2.10 + * @author agudian + */ +@Mojo( name = "resolve-workspace-dependencies", aggregator = true, requiresProject = false ) +public class WorkspaceDependencyResolveMojo + extends AbstractMojo +{ + /** + * The eclipse workspace directory. + * <p> + * If omitted, the parent directories of the working directory are checked. The first directory to contain a + * <code>.metadata</code> subdirectory is chosen. + */ + @Parameter( property = "eclipse.workspace" ) + private File workspace; + + @Component( role = ArtifactFactory.class ) + private ArtifactFactory artifactFactory; + + @Component( role = ArtifactResolver.class ) + private ArtifactResolver artifactResolver; + + @Parameter( property = "project.remoteArtifactRepositories", required = true, readonly = true ) + private List<ArtifactRepository> remoteArtifactRepositories; + + @Parameter( property = "localRepository", required = true, readonly = true ) + private ArtifactRepository localRepository; + + private List<File> findProjectLocations( File workspaceLocation ) + { + return new ReadWorkspaceLocations().readProjectLocations( workspaceLocation, getLog() ); + } + + private void validateWorkspaceLocation() + throws MojoExecutionException + { + if ( workspace != null && !isWorkspaceDirectory( workspace ) ) + { + throw new MojoExecutionException( "Not a workspace directory: there is no subdirectory .metadata at " + + workspace ); + } + + if ( workspace == null ) + { + File currentWorkingDirectory = new File( "." ).getAbsoluteFile(); + while ( currentWorkingDirectory != null ) + { + if ( isWorkspaceDirectory( currentWorkingDirectory ) ) + { + getLog().debug( "Detected workspace at " + currentWorkingDirectory ); + workspace = currentWorkingDirectory; + return; + } + currentWorkingDirectory = currentWorkingDirectory.getParentFile(); + } + } + + throw new MojoExecutionException( "No workspace location configured " + + "and none can be detected in the parent directories." ); + } + + private boolean isWorkspaceDirectory( File currentWorkingDirectory ) + { + return new File( currentWorkingDirectory, ".metadata" ).isDirectory(); + } + + public void execute() + throws MojoExecutionException, MojoFailureException + { + validateWorkspaceLocation(); + + for ( File location : findProjectLocations( workspace ) ) + { + File classpathFile = new File( location, ".classpath" ); + if ( classpathFile.exists() ) + { + getLog().info( "Resolving M2_REPO dependencies in " + classpathFile ); + try + { + Xpp3Dom classpath = Xpp3DomBuilder.build( new FileReader( classpathFile ) ); + + for ( Xpp3Dom entry : classpath.getChildren() ) + { + if ( "var".equals( entry.getAttribute( "kind" ) ) ) + { + resolveIfNecessary( entry.getAttribute( "path" ) ); + resolveIfNecessary( entry.getAttribute( "sourcepath" ) ); + } + } + + } + catch ( Exception e ) + { + getLog().error( "Error parsing " + classpathFile, e ); + } + + } + } + } + + private void resolveIfNecessary( String path ) + throws ArtifactResolutionException + { + if ( null != path && path.startsWith( "M2_REPO" ) ) + { + try + { + Artifact artifact = createArtifactFromPath( path ); + if ( artifact != null ) + { + artifactResolver.resolve( artifact, remoteArtifactRepositories, localRepository ); + } + } + catch ( ArtifactNotFoundException e ) + { + getLog().info( e ); + } + } + } + + private Artifact createArtifactFromPath( String path ) + { + String[] elements = path.split( "/" ); + if ( elements.length < 4 ) + { + getLog().error( "Unexpected repository path structure: " + path ); + return null; + } + + List<String> groupParts = new ArrayList<String>(); + for ( int i = 1; i < elements.length - 3; i++ ) + { + groupParts.add( elements[i] ); + } + String group = StringUtils.join( groupParts.iterator(), "." ); + String artifactId = elements[elements.length - 3]; + String version = elements[elements.length - 2]; + + String classifier = null; + String fileName = elements[elements.length - 1]; + String type = fileName.substring( fileName.lastIndexOf( '.' ) + 1 ); + String possibleClassifier = + fileName.substring( artifactId.length() + version.length() + 1, fileName.length() - type.length() - 1 ); + if ( possibleClassifier.length() > 1 ) + { + classifier = possibleClassifier.substring( 1 ); + } + + return artifactFactory.createArtifactWithClassifier( group, artifactId, version, type, classifier ); + } +} Modified: maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/reader/ReadWorkspaceLocations.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/reader/ReadWorkspaceLocations.java?rev=1681500&r1=1681499&r2=1681500&view=diff ============================================================================== --- maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/reader/ReadWorkspaceLocations.java (original) +++ maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/reader/ReadWorkspaceLocations.java Sun May 24 17:25:06 2015 @@ -26,6 +26,7 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; @@ -542,38 +543,28 @@ public class ReadWorkspaceLocations } /** - * Scan the eclipse workspace and create a array with {@link IdeDependency} for all found artifacts. - * - * @param workspaceConfiguration the location of the eclipse workspace. - * @param logger the logger to report errors and debug info. + * @param workspaceDirectory the directory of the workspace + * @param logger logger + * @return the physical locations of all workspace projects */ - private void readWorkspace( WorkspaceConfiguration workspaceConfiguration, Log logger ) + public List<File> readProjectLocations( File workspaceDirectory, Log logger ) { - ArrayList<IdeDependency> dependencies = new ArrayList<IdeDependency>(); - if ( workspaceConfiguration.getWorkspaceDirectory() != null ) - { - File workspace = - new File( workspaceConfiguration.getWorkspaceDirectory(), - ReadWorkspaceLocations.METADATA_PLUGINS_ORG_ECLIPSE_CORE_RESOURCES_PROJECTS ); + List<File> projectLocations = new ArrayList<File>(); + File projectsDirectory = + new File( workspaceDirectory, ReadWorkspaceLocations.METADATA_PLUGINS_ORG_ECLIPSE_CORE_RESOURCES_PROJECTS ); - File[] directories = workspace.listFiles(); - for ( int index = 0; directories != null && index < directories.length; index++ ) + if ( projectsDirectory.exists() ) + { + for ( File project : projectsDirectory.listFiles() ) { - File project = directories[index]; if ( project.isDirectory() ) { try { - File projectLocation = - getProjectLocation( workspaceConfiguration.getWorkspaceDirectory(), project ); + File projectLocation = getProjectLocation( workspaceDirectory, project ); if ( projectLocation != null ) { - logger.debug( "read workpsace project " + projectLocation ); - IdeDependency ideDependency = readArtefact( projectLocation, logger ); - if ( ideDependency != null ) - { - dependencies.add( ideDependency ); - } + projectLocations.add( projectLocation ); } } catch ( Exception e ) @@ -583,7 +574,40 @@ public class ReadWorkspaceLocations } } } - logger.debug( dependencies.size() + " from workspace " + workspaceConfiguration.getWorkspaceDirectory() ); + + return projectLocations; + } + + /** + * Scan the eclipse workspace and create a array with {@link IdeDependency} for all found artifacts. + * + * @param workspaceConfiguration the location of the eclipse workspace. + * @param logger the logger to report errors and debug info. + */ + private void readWorkspace( WorkspaceConfiguration workspaceConfiguration, Log logger ) + { + List<IdeDependency> dependencies = new ArrayList<IdeDependency>(); + File workspaceDirectory = workspaceConfiguration.getWorkspaceDirectory(); + if ( workspaceDirectory != null ) + { + for ( File projectLocation : readProjectLocations( workspaceDirectory, logger ) ) + { + try + { + logger.debug( "read workpsace project " + projectLocation ); + IdeDependency ideDependency = readArtefact( projectLocation, logger ); + if ( ideDependency != null ) + { + dependencies.add( ideDependency ); + } + } + catch ( Exception e ) + { + logger.warn( "could not read workspace project from:" + projectLocation, e ); + } + } + } + logger.debug( dependencies.size() + " from workspace " + workspaceDirectory ); workspaceConfiguration.setWorkspaceArtefacts( dependencies.toArray( new IdeDependency[dependencies.size()] ) ); } } Modified: maven/plugins/trunk/maven-eclipse-plugin/src/site/apt/index.apt.vm URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-eclipse-plugin/src/site/apt/index.apt.vm?rev=1681500&r1=1681499&r2=1681500&view=diff ============================================================================== --- maven/plugins/trunk/maven-eclipse-plugin/src/site/apt/index.apt.vm (original) +++ maven/plugins/trunk/maven-eclipse-plugin/src/site/apt/index.apt.vm Sun May 24 17:25:06 2015 @@ -50,6 +50,11 @@ ${project.name} * {{{./eclipse-mojo.html}eclipse:eclipse}} generates the Eclipse configuration files. + * {{{./resolve-workspace-dependencies-mojo.html}eclipse:resolve-workspace-dependencies}} is used to download + all missing M2_REPO classpath variable elements for all projects in a workspace. Used if the Eclipse project + configuration files are committed to version control and other users need to resolve new artifacts after an + update. + * {{{./clean-mojo.html}eclipse:clean}} is used to delete the files used by the Eclipse IDE.