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