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 }