All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gov.nist.secauto.metaschema.maven.plugin.AbstractMetaschemaMojo Maven / Gradle / Ivy

The newest version!
/*
 * Portions of this software was developed by employees of the National Institute
 * of Standards and Technology (NIST), an agency of the Federal Government and is
 * being made available as a public service. Pursuant to title 17 United States
 * Code Section 105, works of NIST employees are not subject to copyright
 * protection in the United States. This software may be subject to foreign
 * copyright. Permission in the United States and in foreign countries, to the
 * extent that NIST may hold copyright, to use, copy, modify, create derivative
 * works, and distribute this software and its documentation without fee is hereby
 * granted on a non-exclusive basis, provided that this notice and disclaimer
 * of warranty appears in all copies.
 *
 * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER
 * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY
 * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM
 * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE
 * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE.  IN NO EVENT
 * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT,
 * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM,
 * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY,
 * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR
 * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT
 * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.
 */

package gov.nist.secauto.metaschema.maven.plugin;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.DirectoryScanner;
import org.sonatype.plexus.build.incremental.BuildContext;

import java.io.File;
import java.net.URI;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

public abstract class AbstractMetaschemaMojo
    extends AbstractMojo {
  private static final String SYSTEM_FILE_ENCODING_PROPERTY = "file.encoding";
  private static final String[] DEFAULT_INCLUDES = { "**/*.xml" };

  /**
   * The Maven project context.
   *
   * @parameter default-value="${project}"
   * @required
   * @readonly
   */
  @Parameter(defaultValue = "${project}", required = true, readonly = true)
  MavenProject mavenProject;

  /**
   * This will be injected if this plugin is executed as part of the standard Maven lifecycle. If the
   * mojo is directly invoked, this parameter will not be injected.
   */
  @Parameter(defaultValue = "${mojoExecution}", readonly = true)
  private MojoExecution mojoExecution;

  @Component
  private BuildContext buildContext;

  /**
   * 

* The directory where the staleFile is found. The staleFile is used to determine if re-generation * of generated Java classes is needed, by recording when the last build occurred. *

*

* This directory is expected to be located within the ${project.build.directory}, to * ensure that code (re)generation occurs after cleaning the project. *

*/ @Parameter(defaultValue = "${project.build.directory}/metaschema", readonly = true, required = true) protected File staleFileDirectory; /** *

* Defines the encoding used for generating Java Source files. *

*

* The algorithm for finding the encoding to use is as follows (where the first non-null value found * is used for encoding): *

    *
  1. If the configuration property is explicitly given within the plugin's configuration, use that * value.
  2. *
  3. If the Maven property project.build.sourceEncoding is defined, use its * value.
  4. *
  5. Otherwise use the value from the system property file.encoding.
  6. *
*

* * @see #getEncoding() * @since 2.0 */ @Parameter(defaultValue = "${project.build.sourceEncoding}") private String encoding; /** * Location to generate Java source files in. */ @Parameter(defaultValue = "${project.build.directory}/generated-sources/metaschema", required = true) private File outputDirectory; /** * The directory to read source metaschema from. */ @Parameter(defaultValue = "${basedir}/src/main/metaschema") private File metaschemaDir; /** * A set of inclusion patterns used to select which metaschema are to be processed. By default, all * files are processed. */ @Parameter protected String[] includes; /** * A set of exclusion patterns used to prevent certain files from being processed. By default, this * set is empty such that no files are excluded. */ @Parameter protected String[] excludes; /** * Indicate if the execution should be skipped. */ @Parameter(property = "metaschema.skip", defaultValue = "false") private boolean skip; /** * The BuildContext is used to identify which files or directories were modified since last build. * This is used to determine if Metaschema-based generation must be performed again. * * @return the active Plexus BuildContext. */ protected final BuildContext getBuildContext() { return buildContext; } /** * Retrieve the Maven project context. * * @return The active MavenProject. */ protected final MavenProject getMavenProject() { return mavenProject; } /** * Retrieve the mojo execution context. * * @return The active MojoExecution. */ @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "this is a data holder") public MojoExecution getMojoExecution() { return mojoExecution; } /** * Retrieve the directory where generated classes will be stored. * * @return the directory */ protected File getOutputDirectory() { return outputDirectory; } /** * Set the directory where generated classes will be stored. * * @param outputDirectory * the directory to use */ protected void setOutputDirectory(File outputDirectory) { Objects.requireNonNull(outputDirectory, "outputDirectory"); this.outputDirectory = outputDirectory; } /** * Gets the file encoding to use for generated classes. *

* The algorithm for finding the encoding to use is as follows (where the first non-null value found * is used for encoding): *

*
    *
  1. If the configuration property is explicitly given within the plugin's configuration, use that * value.
  2. *
  3. If the Maven property project.build.sourceEncoding is defined, use its * value.
  4. *
  5. Otherwise use the value from the system property file.encoding.
  6. *
* * @return The encoding to be used by this AbstractJaxbMojo and its tools. */ protected final String getEncoding() { String encoding; if (this.encoding != null) { // first try to use the provided encoding encoding = this.encoding; getLog().debug(String.format("Using configured encoding [%s].", encoding)); } else { encoding = System.getProperty(SYSTEM_FILE_ENCODING_PROPERTY); getLog().warn(String.format("Using system encoding [%s]. This build is platform dependent!", encoding)); } return encoding; } /** * Retrieve a stream of Metaschema file sources. * * @return the stream */ protected Stream getSources() { DirectoryScanner ds = new DirectoryScanner(); ds.setBasedir(metaschemaDir); ds.setIncludes(includes != null && includes.length > 0 ? includes : DEFAULT_INCLUDES); ds.setExcludes(excludes != null && excludes.length > 0 ? excludes : null); ds.addDefaultExcludes(); ds.setCaseSensitive(true); ds.setFollowSymlinks(false); ds.scan(); return Stream.of(ds.getIncludedFiles()).map(filename -> new File(metaschemaDir, filename)).distinct(); } /** * Determine if the execution of this mojo should be skipped. * * @return {@code true} if the mojo execution should be skipped, or {@code false} otherwise */ protected boolean shouldExecutionBeSkipped() { return skip; } /** * Get the name of the file that is used to detect staleness. * * @return the name */ protected abstract String getStaleFileName(); /** * Gets the staleFile for this execution. * * @return the staleFile */ protected final File getStaleFile() { StringBuilder builder = new StringBuilder(); if (getMojoExecution() != null) { builder.append(getMojoExecution().getExecutionId()).append('-'); } builder.append(getStaleFileName()); return new File(staleFileDirectory, builder.toString()); } /** * Determine if code generation is required. This is done by comparing the last modified time of * each Metaschema source file against the stale file managed by this plugin. * * @return {@code true} if the code generation is needed, or {@code false} otherwise */ protected boolean isGenerationRequired() { final File staleFile = getStaleFile(); boolean generate = !staleFile.exists(); if (generate) { getLog().info(String.format("Stale file '%s' doesn't exist! Generating source files.", staleFile.getPath())); generate = true; } else { generate = false; // check for staleness long staleLastModified = staleFile.lastModified(); BuildContext buildContext = getBuildContext(); URI metaschemaDirRelative = getMavenProject().getBasedir().toURI().relativize(metaschemaDir.toURI()); if (buildContext.isIncremental() && buildContext.hasDelta(metaschemaDirRelative.toString())) { getLog().info("metaschemaDirRelative: " + metaschemaDirRelative.toString()); generate = true; } if (!generate) { for (File sourceFile : getSources().collect(Collectors.toList())) { getLog().info("Source file: " + sourceFile.getPath()); if (sourceFile.lastModified() > staleLastModified) { generate = true; } } } } return generate; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy