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

com.mycila.maven.plugin.license.AbstractLicenseMojo Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2008-2024 Mycila ([email protected])
 *
 * Licensed 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
 *
 *         https://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.
 */
package com.mycila.maven.plugin.license;

import com.mycila.maven.plugin.license.dependencies.LicenseMessage;
import com.mycila.maven.plugin.license.dependencies.LicensePolicy;
import com.mycila.maven.plugin.license.document.Document;
import com.mycila.maven.plugin.license.document.DocumentFactory;
import com.mycila.maven.plugin.license.document.DocumentPropertiesLoader;
import com.mycila.maven.plugin.license.document.DocumentType;
import com.mycila.maven.plugin.license.header.AdditionalHeaderDefinition;
import com.mycila.maven.plugin.license.header.Header;
import com.mycila.maven.plugin.license.header.HeaderDefinition;
import com.mycila.maven.plugin.license.header.HeaderSource;
import com.mycila.maven.plugin.license.header.HeaderType;
import com.mycila.maven.plugin.license.util.Selection;
import com.mycila.maven.plugin.license.util.resource.ResourceFinder;
import com.mycila.xmltool.XMLDoc;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Organization;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuilder;
import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
import org.apache.maven.settings.crypto.SettingsDecrypter;
import org.apache.maven.settings.crypto.SettingsDecryptionRequest;
import org.apache.maven.settings.crypto.SettingsDecryptionResult;
import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
import org.xml.sax.InputSource;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.time.Clock;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

import javax.inject.Inject;

import static com.mycila.maven.plugin.license.document.DocumentType.defaultMapping;
import static com.mycila.maven.plugin.license.util.FileUtils.asPath;
import static java.lang.String.format;
import static java.util.Arrays.asList;
import static java.util.Arrays.deepToString;

public abstract class AbstractLicenseMojo extends AbstractMojo {

  private static final String[] DEFAULT_KEYWORDS = {"copyright"};

  @Parameter
  public LicenseSet[] licenseSets;

  /**
   * The base directory, in which to search for project files.
   * 

* This is named `defaultBaseDirectory` as it will be used as the default * value for the base directory. This default value can be overridden * in each LicenseSet by setting {@link LicenseSet#basedir}. */ @Parameter(property = "license.basedir", defaultValue = "${project.basedir}", alias = "basedir", required = true) public File defaultBasedir; /** * Location of the header. It can be a relative path, absolute path, * classpath resource, any URL. The plugin first check if the name specified * is a relative file, then an absolute file, then in the classpath. If not * found, it tries to construct a URL from the location. * * @deprecated use {@link LicenseSet#header} */ @Deprecated @Parameter(property = "license.header", alias = "header") public String legacyConfigHeader; /** * Header, as text, directly in pom file. Using a CDATA section is strongly recommended. * * @deprecated use {@link LicenseSet#inlineHeader} */ @Deprecated @Parameter(property = "license.inlineHeader", alias = "inlineHeader") public String legacyConfigInlineHeader; /** * Specifies additional header files to use when checking for the presence * of a valid header in your sources. *
* When using format goal, this property will be used to detect all valid * headers that don't need formatting. *
* When using remove goal, this property will be used to detect all valid * headers that also must be removed. * * @deprecated use {@link LicenseSet#validHeaders} */ @Deprecated @Parameter(alias = "validHeaders") public String[] legacyConfigValidHeaders = new String[0]; /** * Alternative to `header`, `inlineHeader`, or `validHeaders` * for use when code is multi-licensed. * Whilst you could create a concatenated header yourself, * a cleaner approach may be to specify more than one header * and have them concatenated together by the plugin. This * allows you to maintain each distinct license header in * its own file and combined them in different ways. * * @deprecated use {@link LicenseSet#multi} */ @Deprecated @Parameter public Multi legacyConfigMulti; /** * Allows the use of external header definitions files. These files are * properties like files. *

* This is named `defaultHeaderDefinitions` as it will be used as the default * value for the header definitions. This default value can be overridden * in each LicenseSet by setting {@link LicenseSet#headerDefinitions} or * {@link LicenseSet#inlineHeaderStyles} and is overridden by {@link #defaultInlineHeaderStyles}. */ @Parameter(alias = "headerDefinitions") public String[] defaultHeaderDefinitions = new String[0]; /** * Allows the use of inline header definitions. *

* This is named `defaultInlineHeaderStyles` as it will be used as the default * value for the header definitions. *

* This default value can be overridden * in each LicenseSet by setting {@link LicenseSet#headerDefinitions} or {@link LicenseSet#inlineHeaderStyles}. *

* Inline styles overrides those read from file */ @Parameter public HeaderStyle[] defaultInlineHeaderStyles = new HeaderStyle[0]; /** * HeadSections define special regions of a header that allow for dynamic * substitution and validation. * * @deprecated use {@link LicenseSet#headerSections} */ @Deprecated @Parameter(alias = "headerSections") public HeaderSection[] legacyConfigHeaderSections = new HeaderSection[0]; /** * You can set here some properties that you want to use when reading the * header file. You can use in your header file some properties like * ${year}, ${owner} or whatever you want for the name. They will be * replaced when the header file is read by those you specified in the * command line, in the POM and in system environment. *

* This is named `defaultProperties` as it will be used as the default * value for the properties. This default value can be overridden * in each LicenseSet by setting {@link LicenseSet#properties}. */ @Parameter(alias = "properties") public Map defaultProperties = new HashMap<>(); /** * Specifies files, which are included in the check. By default, all files * are included. * * @deprecated use {@link LicenseSet#includes} */ @Deprecated @Parameter(alias = "includes", property = "license.includes") public String[] legacyConfigIncludes = new String[0]; /** * Specifies files, which are excluded in the check. By default, only the * files matching the default exclude patterns are excluded. * * @deprecated use {@link LicenseSet#excludes} */ @Deprecated @Parameter(alias = "excludes", property = "license.excludes") public String[] legacyConfigExcludes = new String[0]; /** * Specify the list of keywords to use to detect a header. A header must * include all keywords to be valid. By default, the word 'copyright' is * used. Detection is done case insensitive. * * @deprecated use {@link LicenseSet#keywords} */ @Deprecated @Parameter(alias = "keywords") public String[] legacyConfigKeywords = DEFAULT_KEYWORDS; /** * Specify if you want to use default exclusions besides the files you have * excluded. Default exclusions exclude CVS and SVN folders, IDE descriptors * and so on. *

* This is named `defaultUseDefaultExcludes` as it will be used as the default * value for whether to use default excludes. This default value can be overridden * in each LicenseSet by setting {@link LicenseSet#useDefaultExcludes}. */ @Parameter(property = "license.useDefaultExcludes", defaultValue = "true", alias = "useDefaultExcludes") public boolean defaultUseDefaultExcludes = true; /** * You can set this flag to true if you want to check the headers for all * modules of your project. Only used for multi-modules projects, to check * for example the header licenses from the parent module for all sub * modules. */ @Parameter(property = "license.aggregate", defaultValue = "false") public boolean aggregate; /** * Set mapping between document mapping and a supported type to use. This * section is very useful when you want to customize the supported * extensions. If your project is using file extensions not supported by * default by this plugin, you can add a mapping to attach the extension to * an existing type of comment. The tag name is the new extension name to * support, and the value is the name of the comment type to use. */ @Parameter public Map mapping = new LinkedHashMap<>(); /** * Whether to use the default mapping between file extensions and comment * types, or only the one your provide. */ @Parameter(property = "license.useDefaultMapping", defaultValue = "true") public boolean useDefaultMapping = true; /** * Maven license plugin uses concurrency to check license headers. This * factor is used to control the number of threads used to check. The rule * is: *
{@code = * concurrencyFactor} *
* The default is 1.5. */ @Parameter(property = "license.concurrencyFactor", defaultValue = "1.5") public float concurrencyFactor = 1.5f; /** * Maven license plugin uses concurrency to check license headers. With this * option the number of threads used to check can be specified. If given * it take precedence over concurrencyFactor *

* The default is 0 which implies that the default for concurrencyFactor * is used. */ @Parameter(property = "license.nThreads", defaultValue = "0") public int nThreads; /** Whether to skip the plugin execution. */ @Parameter(property = "license.skip", defaultValue = "false") public boolean skip; /** * Determination of the year and author of the first commit and last change year * of a file requires a full git or svn history. By default the plugin will log * warning when using these properties on a shallow or sparse repository. If you * are certain the repository depth will permit accurate determination of these * values, you can disable this check. */ @Parameter(property = "license.warnIfShallow", defaultValue = "true") public boolean warnIfShallow = true; /** If you do not want to see the list of file having a missing header, you can add the quiet flag that will shorten the output. */ @Parameter(property = "license.quiet", defaultValue = "false") public boolean quiet; /** * Set to true if you need a strict check against the headers. By default, * the existence of a header is verified by taking the top portion of a file * and checking if it contains the headers text, not considering special * characters (spaces, tabs, ...). *
* We highly recommend to keep this option set to {@code true}. */ @Parameter(property = "license.strictCheck", defaultValue = "true") public boolean strictCheck = true; /** * Specify the encoding of your files. Default to the project source * encoding property (project.build.sourceEncoding). */ @Parameter(property = "license.encoding", defaultValue = "${project.build.sourceEncoding}") public String encoding = "UTF-8"; /** * You can set this flag to false if you do not want the build to fail when * some headers are missing. */ @Parameter(property = "license.failIfMissing", defaultValue = "true") public boolean failIfMissing = true; /** * You can leave this flag on {@code false} if you do not want the build to * fail for files that do not have an implicit or explicit comment style * definition. Setting this explicitly to {@code true} is a safe way to make * sure that the effective file type mappings cover all files included from * your project. *

* Default is {@code false} for backwards compatibility reasons. * * @since 2.8 */ @Parameter(property = "license.failIfUnknown", defaultValue = "false") public boolean failIfUnknown; /** * If dryRun is enabled, calls to license:format and license:remove will not * overwrite the existing file but instead write the result to a new file * with the same name but ending with `.licensed`. */ @Parameter(property = "license.dryRun", defaultValue = "false") public boolean dryRun; /** * Skip the formatting of files which already contain a detected header. */ @Parameter(property = "license.skipExistingHeaders", defaultValue = "false") public boolean skipExistingHeaders; /** * When enforcing licenses on dependencies, exclude all but these scopes. */ @Parameter(property = "license.dependencies.scope", required = true, defaultValue = "runtime") protected List dependencyScopes; /** * Whether to enforce license.dependencies.allow list. */ @Parameter(property = "license.dependencies.enforce", required = true, defaultValue = "false") protected boolean dependencyEnforce; /** * Block of {@link LicensePolicy} configuration for enforcing license adherence in dependencies. */ @Parameter(property = "license.dependencies.policies") protected Set dependencyPolicies; /** * Exception message prefix to display when an artifact is denied by one of the license policies. */ @Parameter(property = "license.dependencies.exceptionMessage", required = true, defaultValue = LicenseMessage.WARN_POLICY_DENIED) protected String dependencyExceptionMessage; @Parameter(defaultValue = "${project}", required = true) protected MavenProject project; /** * Maven settings. */ @Parameter(defaultValue = "${settings}", readonly = true) private Settings settings; /** * The decrypter for passwords. */ @Inject private SettingsDecrypter settingsDecrypter; @Inject protected DependencyGraphBuilder dependencyGraphBuilder; @Inject protected ProjectBuilder projectBuilder; @Parameter(defaultValue = "${session}") public MavenSession session; /** * The location where to write the report of the plugin execution (file processed, action taken, etc). *

* "PRESENT" means the file has a header (check goal) *

* "MISSING" means the header is missing (check goal) *

* "NOOP" means no action were performed (remove or format goal) *

* "ADDED" means a header was added (format goal) *

* "REPLACED" means a header was replaced (format goal) *

* "REMOVED" means a header was removed (format goal) *

* "UNKNOWN" means that the file extension is unknown *

* Activated by default. */ @Parameter(property = "license.report.location", defaultValue = "${project.reporting.outputDirectory}/license-plugin-report.xml") public File reportLocation; /** * Format of the report. *

* Can be (case-insensitive): 'xml', 'json'. *

* Default is XML. */ @Parameter(property = "license.report.format") public String reportFormat; /** * Skip the report generation. Default: false */ @Parameter(property = "license.report.skip", defaultValue = "false") public boolean reportSkipped; @Parameter(property = "license.prohibitLegacyUse", defaultValue = "false") public boolean prohibitLegacyUse; protected Clock clock = Clock.systemUTC(); protected Report report; protected abstract class AbstractCallback implements Callback { /** * Related to {@link #failIfUnknown}. */ private final Collection unknownFiles = new ConcurrentLinkedQueue<>(); @Override public void onUnknownFile(Document document, Header header) { warn("Unknown file extension: %s", document.getFilePath()); unknownFiles.add(document.getFile()); report.add(document.getFile(), Report.Result.UNKNOWN); } public void checkUnknown() throws MojoExecutionException { if (!unknownFiles.isEmpty()) { String msg = "Unable to find a comment style definition for some " + "files. You may want to add a custom mapping for the relevant file extensions."; if (failIfUnknown) { throw new MojoExecutionException(msg); } getLog().warn(msg); } } } protected final void execute(final Callback callback) throws MojoExecutionException, MojoFailureException { if (skip) { getLog().info("License Plugin is Skipped"); } else { if (prohibitLegacyUse && detectLegacyUse()) { throw new MojoExecutionException("Use of legacy parameters has been prohibited by configuration."); } // make default base dir canonical this.defaultBasedir = this.getCanonicalFile(this.defaultBasedir, "license.basedir"); // collect all the license sets together final LicenseSet[] allLicenseSets; // if we abandon the legacy config this contiguous block can be removed final LicenseSet legacyLicenseSet = convertLegacyConfigToLicenseSet(); if (legacyLicenseSet != null) { if (licenseSets == null) { allLicenseSets = new LicenseSet[]{legacyLicenseSet}; } else { allLicenseSets = Arrays.copyOf(licenseSets, licenseSets.length + 1); allLicenseSets[licenseSets.length] = legacyLicenseSet; } } else { allLicenseSets = licenseSets; } // execute executeForLicenseSets(allLicenseSets, callback); report.exportTo(reportLocation); } } private File getCanonicalFile(final File file, final String description) throws MojoFailureException { if (file == null) { return null; } try { return file.getCanonicalFile(); } catch (final IOException e) { throw new MojoFailureException("Could not get canonical path of " + description, e); } } private void executeForLicenseSets(final LicenseSet[] licenseSets, final Callback callback) throws MojoFailureException, MojoExecutionException { if (licenseSets == null || licenseSets.length == 0) { warn("At least one licenseSet must be specified"); return; } // need to perform validation first for (int i = 0; i < licenseSets.length; i++) { final LicenseSet licenseSet = licenseSets[i]; if (!hasHeader(licenseSet)) { warn("No header file specified to check for license in licenseSet: " + i); return; } // make licenseSet baseDir canonical licenseSet.basedir = this.getCanonicalFile(licenseSet.basedir, "licenseSet[" + i + "].basedir"); } if (!strictCheck) { warn("Property 'strictCheck' is not enabled. Please consider adding true in your pom.xml file."); warn("See https://oss.carbou.me/license-maven-plugin for more information."); } // then execute each license set for (final LicenseSet licenseSet : licenseSets) { executeForLicenseSet(licenseSet, callback); } } private boolean detectLegacyUse() { return legacyConfigHeader != null || legacyConfigInlineHeader != null || (legacyConfigValidHeaders != null && legacyConfigValidHeaders.length > 0) || legacyConfigMulti != null || (legacyConfigHeaderSections != null && legacyConfigHeaderSections.length > 0) || (legacyConfigIncludes != null && legacyConfigIncludes.length > 0) || (legacyConfigExcludes != null && legacyConfigExcludes.length > 0) || (legacyConfigKeywords != null && !Arrays.equals(legacyConfigKeywords, DEFAULT_KEYWORDS)); } private LicenseSet convertLegacyConfigToLicenseSet() { if (legacyConfigHeader == null && (this.legacyConfigInlineHeader == null || this.legacyConfigInlineHeader.isEmpty())) { return null; } final LicenseSet legacyLicenseSet = new LicenseSet(); legacyLicenseSet.header = legacyConfigHeader; legacyLicenseSet.inlineHeader = legacyConfigInlineHeader; legacyLicenseSet.validHeaders = legacyConfigValidHeaders; legacyLicenseSet.multi = legacyConfigMulti; legacyLicenseSet.headerSections = legacyConfigHeaderSections; legacyLicenseSet.includes = legacyConfigIncludes; legacyLicenseSet.excludes = legacyConfigExcludes; legacyLicenseSet.keywords = legacyConfigKeywords; return legacyLicenseSet; } private void executeForLicenseSet(final LicenseSet licenseSet, final Callback callback) throws MojoExecutionException, MojoFailureException { final ResourceFinder finder = new ResourceFinder(firstNonNull(asPath(licenseSet.basedir), asPath(defaultBasedir))); try { finder.setCompileClassPath(project.getCompileClasspathElements()); } catch (DependencyResolutionRequiredException e) { throw new MojoExecutionException(e.getMessage(), e); } finder.setPluginClassPath(getClass().getClassLoader()); final HeaderSource headerSource = HeaderSource.of(licenseSet.multi, licenseSet.inlineHeader, licenseSet.header, Charset.forName(this.encoding), finder); final Header header = new Header(headerSource, licenseSet.headerSections); debug("Header: %s", header.getLocation()); if (licenseSet.validHeaders == null) { licenseSet.validHeaders = new String[0]; } final List

validHeaders = new ArrayList<>(licenseSet.validHeaders.length); for (final String validHeader : licenseSet.validHeaders) { final HeaderSource validHeaderSource = HeaderSource.of(null, null, validHeader, Charset.forName(this.encoding), finder); validHeaders.add(new Header(validHeaderSource, licenseSet.headerSections)); } Map globalProperties = getDefaultProperties(); // we override by properties in the licenseSet if (licenseSet.properties != null) { for (Map.Entry entry : licenseSet.properties.entrySet()) { if (!System.getProperties().contains(entry.getKey())) { globalProperties.put(entry.getKey(), entry.getValue()); } } } if (getLog().isDebugEnabled()) { getLog().debug( "global properties:\n - " + globalProperties.entrySet().stream().map(Objects::toString) .collect(Collectors.joining("\n - "))); } final List propertiesProviders = new LinkedList<>(); int threads = getNumberOfExecutorThreads(); ExecutorService executorService = Executors.newFixedThreadPool(threads); try { for (final PropertiesProvider provider : ServiceLoader.load(PropertiesProvider.class, Thread.currentThread().getContextClassLoader())) { provider.init(this, globalProperties); propertiesProviders.add(provider); } final DocumentPropertiesLoader perDocumentProperties = document -> { // then add per document properties Map perDoc = new LinkedHashMap<>(globalProperties); perDoc.put("file.name", document.getFile().getName()); Map readOnly = Collections.unmodifiableMap(perDoc); for (final PropertiesProvider provider : propertiesProviders) { try { final Map adjustments = provider.adjustProperties( AbstractLicenseMojo.this, readOnly, document); if (getLog().isDebugEnabled()) { getLog().debug("provider: " + provider.getClass() + " adjusted these properties:\n" + adjustments); } for (Map.Entry entry : adjustments.entrySet()) { if (entry.getValue() != null) { perDoc.put(entry.getKey(), entry.getValue()); } else { perDoc.remove(entry.getKey()); } } } catch (Exception e) { if (getLog().isWarnEnabled()) { getLog().warn("failure occurred while calling " + provider.getClass(), e); } } } if (getLog().isDebugEnabled()) { getLog().debug("properties for " + document + ":\n - " + perDoc.entrySet().stream() .map(Objects::toString).collect(Collectors.joining("\n - "))); } return perDoc; }; final DocumentFactory documentFactory = new DocumentFactory( firstNonNull(licenseSet.basedir, defaultBasedir), buildMapping(), buildHeaderDefinitions(licenseSet, finder), Charset.forName(encoding), licenseSet.keywords, perDocumentProperties); CompletionService completionService = new ExecutorCompletionService<>(executorService); int count = 0; debug("Number of execution threads: %s", threads); for (final String file : listSelectedFiles(licenseSet)) { completionService.submit(() -> { Document document = documentFactory.createDocuments(file); debug("Selected file: %s [header style: %s]", document.getFilePath(), document.getHeaderDefinition()); if (document.isNotSupported()) { callback.onUnknownFile(document, header); } else if (document.is(header)) { debug("Skipping header file: %s", document.getFilePath()); } else if (document.hasHeader(header, strictCheck)) { callback.onExistingHeader(document, header); } else { boolean headerFound = false; for (final Header validHeader : validHeaders) { headerFound = document.hasHeader(validHeader, strictCheck); if (headerFound) { callback.onExistingHeader(document, header); break; } } if (!headerFound) { callback.onHeaderNotFound(document, header); } } }, null); count++; } while (count-- > 0) { try { completionService.take().get(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } catch (ExecutionException e) { Throwable cause = e.getCause(); if (cause instanceof Error) { throw (Error) cause; } if (cause instanceof MojoExecutionException) { throw (MojoExecutionException) cause; } if (cause instanceof MojoFailureException) { throw (MojoFailureException) cause; } if (cause instanceof RuntimeException) { throw (RuntimeException) cause; } throw new RuntimeException(cause.getMessage(), cause); } } } finally { executorService.shutdownNow(); propertiesProviders.forEach(PropertiesProvider::close); } } private boolean hasHeader(final LicenseSet licenseSet) { return (licenseSet.multi != null && ((licenseSet.multi.headers != null && licenseSet.multi.headers.length > 0) || (licenseSet.multi.inlineHeaders != null && licenseSet.multi.inlineHeaders.length > 0 && !licenseSet.multi.inlineHeaders[0].isEmpty())) ) || (licenseSet.header != null || (licenseSet.inlineHeader != null && !licenseSet.inlineHeader.isEmpty())); } private int getNumberOfExecutorThreads() { return nThreads > 0 ? nThreads : Math.max(1, (int) (Runtime.getRuntime().availableProcessors() * concurrencyFactor)); } private Map getDefaultProperties() { // first put system environment Map props = new TreeMap<>( System.getenv()); // treemap just to have nice debug logs // then add ${project.XYZ} properties props.put("project.groupId", project.getGroupId()); props.put("project.artifactId", project.getArtifactId()); props.put("project.version", project.getVersion()); props.put("project.name", project.getName()); props.put("project.description", project.getDescription()); props.put("project.inceptionYear", project.getInceptionYear()); props.put("year", project.getInceptionYear()); // maintains backward compatibility props.put("project.url", project.getUrl()); Organization org = project.getOrganization(); if (org != null) { props.put("owner", org.getName()); // maintains backward compatibility props.put("project.organization.name", org.getName()); props.put("project.organization.url", org.getUrl()); } // we override by properties in the POM if (this.defaultProperties != null) { props.putAll(this.defaultProperties); } // then we override by java system properties (command-line -D...) for (String key : System.getProperties().stringPropertyNames()) { props.put(key, System.getProperty(key)); } return props; } private String[] listSelectedFiles(final LicenseSet licenseSet) { final boolean useDefaultExcludes = (licenseSet.useDefaultExcludes != null ? licenseSet.useDefaultExcludes : defaultUseDefaultExcludes); final Selection selection = new Selection( firstNonNull(licenseSet.basedir, defaultBasedir), licenseSet.includes, buildExcludes(licenseSet), useDefaultExcludes, getLog()); debug("From: %s", firstNonNull(licenseSet.basedir, defaultBasedir)); debug("Including: %s", deepToString(selection.getIncluded())); debug("Excluding: %s", deepToString(selection.getExcluded())); return selection.getSelectedFiles(); } private String[] buildExcludes(final LicenseSet licenseSet) { List ex = new ArrayList<>(); ex.addAll(asList(licenseSet.excludes)); if (project != null && project.getModules() != null && !aggregate) { for (String module : project.getModules()) { ex.add(module + "/**"); } } return ex.toArray(new String[ex.size()]); } public final void info(String format, Object... params) { if (!quiet && getLog().isInfoEnabled()) { getLog().info(format(format, params)); } } public final void debug(String format, Object... params) { if (!quiet && getLog().isDebugEnabled()) { getLog().debug(format(format, params)); } } public final void warn(String format, Object... params) { if (!quiet && getLog().isWarnEnabled()) { getLog().warn(format(format, params)); } } private Map buildMapping() { Map extensionMapping = new LinkedHashMap<>(); // force inclusion of unknown item to manage unknown files extensionMapping.put(DocumentType.UNKNOWN.getExtension(), DocumentType.UNKNOWN.getDefaultHeaderTypeName()); for (Map.Entry entry : mapping.entrySet()) { extensionMapping.put(entry.getKey().toLowerCase(), entry.getValue().toLowerCase()); } if (useDefaultMapping) { for (Map.Entry entry : defaultMapping().entrySet()) { if (!extensionMapping.containsKey(entry.getKey())) { extensionMapping.put(entry.getKey(), entry.getValue()); } } } return extensionMapping; } private Map buildHeaderDefinitions(final LicenseSet licenseSet, final ResourceFinder finder) throws MojoFailureException { // like mappings, first get default definitions final Map headers = new HashMap<>(HeaderType.defaultDefinitions()); // and then override them with those provided in base config for (final String headerDefiniton : defaultHeaderDefinitions) { headers.putAll(loadHeaderDefinition(headerDefiniton, finder)); } // then override by inline default styles for (HeaderStyle defaultInlineHeaderStyle : defaultInlineHeaderStyles) { headers.put(defaultInlineHeaderStyle.name, defaultInlineHeaderStyle.toHeaderDefinition()); } // and then override them with those provided in licenseSet config for (final String headerDefiniton : licenseSet.headerDefinitions) { headers.putAll(loadHeaderDefinition(headerDefiniton, finder)); } for (HeaderStyle inlineHeaderStyle : licenseSet.inlineHeaderStyles) { headers.put(inlineHeaderStyle.name, inlineHeaderStyle.toHeaderDefinition()); } // force inclusion of unknown item to manage unknown files headers.put(HeaderType.UNKNOWN.getDefinition().getType(), HeaderType.UNKNOWN.getDefinition()); return headers; } private Map loadHeaderDefinition(final String headerDefinition, final ResourceFinder finder) throws MojoFailureException { try { final InputSource source = new InputSource(finder.findResource(headerDefinition).openStream()); source.setEncoding(encoding); final AdditionalHeaderDefinition fileDefinitions = new AdditionalHeaderDefinition(XMLDoc.from(source, true)); final Map map = fileDefinitions.getDefinitions(); debug("%d header definitions loaded from '%s'", map.size(), headerDefinition); return map; } catch (final IOException ex) { throw new MojoFailureException("Error reading header definition: " + headerDefinition, ex); } } /** * Returns the list of servers with decrypted passwords. * * @return list of servers with decrypted passwords. */ List getDecryptedServers() { final SettingsDecryptionRequest settingsDecryptionRequest = new DefaultSettingsDecryptionRequest(); settingsDecryptionRequest.setServers(settings.getServers()); final SettingsDecryptionResult decrypt = settingsDecrypter.decrypt(settingsDecryptionRequest); return decrypt.getServers(); } /** * Retrieves the credentials for the given server or null if none could be * found. * * @param serverID * @return */ public Credentials findCredentials(String serverID) { if (serverID == null) { return null; } List decryptedServers = getDecryptedServers(); for (Server ds : decryptedServers) { if (ds.getId().equals(serverID)) { if (getLog().isDebugEnabled()) { getLog().debug( "credentials have been found for server: " + serverID + ", login:" + ds.getUsername()); } return new Credentials(ds.getUsername(), ds.getPassword()); } } if (getLog().isDebugEnabled()) { getLog().debug("no credentials found for server: " + serverID); } return null; } private static T firstNonNull(final T t1, final T t2) { return t1 == null ? t2 : t1; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy