Coverage Report - org.apache.maven.archiva.dependency.graph.tasks.DependencyManagementApplier
 
Classes in this File Line Coverage Branch Coverage Complexity
DependencyManagementApplier
0%
0/62
0%
0/16
0
 
 1  
 package org.apache.maven.archiva.dependency.graph.tasks;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *  http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import java.util.HashMap;
 23  
 import java.util.Map;
 24  
 
 25  
 import org.apache.commons.lang.StringUtils;
 26  
 import org.apache.maven.archiva.dependency.graph.DependencyGraph;
 27  
 import org.apache.maven.archiva.dependency.graph.DependencyGraphBuilder;
 28  
 import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
 29  
 import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
 30  
 import org.apache.maven.archiva.dependency.graph.DependencyGraphUtils;
 31  
 import org.apache.maven.archiva.dependency.graph.tasks.DependencyManagementStack.Rules;
 32  
 import org.apache.maven.archiva.dependency.graph.walk.BaseVisitor;
 33  
 import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphVisitor;
 34  
 import org.apache.maven.archiva.model.ArtifactReference;
 35  
 import org.apache.maven.archiva.model.VersionedReference;
 36  
 
 37  
 /**
 38  
  * Takes a stack of DependencyManagement objects and applies them to the node in question.
 39  
  * This merely sets the version / scope / and exclusions on the nodes, as defined by DependencyManagement.
 40  
  * 
 41  
  * @version $Id: DependencyManagementApplier.java 755277 2009-03-17 15:18:35Z brett $
 42  
  */
 43  0
 public class DependencyManagementApplier
 44  
     extends BaseVisitor
 45  
     implements DependencyGraphVisitor
 46  
 {
 47  0
     private DependencyManagementStack depStack = new DependencyManagementStack();
 48  
 
 49  
     private DependencyGraphBuilder builder;
 50  
 
 51  
     /**
 52  
      * Map of changes to node versions (that will likely cause a reorganization of
 53  
      * the graph), this is tracked until the walk is complete, at which point the
 54  
      * changes are applied to the graph.
 55  
      * 
 56  
      * Performing graph changes of this scope during a walk of graph is hazardous,
 57  
      * as you will be moving nodes around, mergeing nodes, dropping edges, etc.
 58  
      */
 59  0
     private Map<ArtifactReference, String> nodeVersionChanges = new HashMap<ArtifactReference, String>();
 60  
 
 61  0
     private int nodesAdded = 0;
 62  
 
 63  
     public void discoverGraph( DependencyGraph graph )
 64  
     {
 65  0
         super.discoverGraph( graph );
 66  0
         nodeVersionChanges.clear();
 67  0
         depStack.reset();
 68  0
         nodesAdded = 0;
 69  0
     }
 70  
 
 71  
     public void discoverNode( DependencyGraphNode node )
 72  
     {
 73  0
         super.discoverNode( node );
 74  
 
 75  0
         depStack.push( node );
 76  
 
 77  0
         for ( DependencyGraphEdge edge : graph.getEdgesFrom( node ) )
 78  
         {
 79  0
             Rules rules = depStack.getRules( edge );
 80  
 
 81  0
             if ( rules == null )
 82  
             {
 83  
                 // No rules for edge, skip it.
 84  0
                 continue;
 85  
             }
 86  
 
 87  0
             DependencyGraphNode subnode = graph.getNode( edge.getNodeTo() );
 88  
 
 89  
             /* There are 3 steps to processing the DependencyManagement. */
 90  
 
 91  
             /* 1) Add exclusions to node ________________________________________________ */
 92  0
             node.getExcludes().addAll( rules.exclusions );
 93  
 
 94  
             /* 2) Track version changes to node _________________________________________ */
 95  
 
 96  
             // This is the version as specified by the rules.
 97  0
             String specifiedVersion = rules.artifact.getVersion();
 98  
 
 99  
             // This is the version as being tracked by the nodeVersionChanges map.
 100  0
             String trackedVersion = (String) nodeVersionChanges.get( edge.getNodeTo() );
 101  
 
 102  
             // This is the version of the subnode. 
 103  0
             String nodeVersion = subnode.getArtifact().getVersion();
 104  
 
 105  
             // This is the actual version as determined by tracked and subnode
 106  0
             String actualVersion = StringUtils.defaultString( trackedVersion, nodeVersion );
 107  
 
 108  
             // If the specified version changes the actual version ...
 109  0
             if ( !StringUtils.equals( specifiedVersion, actualVersion ) )
 110  
             {
 111  
                 // ... save this new value to be track ( for processing in #finishedGraph )
 112  0
                 nodeVersionChanges.put( edge.getNodeTo(), specifiedVersion );
 113  
             }
 114  
 
 115  
             /* 3) Update scope to edge __________________________________________________ */
 116  
 
 117  0
             if ( StringUtils.isNotBlank( rules.scope ) )
 118  
             {
 119  0
                 edge.setScope( rules.scope );
 120  
             }
 121  0
         }
 122  0
     }
 123  
 
 124  
     public void finishNode( DependencyGraphNode node )
 125  
     {
 126  0
         super.finishNode( node );
 127  
 
 128  0
         depStack.pop();
 129  0
     }
 130  
 
 131  
     public void finishGraph( DependencyGraph graph )
 132  
     {
 133  0
         super.finishGraph( graph );
 134  
 
 135  0
         for ( ArtifactReference ref : this.nodeVersionChanges.keySet() )
 136  
         {
 137  0
             String toVersion = this.nodeVersionChanges.get( ref );
 138  
 
 139  0
             collapseVersions( graph, ref, ref.getVersion(), toVersion );
 140  0
         }
 141  0
     }
 142  
 
 143  
     /**
 144  
      * Collapses Versions of nodes.
 145  
      * 
 146  
      * Takes two nodes, with differing versions.
 147  
      * 
 148  
      * 1) Removes the FROM edges connected to the FROM node
 149  
      * 2) Moves the TO edges connected to the FROM node to the TO node.
 150  
      * 3) Removes the FROM node (which is now orphaned)  
 151  
      *  
 152  
      * @param graph the graph to perform operation on
 153  
      * @param fromRef the artifact reference of the FROM node.
 154  
      * @param fromVersion the version of the FROM node
 155  
      * @param toVersion the version of the TO node
 156  
      */
 157  
     private void collapseVersions( DependencyGraph graph, ArtifactReference fromRef, String fromVersion,
 158  
                                    String toVersion )
 159  
     {
 160  0
         if ( StringUtils.equals( fromVersion, toVersion ) )
 161  
         {
 162  
             // No point in doing anything.  nothing has changed.
 163  0
             return;
 164  
         }
 165  
 
 166  0
         ArtifactReference toRef = new ArtifactReference();
 167  0
         toRef.setGroupId( fromRef.getGroupId() );
 168  0
         toRef.setArtifactId( fromRef.getArtifactId() );
 169  0
         toRef.setVersion( toVersion );
 170  0
         toRef.setClassifier( fromRef.getClassifier() );
 171  0
         toRef.setType( fromRef.getType() );
 172  
 
 173  0
         DependencyGraphNode nodeFROM = graph.getNode( fromRef );
 174  0
         DependencyGraphNode nodeTO = graph.getNode( toRef );
 175  
 
 176  0
         if ( nodeTO == null )
 177  
         {
 178  
             // new node doesn't exist in graph (yet)
 179  0
             nodeTO = new DependencyGraphNode( toRef );
 180  0
             nodeTO.setResolved( false );
 181  
 
 182  0
             graph.addNode( nodeTO );
 183  
 
 184  0
             VersionedReference projectRef = new VersionedReference();
 185  0
             projectRef.setGroupId( toRef.getGroupId() );
 186  0
             projectRef.setArtifactId( toRef.getArtifactId() );
 187  0
             projectRef.setVersion( toRef.getVersion() );
 188  
 
 189  0
             builder.resolveNode( graph, nodeTO, projectRef );
 190  0
             nodesAdded++;
 191  
         }
 192  
 
 193  0
         DependencyGraphUtils.collapseNodes( graph, nodeFROM, nodeTO );
 194  0
     }
 195  
 
 196  
     public DependencyGraphBuilder getBuilder()
 197  
     {
 198  0
         return builder;
 199  
     }
 200  
 
 201  
     public void setBuilder( DependencyGraphBuilder builder )
 202  
     {
 203  0
         this.builder = builder;
 204  0
     }
 205  
 
 206  
     public boolean hasCreatedNodes()
 207  
     {
 208  0
         return ( nodesAdded > 0 );
 209  
     }
 210  
 }