Java tutorial
/* * 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(); } }