Java tutorial
package org.codehaus.mojo.setup; /* * 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. */ import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.Collections; import java.util.List; import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.RuntimeInformation; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.codehaus.mojo.setup.SetupExecutionRequest.MergeType; import org.codehaus.plexus.PlexusConstants; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.context.Context; import org.codehaus.plexus.context.ContextException; import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable; import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable; import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException; import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.StringUtils; /** * Abstract Mojo for all setup goals * * @requiresProject false * @author Robert Scholte * @since 1.0.0 */ public abstract class AbstractSetupMojo extends AbstractMojo implements Contextualizable, Initializable { // set during contextualization /** * RuntimeInformation to discover the Maven version */ private RuntimeInformation rti; /** * @parameter expression="${session}" * @readonly * @required */ private MavenSession session; /** * Base directory of the project. * * @parameter expression="${basedir}" //never project.basedir, because pom is not required * @readonly */ private File baseDirectory; /** * Location of the settingstemplate, can be an URL, a relative or absolute path to the file * * @parameter alias="templateFile" expression="${templateFile}" */ private String templateFilename; /** * Define how to merge. Valid values are: none, update, expand and overwrite No default value, so we can detect if * it is set by commandline * * @parameter expression="${merge}" */ private String merge; /** * With dryRun the execution will run as normal, but the target-file won't change. * Instead a folder will be created with the same name as the directory-name containing the target file. * Although there will be a backup-file, this way you can check the result before really changing the file. * * @parameter expression="${dryRun}" * */ private boolean dryRun = false; /** * Setup execution request to use for the setup manager */ private SetupExecutionRequest setupRequest = new DefaultSetupExecutionRequest(); /** * {@inheritDoc} * @since 1.0.0 */ public void contextualize(Context context) throws ContextException { PlexusContainer container = (PlexusContainer) context.get(PlexusConstants.PLEXUS_KEY); try { rti = (RuntimeInformation) container.lookup(RuntimeInformation.class.getName()); } catch (ComponentLookupException e) { getLog().info("Could not retrieve RuntimeInformation to check maven version."); } } /** * {@inheritDoc} * @since 1.0.0 */ @Override public void initialize() throws InitializationException { try { if (!isRequiredMavenVersion(getMavenVersionRange())) { throw new InitializationException( "\nThis goal is not supported. You're using Maven " + rti.getApplicationVersion() + ", it must be within this range: " + getMavenVersionRange().toString()); } } catch (InvalidVersionSpecificationException e) { throw new InitializationException(e.getMessage()); } } // protected getters for subclasses /** * @return the MavenSession * @since 1.0.0 */ protected MavenSession getSession() { return session; } /** * * @return the baseDirectory as File * @since 1.0.0 */ protected File getBaseDirectory() { return baseDirectory; } /** * * @return the template filename * @since 1.0.0 */ protected String getTemplateFilename() { return templateFilename; } /** * * @return the setup request * @since 1.0.0 */ protected SetupExecutionRequest getSetupRequest() { return setupRequest; } // protected abstract getters, which subclasses must provide /** * @return the default-template filename * @since 1.0.0 */ protected abstract String getDefaultTemplateFilename(); /** * * @return the properties filename * @since 1.0.0 */ protected abstract String getPropertiesFilename(); /** * * @return the setup manager * @since 1.0.0 */ protected abstract SetupManager getSetupManager(); // helper methods /** * Exceptionless method to check is the value is a valid URL * * @param value the potential URL * @return true is it's a URL, otherwise false */ private boolean isUrl(String value) { boolean result = true; try { new URL(value); } catch (MalformedURLException e) { result = false; } return result; } /** * The prototype is an (xml)-file which contains comments on the tags to use. * * @return the prototype as InputStream, since it may be part of a jar * @throws IOException if input stream can't be resolved * @since 1.0.0 */ protected InputStream getPrototypeInputStream() throws IOException { return getSetupManager().getPrototypeInputStream(); } /** * Get the templatefile, either a custom or the default template file * * @return resolved templateFile or null * @since 1.0.0 */ protected File resolveTemplateFile() { File result = null; if (StringUtils.isNotEmpty(getTemplateFilename())) { if (isUrl(getTemplateFilename())) { try { result = FileUtils.toFile(new URL(getTemplateFilename())); } catch (MalformedURLException e) { // nop } } else { result = FileUtils.resolveFile(getBaseDirectory(), getTemplateFilename()); } } else { File templateFile = new File(getBaseDirectory(), getDefaultTemplateFilename()); if (templateFile.exists()) { result = templateFile; if (getLog().isDebugEnabled()) { getLog().debug("using " + templateFile); } } } return result; } /** * {@inheritDoc} * @since 1.0.0 */ public void execute() throws MojoExecutionException, MojoFailureException { preProcess(); try { File settingsTemplate = resolveTemplateFile(); if (settingsTemplate != null || !getSetupRequest().getAdditionalProperties().isEmpty()) { // Using merge as String, because translation to MergeType requires a switch/case or a valueOf(), which // might break; getSetupRequest().setSession(getSession()).setTemplateFile(resolveTemplateFile()) .setPropertyFilenames(getPropertyFiles()).setDryRun(dryRun); if (merge != null) { getSetupRequest().setMergeType(MergeType.valueOf(merge.toUpperCase())); } getSetupManager().process(getSetupRequest()); } else if (merge == null) { // copy prototype as default template to baseDirectory IOUtil.copy(getPrototypeInputStream(), new FileWriter(FileUtils.resolveFile(getBaseDirectory(), getDefaultTemplateFilename()))); if (getLog().isInfoEnabled()) { getLog().info(getDefaultTemplateFilename() + " has been created in the current directory."); getLog().info("Change this file for your own configuration and rerun the last maven-goal."); getLog().info("This way it will try to copy the file to the proper location."); } } else { throw new MojoFailureException("merge-property was set, but there was no template available"); } } catch (IOException e) { throw new MojoExecutionException(e.getMessage(), e); } catch (SetupExecutionException e) { throw new MojoExecutionException(e.getMessage(), e); } postProcess(); } /** * Use VersionRange.createFromVersionSpec( String ) to define the range for which the goal can be used * * @return the versionRange * @throws InvalidVersionSpecificationException The specification can't be converted to a range * @since 1.0.0 */ protected abstract VersionRange getMavenVersionRange() throws InvalidVersionSpecificationException; /** * Can be overridden, if you want to add extra info before processing. For instance: setup:security-settings uses * this method to encrypt the master-password * * @throws MojoExecutionException possible executionException * @throws MojoFailureException possible failureException * @since 1.0.0 */ protected void preProcess() throws MojoExecutionException, MojoFailureException { } /** * Can be overridden, if you want to take actions after processing * * @throws MojoExecutionException possible executionException * @throws MojoFailureException possible failureException * @since 1.0.0 */ protected void postProcess() throws MojoExecutionException, MojoFailureException { } /** * Return list of propertyFiles as String, because that's how MavenFileFilter expects them * * @return List of propertyFilePaths or null * @since 1.0.0 */ protected List<String> getPropertyFiles() { List<String> result = null; File propertyFile = FileUtils.resolveFile(getBaseDirectory(), getPropertiesFilename()); if (propertyFile.exists()) { result = Collections.singletonList(propertyFile.getAbsolutePath()); } return result; } /** * During the initializingPhase we can check if the required Maven version is used. * * @param range the version range of Maven for which this goal is executable. * @return true is version is within range, otherwise false. */ private boolean isRequiredMavenVersion(VersionRange range) { return range.containsVersion(rti.getApplicationVersion()); } }