1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one *
3 * or more contributor license agreements. See the NOTICE file *
4 * distributed with this work for additional information *
5 * regarding copyright ownership. The ASF licenses this file *
6 * to you under the Apache License, Version 2.0 (the *
7 * "License"); you may not use this file except in compliance *
8 * with the License. You may obtain a copy of the License at *
9 * *
10 * http://www.apache.org/licenses/LICENSE-2.0 *
11 * *
12 * Unless required by applicable law or agreed to in writing, *
13 * software distributed under the License is distributed on an *
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
15 * KIND, either express or implied. See the License for the *
16 * specific language governing permissions and limitations *
17 * under the License. *
18 */
19 package org.apache.rat.api;
20
21 import java.nio.charset.Charset;
22 import java.util.SortedSet;
23 import java.util.TreeSet;
24 import java.util.function.Predicate;
25 import java.util.stream.Stream;
26
27 import org.apache.rat.license.ILicense;
28 import org.apache.rat.utils.DefaultLog;
29 import org.apache.tika.mime.MediaType;
30
31 /**
32 * Data about the document under test.
33 */
34 public class MetaData {
35
36 /** The list of matched licenses */
37 private final SortedSet<ILicense> matchedLicenses;
38 /** The list of License Family Categories that are approved */
39 private Predicate<ILicense> approvalPredicate;
40 /** The charset for this document */
41 private Charset charset;
42 /** The media type for this document */
43 private MediaType mediaType;
44 /** The document type for this document */
45 private Document.Type documentType;
46 /** The flag for directory types */
47 private boolean isDirectory;
48
49 /**
50 * Create metadata without a content type.
51 */
52 public MetaData() {
53 this.matchedLicenses = new TreeSet<>();
54 }
55
56 /**
57 * Gets the charset for the document. If the charset was not set will return the system default charset.
58 * @return the charset for the document
59 */
60 public Charset getCharset() {
61 return charset == null ? Charset.defaultCharset() : charset;
62 }
63
64 /**
65 * Sets the charset for the document. If set to {@code null} the system default charset will be used.
66 * @param charset the charset to use.
67 */
68 public void setCharset(final Charset charset) {
69 this.charset = charset;
70 }
71
72 /**
73 * Returns {@code true} if {@link #setCharset} has been called.
74 * @return {@code true} if {@link #setCharset} has been called.
75 */
76 public boolean hasCharset() {
77 return charset != null;
78 }
79
80 /**
81 * Gets the defined media type.
82 * @return the media type.
83 */
84 public MediaType getMediaType() {
85 return mediaType;
86 }
87
88 /**
89 * Sets the defined media type.
90 * @param mediaType the media type.
91 */
92 public void setMediaType(final MediaType mediaType) {
93 this.mediaType = mediaType;
94 }
95
96 /**
97 * Determines if a matching license has been detected.
98 * @return true if there is a matching license.
99 */
100 public boolean detectedLicense() {
101 return !matchedLicenses.isEmpty();
102 }
103
104 /**
105 * Gets the predicate to filter approved licenses.
106 * @return The predicate to validate licenses.
107 * @throws IllegalStateException if no predicate was set.
108 */
109 private Predicate<ILicense> getApprovalPredicate() {
110 if (approvalPredicate == null) {
111 DefaultLog.getInstance().error("Approval predicate was not set.");
112 throw new IllegalStateException("Approval predicate was not set.");
113 }
114 return approvalPredicate;
115 }
116
117 /**
118 * Sets the set of approved licenses.
119 * @param approvalPredicate the predicate to validate licenses.
120 */
121 public void setApprovalPredicate(final Predicate<ILicense> approvalPredicate) {
122 this.approvalPredicate = approvalPredicate;
123 }
124
125 /**
126 * Gets the stream of licenses that have been matched.
127 * @return the stream of licenses that have been matched.
128 */
129 public Stream<ILicense> licenses() {
130 return matchedLicenses.stream();
131 }
132
133 /**
134 * Gets the stream of approved licenses that have been matched.
135 * @return the stream of approved licenses that have been matched.
136 */
137 public Stream<ILicense> approvedLicenses() {
138 return licenses().filter(this::isApproved);
139 }
140
141 /**
142 * Determine if the license is an approved license.
143 * @param license the license to check.
144 * @return {@code true} if the license is in the list of approved licenses, {@code false} otherwise.
145 */
146 public boolean isApproved(final ILicense license) {
147 return getApprovalPredicate().test(license);
148 }
149
150 /**
151 * Gets the stream of unapproved licenses that have been matched.
152 * @return the stream of unapproved licenses that have been matched.
153 */
154 public Stream<ILicense> unapprovedLicenses() {
155 return licenses().filter(lic -> !isApproved(lic));
156 }
157
158 /**
159 * Sets the document type.
160 * @param type the document type for the document being recorded.
161 */
162 public void setDocumentType(final Document.Type type) {
163 this.documentType = type;
164 }
165
166 /**
167 * Set the directory flag.
168 * @param state the state to set the directory flag in.
169 */
170 public void setIsDirectory(final boolean state) {
171 this.isDirectory = state;
172 }
173
174 /**
175 * Return {@code true} if the directory flag was set.
176 * @return the directory flag.
177 */
178 public boolean isDirectory() {
179 return isDirectory;
180 }
181
182 /**
183 * Gets the document type.
184 * @return the document type of the document that was recorded.
185 */
186 public Document.Type getDocumentType() {
187 return this.documentType;
188 }
189
190 /**
191 * Add the license information to the metadata.
192 * @param license the license to add metadata for.
193 */
194 public void reportOnLicense(final ILicense license) {
195 this.matchedLicenses.add(license);
196 }
197
198 /**
199 * Remove matched licenses based on a predicate. Will remove licenses for which the predicate
200 * returns true.
201 * @param filter the predicate to use.
202 */
203 public void removeLicenses(final Predicate<ILicense> filter) {
204 this.matchedLicenses.removeIf(filter);
205 }
206
207 @Override
208 public String toString() {
209 return String.format("MetaData[%s license, %s approved]", matchedLicenses.size(),
210 approvalPredicate == null ? "unknown" : matchedLicenses.stream().filter(getApprovalPredicate()).count());
211 }
212 }