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 the dependency node visitor to apply on the resultant dependency tree, or <code>null</code> for
69 * 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 @Override
84 public boolean visit( DependencyNode node )
85 {
86 // clone the node
87 DefaultDependencyNode newNode =
88 new DefaultDependencyNode( parentNodes.isEmpty() ? null : parentNodes.peek(), node.getArtifact(),
89 node.getPremanagedVersion(), node.getPremanagedScope(),
90 node.getVersionConstraint(),
91 node.getOptional() );
92 newNode.setChildren( new ArrayList<DependencyNode>() );
93
94 if ( parentNodes.empty() )
95 {
96 rootNode = newNode;
97 }
98 else
99 {
100 DependencyNode parentNode = parentNodes.peek();
101 parentNode.getChildren().add( newNode );
102 }
103
104 parentNodes.push( newNode );
105
106 return true;
107 }
108
109 /**
110 * {@inheritDoc}
111 */
112 @Override
113 public boolean endVisit( DependencyNode node )
114 {
115 parentNodes.pop();
116
117 // apply the visitor to the resultant tree on the last visit
118 if ( parentNodes.empty() && visitor != null )
119 {
120 rootNode.accept( visitor );
121 }
122
123 return true;
124 }
125
126 // public methods ---------------------------------------------------------
127
128 /**
129 * Gets the dependency node visitor that this visitor applies on the resultant dependency tree.
130 *
131 * @return the dependency node visitor, or <code>null</code> for none
132 */
133 public DependencyNodeVisitor getDependencyNodeVisitor()
134 {
135 return visitor;
136 }
137
138 /**
139 * Gets the root node of the resultant dependency tree constructed by this visitor.
140 *
141 * @return the root node, or <code>null</code> if the source tree has not yet been visited
142 */
143 public DependencyNode getDependencyTree()
144 {
145 return rootNode;
146 }
147 }