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 }