001 /*
002 * #%L
003 * License Maven Plugin
004 *
005 * $Id: DefaultDependenciesTool.java 14411 2011-08-10 22:09:34Z tchemit $
006 * $HeadURL: http://svn.codehaus.org/mojo/tags/license-maven-plugin-1.0/src/main/java/org/codehaus/mojo/license/DefaultDependenciesTool.java $
007 * %%
008 * Copyright (C) 2011 CodeLutin, Codehaus, Tony Chemit
009 * %%
010 * This program is free software: you can redistribute it and/or modify
011 * it under the terms of the GNU Lesser General Public License as
012 * published by the Free Software Foundation, either version 3 of the
013 * License, or (at your option) any later version.
014 *
015 * This program is distributed in the hope that it will be useful,
016 * but WITHOUT ANY WARRANTY; without even the implied warranty of
017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
018 * GNU General Lesser Public License for more details.
019 *
020 * You should have received a copy of the GNU General Lesser Public
021 * License along with this program. If not, see
022 * <http://www.gnu.org/licenses/lgpl-3.0.html>.
023 * #L%
024 */
025 package org.codehaus.mojo.license;
026
027 import org.apache.commons.collections.CollectionUtils;
028 import org.apache.commons.lang.StringUtils;
029 import org.apache.maven.artifact.Artifact;
030 import org.apache.maven.artifact.repository.ArtifactRepository;
031 import org.apache.maven.project.MavenProject;
032 import org.apache.maven.project.MavenProjectBuilder;
033 import org.apache.maven.project.ProjectBuildingException;
034 import org.codehaus.plexus.logging.AbstractLogEnabled;
035 import org.codehaus.plexus.logging.Logger;
036
037 import java.util.List;
038 import java.util.Set;
039 import java.util.SortedMap;
040 import java.util.TreeMap;
041 import java.util.regex.Matcher;
042 import java.util.regex.Pattern;
043 import java.util.regex.PatternSyntaxException;
044
045 /**
046 * Default implementation of the {@link DependenciesTool}.
047 *
048 * @author tchemit <chemit@codelutin.com>
049 * @version $Id: DefaultDependenciesTool.java 14411 2011-08-10 22:09:34Z tchemit $
050 * @plexus.component role="org.codehaus.mojo.license.DependenciesTool" role-hint="default"
051 * @since 1.0
052 */
053 public class DefaultDependenciesTool
054 extends AbstractLogEnabled
055 implements DependenciesTool
056 {
057
058 public static final String INVALID_PATTERN_MESSAGE =
059 "The pattern specified by expression <%s> seems to be invalid.";
060
061 /**
062 * Project builder.
063 *
064 * @plexus.requirement
065 */
066 private MavenProjectBuilder mavenProjectBuilder;
067
068 /**
069 * {@inheritDoc}
070 */
071 public SortedMap<String, MavenProject> loadProjectDependencies( MavenProject project,
072 MavenProjectDependenciesConfigurator configuration,
073 ArtifactRepository localRepository,
074 List<ArtifactRepository> remoteRepositories,
075 SortedMap<String, MavenProject> cache )
076 {
077
078 boolean haveNoIncludedGroups = StringUtils.isEmpty( configuration.getIncludedGroups() );
079 boolean haveNoIncludedArtifacts = StringUtils.isEmpty( configuration.getIncludedArtifacts() );
080
081 boolean haveExcludedGroups = StringUtils.isNotEmpty( configuration.getExcludedGroups() );
082 boolean haveExcludedArtifacts = StringUtils.isNotEmpty( configuration.getExcludedArtifacts() );
083 boolean haveExclusions = haveExcludedGroups || haveExcludedArtifacts;
084
085 Pattern includedGroupPattern = null;
086 Pattern includedArtifactPattern = null;
087 Pattern excludedGroupPattern = null;
088 Pattern excludedArtifactPattern = null;
089
090 if ( !haveNoIncludedGroups )
091 {
092 includedGroupPattern = Pattern.compile( configuration.getIncludedGroups() );
093 }
094 if ( !haveNoIncludedArtifacts )
095 {
096 includedArtifactPattern = Pattern.compile( configuration.getIncludedArtifacts() );
097 }
098 if ( haveExcludedGroups )
099 {
100 excludedGroupPattern = Pattern.compile( configuration.getExcludedGroups() );
101 }
102 if ( haveExcludedArtifacts )
103 {
104 excludedArtifactPattern = Pattern.compile( configuration.getExcludedArtifacts() );
105 }
106
107 Set<?> depArtifacts;
108
109 if ( configuration.isIncludeTransitiveDependencies() )
110 {
111 // All project dependencies
112 depArtifacts = project.getArtifacts();
113 }
114 else
115 {
116 // Only direct project dependencies
117 depArtifacts = project.getDependencyArtifacts();
118 }
119
120 List<String> includedScopes = configuration.getIncludedScopes();
121 List<String> excludeScopes = configuration.getExcludedScopes();
122
123 boolean verbose = configuration.isVerbose();
124
125 SortedMap<String, MavenProject> result = new TreeMap<String, MavenProject>();
126
127 for ( Object o : depArtifacts )
128 {
129 Artifact artifact = (Artifact) o;
130
131 String scope = artifact.getScope();
132 if ( CollectionUtils.isNotEmpty( includedScopes ) && !includedScopes.contains( scope ) )
133 {
134
135 // not in included scopes
136 continue;
137 }
138 {
139 if ( excludeScopes.contains( scope ) )
140 {
141
142 // in exluced scopes
143 continue;
144 }
145 }
146
147 Logger log = getLogger();
148
149 String id = MojoHelper.getArtifactId( artifact );
150
151 if ( verbose )
152 {
153 log.info( "detected artifact " + id );
154 }
155
156 // Check if the project should be included
157 // If there is no specified artifacts and group to include, include all
158 boolean isToInclude = haveNoIncludedArtifacts && haveNoIncludedGroups ||
159 isIncludable( artifact, includedGroupPattern, includedArtifactPattern );
160
161 // Check if the project should be excluded
162 boolean isToExclude = isToInclude && haveExclusions &&
163 isExcludable( artifact, excludedGroupPattern, excludedArtifactPattern );
164
165 if ( !isToInclude || isToExclude )
166 {
167 if ( verbose )
168 {
169 log.info( "skip artifact " + id );
170 }
171 continue;
172 }
173
174 MavenProject depMavenProject = null;
175
176 if ( cache != null )
177 {
178
179 // try to get project from cache
180 depMavenProject = cache.get( id );
181 }
182
183 if ( depMavenProject != null )
184 {
185 if ( verbose )
186 {
187 log.info( "add dependency [" + id + "] (from cache)" );
188 }
189 }
190 else
191 {
192
193 // build project
194
195 try
196 {
197 depMavenProject =
198 mavenProjectBuilder.buildFromRepository( artifact, remoteRepositories, localRepository, true );
199 }
200 catch ( ProjectBuildingException e )
201 {
202 log.warn( "Unable to obtain POM for artifact : " + artifact, e );
203 continue;
204 }
205
206 if ( verbose )
207 {
208 log.info( "add dependency [" + id + "]" );
209 }
210 if ( cache != null )
211 {
212
213 // store it also in cache
214 cache.put( id, depMavenProject );
215 }
216 }
217
218 // keep the project
219 result.put( id, depMavenProject );
220 }
221
222 return result;
223 }
224
225 protected boolean isIncludable( Artifact project, Pattern includedGroupPattern, Pattern includedArtifactPattern )
226 {
227
228 Logger log = getLogger();
229
230 // check if the groupId of the project should be included
231 if ( includedGroupPattern != null )
232 {
233 // we have some defined license filters
234 try
235 {
236 Matcher matchGroupId = includedGroupPattern.matcher( project.getGroupId() );
237 if ( matchGroupId.find() )
238 {
239 if ( log.isDebugEnabled() )
240 {
241 log.debug( "Include " + project.getGroupId() );
242 }
243 return true;
244 }
245 }
246 catch ( PatternSyntaxException e )
247 {
248 log.warn( String.format( INVALID_PATTERN_MESSAGE, includedGroupPattern.pattern() ) );
249 }
250 }
251
252 // check if the artifactId of the project should be included
253 if ( includedArtifactPattern != null )
254 {
255 // we have some defined license filters
256 try
257 {
258 Matcher matchGroupId = includedArtifactPattern.matcher( project.getArtifactId() );
259 if ( matchGroupId.find() )
260 {
261 if ( log.isDebugEnabled() )
262 {
263 log.debug( "Include " + project.getArtifactId() );
264 }
265 return true;
266 }
267 }
268 catch ( PatternSyntaxException e )
269 {
270 log.warn( String.format( INVALID_PATTERN_MESSAGE, includedArtifactPattern.pattern() ) );
271 }
272 }
273
274 return false;
275 }
276
277 protected boolean isExcludable( Artifact project, Pattern excludedGroupPattern, Pattern excludedArtifactPattern )
278 {
279
280 Logger log = getLogger();
281
282 // check if the groupId of the project should be included
283 if ( excludedGroupPattern != null )
284 {
285 // we have some defined license filters
286 try
287 {
288 Matcher matchGroupId = excludedGroupPattern.matcher( project.getGroupId() );
289 if ( matchGroupId.find() )
290 {
291 if ( log.isDebugEnabled() )
292 {
293 log.debug( "Exclude " + project.getGroupId() );
294 }
295 return true;
296 }
297 }
298 catch ( PatternSyntaxException e )
299 {
300 log.warn( String.format( INVALID_PATTERN_MESSAGE, excludedGroupPattern.pattern() ) );
301 }
302 }
303
304 // check if the artifactId of the project should be included
305 if ( excludedArtifactPattern != null )
306 {
307 // we have some defined license filters
308 try
309 {
310 Matcher matchGroupId = excludedArtifactPattern.matcher( project.getArtifactId() );
311 if ( matchGroupId.find() )
312 {
313 if ( log.isDebugEnabled() )
314 {
315 log.debug( "Exclude " + project.getArtifactId() );
316 }
317 return true;
318 }
319 }
320 catch ( PatternSyntaxException e )
321 {
322 log.warn( String.format( INVALID_PATTERN_MESSAGE, excludedArtifactPattern.pattern() ) );
323 }
324 }
325
326 return false;
327 }
328 }