Permalink
Browse files

RAT-125 Applied https://issues.apache.org/jira/browse/RAT-125, adding…

… a new class of license representing the Apache Software License as usually applied outside the ASF. Thanks to Ate Douma for the patch.

git-svn-id: https://svn.apache.org/repos/asf/creadur/rat/trunk@1447920 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
1 parent 3f280f2 commit 990e0b91c1d13ee4540ba345920674a7fa2081eb @itstechupnorth itstechupnorth committed Feb 19, 2013
@@ -0,0 +1,94 @@
+/*
+ * 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.analysis.license;
+
+import java.util.regex.Pattern;
+
+import org.apache.rat.analysis.RatHeaderAnalysisException;
+import org.apache.rat.api.Document;
+import org.apache.rat.api.MetaData;
+
+/**
+ * Matches an applied ASL 2.0 License header, including a <em>required</em>
+ * initial copyright header line, conforming the <a href="http://apache.org/licenses/LICENSE-2.0.html#apply">template</a>
+ * from the ASL 2.0 license itself.
+ *
+ * @since Rat 0.9
+ */
+public class AppliedApacheSoftwareLicense20 extends CopyrightHeader {
+
+ public static final String ASL20_LICENSE_DEFN
+ = "Licensed under the Apache License, Version 2.0 (the \"License\");\n"
+ + "you may not use this file except in compliance with the License.\n"
+ + "You may obtain a copy of the License at\n"
+ + "http://www.apache.org/licenses/LICENSE-2.0\n"
+ + "Unless required by applicable law or agreed to in writing, software\n"
+ + "distributed under the License is distributed on an \"AS IS\" BASIS,\n"
+ + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
+ + "See the License for the specific language governing permissions and\n"
+ + "limitations under the License.\n";
+
+ protected static final Pattern LICENSE_PATTERN = Pattern.compile(".*" + prune(ASL20_LICENSE_DEFN) + ".*", Pattern.CASE_INSENSITIVE);
+
+ protected static String prune(String text) {
+ StringBuilder buffer = new StringBuilder(text);
+ int length = buffer.length();
+ for (int i = length; i > 0;) {
+ char at = buffer.charAt(--i);
+ if (!Character.isLetterOrDigit(at)) {
+ buffer.deleteCharAt(i);
+ }
+ }
+ return buffer.toString();
+ }
+
+ private StringBuilder buffer = new StringBuilder();
+
+ public AppliedApacheSoftwareLicense20() {
+ super(MetaData.RAT_LICENSE_FAMILY_CATEGORY_DATUM_ASL, MetaData.RAT_LICENSE_FAMILY_NAME_DATUM_APACHE_LICENSE_VERSION_2_0,"");
+ }
+
+ public AppliedApacheSoftwareLicense20(String copyrightOwner) {
+ this();
+ setCopyrightOwner(copyrightOwner);
+ }
+
+ @Override
+ public boolean match(Document subject, String s) throws RatHeaderAnalysisException {
+ boolean result = false;
+ if (isCopyrightMatch()) {
+ buffer.append(prune(s));
+ if (LICENSE_PATTERN.matcher(buffer).matches()) {
+ reportOnLicense(subject);
+ return true;
+ }
+ return false;
+ }
+ else {
+ matchCopyright(s);
+ }
+ return result;
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ buffer.setLength(0);
+ }
+}
@@ -0,0 +1,103 @@
+/*
+ * 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.analysis.license;
+
+import java.util.regex.Pattern;
+
+import org.apache.rat.analysis.IHeaderMatcher;
+import org.apache.rat.analysis.RatHeaderAnalysisException;
+import org.apache.rat.api.Document;
+import org.apache.rat.api.MetaData.Datum;
+
+/**
+ * Matches a typical Copyright header line only based on a regex pattern
+ * which allows for one (starting) year or year range, and a
+ * configurable copyright owner.
+ *
+ * <p>The matching is done case insensitive</p>
+ *
+ * <ul>Example supported Copyright header lines, using copyright owner "FooBar"
+ * <li>* Copyright 2010 FooBar. *</li>
+ * <li>* Copyright 2010-2012 FooBar. *</li>
+ * <li>*copyright 2012 foobar*</li>
+ * </ul>
+ *
+ * <p>Note also that the copyright owner is appended to the regex pattern, so
+ * can support additional regex but also requires escaping where needed,<br/>
+ * e.g. use "FooBar \(www\.foobar\.com\)" for matching "FooBar (www.foobar.com)" </p>
+ *
+ * @since Rat 0.9
+ */
+public class CopyrightHeader extends BaseLicense implements IHeaderMatcher {
+
+ public static final String COPYRIGHT_PREFIX_PATTERN_DEFN = ".*Copyright [0-9]{4}(\\-[0-9]{4})? ";
+
+ private Pattern copyrightPattern;
+ private String copyrightOwner;
+ private boolean copyrightMatch = false;
+
+ public CopyrightHeader(){
+ }
+
+ protected CopyrightHeader(Datum licenseFamilyCategory, Datum licenseFamilyName, String notes) {
+ super(licenseFamilyCategory, licenseFamilyName, notes);
+ }
+
+ protected CopyrightHeader(Datum licenseFamilyCategory, Datum licenseFamilyName, String notes, String copyrightOwner) {
+ this(licenseFamilyCategory, licenseFamilyName, notes);
+ setCopyrightOwner(copyrightOwner);
+ }
+
+ public void setCopyrightOwner(String copyrightOwner) {
+ this.copyrightOwner = copyrightOwner;
+ this.copyrightPattern = Pattern.compile(COPYRIGHT_PREFIX_PATTERN_DEFN+copyrightOwner+".*", Pattern.CASE_INSENSITIVE);
+ }
+
+ public String getCopyRightOwner() {
+ return copyrightOwner;
+ }
+
+ public boolean hasCopyrightPattern() {
+ return copyrightPattern != null;
+ }
+
+ protected boolean isCopyrightMatch() {
+ return copyrightMatch;
+ }
+
+ protected boolean matchCopyright(String s) throws RatHeaderAnalysisException {
+ if (!copyrightMatch) {
+ copyrightMatch = copyrightPattern.matcher(s).matches();
+ }
+ return copyrightMatch;
+ }
+
+ public boolean match(Document subject, String s) throws RatHeaderAnalysisException {
+ if (!copyrightMatch) {
+ if (matchCopyright(s)) {
+ reportOnLicense(subject);
+ }
+ }
+ return copyrightMatch;
+ }
+
+ public void reset() {
+ copyrightMatch = false;
+ }
+}
@@ -0,0 +1,92 @@
+/*
+ * 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.analysis.license;
+
+import java.io.BufferedReader;
+import java.io.StringReader;
+
+import org.apache.rat.api.Document;
+import org.apache.rat.document.MockLocation;
+import org.apache.rat.report.claim.impl.xml.MockClaimReporter;
+import org.apache.rat.test.utils.Resources;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class AppliedApacheSoftwareLicense20Test {
+
+ private static final String HEADER
+ = "/*\n"
+ + " * Copyright 2012-2013 FooBar.\n"
+ + " *\n"
+ + " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
+ + " * you may not use this file except in compliance with the License.\n"
+ + " *\n"
+ + " * You may obtain a copy of the License at\n"
+ + " * http://www.apache.org/licenses/LICENSE-2.0\n"
+ + " *\n"
+ + " * Unless required by applicable law or agreed to in writing, software\n"
+ + " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
+ + " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
+ + " * See the License for the specific language governing permissions and\n"
+ + " * limitations under the License.\n"
+ + " */\n";
+
+ AppliedApacheSoftwareLicense20 license;
+
+ MockClaimReporter reporter;
+
+ @Before
+ public void setUp() throws Exception {
+ license = new AppliedApacheSoftwareLicense20("FooBar");
+ reporter = new MockClaimReporter();
+ }
+
+ @Test
+ public void match() throws Exception {
+ BufferedReader in = new BufferedReader(new StringReader(HEADER));
+ String line = in.readLine();
+ boolean result = false;
+ final Document subject = new MockLocation("subject");
+ while (line != null) {
+ result = license.match(subject, line);
+ line = in.readLine();
+ }
+ assertTrue("Applied ASL2.0 license should be matched", result);
+ license.reset();
+ result = license.match(subject, "New line");
+ assertFalse("After reset, content should build up again", result);
+ }
+
+ @Test
+ public void noMatch() throws Exception {
+ BufferedReader in = Resources.getBufferedResourceReader("elements/Source.java");
+ String line = in.readLine();
+ boolean result = false;
+ final Document subject = new MockLocation("subject");
+ while (line != null) {
+ result = license.match(subject, line);
+ line = in.readLine();
+ }
+ assertFalse("Applied ASL2.0 license should not be matched", result);
+ license.reset();
+ }
+}
@@ -0,0 +1,76 @@
+/*
+ * 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.analysis.license;
+
+import org.apache.rat.api.Document;
+import org.apache.rat.api.MetaData;
+import org.apache.rat.document.MockLocation;
+import org.apache.rat.report.claim.impl.xml.MockClaimReporter;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class CopyrightHeaderTest {
+
+ private static final String[] MATCHING_HEADERS =
+ { "/* Copyright 2012 FooBar.*/"
+ , "/* copyright 2012 foobar.*/"
+ , "/* Copyright 2012-2013 FooBar.*/" };
+ private static final String[] NON_MATCHING_HEADERS =
+ { "/* Copyright*/"
+ , "/* Copyright FooBar.*/"
+ , "/* Copyright 2013*/"
+ , "/* Copyright 123a*/"
+ , "/* Copyright 123f oobar*/"
+ , "/* Copyright 2013FooBar*/"
+ , "/* Copyright 2012 2013 FooBar.*/" };
+
+ CopyrightHeader header;
+ MockClaimReporter reporter;
+ Document subject = new MockLocation("subject");
+
+ @Before
+ public void setUp() throws Exception {
+ header = new CopyrightHeader(MetaData.RAT_LICENSE_FAMILY_CATEGORY_DATUM_ASL,MetaData.RAT_LICENSE_FAMILY_NAME_DATUM_APACHE_LICENSE_VERSION_2_0,"","FooBar");
+ reporter = new MockClaimReporter();
+ subject = new MockLocation("subject");
+ }
+
+ @Test
+ public void match() throws Exception {
+ for (String line : MATCHING_HEADERS) {
+ assertTrue("Copyright Header should be matched", header.match(subject, line));
+ header.reset();
+ assertFalse("After reset, content should build up again", header.match(subject, "New line"));
+ header.reset();
+ }
+ }
+
+ @Test
+ public void noMatch() throws Exception {
+ for (String line : NON_MATCHING_HEADERS) {
+ assertFalse("Copyright Header shouldn't be matched", header.match(subject, line));
+ header.reset();
+ assertTrue("After reset, content should build up again", header.match(subject, MATCHING_HEADERS[0]));
+ header.reset();
+ }
+ }
+}

0 comments on commit 990e0b9

Please sign in to comment.