| /* |
| * 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. |
| */ |
| package org.apache.rat.mp; |
| |
| import static org.apache.rat.mp.util.ExclusionHelper.addEclipseDefaults; |
| import static org.apache.rat.mp.util.ExclusionHelper.addIdeaDefaults; |
| import static org.apache.rat.mp.util.ExclusionHelper.addMavenDefaults; |
| import static org.apache.rat.mp.util.ExclusionHelper.addPlexusAndScmDefaults; |
| |
| import java.io.BufferedInputStream; |
| import java.io.BufferedReader; |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.io.Reader; |
| import java.lang.reflect.UndeclaredThrowableException; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.nio.file.Files; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Objects; |
| import java.util.SortedSet; |
| import java.util.function.Consumer; |
| import java.util.stream.Collectors; |
| import java.util.stream.Stream; |
| |
| import org.apache.commons.lang3.StringUtils; |
| import org.apache.maven.plugin.AbstractMojo; |
| import org.apache.maven.plugin.MojoExecutionException; |
| import org.apache.maven.plugin.logging.Log; |
| import org.apache.maven.plugins.annotations.Parameter; |
| import org.apache.maven.project.MavenProject; |
| import org.apache.rat.ConfigurationException; |
| import org.apache.rat.Defaults; |
| import org.apache.rat.ReportConfiguration; |
| import org.apache.rat.analysis.license.DeprecatedConfig; |
| import org.apache.rat.config.SourceCodeManagementSystems; |
| import org.apache.rat.configuration.Format; |
| import org.apache.rat.configuration.LicenseReader; |
| import org.apache.rat.configuration.MatcherReader; |
| import org.apache.rat.license.ILicense; |
| import org.apache.rat.license.ILicenseFamily; |
| import org.apache.rat.license.LicenseSetFactory.LicenseFilter; |
| import org.apache.rat.license.SimpleLicenseFamily; |
| import org.apache.rat.mp.util.ScmIgnoreParser; |
| import org.apache.rat.mp.util.ignore.GlobIgnoreMatcher; |
| import org.apache.rat.mp.util.ignore.IgnoreMatcher; |
| import org.apache.rat.mp.util.ignore.IgnoringDirectoryScanner; |
| import org.apache.rat.report.IReportable; |
| import org.apache.rat.walker.NameBasedHiddenFileFilter; |
| import org.codehaus.plexus.util.DirectoryScanner; |
| |
| /** |
| * Abstract base class for Mojos, which are running Rat. |
| */ |
| public abstract class AbstractRatMojo extends AbstractMojo { |
| |
| /** |
| * The base directory, in which to search for files. |
| */ |
| @Parameter(property = "rat.basedir", defaultValue = "${basedir}", required = true) |
| private File basedir; |
| |
| /** |
| * Specifies the licenses to accept. By default, these are added to the default |
| * licenses, unless you set {@link #addDefaultLicenseMatchers} to false. |
| * |
| * @since 0.8 |
| */ |
| @Parameter |
| private String[] defaultLicenseFiles; |
| |
| @Parameter |
| private String[] additionalLicenseFiles; |
| |
| /** |
| * Whether to add the default list of licenses. |
| */ |
| @Parameter(property = "rat.addDefaultLicenses", defaultValue = "true") |
| private boolean addDefaultLicenses; |
| |
| /** |
| * Whether to add the default list of license matchers. |
| */ |
| @Parameter(property = "rat.addDefaultLicenseMatchers", defaultValue = "true") |
| private boolean addDefaultLicenseMatchers; |
| |
| @Parameter(required = false) |
| private String[] approvedLicenses; |
| |
| @Parameter(property = "rat.approvedFile") |
| private String approvedLicenseFile; |
| |
| /** |
| * Specifies the license families to accept. |
| * |
| * @since 0.8 |
| * @deprecated |
| */ |
| @Deprecated // remove in v1.0 |
| @Parameter |
| private SimpleLicenseFamily[] licenseFamilies; |
| |
| /** |
| * This is an object to accept both License of DeprecatedConfig objects. |
| */ |
| @Deprecated // convert this to an org.apache.rat.mp.License object in v1.0 |
| @Parameter |
| private Object[] licenses; |
| |
| @Parameter |
| private Family[] families; |
| |
| /** |
| * Specifies files, which are included in the report. By default, all files are |
| * included. |
| */ |
| @Parameter |
| private String[] includes; |
| |
| /** |
| * Specifies a file, from which to read includes. Basically, an alternative to |
| * specifying the includes as a list. |
| */ |
| @Parameter(property = "rat.includesFile") |
| private String includesFile; |
| |
| /** |
| * Specifies the include files character set. Defaults |
| * to @code{${project.build.sourceEncoding}), or @code{UTF8}. |
| */ |
| @Parameter(property = "rat.includesFileCharset", defaultValue = "${project.build.sourceEncoding}") |
| private String includesFileCharset; |
| |
| /** |
| * Specifies files, which are excluded in the report. By default, no files are |
| * excluded. |
| */ |
| @Parameter |
| private String[] excludes; |
| |
| /** |
| * Specifies a file, from which to read excludes. Basically, an alternative to |
| * specifying the excludes as a list. The excludesFile is assumed to be using |
| * the UFT8 character set. |
| */ |
| @Parameter(property = "rat.excludesFile") |
| private String excludesFile; |
| |
| /** |
| * Specifies the include files character set. Defaults |
| * to @code{${project.build.sourceEncoding}), or @code{UTF8}. |
| */ |
| @Parameter(property = "rat.excludesFileCharset", defaultValue = "${project.build.sourceEncoding}") |
| private String excludesFileCharset; |
| |
| /** |
| * Whether to use the default excludes when scanning for files. The default |
| * excludes are: |
| * <ul> |
| * <li>meta data files for source code management / revision control systems, |
| * see {@link SourceCodeManagementSystems}</li> |
| * <li>temporary files used by Maven, see |
| * <a href="#useMavenDefaultExcludes">useMavenDefaultExcludes</a></li> |
| * <li>configuration files for Eclipse, see |
| * <a href="#useEclipseDefaultExcludes">useEclipseDefaultExcludes</a></li> |
| * <li>configuration files for IDEA, see |
| * <a href="#useIdeaDefaultExcludes">useIdeaDefaultExcludes</a></li> |
| * </ul> |
| */ |
| @Parameter(property = "rat.useDefaultExcludes", defaultValue = "true") |
| private boolean useDefaultExcludes; |
| |
| /** |
| * Whether to use the Maven specific default excludes when scanning for files. |
| * Maven specific default excludes are given by the constant |
| * MAVEN_DEFAULT_EXCLUDES: The <code>target</code> directory, the |
| * <code>cobertura.ser</code> file, and so on. |
| */ |
| @Parameter(property = "rat.useMavenDefaultExcludes", defaultValue = "true") |
| private boolean useMavenDefaultExcludes; |
| |
| /** |
| * Whether to parse source code management system (SCM) ignore files and use |
| * their contents as excludes. At the moment this works for the following SCMs: |
| * |
| * @see org.apache.rat.config.SourceCodeManagementSystems |
| */ |
| @Parameter(property = "rat.parseSCMIgnoresAsExcludes", defaultValue = "true") |
| private boolean parseSCMIgnoresAsExcludes; |
| |
| /** |
| * Whether to use the Eclipse specific default excludes when scanning for files. |
| * Eclipse specific default excludes are given by the constant |
| * ECLIPSE_DEFAULT_EXCLUDES: The <code>.classpath</code> and |
| * <code>.project</code> files, the <code>.settings</code> directory, and so on. |
| */ |
| @Parameter(property = "rat.useEclipseDefaultExcludes", defaultValue = "true") |
| private boolean useEclipseDefaultExcludes; |
| |
| /** |
| * Whether to use the IDEA specific default excludes when scanning for files. |
| * IDEA specific default excludes are given by the constant |
| * IDEA_DEFAULT_EXCLUDES: The <code>*.iml</code>, <code>*.ipr</code> and |
| * <code>*.iws</code> files and the <code>.idea</code> directory. |
| */ |
| @Parameter(property = "rat.useIdeaDefaultExcludes", defaultValue = "true") |
| private boolean useIdeaDefaultExcludes; |
| |
| /** |
| * Whether to exclude subprojects. This is recommended, if you want a separate |
| * apache-rat-plugin report for each subproject. |
| */ |
| @Parameter(property = "rat.excludeSubprojects", defaultValue = "true") |
| private boolean excludeSubProjects; |
| |
| /** |
| * Will skip the plugin execution, e.g. for technical builds that do not take |
| * license compliance into account. |
| * |
| * @since 0.11 |
| */ |
| @Parameter(property = "rat.skip", defaultValue = "false") |
| protected boolean skip; |
| |
| /** |
| * Holds the maven-internal project to allow resolution of artifact properties |
| * during mojo runs. |
| */ |
| @Parameter(defaultValue = "${project}", required = true, readonly = true) |
| protected MavenProject project; |
| |
| /** |
| * @return Returns the Maven project. |
| */ |
| protected MavenProject getProject() { |
| return project; |
| } |
| |
| protected Defaults.Builder getDefaultsBuilder() { |
| Defaults.Builder result = Defaults.builder(); |
| if (defaultLicenseFiles != null) { |
| for (String defaultLicenseFile : defaultLicenseFiles) { |
| try { |
| result.add(defaultLicenseFile); |
| } catch (MalformedURLException e) { |
| throw new ConfigurationException(defaultLicenseFile + " is not a valid license file", e); |
| } |
| } |
| } |
| return result; |
| } |
| |
| @Deprecated // remove this for version 1.0 |
| private Stream<License> getLicenses() { |
| if (licenses == null) { |
| return Stream.empty(); |
| } |
| return Arrays.stream(licenses).filter( s -> {return s instanceof License;}).map(License.class::cast); |
| } |
| |
| @Deprecated // remove this for version 1.0 |
| private Stream<DeprecatedConfig> getDeprecatedConfigs() { |
| if (licenses == null) { |
| return Stream.empty(); |
| } |
| return Arrays.stream(licenses).filter( s -> {return s instanceof DeprecatedConfig;}).map(DeprecatedConfig.class::cast); |
| } |
| |
| @Deprecated // remove this for version 1.0 |
| private void reportDeprecatedProcessing() |
| { |
| if (getDeprecatedConfigs().findAny().isPresent()) { |
| Log log = getLog(); |
| log.warn("Configuration uses deprecated configuration. Please upgrade to v0.17 configuration options"); |
| } |
| } |
| |
| @Deprecated // remove this for version 1.0 |
| private void processLicenseFamilies(ReportConfiguration config) { |
| List<ILicenseFamily> families = getDeprecatedConfigs().map(DeprecatedConfig::getLicenseFamily).filter(Objects::nonNull).collect(Collectors.toList()); |
| if (licenseFamilies != null) { |
| for (SimpleLicenseFamily slf : licenseFamilies) { |
| if (StringUtils.isBlank(slf.getFamilyCategory())) { |
| families.stream().filter( f -> f.getFamilyName().equalsIgnoreCase(slf.getFamilyName())).findFirst() |
| .ifPresent(config::addApprovedLicenseCategory); |
| } else { |
| config.addApprovedLicenseCategory(ILicenseFamily.builder().setLicenseFamilyCategory(slf.getFamilyCategory()) |
| .setLicenseFamilyName(StringUtils.defaultIfBlank(slf.getFamilyName(), slf.getFamilyCategory())) |
| .build()); |
| } |
| } |
| } |
| } |
| |
| private org.apache.rat.utils.Log makeLog() { |
| return new org.apache.rat.utils.Log() { |
| Log log = getLog(); |
| @Override |
| public void log(Level level, String msg) { |
| switch (level) |
| { |
| case DEBUG: |
| log.debug(msg); |
| break; |
| case INFO: |
| log.info(msg);; |
| break; |
| case WARN: |
| log.warn(msg); |
| break; |
| case ERROR: |
| log.error(msg); |
| break; |
| case OFF: |
| break; |
| } |
| }}; |
| } |
| |
| protected ReportConfiguration getConfiguration() throws MojoExecutionException { |
| ReportConfiguration config = new ReportConfiguration(makeLog()); |
| reportDeprecatedProcessing(); |
| Defaults defaults = getDefaultsBuilder().build(config.getLog()); |
| if (addDefaultLicenses) { |
| config.setFrom(defaults); |
| } else { |
| config.setStyleSheet(Defaults.getPlainStyleSheet()); |
| config.setDirectoriesToIgnore(defaults.getDirectoriesToIgnore()); |
| config.setFilesToIgnore(defaults.getFilesToIgnore()); |
| } |
| |
| if (additionalLicenseFiles != null) { |
| for (String licenseFile : additionalLicenseFiles) { |
| try { |
| URL url = new File(licenseFile).toURI().toURL(); |
| Format fmt = Format.fromName(licenseFile); |
| MatcherReader mReader = fmt.matcherReader(); |
| if (mReader != null) { |
| mReader.addMatchers(url); |
| } |
| LicenseReader lReader = fmt.licenseReader(); |
| if (lReader != null) { |
| lReader.addLicenses(url); |
| config.addLicenses(lReader.readLicenses()); |
| config.addApprovedLicenseCategories(lReader.approvedLicenseId()); |
| } |
| } catch (MalformedURLException e) { |
| throw new ConfigurationException(licenseFile + " is not a valid license file", e); |
| } |
| } |
| } |
| if (families != null || getDeprecatedConfigs().findAny().isPresent()) { |
| Log log = getLog(); |
| if (log.isDebugEnabled()) { |
| log.debug(String.format("%s license families loaded from pom", families.length)); |
| } |
| Consumer<ILicenseFamily> logger = log.isDebugEnabled() ? (l) -> log.debug(String.format("Family: %s", l)) |
| : (l) -> { |
| }; |
| |
| Consumer<ILicenseFamily> process = logger.andThen(config::addFamily); |
| getDeprecatedConfigs().map(DeprecatedConfig::getLicenseFamily).filter(Objects::nonNull).forEach(process); |
| if (families != null) { // TODO remove if check in v1.0 |
| Arrays.stream(families).map(Family::build).forEach(process); |
| } |
| } |
| |
| processLicenseFamilies(config); |
| |
| if (approvedLicenses != null && approvedLicenses.length > 0) { |
| Arrays.stream(approvedLicenses).forEach(config::addApprovedLicenseCategory); |
| } |
| |
| if (licenses != null) { |
| Log log = getLog(); |
| if (log.isDebugEnabled()) { |
| log.debug(String.format("%s licenses loaded from pom", licenses.length)); |
| } |
| Consumer<ILicense> logger = log.isDebugEnabled() ? (l) -> log.debug(String.format("License: %s", l)) |
| : (l) -> { |
| }; |
| Consumer<ILicense> addApproved = (approvedLicenses == null || approvedLicenses.length == 0) |
| ? (l) -> config.addApprovedLicenseCategory(l.getLicenseFamily()) |
| : (l) -> { |
| }; |
| |
| Consumer<ILicense> process = logger.andThen(config::addLicense).andThen(addApproved); |
| SortedSet<ILicenseFamily> families = config.getLicenseFamilies(LicenseFilter.ALL); |
| getDeprecatedConfigs().map(DeprecatedConfig::getLicense).filter(Objects::nonNull) |
| .map(x -> x.setLicenseFamilies(families).build()).forEach(process); |
| getLicenses().map(x -> x.build(families)).forEach(process); |
| } |
| |
| config.setReportable(getReportable()); |
| return config; |
| } |
| |
| protected void logLicenses(Collection<ILicense> licenses) { |
| if (getLog().isDebugEnabled()) { |
| getLog().debug("The following " + licenses.size() + " licenses are activated:"); |
| for (ILicense license : licenses) { |
| getLog().debug("* " + license.toString()); |
| } |
| } |
| } |
| |
| /** |
| * Creates an iterator over the files to check. |
| * |
| * @return A container of files, which are being checked. |
| * @throws MojoExecutionException in case of errors. I/O errors result in |
| * UndeclaredThrowableExceptions. |
| */ |
| private IReportable getReportable() throws MojoExecutionException { |
| final IgnoringDirectoryScanner ds = new IgnoringDirectoryScanner(); |
| ds.setBasedir(basedir); |
| setExcludes(ds); |
| setIncludes(ds); |
| ds.scan(); |
| whenDebuggingLogExcludedFiles(ds); |
| final String[] files = ds.getIncludedFiles(); |
| logAboutIncludedFiles(files); |
| try { |
| return new FilesReportable(basedir, files); |
| } catch (final IOException e) { |
| throw new UndeclaredThrowableException(e); |
| } |
| } |
| |
| private void logAboutIncludedFiles(final String[] files) { |
| if (files.length == 0) { |
| getLog().warn("No resources included."); |
| } else { |
| getLog().debug(files.length + " resources included"); |
| if (getLog().isDebugEnabled()) { |
| for (final String resource : files) { |
| getLog().debug(" - included " + resource); |
| } |
| } |
| } |
| } |
| |
| private void whenDebuggingLogExcludedFiles(final DirectoryScanner ds) { |
| if (getLog().isDebugEnabled()) { |
| final String[] excludedFiles = ds.getExcludedFiles(); |
| if (excludedFiles.length == 0) { |
| getLog().debug("No excluded resources."); |
| } else { |
| getLog().debug("Excluded " + excludedFiles.length + " resources:"); |
| for (final String resource : excludedFiles) { |
| getLog().debug(" - excluded " + resource); |
| } |
| } |
| } |
| } |
| |
| private void setIncludes(DirectoryScanner ds) throws MojoExecutionException { |
| if ((includes != null && includes.length > 0) || includesFile != null) { |
| final List<String> includeList = new ArrayList<>(); |
| if (includes != null) { |
| includeList.addAll(Arrays.asList(includes)); |
| } |
| if (includesFile != null) { |
| final String charset = includesFileCharset == null ? "UTF8" : includesFileCharset; |
| final File f = new File(includesFile); |
| if (!f.isFile()) { |
| getLog().error("IncludesFile not found: " + f.getAbsolutePath()); |
| } else { |
| getLog().debug("Includes loaded from file " + includesFile + ", using character set " + charset); |
| } |
| includeList.addAll(getPatternsFromFile(f, charset)); |
| } |
| ds.setIncludes(includeList.toArray(new String[includeList.size()])); |
| } |
| } |
| |
| private List<String> getPatternsFromFile(File pFile, String pCharset) throws MojoExecutionException { |
| InputStream is = null; |
| BufferedInputStream bis = null; |
| Reader r = null; |
| BufferedReader br = null; |
| Throwable th = null; |
| final List<String> patterns = new ArrayList<>(); |
| try { |
| is = Files.newInputStream(pFile.toPath()); |
| bis = new BufferedInputStream(is); |
| r = new InputStreamReader(bis, pCharset); |
| br = new BufferedReader(r); |
| for (;;) { |
| final String s = br.readLine(); |
| if (s == null) { |
| break; |
| } |
| patterns.add(s); |
| } |
| br.close(); |
| br = null; |
| r.close(); |
| r = null; |
| bis.close(); |
| bis = null; |
| is.close(); |
| is = null; |
| } catch (Throwable t) { |
| th = t; |
| } finally { |
| if (br != null) { |
| try { |
| br.close(); |
| } catch (Throwable t) { |
| if (th == null) { |
| th = t; |
| } |
| } |
| } |
| if (r != null) { |
| try { |
| r.close(); |
| } catch (Throwable t) { |
| if (th == null) { |
| th = t; |
| } |
| } |
| } |
| if (bis != null) { |
| try { |
| bis.close(); |
| } catch (Throwable t) { |
| if (th == null) { |
| th = t; |
| } |
| } |
| } |
| if (is != null) { |
| try { |
| is.close(); |
| } catch (Throwable t) { |
| if (th == null) { |
| th = t; |
| } |
| } |
| } |
| } |
| if (th != null) { |
| if (th instanceof RuntimeException) { |
| throw (RuntimeException) th; |
| } |
| if (th instanceof Error) { |
| throw (Error) th; |
| } |
| throw new MojoExecutionException(th.getMessage(), th); |
| } |
| return patterns; |
| } |
| |
| private void setExcludes(IgnoringDirectoryScanner ds) throws MojoExecutionException { |
| final List<IgnoreMatcher> ignoreMatchers = mergeDefaultExclusions(); |
| if (excludes == null || excludes.length == 0) { |
| getLog().debug("No excludes explicitly specified."); |
| } else { |
| getLog().debug(excludes.length + " explicit excludes."); |
| for (final String exclude : excludes) { |
| getLog().debug("Exclude: " + exclude); |
| } |
| } |
| |
| final List<String> globExcludes = new ArrayList<>(); |
| for (IgnoreMatcher ignoreMatcher : ignoreMatchers) { |
| if (ignoreMatcher instanceof GlobIgnoreMatcher) { |
| // The glob matching we do via the DirectoryScanner |
| globExcludes.addAll(((GlobIgnoreMatcher) ignoreMatcher).getExclusionLines()); |
| } else { |
| // All others (git) are used directly |
| ds.addIgnoreMatcher(ignoreMatcher); |
| } |
| } |
| |
| if (excludes != null) { |
| Collections.addAll(globExcludes, excludes); |
| } |
| if (!globExcludes.isEmpty()) { |
| final String[] allExcludes = globExcludes.toArray(new String[globExcludes.size()]); |
| ds.setExcludes(allExcludes); |
| } |
| } |
| |
| private List<IgnoreMatcher> mergeDefaultExclusions() throws MojoExecutionException { |
| List<IgnoreMatcher> ignoreMatchers = new ArrayList<>(); |
| |
| final GlobIgnoreMatcher basicRules = new GlobIgnoreMatcher(); |
| |
| basicRules.addRules(addPlexusAndScmDefaults(getLog(), useDefaultExcludes)); |
| basicRules.addRules(addMavenDefaults(getLog(), useMavenDefaultExcludes)); |
| basicRules.addRules(addEclipseDefaults(getLog(), useEclipseDefaultExcludes)); |
| basicRules.addRules(addIdeaDefaults(getLog(), useIdeaDefaultExcludes)); |
| |
| if (parseSCMIgnoresAsExcludes) { |
| getLog().debug("Will parse SCM ignores for exclusions..."); |
| ignoreMatchers.addAll(ScmIgnoreParser.getExclusionsFromSCM(getLog(), project.getBasedir())); |
| getLog().debug("Finished adding exclusions from SCM ignore files."); |
| } |
| |
| if (excludeSubProjects && project != null && project.getModules() != null) { |
| for (final String moduleSubPath : project.getModules()) { |
| if (new File(basedir, moduleSubPath).isDirectory()) { |
| basicRules.addRule(moduleSubPath + "/**/*"); |
| } else { |
| basicRules.addRule(StringUtils.substringBeforeLast(moduleSubPath, "/") + "/**/*"); |
| } |
| } |
| } |
| |
| if (getLog().isDebugEnabled()) { |
| getLog().debug("Finished creating list of implicit excludes."); |
| if (basicRules.getExclusionLines().isEmpty() && ignoreMatchers.isEmpty()) { |
| getLog().debug("No excludes implicitly specified."); |
| } else { |
| if (!basicRules.getExclusionLines().isEmpty()) { |
| getLog().debug(basicRules.getExclusionLines().size() + " implicit excludes."); |
| for (final String exclude : basicRules.getExclusionLines()) { |
| getLog().debug("Implicit exclude: " + exclude); |
| } |
| } |
| for (IgnoreMatcher ignoreMatcher : ignoreMatchers) { |
| if (ignoreMatcher instanceof GlobIgnoreMatcher) { |
| GlobIgnoreMatcher globIgnoreMatcher = (GlobIgnoreMatcher) ignoreMatcher; |
| if (!globIgnoreMatcher.getExclusionLines().isEmpty()) { |
| getLog().debug(globIgnoreMatcher.getExclusionLines().size() + " implicit excludes from SCM."); |
| for (final String exclude : globIgnoreMatcher.getExclusionLines()) { |
| getLog().debug("Implicit exclude: " + exclude); |
| } |
| } |
| } else { |
| getLog().debug("Implicit exclude: \n" + ignoreMatcher); |
| } |
| } |
| } |
| } |
| if (excludesFile != null) { |
| final File f = new File(excludesFile); |
| if (!f.isFile()) { |
| getLog().error("Excludes file not found: " + f.getAbsolutePath()); |
| } |
| if (!f.canRead()) { |
| getLog().error("Excludes file not readable: " + f.getAbsolutePath()); |
| } |
| final String charset = excludesFileCharset == null ? "UTF8" : excludesFileCharset; |
| getLog().debug("Loading excludes from file " + f + ", using character set " + charset); |
| basicRules.addRules(getPatternsFromFile(f, charset)); |
| } |
| |
| if (!basicRules.isEmpty()) { |
| ignoreMatchers.add(basicRules); |
| } |
| |
| return ignoreMatchers; |
| } |
| } |