001 /*
002 * Licensed under the Apache License, Version 2.0 (the "License");
003 * you may not use this file except in compliance with the License.
004 * You may obtain a copy of the License at
005 *
006 * http://www.apache.org/licenses/LICENSE-2.0
007 *
008 * Unless required by applicable law or agreed to in writing, software
009 * distributed under the License is distributed on an "AS IS" BASIS,
010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011 * See the License for the specific language governing permissions and
012 * limitations under the License.
013 */
014 /*
015 * This file has been modified by Chris Pheby in accordance with Section 4.2
016 * of the Apache Software License
017 */
018 package org.jadira.dependencynavigator.assembler;
019
020 import java.util.ArrayList;
021 import java.util.Collections;
022 import java.util.HashMap;
023 import java.util.Iterator;
024 import java.util.List;
025 import java.util.Map;
026
027 import org.apache.maven.artifact.Artifact;
028 import org.apache.maven.artifact.factory.ArtifactFactory;
029 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
030 import org.apache.maven.artifact.versioning.VersionRange;
031 import org.apache.maven.model.Dependency;
032 import org.apache.maven.model.Model;
033 import org.apache.maven.model.Parent;
034 import org.apache.maven.project.ModelUtils;
035 import org.apache.maven.project.inheritance.ModelInheritanceAssembler;
036 import org.apache.maven.project.interpolation.ModelInterpolationException;
037 import org.apache.maven.project.interpolation.ModelInterpolator;
038 import org.jadira.dependencynavigator.implementations.Repository;
039
040 /**
041 * Provides pom inheritance & properties support
042 */
043 public class Assembler {
044
045 public static final String ROLE = "org.jadira.dependencynavigator.assembler.Assembler";
046
047 private ModelInheritanceAssembler assembler;
048 private ModelInterpolator interpolator;
049 private ArtifactFactory artifactFactory;
050
051 /**
052 * create a list of pom parents starting with the raw pom
053 */
054 private void lookupLineage(Model child, Repository repository, List<Model> lineage) {
055 if (child == null) {
056 return;
057 }
058 lineage.add(child);
059 Parent parentStub = child.getParent();
060 if (parentStub == null) {
061 return;
062 }
063 Model parent = repository.resolveFile(parentStub.getGroupId(), parentStub.getArtifactId(), parentStub.getVersion());
064 lookupLineage(parent, repository, lineage);
065 }
066
067 /**
068 * work down the pom parents, merging the the parent into the child
069 */
070 private Model assemble(Model parent, List<Model> lineage, Repository repository) {
071 if (lineage.size() == 0) {
072 return parent;
073 }
074 Model child = (Model) lineage.remove(0);
075 assembler.assembleModelInheritance(child, parent);
076 return assemble(child, lineage, repository);
077 }
078
079 private Model dependencyManagement(Model interpolated) throws AssemblerException {
080 try {
081 if (interpolated.getDependencyManagement() == null) {
082 return interpolated;
083 }
084 Model managed = ModelUtils.cloneModel(interpolated);
085 Map<String, Dependency> managees = new HashMap<String, Dependency>();
086 for (Iterator<Dependency> iter = managed.getDependencies().iterator(); iter.hasNext();) {
087 Dependency dependency = (Dependency) iter.next();
088 managees.put(dependency.getGroupId() + ":" + dependency.getArtifactId(), dependency);
089 }
090 for (Iterator<Dependency> iter = interpolated.getDependencyManagement().getDependencies().iterator(); iter.hasNext();) {
091 Dependency manager = (Dependency) iter.next();
092 VersionRange versionRange = VersionRange.createFromVersionSpec(manager.getVersion());
093 Artifact artifact = artifactFactory.createDependencyArtifact(manager.getGroupId(), manager.getArtifactId(), versionRange, manager.getType(), manager.getClassifier(), manager
094 .getScope(), manager.isOptional());
095 Dependency managee = (Dependency) managees.get(manager.getGroupId() + ":" + manager.getArtifactId());
096 if (managee != null) {
097 managee.setVersion(artifact.getVersion());
098 }
099 }
100 return managed;
101 } catch (InvalidVersionSpecificationException e) {
102 throw new AssemblerException(e);
103 }
104 }
105
106 public AssembledModel assemble(Model raw, Repository repository) throws AssemblerException {
107 try {
108 List<Model> lineage = new ArrayList<Model>();
109 lookupLineage(raw, repository, lineage);
110 Collections.reverse(lineage);
111 Model root = (Model) lineage.remove(0);
112 Model assembled = assemble(root, lineage, repository);
113 Model interpolated = interpolator.interpolate(assembled, new HashMap<String, Object>());
114 Model managed = dependencyManagement(interpolated);
115 return new AssembledModel(managed);
116 } catch (ModelInterpolationException e) {
117 throw new AssemblerException(e);
118 }
119 }
120 }