1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.rat.analysis.matchers;
20
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
23
24 import org.apache.commons.lang3.StringUtils;
25 import org.apache.rat.ConfigurationException;
26 import org.apache.rat.analysis.IHeaders;
27 import org.apache.rat.config.parameters.ComponentType;
28 import org.apache.rat.config.parameters.ConfigComponent;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 @ConfigComponent(type = ComponentType.MATCHER, name = "copyright", desc = "Matches copyright statements.")
56 public class CopyrightMatcher extends AbstractHeaderMatcher {
57
58 private static final String COPYRIGHT_SYMBOL_DEFN = "\\([Cc]\\)|©|\\&[Cc][Oo][Pp][Yy]\\;";
59 private static final String COPYRIGHT_PATTERN_DEFN = "(\\b)?" + COPYRIGHT_SYMBOL_DEFN + "|Copyright\\b";
60 private static final Pattern COPYRIGHT_PATTERN = Pattern.compile(COPYRIGHT_PATTERN_DEFN);
61 private static final String ONE_PART = "\\s+((" + COPYRIGHT_SYMBOL_DEFN + ")\\s+)?%s";
62 private static final String TWO_PART = "\\s+((" + COPYRIGHT_SYMBOL_DEFN + ")\\s+)?%s,?\\s+%s";
63
64 private final Pattern dateOwnerPattern;
65 private final Pattern ownerDatePattern;
66 @ConfigComponent(type = ComponentType.PARAMETER, desc = "The initial date of the copyright")
67 private final String start;
68 @ConfigComponent(type = ComponentType.PARAMETER, desc = "The last date the copyright was modifed")
69 private final String end;
70 @ConfigComponent(type = ComponentType.PARAMETER, desc = "The owner of the copyright")
71 private final String owner;
72
73
74
75
76
77
78
79
80
81
82 public CopyrightMatcher(String start, String end, String owner) {
83 this(null, start, end, owner);
84 }
85
86 private static void assertNumber(String label, String value) {
87 try {
88 if (StringUtils.isNotEmpty(value)) {
89 Integer.parseInt(value);
90 }
91 } catch (NumberFormatException e) {
92 throw new ConfigurationException(String.format("'%s' must be numeric (value provided: '%s')", label, value));
93 }
94 }
95
96
97
98
99
100
101
102
103
104
105 public CopyrightMatcher(String id, String start, String end, String owner) {
106 super(id);
107 if (StringUtils.isBlank(start) && !StringUtils.isBlank(end)) {
108 throw new ConfigurationException("'end' may not be set if 'start' is not set.");
109 }
110 assertNumber("start", start);
111 assertNumber("end", end);
112 this.start = start;
113 this.end = end;
114 this.owner = owner;
115 String dateDefn = "";
116 if (StringUtils.isNotEmpty(start)) {
117 if (StringUtils.isNotEmpty(end)) {
118 dateDefn = String.format("%s\\s*-\\s*%s", this.start, this.end);
119 } else {
120 dateDefn = this.start;
121 }
122 }
123 if (StringUtils.isEmpty(owner)) {
124
125 if (StringUtils.isEmpty(dateDefn)) {
126 dateDefn = "[0-9]{4}";
127 }
128 dateOwnerPattern = Pattern.compile(String.format(ONE_PART, dateDefn));
129 ownerDatePattern = null;
130 } else {
131 if (StringUtils.isEmpty(dateDefn)) {
132
133 dateOwnerPattern = Pattern.compile(String.format(ONE_PART, owner));
134 ownerDatePattern = null;
135 } else {
136 dateOwnerPattern = Pattern.compile(String.format(TWO_PART, dateDefn, owner));
137 ownerDatePattern = Pattern.compile(String.format(TWO_PART, owner, dateDefn));
138 }
139 }
140 }
141
142
143
144
145
146 public String getStart() {
147 return start;
148 }
149
150
151
152
153
154 public String getEnd() {
155 return end;
156 }
157
158
159
160
161
162 public String getOwner() {
163 return owner;
164 }
165
166 @Override
167 public boolean matches(IHeaders headers) {
168 String lowerLine = headers.raw().toLowerCase();
169 if (lowerLine.contains("copyright") || lowerLine.contains("(c)") || lowerLine.contains("©") ||
170 lowerLine.contains("©")) {
171 Matcher matcher = COPYRIGHT_PATTERN.matcher(headers.raw());
172 if (matcher.find()) {
173 String buffer = headers.raw().substring(matcher.end());
174 matcher = dateOwnerPattern.matcher(buffer);
175 if (matcher.find() && matcher.start() == 0) {
176 return true;
177 }
178 if (ownerDatePattern != null) {
179 matcher = ownerDatePattern.matcher(buffer);
180 return matcher.find() && matcher.start() == 0;
181 }
182 }
183 }
184 return false;
185 }
186 }