| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.maven.plugins.assembly.utils; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.LinkedHashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.apache.maven.artifact.Artifact; |
| import org.apache.maven.project.MavenProject; |
| import org.slf4j.Logger; |
| |
| /** |
| * |
| */ |
| public final class ProjectUtils { |
| |
| private ProjectUtils() {} |
| |
| public static String getClassifier(Artifact artifact) { |
| String classifier = artifact.getClassifier(); |
| if (classifier != null && classifier.length() == 0) { |
| classifier = null; |
| } |
| return classifier; |
| } |
| |
| public static Set<MavenProject> getProjectModules( |
| final MavenProject project, |
| final List<MavenProject> reactorProjects, |
| final boolean includeSubModules, |
| final Logger logger) |
| throws IOException { |
| final Set<MavenProject> singleParentSet = Collections.singleton(project); |
| |
| final Set<MavenProject> moduleCandidates = new LinkedHashSet<>(reactorProjects); |
| |
| final Set<MavenProject> modules = new LinkedHashSet<>(); |
| |
| // we temporarily add the master project to the modules set, since this |
| // set is pulling double duty as a set of |
| // potential module parents in the tree rooted at the master |
| // project...this allows us to use the same looping |
| // algorithm below to discover both direct modules of the master project |
| // AND modules of those direct modules. |
| modules.add(project); |
| |
| int changed; |
| |
| do { |
| changed = 0; |
| |
| for (final Iterator<MavenProject> candidateIterator = moduleCandidates.iterator(); |
| candidateIterator.hasNext(); ) { |
| final MavenProject moduleCandidate = candidateIterator.next(); |
| |
| if (moduleCandidate.getFile() == null) { |
| logger.warn("Cannot compute whether " + moduleCandidate.getId() + " is a module of: " |
| + project.getId() + "; it does not have an associated POM file on the local filesystem."); |
| continue; |
| } |
| |
| Set<MavenProject> currentPotentialParents; |
| if (includeSubModules) { |
| currentPotentialParents = new LinkedHashSet<>(modules); |
| } else { |
| currentPotentialParents = singleParentSet; |
| } |
| |
| for (final MavenProject potentialParent : currentPotentialParents) { |
| if (potentialParent.getFile() == null) { |
| logger.warn("Cannot use: " + moduleCandidate.getId() |
| + " as a potential module-parent while computing the module set for: " |
| + project.getId() |
| + "; it does not have an associated POM file on the local filesystem."); |
| continue; |
| } |
| |
| // if this parent has an entry for the module candidate in |
| // the path adjustments map, it's a direct |
| // module of that parent. |
| if (projectContainsModule(potentialParent, moduleCandidate)) { |
| // add the candidate to the list of modules (and |
| // potential parents) |
| modules.add(moduleCandidate); |
| |
| // remove the candidate from the candidate pool, because |
| // it's been verified. |
| candidateIterator.remove(); |
| |
| // increment the change counter, to show that we |
| // verified a new module on this pass. |
| changed++; |
| |
| // We need to move on to the next candidate since this one was just verified |
| break; |
| } |
| } |
| } |
| } while (changed != 0); |
| |
| // remove the master project from the modules set, now that we're done |
| // using it as a set of potential module |
| // parents... |
| modules.remove(project); |
| |
| return modules; |
| } |
| |
| private static boolean projectContainsModule(final MavenProject mainProject, final MavenProject moduleProject) |
| throws IOException { |
| final List<String> modules = mainProject.getModules(); |
| final File basedir = mainProject.getBasedir(); |
| |
| final File moduleFile = moduleProject.getFile().getCanonicalFile(); |
| |
| File moduleBasedir = moduleProject.getBasedir(); |
| |
| if (moduleBasedir == null) { |
| moduleBasedir = moduleFile.getParentFile(); |
| |
| if (moduleBasedir == null) { |
| moduleBasedir = new File("."); |
| } |
| } |
| |
| moduleBasedir = moduleBasedir.getCanonicalFile(); |
| |
| for (final String moduleSubpath : modules) { |
| final File moduleDir = new File(basedir, moduleSubpath).getCanonicalFile(); |
| |
| if (moduleDir.equals(moduleFile) || moduleDir.equals(moduleBasedir)) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| } |