/* * Copyright (C) 2011 Laurent Caillette * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.novelang.maven; import java.io.File; import java.io.IOException; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.google.common.collect.ImmutableList; import org.apache.commons.io.FileUtils; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; import org.novelang.logger.ConcreteLoggerFactory; import org.novelang.logger.LoggerFactory; /** * Aggregates the sources of the dependencies. * * @goal aggregate * @requiresDependencyResolution runtime * @threadSafe * * @author Laurent Caillette */ @SuppressWarnings( { "UnusedDeclaration" } ) public class SourceAggregatorMojo extends AbstractMojo { /** * @parameter expression="${project}" * @required * @readonly */ protected MavenProject project ; /** * Where to copy the sources to. * * @parameter expression="${project.build.directory}/aggregated-sources" */ private File outputDirectory = null ; /** * The regular expression to grab directory name from dependency project name. * Must have exactly one group, like: {@code Novelang-(\w+(?:-\w+)*) */ private static final Pattern DIRECTORY_NAME_GRABBER_PATTERN = Pattern.compile( "Novelang-(\\w+(?:-\\w+)*)" ) ; private static final String MAIN_JAVA_SOURCE_DIRECTORY = "/src/main/java/" ; private static final String MODULES_RELATIVE_PATH_FROM_ROOT_PROJECT = "/modules/" ; @Override public void execute() throws MojoExecutionException, MojoFailureException { ConcreteLoggerFactory.setMojoLog( getLog() ) ; LoggerFactory.configurationComplete() ; final List< File > sourcePathList = buildSourcePathList( project ) ; outputDirectory.mkdirs() ; for( final File sourcePath : sourcePathList ) { try { FileUtils.copyDirectory( sourcePath, outputDirectory, true ) ; } catch( IOException e ) { throw new MojoExecutionException( "Could not copy '" + sourcePath.getAbsolutePath() + "' " + "to '" + outputDirectory.getAbsolutePath() + "'" , e ) ; } } } private static List< File > buildSourcePathList( final MavenProject project ) throws MojoExecutionException { @SuppressWarnings( { "unchecked" } ) final List<Dependency> dependencies = project.getRuntimeDependencies() ; final ImmutableList.Builder< File > sourcePathListBuilder = ImmutableList.builder() ; final File parentRoot = findParentRoot( project ) ; for( final Dependency dependency : dependencies ) { final Matcher matcher = DIRECTORY_NAME_GRABBER_PATTERN.matcher( dependency.getArtifactId() ) ; final String moduleDirectory ; if( matcher.find() ) { if( matcher.groupCount() == 1 ) { moduleDirectory = matcher.group( 1 ) ; final String moduleFileName = parentRoot.getAbsolutePath() + MODULES_RELATIVE_PATH_FROM_ROOT_PROJECT + moduleDirectory + MAIN_JAVA_SOURCE_DIRECTORY ; sourcePathListBuilder.add( new File( moduleFileName ) ) ; } else { throw new MojoExecutionException( "Couldn't apply pattern '" + DIRECTORY_NAME_GRABBER_PATTERN.pattern() + " to '" + dependency.getArtifactId() + "'" ) ; } } } return sourcePathListBuilder.build() ; } private static File findParentRoot( final MavenProject project ) { MavenProject maybeRoot = project ; while( true ) { final MavenProject parent = maybeRoot.getParent() ; if( parent == null ) { break ; } else { maybeRoot = parent ; } } return maybeRoot.getBasedir() ; } }