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.license;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  import java.util.Objects;
24  import java.util.Optional;
25  import java.util.SortedSet;
26  
27  import org.apache.commons.lang3.StringUtils;
28  import org.apache.rat.ConfigurationException;
29  import org.apache.rat.ImplementationException;
30  import org.apache.rat.analysis.IHeaderMatcher;
31  import org.apache.rat.analysis.IHeaders;
32  import org.apache.rat.config.parameters.ComponentType;
33  import org.apache.rat.config.parameters.ConfigComponent;
34  
35  /**
36   * A simple implementation of ILicense.
37   */
38  @ConfigComponent(type = ComponentType.LICENSE)
39  public class SimpleLicense implements ILicense {
40      /** The license family for this license */
41      @ConfigComponent(type = ComponentType.BUILD_PARAMETER, desc = "The defined license families.", name = "licenseFamilies")
42      private final ILicenseFamily family;
43      /** The matcher for this license */
44      @ConfigComponent(type = ComponentType.PARAMETER, desc = "The matcher for this license.", required = true)
45      private final IHeaderMatcher matcher;
46      /** The notes for this license */
47      @ConfigComponent(type = ComponentType.PARAMETER, desc = "The notes about this license.")
48      private final String note;
49      /** The name of this license */
50      @ConfigComponent(type = ComponentType.PARAMETER, desc = "The name of this license.")
51      private final String name;
52      /** The ID for this license.  Must be unique */
53      @ConfigComponent(type = ComponentType.PARAMETER, desc = "The ID for this license.")
54      private final String id;
55  
56      SimpleLicense(final ILicenseFamily family, final IHeaderMatcher matcher, final String notes, final String name, final String id) {
57          Objects.requireNonNull(matcher, "Matcher must not be null");
58          Objects.requireNonNull(family, "Family must not be null");
59          this.family = family;
60          this.matcher = matcher;
61          this.note = notes;
62          this.name = StringUtils.defaultIfBlank(name, family.getFamilyName());
63          this.id = StringUtils.defaultIfBlank(id, family.getFamilyCategory().trim());
64      }
65  
66      @Override
67      public String toString() {
68          return String.format("%s:%s", getId(), getName());
69      }
70  
71      @ConfigComponent(type = ComponentType.PARAMETER, desc = "The license family category for this license.", required = true)
72      public String getFamily() {
73          return family.getFamilyCategory();
74      }
75  
76      @Override
77      public IHeaderMatcher getMatcher() {
78          return matcher;
79      }
80  
81      @Override
82      public String getId() {
83          return id;
84      }
85  
86      @Override
87      public void reset() {
88          matcher.reset();
89      }
90  
91      @Override
92      public boolean matches(final IHeaders line) {
93          return matcher.matches(line);
94      }
95  
96      @Override
97      public ILicenseFamily getLicenseFamily() {
98          return family;
99      }
100 
101     @Override
102     public boolean equals(final Object o) {
103         return ILicense.equals(this, o);
104     }
105 
106     @Override
107     public int hashCode() {
108         return ILicense.hash(this);
109     }
110 
111     @Override
112     public String getNote() {
113         return note;
114     }
115 
116     @Override
117     public String getName() {
118         return name;
119     }
120 
121     public static class Builder implements ILicense.Builder {
122         /** The set of known license families */
123         private SortedSet<ILicenseFamily> licenseFamilies;
124         /** The matcher builder in use for this license */
125         private IHeaderMatcher.Builder matcher;
126         /** The notes for the license */
127         private final List<String> notes = new ArrayList<>();
128         /** The name of this license */
129         private String name;
130         /** The ID of this license */
131         private String id;
132         /** The family category of this license */
133         private String familyCategory;
134 
135         /**
136          * Sets the matcher from a builder.
137          * @param matcher the builder for the matcher for the license.
138          * @return this builder for chaining.
139          */
140         @Override
141         public Builder setMatcher(final IHeaderMatcher.Builder matcher) {
142             this.matcher = matcher;
143             return this;
144         }
145 
146         /**
147          * Sets the matcher.
148          * @param matcher the matcher for the license.
149          * @return this builder for chaining.
150          */
151         @Override
152         public Builder setMatcher(final IHeaderMatcher matcher) {
153             this.matcher = () -> matcher;
154             return this;
155         }
156 
157         /**
158          * Sets the notes for the license. If called multiple times the notes are
159          * concatenated to create a single note.
160          * @param note the note for the license.
161          * @return this builder.
162          */
163         @Override
164         public Builder setNote(final String note) {
165             if (StringUtils.isNotBlank(note)) {
166                 this.notes.add(note);
167             }
168             return this;
169         }
170 
171         /**
172          * Sets the ID of the license. If the ID is not set then the ID of the license
173          * family is used.
174          * @param id the ID for the license
175          * @return this builder for chaining.
176          */
177         @Override
178         public Builder setId(final String id) {
179             this.id = id;
180             return this;
181         }
182 
183         /**
184          * Set the family category for this license. The category must be unique across
185          * all licenses and must be 5 characters. If more than 5 characters are provided
186          * then only the first 5 are taken. If fewer than 5 characters are provided the
187          * category is padded with spaces.
188          * @param licenseFamilyCategory the family category for the license.
189          * @return this builder for chaining.
190          */
191         @Override
192         public Builder setFamily(final String licenseFamilyCategory) {
193             this.familyCategory = licenseFamilyCategory;
194             return this;
195         }
196 
197         /**
198          * Sets the name of the license. If the name is not set then the name of the
199          * license family is used.
200          * @param name the name for the license
201          * @return this builder for chaining.
202          */
203         @Override
204         public Builder setName(final String name) {
205             this.name = name;
206             return this;
207         }
208 
209         @Override
210         public Builder setLicenseFamilies(final SortedSet<ILicenseFamily> licenseFamilies) {
211             this.licenseFamilies = licenseFamilies;
212             return this;
213         }
214 
215         @Override
216         public SimpleLicense build() {
217             if (matcher == null) {
218                 throw new ConfigurationException("'matcher' must not be null");
219             }
220             if (licenseFamilies == null) {
221                 throw new ImplementationException("'licenseFamilies' must not be null");
222             }
223             if (StringUtils.isBlank(familyCategory)) {
224                 throw new ImplementationException("License 'family' must be specified");
225             }
226 
227             String familyCat = ILicenseFamily.makeCategory(familyCategory);
228             Optional<ILicenseFamily> family = licenseFamilies.stream().filter(f ->  f.getFamilyCategory().equals(familyCat)).findFirst();
229             if (!family.isPresent()) {
230                 throw new ConfigurationException(String.format("License family '%s' not found.", familyCategory));
231             }
232 
233             return new SimpleLicense(family.get(), matcher.build(), String.join(System.lineSeparator(), notes), name, id);
234         }
235     }
236 }