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 }