1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.rat.help;
20
21 import java.io.IOException;
22 import java.io.PrintWriter;
23 import java.io.Writer;
24 import java.lang.reflect.InvocationTargetException;
25 import java.util.Collection;
26 import java.util.Comparator;
27 import java.util.Map;
28 import java.util.SortedSet;
29 import java.util.TreeSet;
30 import java.util.UUID;
31
32 import org.apache.commons.cli.HelpFormatter;
33 import org.apache.commons.lang3.StringUtils;
34 import org.apache.rat.ConfigurationException;
35 import org.apache.rat.ReportConfiguration;
36 import org.apache.rat.analysis.IHeaderMatcher;
37 import org.apache.rat.config.parameters.ComponentType;
38 import org.apache.rat.config.parameters.Description;
39 import org.apache.rat.config.parameters.DescriptionBuilder;
40 import org.apache.rat.configuration.MatcherBuilderTracker;
41 import org.apache.rat.configuration.builders.AbstractBuilder;
42 import org.apache.rat.license.ILicense;
43 import org.apache.rat.license.ILicenseFamily;
44 import org.apache.rat.license.LicenseSetFactory.LicenseFilter;
45
46 import static java.lang.String.format;
47
48
49
50
51
52 public final class Licenses extends AbstractHelp {
53
54 private final ReportConfiguration config;
55
56 private final SortedSet<ILicense> licenses;
57
58 private final HelpFormatter formatter;
59
60 private final PrintWriter printWriter;
61
62
63
64
65
66
67 public Licenses(final ReportConfiguration config, final Writer writer) {
68 this.config = config;
69 this.licenses = config.getLicenses(LicenseFilter.ALL);
70 printWriter = new PrintWriter(writer);
71 formatter = HelpFormatter.builder().setShowDeprecated(false).setPrintWriter(printWriter).get();
72 }
73
74
75
76
77
78
79 void print(final int indent, final String text) {
80 int leftMargin = indent * HELP_PADDING;
81 int tabStop = leftMargin + (HELP_PADDING / 2);
82 formatter.printWrapped(printWriter, HELP_WIDTH, tabStop, createPadding(leftMargin) + text);
83 }
84
85
86
87
88
89 public void printHelp() throws IOException {
90 print(0, format("Listing of licenses for %s", versionInfo));
91 output();
92 }
93
94
95
96
97
98 public void output() throws IOException {
99
100 print(0, header("LICENSES"));
101
102 if (licenses.isEmpty()) {
103 print(0, "No licenses defined");
104 } else {
105 Description licenseDescription = DescriptionBuilder.build(licenses.first());
106 Collection<Description> licenseParams = licenseDescription.filterChildren(d -> d.getType() == ComponentType.PARAMETER);
107
108 print(0, format("Licenses have the following properties:%n"));
109
110 for (Description param : licenseParams) {
111 print(1, format("%s: %s%n", param.getCommonName(), param.getDescription()));
112 }
113
114 print(0, format("%nThe defined licenses are:%n"));
115 for (ILicense l : licenses) {
116 print(0, System.lineSeparator());
117 printObject(0, l);
118 }
119 }
120 print(0, header("DEFINED MATCHERS"));
121 SortedSet<Description> matchers = new TreeSet<>(Comparator.comparing(Description::getCommonName));
122 for (Class<? extends AbstractBuilder> mClazz : MatcherBuilderTracker.instance().getClasses()) {
123 try {
124 AbstractBuilder builder = mClazz.getConstructor().newInstance();
125 matchers.add(builder.getDescription());
126 } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException
127 | IllegalArgumentException | InvocationTargetException e) {
128 throw new ConfigurationException(
129 format("Can not instantiate matcher builder %s ", mClazz.getName()), e);
130 }
131 }
132 for (Description description : matchers) {
133 print(0, format("%n%s: %s%n", description.getCommonName(), description.getDescription()));
134 for (Description child : description.getChildren().values()) {
135 if (IHeaderMatcher.class.isAssignableFrom(child.getChildType())) {
136 if (child.isCollection()) {
137 print(2, "Encloses multiple matchers");
138 } else {
139 print(2, "Wraps a single matcher");
140 }
141 } else {
142 print(1, format("%s: %s%s", child.getCommonName(), child.isRequired() ? "(required) " : "", child.getDescription()));
143 }
144 }
145 }
146
147 print(0, header("DEFINED FAMILIES"));
148 for (ILicenseFamily family : config.getLicenseFamilies(LicenseFilter.ALL)) {
149 print(1, format("%s - %s%n", family.getFamilyCategory(), family.getFamilyName()));
150 }
151 printWriter.flush();
152 }
153
154
155
156
157
158
159
160 private void printObject(final int indent, final Object object) throws IOException {
161 if (object == null) {
162 return;
163 }
164 Description description = DescriptionBuilder.build(object);
165 if (description == null) {
166 print(indent, format("Unknown Object of class: %s%n", object.getClass().getName()));
167 } else {
168 print(indent, format("%s (%s)%n", description.getCommonName(), description.getDescription()));
169 printChildren(indent + 1, object, description.getChildren());
170 }
171 }
172
173
174
175
176
177
178 private boolean isUUID(final String s) {
179 try {
180 UUID.fromString(s);
181 return true;
182 } catch (IllegalArgumentException expected) {
183 return false;
184 }
185 }
186
187
188
189
190
191
192
193
194 private void printChildren(final int indent, final Object parent, final Map<String, Description> children) throws IOException {
195 for (Description d : children.values()) {
196 switch (d.getType()) {
197 case PARAMETER:
198 if (d.isCollection()) {
199 print(indent, format("%s: %n", d.getCommonName()));
200 try {
201 Collection<?> result = (Collection<?>) d.getter(parent.getClass()).invoke(parent);
202 for (Object o : result) {
203 printObject(indent + 1, o);
204 }
205 return;
206 } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
207 throw new RuntimeException(e);
208 }
209 }
210 if (IHeaderMatcher.class.isAssignableFrom(d.getChildType())) {
211 print(indent, format("%s: %n", d.getCommonName()));
212
213 try {
214 Object matcher = d.getter(parent.getClass()).invoke(parent);
215 printObject(indent + 1, matcher);
216 } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
217 throw new RuntimeException(e);
218 }
219 } else {
220 String txt = StringUtils.defaultIfBlank(d.getParamValue(parent), "").replaceAll("\\s{2,}", " ");
221 if (!txt.isEmpty() && !(d.getCommonName().equals("id") && isUUID(txt))) {
222 print(indent, format("%s: %s%n", d.getCommonName(), txt.replaceAll("\\s{2,}", " ")));
223 }
224 }
225 break;
226 case BUILD_PARAMETER:
227 case LICENSE:
228
229 break;
230 case MATCHER:
231 printChildren(indent + 1, parent, d.getChildren());
232 break;
233 }
234 }
235 }
236 }