1 package org.apache.maven.shared.dependency.graph.traversal;
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.ArrayList;
23 import java.util.Stack;
24
25 import org.apache.maven.shared.dependency.graph.DependencyNode;
26 import org.apache.maven.shared.dependency.graph.internal.DefaultDependencyNode;
27
28 /**
29 * A dependency node visitor that clones visited nodes into a new dependency tree. This can be used in conjunction with
30 * a dependency node filter to construct subtrees.
31 *
32 * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
33 */
34 public class BuildingDependencyNodeVisitor
35 implements DependencyNodeVisitor
36 {
37 // fields -----------------------------------------------------------------
38
39 /**
40 * The dependency node visitor to apply on the resultant dependency tree, or <code>null</code> for none.
41 */
42 private final DependencyNodeVisitor visitor;
43
44 /**
45 * The resultant tree parent nodes for the currently visited node.
46 */
47 private final Stack<DependencyNode> parentNodes;
48
49 /**
50 * The root node of the resultant tree.
51 */
52 private DependencyNode rootNode;
53
54 // constructors -----------------------------------------------------------
55
56 /**
57 * Creates a dependency node visitor that clones visited nodes into a new dependency tree.
58 */
59 public BuildingDependencyNodeVisitor()
60 {
61 this( null );
62 }
63
64 /**
65 * Creates a dependency node visitor that clones visited nodes into a new dependency tree, and then applies the
66 * specified dependency node visitor on the resultant dependency tree.
67 *
68 * @param visitor
69 * the dependency node visitor to apply on the resultant dependency tree, or <code>null</code> for none
70 */
71 public BuildingDependencyNodeVisitor( DependencyNodeVisitor visitor )
72 {
73 this.visitor = visitor;
74
75 parentNodes = new Stack<DependencyNode>();
76 }
77
78 // DependencyNodeVisitor methods ------------------------------------------
79
80 /**
81 * {@inheritDoc}
82 */
83 public boolean visit( DependencyNode node )
84 {
85 // clone the node
86 DefaultDependencyNode newNode =
87 new DefaultDependencyNode( parentNodes.isEmpty() ? null : parentNodes.peek(), node.getArtifact(),
88 node.getPremanagedVersion(), node.getPremanagedScope(),
89 node.getVersionConstraint() );
90 newNode.setChildren( new ArrayList<DependencyNode>() );
91
92 if ( parentNodes.empty() )
93 {
94 rootNode = newNode;
95 }
96 else
97 {
98 DependencyNode parentNode = parentNodes.peek();
99 parentNode.getChildren().add( newNode );
100 }
101
102 parentNodes.push( newNode );
103
104 return true;
105 }
106
107 /**
108 * {@inheritDoc}
109 */
110 public boolean endVisit( DependencyNode node )
111 {
112 parentNodes.pop();
113
114 // apply the visitor to the resultant tree on the last visit
115 if ( parentNodes.empty() && visitor != null )
116 {
117 rootNode.accept( visitor );
118 }
119
120 return true;
121 }
122
123 // public methods ---------------------------------------------------------
124
125 /**
126 * Gets the dependency node visitor that this visitor applies on the resultant dependency tree.
127 *
128 * @return the dependency node visitor, or <code>null</code> for none
129 */
130 public DependencyNodeVisitor getDependencyNodeVisitor()
131 {
132 return visitor;
133 }
134
135 /**
136 * Gets the root node of the resultant dependency tree constructed by this visitor.
137 *
138 * @return the root node, or <code>null</code> if the source tree has not yet been visited
139 */
140 public DependencyNode getDependencyTree()
141 {
142 return rootNode;
143 }
144 }