001 /**
002 * Copyright 2010-2013 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.codehaus.plexus.logging.AbstractLogEnabled;
033 import org.codehaus.plexus.logging.Logger;
034
035 /**
036 * Default implementation of the {@link DependenciesTool}.
037 *
038 * @author tchemit <chemit@codelutin.com>
039 * @version $Id: DefaultDependenciesTool.java 14411 2011-08-10 22:09:34Z tchemit $
040 * @plexus.component role="org.codehaus.mojo.license.DependenciesTool" role-hint="default"
041 * @since 1.0
042 */
043 public class DefaultDependenciesTool extends AbstractLogEnabled implements DependenciesTool {
044
045 public static final String INVALID_PATTERN_MESSAGE = "The pattern specified by expression <%s> seems to be invalid.";
046
047 /**
048 * Project builder.
049 *
050 * @plexus.requirement
051 */
052 private MavenProjectBuilder mavenProjectBuilder;
053
054 /**
055 * {@inheritDoc}
056 */
057 @Override
058 public SortedMap<String, MavenProject> loadProjectDependencies(MavenProject project, MavenProjectDependenciesConfigurator configuration, ArtifactRepository localRepository,
059 List<ArtifactRepository> remoteRepositories, SortedMap<String, MavenProject> cache) {
060
061 boolean haveNoIncludedGroups = StringUtils.isEmpty(configuration.getIncludedGroups());
062 boolean haveNoIncludedArtifacts = StringUtils.isEmpty(configuration.getIncludedArtifacts());
063
064 boolean haveExcludedGroups = StringUtils.isNotEmpty(configuration.getExcludedGroups());
065 boolean haveExcludedArtifacts = StringUtils.isNotEmpty(configuration.getExcludedArtifacts());
066 boolean haveExclusions = haveExcludedGroups || haveExcludedArtifacts;
067
068 Pattern includedGroupPattern = null;
069 Pattern includedArtifactPattern = null;
070 Pattern excludedGroupPattern = null;
071 Pattern excludedArtifactPattern = null;
072
073 if (!haveNoIncludedGroups) {
074 includedGroupPattern = Pattern.compile(configuration.getIncludedGroups());
075 }
076 if (!haveNoIncludedArtifacts) {
077 includedArtifactPattern = Pattern.compile(configuration.getIncludedArtifacts());
078 }
079 if (haveExcludedGroups) {
080 excludedGroupPattern = Pattern.compile(configuration.getExcludedGroups());
081 }
082 if (haveExcludedArtifacts) {
083 excludedArtifactPattern = Pattern.compile(configuration.getExcludedArtifacts());
084 }
085
086 Set<?> depArtifacts;
087
088 if (configuration.isIncludeTransitiveDependencies()) {
089 // All project dependencies
090 depArtifacts = project.getArtifacts();
091 } else {
092 // Only direct project dependencies
093 depArtifacts = project.getDependencyArtifacts();
094 }
095
096 List<String> includedScopes = configuration.getIncludedScopes();
097 List<String> excludeScopes = configuration.getExcludedScopes();
098
099 boolean verbose = configuration.isVerbose();
100
101 SortedMap<String, MavenProject> result = new TreeMap<String, MavenProject>();
102
103 for (Object o : depArtifacts) {
104 Artifact artifact = (Artifact) o;
105
106 String scope = artifact.getScope();
107 if (CollectionUtils.isNotEmpty(includedScopes) && !includedScopes.contains(scope)) {
108 // not in included scopes
109 continue;
110 }
111 if (excludeScopes.contains(scope)) {
112 // in excluded scopes
113 continue;
114 }
115
116 Logger log = getLogger();
117
118 String id = MojoHelper.getArtifactId(artifact);
119
120 if (verbose) {
121 log.info("detected artifact " + id);
122 }
123
124 // Check if the project should be included
125 // If there is no specified artifacts and group to include, include all
126 boolean isToInclude = haveNoIncludedArtifacts && haveNoIncludedGroups || isIncludable(artifact, includedGroupPattern, includedArtifactPattern);
127
128 // Check if the project should be excluded
129 boolean isToExclude = isToInclude && haveExclusions && isExcludable(artifact, excludedGroupPattern, excludedArtifactPattern);
130
131 if (!isToInclude || isToExclude) {
132 if (verbose) {
133 log.info("skip artifact " + id);
134 }
135 continue;
136 }
137
138 MavenProject depMavenProject = null;
139
140 if (cache != null) {
141
142 // try to get project from cache
143 depMavenProject = cache.get(id);
144 }
145
146 if (depMavenProject != null) {
147 if (verbose) {
148 log.info("add dependency [" + id + "] (from cache)");
149 }
150 } else {
151 // build project
152 try {
153 depMavenProject = mavenProjectBuilder.buildFromRepository(artifact, remoteRepositories, localRepository, true);
154 } catch (Exception e) {
155 log.warn("Unable to obtain POM for artifact : " + artifact, e);
156 continue;
157 }
158
159 if (verbose) {
160 log.info("add dependency [" + id + "]");
161 }
162 if (cache != null) {
163 // store it also in cache
164 cache.put(id, depMavenProject);
165 }
166 }
167
168 // keep the project
169 result.put(id, depMavenProject);
170 }
171
172 return result;
173 }
174
175 protected boolean isIncludable(Artifact project, Pattern includedGroupPattern, Pattern includedArtifactPattern) {
176
177 Logger log = getLogger();
178
179 // check if the groupId of the project should be included
180 if (includedGroupPattern != null) {
181 // we have some defined license filters
182 try {
183 Matcher matchGroupId = includedGroupPattern.matcher(project.getGroupId());
184 if (matchGroupId.find()) {
185 if (log.isDebugEnabled()) {
186 log.debug("Include " + project.getGroupId());
187 }
188 return true;
189 }
190 } catch (PatternSyntaxException e) {
191 log.warn(String.format(INVALID_PATTERN_MESSAGE, includedGroupPattern.pattern()));
192 }
193 }
194
195 // check if the artifactId of the project should be included
196 if (includedArtifactPattern != null) {
197 // we have some defined license filters
198 try {
199 Matcher matchGroupId = includedArtifactPattern.matcher(project.getArtifactId());
200 if (matchGroupId.find()) {
201 if (log.isDebugEnabled()) {
202 log.debug("Include " + project.getArtifactId());
203 }
204 return true;
205 }
206 } catch (PatternSyntaxException e) {
207 log.warn(String.format(INVALID_PATTERN_MESSAGE, includedArtifactPattern.pattern()));
208 }
209 }
210
211 return false;
212 }
213
214 protected boolean isExcludable(Artifact project, Pattern excludedGroupPattern, Pattern excludedArtifactPattern) {
215
216 Logger log = getLogger();
217
218 // check if the groupId of the project should be included
219 if (excludedGroupPattern != null) {
220 // we have some defined license filters
221 try {
222 Matcher matchGroupId = excludedGroupPattern.matcher(project.getGroupId());
223 if (matchGroupId.find()) {
224 if (log.isDebugEnabled()) {
225 log.debug("Exclude " + project.getGroupId());
226 }
227 return true;
228 }
229 } catch (PatternSyntaxException e) {
230 log.warn(String.format(INVALID_PATTERN_MESSAGE, excludedGroupPattern.pattern()));
231 }
232 }
233
234 // check if the artifactId of the project should be included
235 if (excludedArtifactPattern != null) {
236 // we have some defined license filters
237 try {
238 Matcher matchGroupId = excludedArtifactPattern.matcher(project.getArtifactId());
239 if (matchGroupId.find()) {
240 if (log.isDebugEnabled()) {
241 log.debug("Exclude " + project.getArtifactId());
242 }
243 return true;
244 }
245 } catch (PatternSyntaxException e) {
246 log.warn(String.format(INVALID_PATTERN_MESSAGE, excludedArtifactPattern.pattern()));
247 }
248 }
249
250 return false;
251 }
252 }