/** * Copyright (c) 2012 Cloudsmith Inc. and other contributors, as listed below. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Cloudsmith * */ package org.cloudsmith.geppetto.forge.maven.plugin; import static org.cloudsmith.geppetto.injectable.CommonModuleProvider.getCommonModule; import java.io.File; import java.io.FileFilter; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Properties; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Build; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; import org.cloudsmith.geppetto.diagnostic.Diagnostic; import org.cloudsmith.geppetto.forge.Forge; import org.cloudsmith.geppetto.forge.util.ModuleUtils; import org.cloudsmith.geppetto.forge.v2.MetadataRepository; import org.cloudsmith.geppetto.forge.v2.model.Metadata; import org.cloudsmith.geppetto.forge.v2.service.ReleaseService; import org.cloudsmith.geppetto.validation.ValidationService; import org.cloudsmith.geppetto.validation.impl.ValidationModule; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.JsonParseException; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Module; /** * Goal which performs basic validation. */ public abstract class AbstractForgeMojo extends AbstractMojo { static final String IMPORTED_MODULES_ROOT = "importedModules"; static final Charset UTF_8 = Charset.forName("UTF-8"); public static boolean isNull(String field) { if(field == null) return true; field = field.trim(); if(field.length() == 0) return true; return "null".equals(field); } public static boolean isParentOrEqual(File dir, File subdir) { if(dir == null || subdir == null) return false; return dir.equals(subdir) || isParentOrEqual(dir, subdir.getParentFile()); } public static Properties readForgeProperties() throws IOException { Properties props = new Properties(); InputStream inStream = AbstractForgeMojo.class.getResourceAsStream("/forge.properties"); if(inStream == null) throw new FileNotFoundException("Resource forge.properties"); try { props.load(inStream); return props; } finally { inStream.close(); } } /** * The directory where this plug-in will search for modules. The directory itself * can be a module or it may be the root of a hierarchy where modules can be found. */ @Parameter(property = "forge.modules.root", defaultValue = "${project.basedir}") private String modulesRoot; @Component private MavenSession session; private transient File baseDir; private transient File buildDir; private transient File modulesDir; private transient Injector injector; private transient Logger log; protected void addModules(Diagnostic diagnostic, List<Module> modules) { modules.add(new ForgeMavenModule(getFileFilter(), session.getCurrentProject())); modules.add(new ValidationModule()); modules.add(getCommonModule()); } public void execute() throws MojoExecutionException, MojoFailureException { Diagnostic diagnostic = new LoggingDiagnostic(getLogger()); try { List<Module> modules = new ArrayList<Module>(); addModules(diagnostic, modules); if(diagnostic.getSeverity() <= Diagnostic.WARNING) { injector = Guice.createInjector(modules); invoke(diagnostic); } } catch(JsonParseException e) { throw new MojoFailureException(getActionName() + " failed: Invalid Json: " + e.getMessage(), e); } catch(RuntimeException e) { throw e; } catch(Exception e) { throw new MojoFailureException(getActionName() + " failed: " + e.getMessage(), e); } if(diagnostic.getSeverity() == Diagnostic.ERROR) { Exception e = diagnostic.getException(); if(e == null) throw new MojoFailureException(diagnostic.getErrorText()); throw new MojoFailureException(diagnostic.getErrorText(), e); } } protected Collection<File> findModuleRoots() { return getForgeUtil().findModuleRoots(getModulesDir(), null); } protected abstract String getActionName(); /** * Returns the basedir as an absolute path string without any '..' constructs. * * @return The absolute path of basedir */ public File getBasedir() { if(baseDir == null) { MavenProject project = session.getCurrentProject(); URI basedirURI; File basedir = project.getBasedir(); if(basedir != null) basedirURI = basedir.toURI(); else basedirURI = URI.create(session.getExecutionRootDirectory()); baseDir = new File(basedirURI.normalize()); } return baseDir; } protected synchronized File getBuildDir() { if(buildDir == null) { Build build = session.getCurrentProject().getBuild(); String buildDirStr = build == null ? null : build.getDirectory(); if(buildDirStr == null) buildDir = new File(getBasedir(), "target"); else { File bd = new File(buildDirStr); buildDir = new File(bd.toURI().normalize()); } } return buildDir; } /** * Returns an exclusion filter that rejects everything beneath the build directory plus everything that * the default exclusion filter would reject. * * @return <tt>true</tt> if the file can be accepted for inclusion */ protected FileFilter getFileFilter() { return new FileFilter() { @Override public boolean accept(File file) { return ModuleUtils.DEFAULT_FILE_FILTER.accept(file) && !isParentOrEqual(getBuildDir(), file); } }; } protected Forge getForgeUtil() { return injector.getInstance(Forge.class); } protected Injector getInjector() { return injector; } protected Logger getLogger() { if(log == null) { log = LoggerFactory.getLogger(getClass()); } return log; } protected MetadataRepository getMetadataRepository() { return injector.getInstance(MetadataRepository.class); } protected Metadata getModuleMetadata(File moduleDirectory, Diagnostic diag) throws IOException { return getForgeUtil().createFromModuleDirectory(moduleDirectory, true, null, null, diag); } protected File getModulesDir() { if(modulesDir == null) { if(modulesRoot == null) modulesDir = getBasedir(); else { File md = new File(modulesRoot); if(!md.isAbsolute()) md = new File(getBasedir(), modulesRoot); modulesDir = new File(md.toURI().normalize()); } } return modulesDir; } protected MavenProject getProject() { return session.getCurrentProject(); } protected String getRelativePath(File file) { IPath rootPath = Path.fromOSString(getModulesDir().getAbsolutePath()); IPath path = Path.fromOSString(file.getAbsolutePath()); IPath relative = path.makeRelativeTo(rootPath); return relative.toPortableString(); } protected ReleaseService getReleaseService() { return injector.getInstance(ReleaseService.class); } protected ValidationService getValidationService() { return injector.getInstance(ValidationService.class); } protected abstract void invoke(Diagnostic result) throws Exception; public void setLogger(Logger log) { this.log = log; } }