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 }