View Javadoc
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.analysis;
20  
21  import java.util.Collection;
22  import java.util.Set;
23  import java.util.function.Predicate;
24  
25  import org.apache.rat.ConfigurationException;
26  import org.apache.rat.Defaults;
27  import org.apache.rat.ReportConfiguration;
28  import org.apache.rat.api.Document;
29  import org.apache.rat.api.RatException;
30  import org.apache.rat.document.DocumentAnalyser;
31  import org.apache.rat.document.RatDocumentAnalysisException;
32  import org.apache.rat.license.ILicense;
33  import org.apache.rat.license.LicenseSetFactory;
34  import org.apache.rat.utils.DefaultLog;
35  import org.apache.rat.utils.Log;
36  import org.apache.rat.walker.ArchiveWalker;
37  
38  /**
39   * Creates default analysers.
40   */
41  public final class AnalyserFactory {
42  
43      private AnalyserFactory() {
44          // do not instantiate
45      }
46  
47      /**
48       * Creates an analyser that adds the approved license predicate to the document metadata.
49       * <p>
50       *     Note you probably do not want this as it is automatically added to {@link #createConfiguredAnalyser}.
51       * </p>
52       * @param approvalPredicate the predicate to approve licenses.
53       * @return A document analyser that sets the approvalPredicate in document metadata.
54       */
55      public static DocumentAnalyser createPolicy(final Predicate<ILicense> approvalPredicate) {
56          return document -> {
57              if (document != null) {
58                  document.getMetaData().setApprovalPredicate(approvalPredicate);
59              }
60          };
61      }
62  
63      /**
64       * Creates an analyser that calls each of the provided analysers in order.
65       * @param analysers the array of analysers to call.
66       * @return an analyser that will call all the provided analysers.
67       */
68      public static DocumentAnalyser createMultiplexer(final DocumentAnalyser... analysers) {
69          return document -> {
70              for (DocumentAnalyser analyser : analysers) {
71                  analyser.analyse(document);
72              }
73          };
74      }
75  
76      /**
77       * Creates a DocumentAnalyser from the report configuration.
78       * @param configuration the ReportConfiguration
79       * @return A document analyser that uses the provided licenses.
80       */
81      public static DocumentAnalyser createConfiguredAnalyser(final ReportConfiguration configuration) {
82          LicenseSetFactory licenseSetFactory = configuration.getLicenseSetFactory();
83          Set<ILicense> licenses = licenseSetFactory.getLicenses(LicenseSetFactory.LicenseFilter.ALL);
84          if (licenses.isEmpty()) {
85              throw new ConfigurationException("At least one license must be defined");
86          }
87          if (DefaultLog.getInstance().isEnabled(Log.Level.DEBUG)) {
88              DefaultLog.getInstance().debug("Currently active licenses are:");
89              licenses.forEach(DefaultLog.getInstance()::debug);
90          }
91          return createMultiplexer(createPolicy(licenseSetFactory.getApprovedLicensePredicate()),
92           new DefaultAnalyser(configuration, licenses));
93      }
94  
95      /**
96       * A DocumentAnalyser a collection of licenses.
97       */
98      private static final class DefaultAnalyser implements DocumentAnalyser {
99  
100         /** The licenses to analyze */
101         private final Collection<ILicense> licenses;
102         /** the Report Configuration */
103         private final ReportConfiguration configuration;
104         /** The matcher for generated files */
105         private final IHeaderMatcher generatedMatcher;
106 
107         /**
108          * Constructs a DocumentAnalyser for the specified license.
109          * @param config the ReportConfiguration
110          * @param licenses The licenses to analyse
111          */
112         DefaultAnalyser(final ReportConfiguration config, final Collection<ILicense> licenses) {
113             this.licenses = licenses;
114             this.configuration = config;
115             this.generatedMatcher = configuration.getGeneratedMatcher();
116         }
117 
118         /**
119          * Generates a predicate to filter out licenses that should not be reported.
120          * @param proc the processing status to filter.
121          * @return a Predicate to do the filtering.
122          */
123         private Predicate<ILicense> licenseFilter(final ReportConfiguration.Processing proc)  {
124             return license -> {
125                 switch (proc) {
126                     case PRESENCE:
127                         return !license.getLicenseFamily().equals(UnknownLicense.INSTANCE.getLicenseFamily());
128                     case ABSENCE:
129                         return true;
130                     default:
131                         return false;
132                 }
133             };
134         }
135 
136         @Override
137         public void analyse(final Document document) throws RatDocumentAnalysisException {
138             Predicate<ILicense> licensePredicate;
139 
140             TikaProcessor.process(document);
141             switch (document.getMetaData().getDocumentType()) {
142                 case STANDARD:
143                     new DocumentHeaderAnalyser(generatedMatcher, licenses).analyse(document);
144                     if (configuration.getStandardProcessing() != Defaults.STANDARD_PROCESSING) {
145                         licensePredicate = licenseFilter(configuration.getStandardProcessing()).negate();
146                         document.getMetaData().removeLicenses(licensePredicate);
147                     }
148                     break;
149                 case ARCHIVE:
150                     if (configuration.getArchiveProcessing() != ReportConfiguration.Processing.NOTIFICATION) {
151                         ArchiveWalker archiveWalker = new ArchiveWalker(document);
152                         try {
153                             licensePredicate = licenseFilter(configuration.getArchiveProcessing());
154                             for (Document doc : archiveWalker.getDocuments()) {
155                                 analyse(doc);
156                                 doc.getMetaData().licenses().filter(licensePredicate).forEach(lic -> document.getMetaData().reportOnLicense(lic));
157                             }
158                         } catch (RatException e) {
159                             throw new RatDocumentAnalysisException(e);
160                         }
161                     }
162                     break;
163                 default:
164                     break;
165             }
166         }
167     }
168 }