1 /**
2 * The Maven License Verifier Plugin
3 *
4 * Copyright (c) 2009, 2010, 2011 by SoftwareEntwicklung Beratung Schulung (SoEBeS)
5 * Copyright (c) 2009, 2010, 2011 by Karl Heinz Marbaise
6 *
7 * Licensed to the Apache Software Foundation (ASF) under one or more
8 * contributor license agreements. See the NOTICE file distributed with
9 * this work for additional information regarding copyright ownership.
10 * The ASF licenses this file to You under the Apache License, Version 2.0
11 * (the "License"); you may not use this file except in compliance with
12 * the License. You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 */
22 package com.soebes.maven.plugins.mlv;
23
24 import java.io.File;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.net.URL;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Set;
33
34 import org.apache.maven.artifact.Artifact;
35 import org.apache.maven.artifact.repository.ArtifactRepository;
36 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
37 import org.apache.maven.model.License;
38 import org.apache.maven.plugin.AbstractMojo;
39 import org.apache.maven.plugin.MojoExecutionException;
40 import org.apache.maven.project.MavenProject;
41 import org.apache.maven.project.MavenProjectBuilder;
42 import org.apache.maven.project.ProjectBuildingException;
43 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
44
45 import com.soebes.maven.plugins.mlv.filter.PatternExcludeFilter;
46 import com.soebes.maven.plugins.mlv.licenses.LicenseValidator;
47 import com.soebes.maven.plugins.mlv.licenses.LicensesFile;
48 import com.soebes.maven.plugins.mlv.model.LicensesContainer;
49
50 /**
51 * @author <a href="mailto:kama@soebes.de">Karl Heinz Marbaise</a>
52 * @requiresDependencyResolution test
53 */
54 public abstract class AbstractLicenseVerifierPlugIn
55 extends AbstractMojo
56 {
57 /**
58 * The Maven project.
59 *
60 * @parameter expression="${project}"
61 * @required
62 * @readonly
63 */
64 protected MavenProject project;
65
66 /**
67 * Used to build a maven projects from artifacts in the remote repository.
68 *
69 * @component
70 * @required
71 * @readonly
72 */
73 protected MavenProjectBuilder projectBuilder;
74
75 /**
76 * Location of the local repository.
77 *
78 * @parameter expression="${localRepository}"
79 * @readonly
80 * @required
81 */
82 protected ArtifactRepository localRepository;
83
84 /**
85 * List of Remote Repositories used by the resolver
86 *
87 * @parameter expression="${project.remoteArtifactRepositories}"
88 * @readonly
89 * @required
90 */
91 protected List<ArtifactRepository> remoteRepositories;
92
93
94 /**
95 * This will turn on verbose behavior and will print out
96 * all information about the artifacts.
97 *
98 * @parameter expression="${mlv.verbose}" default-value="false"
99 */
100 private boolean verbose;
101
102 /**
103 * This will turn on strictChecking behavior which
104 * will check URL and Name of a license instead of
105 * only URL or Name.
106 *
107 * @parameter expression="${mlv.strickChecking}" default-value="false"
108 */
109 private boolean stricktChecking;
110
111 /**
112 * The build will fail if a license with the category <b>Valid</b>
113 * has been found.
114 * @parameter expression="${mlv.failOnValid}" default-value="false"
115 */
116 protected boolean failOnValid;
117 /**
118 * The build will fail if a license with the category <b>Invalid</b>
119 * has been found.
120 * @parameter expression="${mlv.failOnInvalid}" default-value="false"
121 */
122 protected boolean failOnInvalid;
123 /**
124 * The build will fail if a license with the category <b>Warning</b>
125 * has been found.
126 * @parameter expression="${mlv.failOnWarning}" default-value="false"
127 */
128 protected boolean failOnWarning;
129 /**
130 * The build will fail if a license can not be categorized
131 * in any of the categories.
132 * @parameter expression="${mlv.failOnUnknown}" default-value="false"
133 */
134 protected boolean failOnUnknown;
135
136 /**
137 * The name of the licenses.xml file which will be used to categorize
138 * the licenses of the artifacts.
139 * @parameter expression="${mlv.licenseFile}"
140 * default-value="${project.basedir}/src/licenses/licenses.xml"
141 */
142 protected File licenseFile;
143
144 /**
145 * By using excludes you can exclude particular artifacts from being checked
146 * by the Maven Licenses Verifier Plugin.
147 * <pre>
148 * <excludes>
149 * <exclude>groupId:artifactId:type:version</exclude>
150 * ..
151 * </excludes>
152 * </pre>
153 * @parameter
154 */
155 protected List<String> excludes;
156
157 /**
158 * This is just for simplicity to store all license information
159 * here to make the checkings and other operation simpler.
160 */
161 private ArrayList<LicenseInformation> licenseInformations = new ArrayList<LicenseInformation>();
162
163 private HashMap<String, LicenseInformation> licenseList = new HashMap<String, LicenseInformation>();
164
165 protected LicenseValidator licenseValidator = null;
166 protected LicensesContainer licensesContainer = null;
167
168 /**
169 * Get all their dependencies and put the information
170 * into the intermediate list of licenses.
171 *
172 * @param depArtifacts
173 * @throws MojoExecutionException
174 */
175 protected void getDependArtifacts(Set<?> depArtifacts)
176 throws MojoExecutionException {
177
178 PatternExcludeFilter patternExcludeFilter = new PatternExcludeFilter();
179 ArtifactFilter filter = patternExcludeFilter.createFilter(excludes);
180
181 for (Iterator<?> depArtIter = depArtifacts.iterator(); depArtIter.hasNext(); ) {
182 Artifact depArt = (Artifact) depArtIter.next();
183
184 if (!filter.include(depArt)) {
185 if (isVerbose()) {
186 getLog().warn("The artifact: " + depArt.getId() + " has been execluded by the configuration.");
187 }
188 continue;
189 }
190
191 LicenseInformation li = new LicenseInformation();
192
193 // Here we access to the files so we can check if they contain LICENSE file etc. (check for JAR file reading? Other file types ? )
194 // if (verbose) {
195 // getLog().info("Artifact file:" + depArt.getFile().getAbsolutePath());
196 // }
197
198 //store the artifact about which the following license information
199 //will be extracted.
200 li.setArtifact(depArt);
201 MavenProject depProject = null;
202 try
203 {
204 depProject = projectBuilder.buildFromRepository(depArt, remoteRepositories, localRepository, true);
205 }
206 catch (ProjectBuildingException e)
207 {
208 throw new MojoExecutionException( "Unable to build project: " + depArt.getDependencyConflictId(), e );
209 }
210
211 // depArt.getScope() => Can be use eventually
212 //Set the project of the current license information
213 li.setProject(depProject);
214
215 //Add all licenses of the particular artifact to it's other informations.
216 List<?> licenses = depProject.getLicenses();
217 Iterator<?> licenseIter = licenses.iterator();
218 while (licenseIter.hasNext())
219 {
220 License license = (License) licenseIter.next();
221 li.addLicense(license);
222 }
223 licenseInformations.add(li);
224 }
225 }
226
227 public HashMap<String, LicenseInformation> getLicenseList() {
228 return licenseList;
229 }
230
231 public ArrayList<LicenseInformation> getLicenseInformations() {
232 return licenseInformations;
233 }
234
235 /**
236 * This method will load the licenses.xml file.
237 *
238 * @throws MojoExecutionException
239 */
240 protected void loadLicensesFile() throws MojoExecutionException {
241 if (licenseFile == null)
242 {
243 //If no licenseFile configuration given we will end.
244 return;
245 }
246 try {
247 getLog().debug("Trying to find " + licenseFile.getAbsolutePath() + " in file system.");
248 if (licenseFile.exists()) {
249 getLog().debug("Found licenses file in file system.");
250 getLog().info("Loading " + licenseFile.getAbsolutePath() + " licenses file.");
251 licensesContainer = LicensesFile.getLicenses(licenseFile);
252 } else {
253 getLog().info("Loading license file via classpath.");
254 URL licenseURL = this.getClass().getResource(licenseFile.getPath());
255 InputStream inputStream = null;
256 if (licenseURL == null) {
257 inputStream = this.getClass().getResourceAsStream("/licenses/licenses.xml");
258 licenseURL = this.getClass().getResource("/licenses/licenses.xml");
259 } else {
260 inputStream = this.getClass().getResourceAsStream(licenseFile.getPath());
261 licenseURL = this.getClass().getResource(licenseFile.getPath());
262 }
263 getLog().debug("Loading licenses.xml from " + licenseURL);
264 licensesContainer = LicensesFile.getLicenses(inputStream);
265 }
266 licenseValidator = new LicenseValidator(licensesContainer);
267 licenseValidator.setStrictChecking(stricktChecking);
268
269 } catch (IOException e) {
270 //Use the internal licenses.xml file.???
271 throw new MojoExecutionException(
272 "The LicenseFile configuration is wrong, " +
273 "cause we couldn't find the " + licenseFile.getAbsolutePath());
274 } catch (XmlPullParserException e) {
275 //Use the internal licenses.xml file.???
276 throw new MojoExecutionException(
277 "The LicenseFile is wrong, " +
278 "cause we couldn't read it " + e);
279 }
280 }
281
282 public void setVerbose(boolean verbose) {
283 this.verbose = verbose;
284 }
285
286 public boolean isVerbose() {
287 return verbose;
288 }
289 }