001 /**
002 * Copyright 2010-2012 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.codehaus.mojo.license;
017
018 import java.util.List;
019 import java.util.Set;
020 import java.util.SortedMap;
021 import java.util.TreeMap;
022 import java.util.regex.Matcher;
023 import java.util.regex.Pattern;
024 import java.util.regex.PatternSyntaxException;
025
026 import org.apache.commons.collections.CollectionUtils;
027 import org.apache.commons.lang.StringUtils;
028 import org.apache.maven.artifact.Artifact;
029 import org.apache.maven.artifact.repository.ArtifactRepository;
030 import org.apache.maven.project.MavenProject;
031 import org.apache.maven.project.MavenProjectBuilder;
032 import org.apache.maven.project.ProjectBuildingException;
033 import org.codehaus.plexus.logging.AbstractLogEnabled;
034 import org.codehaus.plexus.logging.Logger;
035
036 /**
037 * Default implementation of the {@link DependenciesTool}.
038 *
039 * @author tchemit <chemit@codelutin.com>
040 * @version $Id: DefaultDependenciesTool.java 14411 2011-08-10 22:09:34Z tchemit $
041 * @plexus.component role="org.codehaus.mojo.license.DependenciesTool" role-hint="default"
042 * @since 1.0
043 */
044 public class DefaultDependenciesTool extends AbstractLogEnabled implements DependenciesTool {
045
046 public static final String INVALID_PATTERN_MESSAGE = "The pattern specified by expression <%s> seems to be invalid.";
047
048 /**
049 * Project builder.
050 *
051 * @plexus.requirement
052 */
053 private MavenProjectBuilder mavenProjectBuilder;
054
055 /**
056 * {@inheritDoc}
057 */
058 @Override
059 public SortedMap<String, MavenProject> loadProjectDependencies(MavenProject project,
060 MavenProjectDependenciesConfigurator configuration, ArtifactRepository localRepository,
061 List<ArtifactRepository> remoteRepositories, SortedMap<String, MavenProject> cache) {
062
063 boolean haveNoIncludedGroups = StringUtils.isEmpty(configuration.getIncludedGroups());
064 boolean haveNoIncludedArtifacts = StringUtils.isEmpty(configuration.getIncludedArtifacts());
065
066 boolean haveExcludedGroups = StringUtils.isNotEmpty(configuration.getExcludedGroups());
067 boolean haveExcludedArtifacts = StringUtils.isNotEmpty(configuration.getExcludedArtifacts());
068 boolean haveExclusions = haveExcludedGroups || haveExcludedArtifacts;
069
070 Pattern includedGroupPattern = null;
071 Pattern includedArtifactPattern = null;
072 Pattern excludedGroupPattern = null;
073 Pattern excludedArtifactPattern = null;
074
075 if (!haveNoIncludedGroups) {
076 includedGroupPattern = Pattern.compile(configuration.getIncludedGroups());
077 }
078 if (!haveNoIncludedArtifacts) {
079 includedArtifactPattern = Pattern.compile(configuration.getIncludedArtifacts());
080 }
081 if (haveExcludedGroups) {
082 excludedGroupPattern = Pattern.compile(configuration.getExcludedGroups());
083 }
084 if (haveExcludedArtifacts) {
085 excludedArtifactPattern = Pattern.compile(configuration.getExcludedArtifacts());
086 }
087
088 Set<?> depArtifacts;
089
090 if (configuration.isIncludeTransitiveDependencies()) {
091 // All project dependencies
092 depArtifacts = project.getArtifacts();
093 } else {
094 // Only direct project dependencies
095 depArtifacts = project.getDependencyArtifacts();
096 }
097
098 List<String> includedScopes = configuration.getIncludedScopes();
099 List<String> excludeScopes = configuration.getExcludedScopes();
100
101 boolean verbose = configuration.isVerbose();
102
103 SortedMap<String, MavenProject> result = new TreeMap<String, MavenProject>();
104
105 for (Object o : depArtifacts) {
106 Artifact artifact = (Artifact) o;
107
108 String scope = artifact.getScope();
109 if (CollectionUtils.isNotEmpty(includedScopes) && !includedScopes.contains(scope)) {
110
111 // not in included scopes
112 continue;
113 }
114 {
115 if (excludeScopes.contains(scope)) {
116
117 // in excluded scopes
118 continue;
119 }
120 }
121
122 Logger log = getLogger();
123
124 String id = MojoHelper.getArtifactId(artifact);
125
126 if (verbose) {
127 log.info("detected artifact " + id);
128 }
129
130 // Check if the project should be included
131 // If there is no specified artifacts and group to include, include all
132 boolean isToInclude = haveNoIncludedArtifacts && haveNoIncludedGroups
133 || isIncludable(artifact, includedGroupPattern, includedArtifactPattern);
134
135 // Check if the project should be excluded
136 boolean isToExclude = isToInclude && haveExclusions
137 && isExcludable(artifact, excludedGroupPattern, excludedArtifactPattern);
138
139 if (!isToInclude || isToExclude) {
140 if (verbose) {
141 log.info("skip artifact " + id);
142 }
143 continue;
144 }
145
146 MavenProject depMavenProject = null;
147
148 if (cache != null) {
149
150 // try to get project from cache
151 depMavenProject = cache.get(id);
152 }
153
154 if (depMavenProject != null) {
155 if (verbose) {
156 log.info("add dependency [" + id + "] (from cache)");
157 }
158 } else {
159
160 // build project
161
162 try {
163 depMavenProject = mavenProjectBuilder.buildFromRepository(artifact, remoteRepositories,
164 localRepository, true);
165 } catch (ProjectBuildingException e) {
166 log.warn("Unable to obtain POM for artifact : " + artifact, e);
167 continue;
168 }
169
170 if (verbose) {
171 log.info("add dependency [" + id + "]");
172 }
173 if (cache != null) {
174
175 // store it also in cache
176 cache.put(id, depMavenProject);
177 }
178 }
179
180 // keep the project
181 result.put(id, depMavenProject);
182 }
183
184 return result;
185 }
186
187 protected boolean isIncludable(Artifact project, Pattern includedGroupPattern, Pattern includedArtifactPattern) {
188
189 Logger log = getLogger();
190
191 // check if the groupId of the project should be included
192 if (includedGroupPattern != null) {
193 // we have some defined license filters
194 try {
195 Matcher matchGroupId = includedGroupPattern.matcher(project.getGroupId());
196 if (matchGroupId.find()) {
197 if (log.isDebugEnabled()) {
198 log.debug("Include " + project.getGroupId());
199 }
200 return true;
201 }
202 } catch (PatternSyntaxException e) {
203 log.warn(String.format(INVALID_PATTERN_MESSAGE, includedGroupPattern.pattern()));
204 }
205 }
206
207 // check if the artifactId of the project should be included
208 if (includedArtifactPattern != null) {
209 // we have some defined license filters
210 try {
211 Matcher matchGroupId = includedArtifactPattern.matcher(project.getArtifactId());
212 if (matchGroupId.find()) {
213 if (log.isDebugEnabled()) {
214 log.debug("Include " + project.getArtifactId());
215 }
216 return true;
217 }
218 } catch (PatternSyntaxException e) {
219 log.warn(String.format(INVALID_PATTERN_MESSAGE, includedArtifactPattern.pattern()));
220 }
221 }
222
223 return false;
224 }
225
226 protected boolean isExcludable(Artifact project, Pattern excludedGroupPattern, Pattern excludedArtifactPattern) {
227
228 Logger log = getLogger();
229
230 // check if the groupId of the project should be included
231 if (excludedGroupPattern != null) {
232 // we have some defined license filters
233 try {
234 Matcher matchGroupId = excludedGroupPattern.matcher(project.getGroupId());
235 if (matchGroupId.find()) {
236 if (log.isDebugEnabled()) {
237 log.debug("Exclude " + project.getGroupId());
238 }
239 return true;
240 }
241 } catch (PatternSyntaxException e) {
242 log.warn(String.format(INVALID_PATTERN_MESSAGE, excludedGroupPattern.pattern()));
243 }
244 }
245
246 // check if the artifactId of the project should be included
247 if (excludedArtifactPattern != null) {
248 // we have some defined license filters
249 try {
250 Matcher matchGroupId = excludedArtifactPattern.matcher(project.getArtifactId());
251 if (matchGroupId.find()) {
252 if (log.isDebugEnabled()) {
253 log.debug("Exclude " + project.getArtifactId());
254 }
255 return true;
256 }
257 } catch (PatternSyntaxException e) {
258 log.warn(String.format(INVALID_PATTERN_MESSAGE, excludedArtifactPattern.pattern()));
259 }
260 }
261
262 return false;
263 }
264 }