From e230d92e13ff52cdda8c2624e7fe058433bb6dff Mon Sep 17 00:00:00 2001 From: Jochen Wiedmann Date: Tue, 13 Jul 2010 16:10:23 +0000 Subject: [PATCH] PR: RAT-76 - Added support for adding license headers to the Maven plugin and the Ant tasks. - Refactoring and code simplification. git-svn-id: https://svn.apache.org/repos/asf/incubator/rat/main/trunk@963778 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/main/java/org/apache/rat/Report.java | 97 ++++-------- .../org/apache/rat/ReportConfiguration.java | 106 +++++++++++++ .../GeneratedLicenseNotRequired.java | 1 - .../java/org/apache/rat/api/MetaData.java | 1 + .../java/org/apache/rat/api/Reporter.java | 31 ---- .../org/apache/rat/report/AbstractReport.java | 22 +++ .../claim/impl/AbstractClaimReporter.java | 7 +- .../report/claim/impl/ClaimAggregator.java | 18 +-- .../impl/xml/SimpleXmlClaimReporter.java | 22 ++- .../claim/util/ClaimReporterMultiplexer.java | 47 ++++-- .../claim/util/LicenseAddingReport.java | 38 +++++ .../org/apache/rat/report/xml/XmlReport.java | 73 --------- .../rat/report/xml/XmlReportFactory.java | 59 +++----- .../test/java/org/apache/rat/ReportTest.java | 4 +- .../claim/impl/xml/MockClaimReporter.java | 9 +- .../rat/report/xml/XmlReportFactoryTest.java | 7 +- .../apache/rat/report/xml/XmlReportTest.java | 10 +- .../org/apache/rat/mp/AbstractRatMojo.java | 17 ++- .../java/org/apache/rat/mp/RatCheckMojo.java | 37 +++++ apache-rat-plugin/src/test/it3/pom.xml | 13 +- apache-rat-plugin/src/test/it3/src.apt | 8 + .../org/apache/rat/mp/RatCheckMojoTest.java | 141 ++++++++++++++++-- .../java/org/apache/rat/anttasks/Report.java | 71 ++++++++- .../org/apache/rat/anttasks/ReportTest.java | 25 ++++ .../src/test/resources/antunit/index.apt | 8 + .../test/resources/antunit/report-junit.xml | 9 ++ 26 files changed, 591 insertions(+), 290 deletions(-) create mode 100644 apache-rat-core/src/main/java/org/apache/rat/ReportConfiguration.java delete mode 100644 apache-rat-core/src/main/java/org/apache/rat/api/Reporter.java create mode 100644 apache-rat-core/src/main/java/org/apache/rat/report/AbstractReport.java create mode 100644 apache-rat-core/src/main/java/org/apache/rat/report/claim/util/LicenseAddingReport.java delete mode 100644 apache-rat-core/src/main/java/org/apache/rat/report/xml/XmlReport.java create mode 100644 apache-rat-plugin/src/test/it3/src.apt create mode 100644 apache-rat-tasks/src/test/resources/antunit/index.apt diff --git a/apache-rat-core/src/main/java/org/apache/rat/Report.java b/apache-rat-core/src/main/java/org/apache/rat/Report.java index dfce186e8..f2c042290 100644 --- a/apache-rat-core/src/main/java/org/apache/rat/Report.java +++ b/apache-rat-core/src/main/java/org/apache/rat/Report.java @@ -18,24 +18,18 @@ */ package org.apache.rat; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PipedReader; import java.io.PipedWriter; import java.io.PrintStream; -import java.io.UnsupportedEncodingException; import java.io.Writer; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerConfigurationException; import org.apache.commons.cli.CommandLine; @@ -48,32 +42,24 @@ import org.apache.commons.cli.PosixParser; import org.apache.commons.io.filefilter.NotFileFilter; import org.apache.commons.io.filefilter.WildcardFileFilter; -import org.apache.rat.analysis.IHeaderMatcher; -import org.apache.rat.annotation.AbstractLicenceAppender; -import org.apache.rat.annotation.ApacheV2LicenceAppender; import org.apache.rat.api.RatException; -import org.apache.rat.license.ILicenseFamily; import org.apache.rat.report.IReportable; import org.apache.rat.report.RatReport; import org.apache.rat.report.claim.ClaimStatistic; import org.apache.rat.report.xml.XmlReportFactory; import org.apache.rat.report.xml.writer.IXmlWriter; import org.apache.rat.report.xml.writer.impl.base.XmlWriter; -import org.apache.rat.walker.DirectoryWalker; import org.apache.rat.walker.ArchiveWalker; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; +import org.apache.rat.walker.DirectoryWalker; public class Report { - private static final char EXCLUDE_CLI = 'e'; private static final char STYLESHEET_CLI = 's'; //@SuppressWarnings("unchecked") public static final void main(String args[]) throws Exception { + final ReportConfiguration configuration = new ReportConfiguration(); Options opts = buildOptions(); PosixParser parser = new PosixParser(); @@ -96,7 +82,9 @@ public static final void main(String args[]) throws Exception { Report report = new Report(args[0]); if (cl.hasOption('a')) { - configureForAddLicense(cl, report); + configuration.setAddingLicenses(true); + configuration.setAddingLicensesForced(cl.hasOption('f')); + configuration.setCopyrightMessage(cl.getOptionValue("c")); } if (cl.hasOption(EXCLUDE_CLI)) { @@ -119,10 +107,11 @@ public static final void main(String args[]) throws Exception { System.exit(1); } try { - report.report(System.out, - report.getDirectory(System.out), - new FileInputStream(style[0]), - Defaults.createDefaultMatcher(), null); + configuration.setHeaderMatcher(Defaults.createDefaultMatcher()); + report(System.out, + report.getDirectory(System.out), + new FileInputStream(style[0]), + configuration); } catch (FileNotFoundException fnfe) { System.err.println("stylesheet " + style[0] + " doesn't exist"); @@ -198,45 +187,6 @@ private static Options buildOptions() { return opts; } - private static void configureForAddLicense(CommandLine cl, Report report) throws Exception, UnsupportedEncodingException, SAXException, IOException, ParserConfigurationException { - OutputStream reportOutput = new ByteArrayOutputStream(); - PrintStream stream = new PrintStream(reportOutput, true); - report.report(stream); - - AbstractLicenceAppender appender; - String copyrightMsg = cl.getOptionValue("c"); - if ( copyrightMsg != null) { - appender = new ApacheV2LicenceAppender(copyrightMsg); - } else { - appender = new ApacheV2LicenceAppender(); - } - if (cl.hasOption("f")) { - appender.setForce(true); - } - - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setValidating(false); - ByteArrayInputStream xmlStream = new ByteArrayInputStream(reportOutput.toString().getBytes("UTF-8")); - Document doc = factory.newDocumentBuilder().parse(xmlStream); - - NodeList resourceHeaders = doc.getElementsByTagName("header-type"); - String value = null; - for (int i = 0; i < resourceHeaders.getLength(); i++) { - Node headerType = resourceHeaders.item(i).getAttributes().getNamedItem("name"); - if(headerType != null) { - value = headerType.getNodeValue(); - } else { - value = null; - } - if (value != null &&value.equals("?????")) { - Node resource = resourceHeaders.item(i).getParentNode(); - String filename = resource.getAttributes().getNamedItem("name").getNodeValue(); - File document = new File(filename); - appender.append(document); - } - } - } - private static final void printUsage(Options opts) { HelpFormatter f = new HelpFormatter(); String header = "Options"; @@ -283,7 +233,9 @@ public void setInputFileFilter(FilenameFilter inputFileFilter) { public ClaimStatistic report(PrintStream out) throws Exception { final IReportable base = getDirectory(out); if (base != null) { - return report(base, new OutputStreamWriter(out), Defaults.createDefaultMatcher(), null); + final ReportConfiguration configuration = new ReportConfiguration(); + configuration.setHeaderMatcher(Defaults.createDefaultMatcher()); + return report(base, new OutputStreamWriter(out), configuration); } return null; } @@ -322,7 +274,9 @@ public void styleReport(PrintStream out) throws Exception { final IReportable base = getDirectory(out); if (base != null) { InputStream style = Defaults.getDefaultStyleSheet(); - report(out, base, style, Defaults.createDefaultMatcher(), null); + final ReportConfiguration configuration = new ReportConfiguration(); + configuration.setHeaderMatcher(Defaults.createDefaultMatcher()); + report(out, base, style, configuration); } } @@ -339,11 +293,10 @@ public void styleReport(PrintStream out) throws Exception { * @throws InterruptedException * @throws RatException */ - public static void report(PrintStream out, IReportable base, final InputStream style, final IHeaderMatcher matcher, - final ILicenseFamily[] approvedLicenseNames) - throws IOException, TransformerConfigurationException, - InterruptedException, RatException { - report(new OutputStreamWriter(out), base, style, matcher, approvedLicenseNames); + public static void report(PrintStream out, IReportable base, final InputStream style, + ReportConfiguration pConfiguration) + throws IOException, TransformerConfigurationException, InterruptedException, RatException { + report(new OutputStreamWriter(out), base, style, pConfiguration); } /** @@ -362,14 +315,14 @@ public static void report(PrintStream out, IReportable base, final InputStream s * @throws RatException */ public static ClaimStatistic report(Writer out, IReportable base, final InputStream style, - final IHeaderMatcher matcher, final ILicenseFamily[] approvedLicenseNames) + ReportConfiguration pConfiguration) throws IOException, TransformerConfigurationException, FileNotFoundException, InterruptedException, RatException { PipedReader reader = new PipedReader(); PipedWriter writer = new PipedWriter(reader); ReportTransformer transformer = new ReportTransformer(out, style, reader); Thread transformerThread = new Thread(transformer); transformerThread.start(); - final ClaimStatistic statistic = report(base, writer, matcher, approvedLicenseNames); + final ClaimStatistic statistic = report(base, writer, pConfiguration); writer.flush(); writer.close(); transformerThread.join(); @@ -385,11 +338,11 @@ public static ClaimStatistic report(Writer out, IReportable base, final InputStr * @throws IOException * @throws RatException */ - public static ClaimStatistic report(final IReportable container, final Writer out, final IHeaderMatcher matcher, - final ILicenseFamily[] approvedLicenseNames) throws IOException, RatException { + public static ClaimStatistic report(final IReportable container, final Writer out, + ReportConfiguration pConfiguration) throws IOException, RatException { IXmlWriter writer = new XmlWriter(out); final ClaimStatistic statistic = new ClaimStatistic(); - RatReport report = XmlReportFactory.createStandardReport(writer, matcher, approvedLicenseNames, statistic); + RatReport report = XmlReportFactory.createStandardReport(writer, statistic, pConfiguration); report.startReport(); container.run(report); report.endReport(); diff --git a/apache-rat-core/src/main/java/org/apache/rat/ReportConfiguration.java b/apache-rat-core/src/main/java/org/apache/rat/ReportConfiguration.java new file mode 100644 index 000000000..1e8d506fb --- /dev/null +++ b/apache-rat-core/src/main/java/org/apache/rat/ReportConfiguration.java @@ -0,0 +1,106 @@ +package org.apache.rat; + +import org.apache.rat.analysis.IHeaderMatcher; +import org.apache.rat.license.ILicenseFamily; + + +/** + * A configuration object is used by the frontend to invoke the + * {@link Report}. Basically, the sole purpose of the frontends is + * to create the configuration and invoke the {@link Report}. + */ +public class ReportConfiguration { + private IHeaderMatcher headerMatcher; + private ILicenseFamily[] approvedLicenseNames; + private boolean addingLicenses; + private boolean addingLicensesForced; + private String copyrightMessage; + + /** + * Returns the header matcher. + */ + public IHeaderMatcher getHeaderMatcher() { + return headerMatcher; + } + + /** + * Sets the header matcher. + */ + public void setHeaderMatcher(IHeaderMatcher headerMatcher) { + this.headerMatcher = headerMatcher; + } + + /** + * Returns the set of approved license names. + */ + public ILicenseFamily[] getApprovedLicenseNames() { + return approvedLicenseNames; + } + + /** + * Sets the set of approved license names. + */ + public void setApprovedLicenseNames(ILicenseFamily[] approvedLicenseNames) { + this.approvedLicenseNames = approvedLicenseNames; + } + + /** + * If RAT is adding license headers: Returns the optional + * copyright message. This value is ignored, if no + * license headers are added. + * @see #isAddingLicenses() + */ + public String getCopyrightMessage() { + return copyrightMessage; + } + + /** + * If RAT is adding license headers: Sets the optional + * copyright message. This value is ignored, if no + * license headers are added. + * @see #setAddingLicenses(boolean) + */ + public void setCopyrightMessage(String copyrightMessage) { + this.copyrightMessage = copyrightMessage; + } + + /** + * If RAT is adding license headers: Returns, whether adding + * license headers is enforced. This value is ignored, if no + * license headers are added. + * @see #isAddingLicenses() + */ + public boolean isAddingLicensesForced() { + return addingLicensesForced; + } + + /** + * If RAT is adding license headers: Sets, whether adding + * license headers is enforced. This value is ignored, if no + * license headers are added. + * @see #isAddingLicenses() + */ + public void setAddingLicensesForced(boolean addingLicensesForced) { + this.addingLicensesForced = addingLicensesForced; + } + + /** + * Returns, whether RAT should add missing license headers. + * @see #isAddingLicensesForced() + * @see #getCopyrightMessage() + */ + public boolean isAddingLicenses() { + return addingLicenses; + } + + /** + * Returns, whether RAT should add missing license headers. + * @see #setAddingLicensesForced(boolean) + * @see #setCopyrightMessage(String) + */ + public void setAddingLicenses(boolean addingLicenses) { + this.addingLicenses = addingLicenses; + } + + +} diff --git a/apache-rat-core/src/main/java/org/apache/rat/analysis/generation/GeneratedLicenseNotRequired.java b/apache-rat-core/src/main/java/org/apache/rat/analysis/generation/GeneratedLicenseNotRequired.java index d772cff3f..d7abb2bb9 100644 --- a/apache-rat-core/src/main/java/org/apache/rat/analysis/generation/GeneratedLicenseNotRequired.java +++ b/apache-rat-core/src/main/java/org/apache/rat/analysis/generation/GeneratedLicenseNotRequired.java @@ -23,7 +23,6 @@ import org.apache.rat.analysis.IHeaderMatcher; import org.apache.rat.analysis.RatHeaderAnalysisException; import org.apache.rat.api.Document; -import org.apache.rat.api.Reporter; import org.apache.rat.api.MetaData; public class GeneratedLicenseNotRequired implements IHeaderMatcher { diff --git a/apache-rat-core/src/main/java/org/apache/rat/api/MetaData.java b/apache-rat-core/src/main/java/org/apache/rat/api/MetaData.java index aacd8c93d..7ef191c37 100644 --- a/apache-rat-core/src/main/java/org/apache/rat/api/MetaData.java +++ b/apache-rat-core/src/main/java/org/apache/rat/api/MetaData.java @@ -277,3 +277,4 @@ public String toString() } } } + \ No newline at end of file diff --git a/apache-rat-core/src/main/java/org/apache/rat/api/Reporter.java b/apache-rat-core/src/main/java/org/apache/rat/api/Reporter.java deleted file mode 100644 index 020e64976..000000000 --- a/apache-rat-core/src/main/java/org/apache/rat/api/Reporter.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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.api; - - -public interface Reporter { - - /** - * Starts a report on the given document. - * All claims concern this document until this is called next. - * @param subject not null - * @throws RatReportFailedException - */ - void report(Document subject) throws RatException; -} diff --git a/apache-rat-core/src/main/java/org/apache/rat/report/AbstractReport.java b/apache-rat-core/src/main/java/org/apache/rat/report/AbstractReport.java new file mode 100644 index 000000000..763b5b868 --- /dev/null +++ b/apache-rat-core/src/main/java/org/apache/rat/report/AbstractReport.java @@ -0,0 +1,22 @@ +package org.apache.rat.report; + +import org.apache.rat.api.Document; +import org.apache.rat.api.RatException; + + +/** + * Abstract base class for deriving implementations of {@link RatReport}. + */ +public abstract class AbstractReport implements RatReport { + public void startReport() throws RatException { + // Does nothing + } + + public void report(Document document) throws RatException { + // Does nothing + } + + public void endReport() throws RatException { + // Does nothing + } +} diff --git a/apache-rat-core/src/main/java/org/apache/rat/report/claim/impl/AbstractClaimReporter.java b/apache-rat-core/src/main/java/org/apache/rat/report/claim/impl/AbstractClaimReporter.java index f02de9a31..4d95052f7 100644 --- a/apache-rat-core/src/main/java/org/apache/rat/report/claim/impl/AbstractClaimReporter.java +++ b/apache-rat-core/src/main/java/org/apache/rat/report/claim/impl/AbstractClaimReporter.java @@ -20,9 +20,9 @@ package org.apache.rat.report.claim.impl; import org.apache.rat.api.Document; -import org.apache.rat.api.RatException; -import org.apache.rat.api.Reporter; import org.apache.rat.api.MetaData; +import org.apache.rat.api.RatException; +import org.apache.rat.report.AbstractReport; /** @@ -30,8 +30,7 @@ * It is strongly suggested, that implementations derive from * this class. */ -public abstract class AbstractClaimReporter implements Reporter { - +public abstract class AbstractClaimReporter extends AbstractReport { protected void handleDocumentCategoryClaim(String documentCategoryName) { // Does nothing } diff --git a/apache-rat-core/src/main/java/org/apache/rat/report/claim/impl/ClaimAggregator.java b/apache-rat-core/src/main/java/org/apache/rat/report/claim/impl/ClaimAggregator.java index 9a31b4631..0be87a82e 100644 --- a/apache-rat-core/src/main/java/org/apache/rat/report/claim/impl/ClaimAggregator.java +++ b/apache-rat-core/src/main/java/org/apache/rat/report/claim/impl/ClaimAggregator.java @@ -24,7 +24,6 @@ import org.apache.rat.api.Document; import org.apache.rat.api.RatException; -import org.apache.rat.api.Reporter; import org.apache.rat.api.MetaData; import org.apache.rat.report.claim.ClaimStatistic; @@ -34,16 +33,16 @@ * of claims. */ public class ClaimAggregator extends AbstractClaimReporter { - private final Reporter reporter; + private final ClaimStatistic statistic; private final Map numsByLicenseFamilyName = new HashMap(); private final Map numsByLicenseFamilyCode = new HashMap(); private final Map numsByFileType = new HashMap(); private int numApproved, numUnApproved, numGenerated, numUnknown; - public ClaimAggregator(Reporter pReporter) { - reporter = pReporter; + public ClaimAggregator(ClaimStatistic pStatistic) { + statistic = pStatistic; } - + private void incMapValue(Map pMap, Object pKey) { final Integer num = (Integer) pMap.get(pKey); final int newNum; @@ -92,11 +91,8 @@ public void fillClaimStatistic(ClaimStatistic pStatistic) { pStatistic.setNumUnknown(numUnknown); } - - public void report(Document document) throws RatException { - super.report(document); - if (reporter != null) { - reporter.report(document); - } + public void endReport() throws RatException { + super.endReport(); + fillClaimStatistic(statistic); } } diff --git a/apache-rat-core/src/main/java/org/apache/rat/report/claim/impl/xml/SimpleXmlClaimReporter.java b/apache-rat-core/src/main/java/org/apache/rat/report/claim/impl/xml/SimpleXmlClaimReporter.java index ef755e49d..06ca80a77 100644 --- a/apache-rat-core/src/main/java/org/apache/rat/report/claim/impl/xml/SimpleXmlClaimReporter.java +++ b/apache-rat-core/src/main/java/org/apache/rat/report/claim/impl/xml/SimpleXmlClaimReporter.java @@ -21,12 +21,12 @@ import java.io.IOException; import org.apache.rat.api.Document; -import org.apache.rat.api.RatException; -import org.apache.rat.api.Reporter; import org.apache.rat.api.MetaData; +import org.apache.rat.api.RatException; +import org.apache.rat.report.AbstractReport; import org.apache.rat.report.xml.writer.IXmlWriter; -public class SimpleXmlClaimReporter implements Reporter { +public class SimpleXmlClaimReporter extends AbstractReport { public static final String LICENSE_APPROVAL_PREDICATE = "license-approval"; public static final String LICENSE_FAMILY_PREDICATE = "license-family"; public static final String HEADER_SAMPLE_PREDICATE = "header-sample"; @@ -129,4 +129,20 @@ private void writeDocumentCategory(final MetaData metaData) throws IOException, writeClaim(FILE_TYPE_PREDICATE, documentCategory, false); } } + + public void startReport() throws RatException { + try { + writer.openElement("rat-report"); + } catch (IOException e) { + throw new RatException("Cannot open start element", e); + } + } + + public void endReport() throws RatException { + try { + writer.closeDocument(); + } catch (IOException e) { + throw new RatException("Cannot close last element", e); + } + } } diff --git a/apache-rat-core/src/main/java/org/apache/rat/report/claim/util/ClaimReporterMultiplexer.java b/apache-rat-core/src/main/java/org/apache/rat/report/claim/util/ClaimReporterMultiplexer.java index 6c153c1fa..eb2f5224d 100644 --- a/apache-rat-core/src/main/java/org/apache/rat/report/claim/util/ClaimReporterMultiplexer.java +++ b/apache-rat-core/src/main/java/org/apache/rat/report/claim/util/ClaimReporterMultiplexer.java @@ -18,23 +18,52 @@ */ package org.apache.rat.report.claim.util; +import java.util.List; + import org.apache.rat.api.Document; import org.apache.rat.api.RatException; -import org.apache.rat.api.Reporter; +import org.apache.rat.document.IDocumentAnalyser; +import org.apache.rat.document.RatDocumentAnalysisException; +import org.apache.rat.report.RatReport; + -public class ClaimReporterMultiplexer implements Reporter { +public class ClaimReporterMultiplexer implements RatReport { + private final IDocumentAnalyser analyser; + private final List reporters; - private final Reporter[] reporters; - - public ClaimReporterMultiplexer(final Reporter[] reporters) { - super(); + public ClaimReporterMultiplexer(final IDocumentAnalyser pAnalyser, final List reporters) { + analyser = pAnalyser; this.reporters = reporters; } public void report(Document document) throws RatException { - final int length = reporters.length; - for (int i=0;i org.apache.rat.test - it1 + it3 1.0 @@ -33,15 +33,4 @@ - - - - org.apache.rat - apche-rat-plugin - 0.7-SNAPSHOT - - - - - diff --git a/apache-rat-plugin/src/test/it3/src.apt b/apache-rat-plugin/src/test/it3/src.apt new file mode 100644 index 000000000..f5561a5a0 --- /dev/null +++ b/apache-rat-plugin/src/test/it3/src.apt @@ -0,0 +1,8 @@ + -------------- + Some text file + -------------- + +Some text file + + This is a text file, which intentionally has no Apache License Header. + The RAT plugin should detect it. diff --git a/apache-rat-plugin/src/test/java/org/apache/rat/mp/RatCheckMojoTest.java b/apache-rat-plugin/src/test/java/org/apache/rat/mp/RatCheckMojoTest.java index 93bbe4f95..e4c8b42e3 100644 --- a/apache-rat-plugin/src/test/java/org/apache/rat/mp/RatCheckMojoTest.java +++ b/apache-rat-plugin/src/test/java/org/apache/rat/mp/RatCheckMojoTest.java @@ -19,8 +19,11 @@ import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; +import java.io.InputStreamReader; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; @@ -42,6 +45,7 @@ import org.apache.rat.mp.RatCheckException; import org.apache.rat.mp.RatCheckMojo; import org.apache.rat.mp.RatReportMojo; +import org.codehaus.plexus.util.DirectoryScanner; /** @@ -138,7 +142,7 @@ private ArtifactRepository newArtifactRepository() private RatCheckMojo newRatCheckMojo( String pDir ) throws Exception { - return (RatCheckMojo) newRatMojo( pDir, "check" ); + return (RatCheckMojo) newRatMojo( pDir, "check", false ); } /** @@ -148,11 +152,11 @@ private RatCheckMojo newRatCheckMojo( String pDir ) * @return The configured Mojo. * @throws Exception An error occurred while creating the Mojo. */ - private AbstractRatMojo newRatMojo( String pDir, String pGoal ) + private AbstractRatMojo newRatMojo( String pDir, String pGoal, boolean pCreateCopy ) throws Exception { final File baseDir = new File( getBasedir() ); - final File testBaseDir = new File( new File( baseDir, "src/test" ), pDir ); + final File testBaseDir = getSourceDirectory(pDir, pCreateCopy, baseDir); File testPom = new File( testBaseDir, "pom.xml" ); AbstractRatMojo mojo = (AbstractRatMojo) lookupMojo( pGoal, testPom ); assertNotNull( mojo ); @@ -162,6 +166,7 @@ private AbstractRatMojo newRatMojo( String pDir, String pGoal ) setVariableValueToObject( mojo, "useDefaultExcludes", Boolean.TRUE ); setVariableValueToObject( mojo, "useMavenDefaultExcludes", Boolean.TRUE ); setVariableValueToObject( mojo, "useEclipseDefaultExcludes", Boolean.TRUE ); + setVariableValueToObject( mojo, "addLicenseHeaders", "false" ); final Build build = new Build(); build.setDirectory( buildDirectory.getPath() ); final MavenProjectStub project = new MavenProjectStub(){ @@ -186,6 +191,99 @@ else if ( mojo instanceof RatCheckMojo ) return mojo; } + private File getSourceDirectory(String pDir, boolean pCreateCopy, + final File baseDir) throws IOException { + return makeSourceDirectory( new File( new File( baseDir, "src/test" ), pDir ), pDir, pCreateCopy ); + } + + private void remove( File pDir ) throws IOException { + if ( pDir.isFile() ) + { + if ( ! pDir.delete() ) + { + throw new IOException( "Unable to delete file: " + pDir ); + } + } + else if ( pDir.isDirectory() ) + { + final File[] files = pDir.listFiles(); + for ( int i = 0; i < files.length; i++ ) + { + remove( files[i] ); + } + if ( ! pDir.delete() ) + { + throw new IOException( "Unable to delete directory: " + pDir ); + } + } + else if ( pDir.exists() ) + { + throw new IOException( "Unable to delete unknown object " + pDir ); + } + } + + private void copy( File pSource, File pTarget ) throws IOException + { + if ( pSource.isDirectory() ) + { + if ( !pTarget.isDirectory() && !pTarget.mkdirs() ) { + throw new IOException("Unable to create directory: " + pTarget); + } + final DirectoryScanner scanner = new DirectoryScanner(); + scanner.setBasedir(pSource); + scanner.addDefaultExcludes(); + scanner.setIncludes(new String[]{"*"}); + scanner.scan(); + final String[] dirs = scanner.getIncludedDirectories(); + + for (int i = 0; i < dirs.length; i++) { + final String dir = dirs[i]; + if (!"".equals(dir)) { + copy( new File(pSource, dir), new File(pTarget, dir)); + } + } + final String[] files = scanner.getIncludedFiles(); + for (int i = 0; i < files.length; i++) { + copy( new File(pSource, files[i]), new File(pTarget, files[i])); + } + } + else if ( pSource.isFile() ) + { + final FileInputStream fis = new FileInputStream( pSource ); + final FileOutputStream fos = new FileOutputStream( pTarget ); + final byte[] buffer = new byte[8192]; + for ( ;; ) + { + int res = fis.read(buffer); + if (res == -1) { + break; + } + if (res > 0) { + fos.write(buffer, 0, res); + } + } + fos.close(); + fis.close(); + } + else + { + throw new IOException( "Unable to copy unknown object " + pSource ); + } + } + + private File makeSourceDirectory(File pFile, String pDir, boolean pCreateCopy) throws IOException { + if ( ! pCreateCopy ) + { + return pFile; + } + + final File baseDir = new File( getBasedir() ); + final File targetDir = new File( new File( baseDir, "target/it-source" ), pDir ); + remove( targetDir ); + copy( pFile, targetDir ); + return targetDir; + } + /** * Reads the location of the rat text file from the Mojo. * @param pMojo The configured Mojo. @@ -266,12 +364,33 @@ public void testIt2() throws Exception { checkResult( ratTxtFile, 1, 1 ); } -// /** -// * Runs a report, which should detect no problems. -// * @throws Exception The test failed. -// */ -// public void testIt3() throws Exception { -// final RatReportMojo mojo = newRatReportMojo( "it3" ); -// mojo.execute(); -// } + private String getFirstLine(File pFile) throws IOException { + final FileInputStream fis = new FileInputStream(pFile); + final InputStreamReader reader = new InputStreamReader(fis, "UTF8"); + final BufferedReader breader = new BufferedReader(reader); + final String result = breader.readLine(); + breader.close(); + return result; + } + + /** + * Tests adding license headers. + */ + public void testIt3() throws Exception { + final RatCheckMojo mojo = (RatCheckMojo) newRatMojo( "it3", "check", true ); + setVariableValueToObject( mojo, "addLicenseHeaders", "true" ); + setVariableValueToObject( mojo, "numUnapprovedLicenses", new Integer(1)); + mojo.execute(); + final File ratTxtFile = getRatTxtFile( mojo ); + checkResult( ratTxtFile, 1, 1 ); + + final File baseDir = new File( getBasedir() ); + final File sourcesDir = new File( new File( baseDir, "target/it-source" ), "it3" ); + final String firstLineOrig = getFirstLine(new File(sourcesDir, "src.apt")); + assertTrue(firstLineOrig.indexOf("--") != -1); + assertTrue(firstLineOrig.indexOf("~~") == -1); + final String firstLineModified = getFirstLine(new File(sourcesDir, "src.apt.new")); + assertTrue(firstLineModified.indexOf("--") == -1); + assertTrue(firstLineModified.indexOf("~~") != -1); + } } diff --git a/apache-rat-tasks/src/main/java/org/apache/rat/anttasks/Report.java b/apache-rat-tasks/src/main/java/org/apache/rat/anttasks/Report.java index b5893f342..ff0174193 100644 --- a/apache-rat-tasks/src/main/java/org/apache/rat/anttasks/Report.java +++ b/apache-rat-tasks/src/main/java/org/apache/rat/anttasks/Report.java @@ -39,6 +39,7 @@ import org.apache.tools.ant.util.FileUtils; import org.apache.rat.Defaults; +import org.apache.rat.ReportConfiguration; import org.apache.rat.analysis.IHeaderMatcher; import org.apache.rat.analysis.util.HeaderMatcherMultiplexer; import org.apache.rat.api.RatException; @@ -90,6 +91,14 @@ public class Report extends Task { * Which stylesheet to use. */ private Resource stylesheet; + /** + * Whether to add license headers. + */ + private AddLicenseHeaders addLicenseHeaders = new AddLicenseHeaders(AddLicenseHeaders.FALSE); + /** + * The copyright message. + */ + private String copyrightMessage; /** * Adds resources that will be checked. @@ -136,6 +145,23 @@ public void setFormat(Format f) { format = f; } + /** + * Wether to add license headers. + */ + public void setAddLicenseHeaders(AddLicenseHeaders pAdd) { + if (pAdd == null) { + throw new IllegalArgumentException("addLicenseHeaders must not be null"); + } + addLicenseHeaders = pAdd; + } + + /** + * Sets the copyright message. + */ + public void setCopyrightMessage(String pMessage) { + copyrightMessage = pMessage; + } + /** * Which stylesheet to use (only meaningful with format='styled'). */ @@ -215,12 +241,24 @@ private void validate() { * @throws RatException */ private void createReport(PrintWriter out) throws IOException, TransformerException, InterruptedException, RatException { - HeaderMatcherMultiplexer m = new HeaderMatcherMultiplexer(getLicenseMatchers()); - ResourceCollectionContainer rcElement = - new ResourceCollectionContainer(nestedResources); + final ReportConfiguration configuration = new ReportConfiguration(); + configuration.setHeaderMatcher(new HeaderMatcherMultiplexer(getLicenseMatchers())); + configuration.setApprovedLicenseNames(getApprovedLicenseNames()); + if (AddLicenseHeaders.FALSE.equalsIgnoreCase(addLicenseHeaders.getValue())) { + // Nothing to do + } else if (AddLicenseHeaders.FORCED.equalsIgnoreCase(addLicenseHeaders.getValue())) { + configuration.setAddingLicenses(true); + configuration.setAddingLicensesForced(true); + configuration.setCopyrightMessage(copyrightMessage); + } else if (AddLicenseHeaders.TRUE.equalsIgnoreCase(addLicenseHeaders.getValue())) { + configuration.setAddingLicenses(true); + configuration.setCopyrightMessage(copyrightMessage); + } else { + throw new BuildException("Invalid value for addLicenseHeaders: " + addLicenseHeaders.getValue()); + } + ResourceCollectionContainer rcElement = new ResourceCollectionContainer(nestedResources); if (format.getValue().equals(Format.XML_KEY)) { - org.apache.rat.Report.report(rcElement, out, m, - getApprovedLicenseNames()); + org.apache.rat.Report.report(rcElement, out, configuration); } else { InputStream style = null; try { @@ -233,7 +271,7 @@ private void createReport(PrintWriter out) throws IOException, TransformerExcept + format.getValue() + "'"); } org.apache.rat.Report.report(out, rcElement, style, - m, getApprovedLicenseNames()); + configuration); } finally { FileUtils.close(style); } @@ -296,4 +334,25 @@ public String[] getValues() { }; } } + + /** + * Type for the addLicenseHeaders attribute. + */ + public static class AddLicenseHeaders extends EnumeratedAttribute { + static final String TRUE = "true"; + static final String FALSE = "false"; + static final String FORCED = "forced"; + + public AddLicenseHeaders() {} + public AddLicenseHeaders(String s) { + setValue(s); + } + + + public String[] getValues() { + return new String[] { + TRUE, FALSE, FORCED + }; + } + } } diff --git a/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/ReportTest.java b/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/ReportTest.java index 2437dfeee..862c38f5b 100644 --- a/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/ReportTest.java +++ b/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/ReportTest.java @@ -16,8 +16,11 @@ */ package org.apache.rat.anttasks; +import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStreamReader; import org.apache.tools.ant.BuildException; @@ -85,4 +88,26 @@ public void testNoLicenseMatchers() throws Exception { private String getAntFileName() { return getAntFile().getPath().replace('\\', '/'); } + + private String getFirstLine(File pFile) throws IOException { + final FileInputStream fis = new FileInputStream(pFile); + final InputStreamReader reader = new InputStreamReader(fis, "UTF8"); + final BufferedReader breader = new BufferedReader(reader); + final String result = breader.readLine(); + breader.close(); + return result; + } + + public void testAddLicenseHeaders() throws Exception { + executeTarget("testAddLicenseHeaders"); + + final File origFile = new File("target/anttasks/it-sources/index.apt"); + final String origFirstLine = getFirstLine(origFile); + assertTrue(origFirstLine.indexOf("--") != -1); + assertTrue(origFirstLine.indexOf("~~") == -1); + final File modifiedFile = new File("target/anttasks/it-sources/index.apt.new"); + final String modifiedFirstLine = getFirstLine(modifiedFile); + assertTrue(modifiedFirstLine.indexOf("--") == -1); + assertTrue(modifiedFirstLine.indexOf("~~") != -1); + } } diff --git a/apache-rat-tasks/src/test/resources/antunit/index.apt b/apache-rat-tasks/src/test/resources/antunit/index.apt new file mode 100644 index 000000000..f5561a5a0 --- /dev/null +++ b/apache-rat-tasks/src/test/resources/antunit/index.apt @@ -0,0 +1,8 @@ + -------------- + Some text file + -------------- + +Some text file + + This is a text file, which intentionally has no Apache License Header. + The RAT plugin should detect it. diff --git a/apache-rat-tasks/src/test/resources/antunit/report-junit.xml b/apache-rat-tasks/src/test/resources/antunit/report-junit.xml index a744727fd..83b716650 100644 --- a/apache-rat-tasks/src/test/resources/antunit/report-junit.xml +++ b/apache-rat-tasks/src/test/resources/antunit/report-junit.xml @@ -84,4 +84,13 @@ + + + + + + + + +