1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 package org.apache.maven.shared.dependency.graph.traversal; 20 21 import java.util.ArrayList; 22 import java.util.Stack; 23 24 import org.apache.maven.shared.dependency.graph.DependencyNode; 25 import org.apache.maven.shared.dependency.graph.internal.DefaultDependencyNode; 26 27 /** 28 * A dependency node visitor that clones visited nodes into a new dependency tree. This can be used in conjunction with 29 * a dependency node filter to construct subtrees. 30 * 31 * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a> 32 */ 33 public class BuildingDependencyNodeVisitor implements DependencyNodeVisitor { 34 // fields ----------------------------------------------------------------- 35 36 /** 37 * The dependency node visitor to apply on the resultant dependency tree, or <code>null</code> for none. 38 */ 39 private final DependencyNodeVisitor visitor; 40 41 /** 42 * The resultant tree parent nodes for the currently visited node. 43 */ 44 private final Stack<DependencyNode> parentNodes; 45 46 /** 47 * The root node of the resultant tree. 48 */ 49 private DependencyNode rootNode; 50 51 // constructors ----------------------------------------------------------- 52 53 /** 54 * Creates a dependency node visitor that clones visited nodes into a new dependency tree. 55 */ 56 public BuildingDependencyNodeVisitor() { 57 this(null); 58 } 59 60 /** 61 * Creates a dependency node visitor that clones visited nodes into a new dependency tree, and then applies the 62 * specified dependency node visitor on the resultant dependency tree. 63 * 64 * @param visitor the dependency node visitor to apply on the resultant dependency tree, or <code>null</code> for 65 * none 66 */ 67 public BuildingDependencyNodeVisitor(DependencyNodeVisitor visitor) { 68 this.visitor = visitor; 69 70 parentNodes = new Stack<>(); 71 } 72 73 // DependencyNodeVisitor methods ------------------------------------------ 74 75 /** 76 * {@inheritDoc} 77 */ 78 @Override 79 public boolean visit(DependencyNode node) { 80 // clone the node 81 DefaultDependencyNode newNode = new DefaultDependencyNode( 82 parentNodes.isEmpty() ? null : parentNodes.peek(), 83 node.getArtifact(), 84 node.getPremanagedVersion(), 85 node.getPremanagedScope(), 86 node.getVersionConstraint(), 87 node.getOptional(), 88 node.getExclusions()); 89 newNode.setChildren(new ArrayList<>()); 90 91 if (parentNodes.empty()) { 92 rootNode = newNode; 93 } else { 94 DependencyNode parentNode = parentNodes.peek(); 95 parentNode.getChildren().add(newNode); 96 } 97 98 parentNodes.push(newNode); 99 100 return true; 101 } 102 103 /** 104 * {@inheritDoc} 105 */ 106 @Override 107 public boolean endVisit(DependencyNode node) { 108 parentNodes.pop(); 109 110 // apply the visitor to the resultant tree on the last visit 111 if (parentNodes.empty() && visitor != null) { 112 rootNode.accept(visitor); 113 } 114 115 return true; 116 } 117 118 // public methods --------------------------------------------------------- 119 120 /** 121 * Gets the dependency node visitor that this visitor applies on the resultant dependency tree. 122 * 123 * @return the dependency node visitor, or <code>null</code> for none 124 */ 125 public DependencyNodeVisitor getDependencyNodeVisitor() { 126 return visitor; 127 } 128 129 /** 130 * Gets the root node of the resultant dependency tree constructed by this visitor. 131 * 132 * @return the root node, or <code>null</code> if the source tree has not yet been visited 133 */ 134 public DependencyNode getDependencyTree() { 135 return rootNode; 136 } 137 }