1 /**
2 * Copyright 2011-2012 The Kuali Foundation
3 *
4 * Licensed under the Educational Community License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/ecl2.php
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.kuali.maven.plugins.graph.sanitize;
17
18 import static org.kuali.maven.plugins.graph.pojo.State.CONFLICT;
19 import static org.kuali.maven.plugins.graph.pojo.State.DUPLICATE;
20
21 import java.util.List;
22
23 import org.apache.maven.artifact.Artifact;
24 import org.apache.maven.shared.dependency.tree.DependencyNode;
25 import org.kuali.maven.plugins.graph.pojo.MavenContext;
26 import org.kuali.maven.plugins.graph.pojo.State;
27 import org.kuali.maven.plugins.graph.tree.Node;
28 import org.kuali.maven.plugins.graph.tree.TreeHelper;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31 import org.springframework.util.Assert;
32
33 /**
34 * <p>
35 * Nothing in this sanitizer takes into account the overall build tree. It only performs checks on individual nodes.
36 * </p>
37 *
38 * <p>
39 * Checks that nodes marked as <code>State.DUPLICATE</code> have 'related' artifacts identical to the main artifact
40 * stored at that node. Also checks to make sure nodes marked as <code>State.CONFLICT</code> have a 'related' artifact
41 * that is a different version from the main artifact stored at that node.
42 * </p>
43 *
44 * <p>
45 * Any <code>State.DUPLICATE</code> node that does not have an identical related artifact is switched to
46 * <code>State.CONFLICT</code>
47 * </p>
48 *
49 * <p>
50 * Any <code>State.CONFLICT</code> node that has an identical related artifact is switched to
51 * <code>State.DUPLICATE</code>
52 * </p>
53 *
54 * @author jeffcaddel
55 */
56 public class RelatedArtifactSanitizer implements NodeSanitizer<MavenContext> {
57 private static final Logger logger = LoggerFactory.getLogger(RelatedArtifactSanitizer.class);
58 TreeHelper helper = new TreeHelper();
59
60 @Override
61 public void sanitize(Node<MavenContext> node) {
62 // Extract anything Maven has marked as a duplicate or conflict
63 List<MavenContext> contexts = helper.getList(node, DUPLICATE, CONFLICT);
64 for (MavenContext context : contexts) {
65 // Restore sanity
66 sanitize(context);
67
68 }
69 }
70
71 protected void sanitize(MavenContext context) {
72 DependencyNode dn = context.getDependencyNode();
73 // The validation logic assures that artifact and related are not null for conflicts and duplicates
74 Artifact artifact = dn.getArtifact();
75 Artifact related = dn.getRelatedArtifact();
76 State state = State.getState(dn.getState());
77
78 // Test them to see if they are exactly the same or just similar
79 boolean equal = helper.equals(artifact, related);
80 boolean similar = helper.similar(artifact, related);
81
82 // The validation logic assures that at least one is true, but no harm in double checking
83 Assert.isTrue(equal || similar, "Invalid state.");
84
85 if (equal) {
86 // The main artifact and related artifact are exactly the same
87 if (state == CONFLICT) {
88 // Maven told us this was a CONFLICT, yet the artifacts are exactly the same.
89 // WTF is up with that? The only thing it is possible to do at this point is
90 // switch this artifact out WITH THE EXACT SAME ARTIFACT!!! How is that a conflict?
91 logger.info(CONFLICT + "->" + DUPLICATE + " " + artifact);
92 }
93 // Set state to duplicate and make sure replacement is nulled out
94 context.setState(DUPLICATE);
95 context.setReplacement(null);
96 } else if (similar) {
97 // The main artifact and related artifact are NOT exactly the same, but they differ only by version
98 if (state == DUPLICATE) {
99 // Maven told us this was a DUPLICATE, yet the related artifact is a different version
100 // We are going to assume the duplicate flag is a mistake and re-flag this as a conflict
101 logger.info(DUPLICATE + "->" + CONFLICT + " " + artifact);
102 }
103 // Set state to conflict, and store the artifact Maven replaced it with
104 context.setState(CONFLICT);
105 context.setReplacement(related);
106 } else {
107 // Something has gone horribly wrong
108 Assert.isTrue(false, "Invalid state");
109 }
110 }
111
112 }