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 // not in included scopes 111 continue; 112 } 113 if (excludeScopes.contains(scope)) { 114 // in excluded scopes 115 continue; 116 } 117 118 Logger log = getLogger(); 119 120 String id = MojoHelper.getArtifactId(artifact); 121 122 if (verbose) { 123 log.info("detected artifact " + id); 124 } 125 126 // Check if the project should be included 127 // If there is no specified artifacts and group to include, include all 128 boolean isToInclude = haveNoIncludedArtifacts && haveNoIncludedGroups 129 || isIncludable(artifact, includedGroupPattern, includedArtifactPattern); 130 131 // Check if the project should be excluded 132 boolean isToExclude = isToInclude && haveExclusions 133 && isExcludable(artifact, excludedGroupPattern, excludedArtifactPattern); 134 135 if (!isToInclude || isToExclude) { 136 if (verbose) { 137 log.info("skip artifact " + id); 138 } 139 continue; 140 } 141 142 MavenProject depMavenProject = null; 143 144 if (cache != null) { 145 146 // try to get project from cache 147 depMavenProject = cache.get(id); 148 } 149 150 if (depMavenProject != null) { 151 if (verbose) { 152 log.info("add dependency [" + id + "] (from cache)"); 153 } 154 } else { 155 // build project 156 try { 157 depMavenProject = mavenProjectBuilder.buildFromRepository(artifact, remoteRepositories, 158 localRepository, true); 159 } catch (ProjectBuildingException e) { 160 log.warn("Unable to obtain POM for artifact : " + artifact, e); 161 continue; 162 } 163 164 if (verbose) { 165 log.info("add dependency [" + id + "]"); 166 } 167 if (cache != null) { 168 // store it also in cache 169 cache.put(id, depMavenProject); 170 } 171 } 172 173 // keep the project 174 result.put(id, depMavenProject); 175 } 176 177 return result; 178 } 179 180 protected boolean isIncludable(Artifact project, Pattern includedGroupPattern, Pattern includedArtifactPattern) { 181 182 Logger log = getLogger(); 183 184 // check if the groupId of the project should be included 185 if (includedGroupPattern != null) { 186 // we have some defined license filters 187 try { 188 Matcher matchGroupId = includedGroupPattern.matcher(project.getGroupId()); 189 if (matchGroupId.find()) { 190 if (log.isDebugEnabled()) { 191 log.debug("Include " + project.getGroupId()); 192 } 193 return true; 194 } 195 } catch (PatternSyntaxException e) { 196 log.warn(String.format(INVALID_PATTERN_MESSAGE, includedGroupPattern.pattern())); 197 } 198 } 199 200 // check if the artifactId of the project should be included 201 if (includedArtifactPattern != null) { 202 // we have some defined license filters 203 try { 204 Matcher matchGroupId = includedArtifactPattern.matcher(project.getArtifactId()); 205 if (matchGroupId.find()) { 206 if (log.isDebugEnabled()) { 207 log.debug("Include " + project.getArtifactId()); 208 } 209 return true; 210 } 211 } catch (PatternSyntaxException e) { 212 log.warn(String.format(INVALID_PATTERN_MESSAGE, includedArtifactPattern.pattern())); 213 } 214 } 215 216 return false; 217 } 218 219 protected boolean isExcludable(Artifact project, Pattern excludedGroupPattern, Pattern excludedArtifactPattern) { 220 221 Logger log = getLogger(); 222 223 // check if the groupId of the project should be included 224 if (excludedGroupPattern != null) { 225 // we have some defined license filters 226 try { 227 Matcher matchGroupId = excludedGroupPattern.matcher(project.getGroupId()); 228 if (matchGroupId.find()) { 229 if (log.isDebugEnabled()) { 230 log.debug("Exclude " + project.getGroupId()); 231 } 232 return true; 233 } 234 } catch (PatternSyntaxException e) { 235 log.warn(String.format(INVALID_PATTERN_MESSAGE, excludedGroupPattern.pattern())); 236 } 237 } 238 239 // check if the artifactId of the project should be included 240 if (excludedArtifactPattern != null) { 241 // we have some defined license filters 242 try { 243 Matcher matchGroupId = excludedArtifactPattern.matcher(project.getArtifactId()); 244 if (matchGroupId.find()) { 245 if (log.isDebugEnabled()) { 246 log.debug("Exclude " + project.getArtifactId()); 247 } 248 return true; 249 } 250 } catch (PatternSyntaxException e) { 251 log.warn(String.format(INVALID_PATTERN_MESSAGE, excludedArtifactPattern.pattern())); 252 } 253 } 254 255 return false; 256 } 257 }