1 package org.eclipse.aether.util.graph.visitor;
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 org.eclipse.aether.graph.DependencyFilter;
23 import org.eclipse.aether.graph.DependencyNode;
24 import org.eclipse.aether.graph.DependencyVisitor;
25
26 /**
27 * A dependency visitor that delegates to another visitor if nodes match a filter. Note that in case of a mismatching
28 * node, the children of that node are still visisted and presented to the filter.
29 */
30 public final class FilteringDependencyVisitor
31 implements DependencyVisitor
32 {
33
34 private final DependencyFilter filter;
35
36 private final DependencyVisitor visitor;
37
38 private final Stack<Boolean> accepts;
39
40 private final Stack<DependencyNode> parents;
41
42 /**
43 * Creates a new visitor that delegates traversal of nodes matching the given filter to the specified visitor.
44 *
45 * @param visitor The visitor to delegate to, must not be {@code null}.
46 * @param filter The filter to apply, may be {@code null} to not filter.
47 */
48 public FilteringDependencyVisitor( DependencyVisitor visitor, DependencyFilter filter )
49 {
50 if ( visitor == null )
51 {
52 throw new IllegalArgumentException( "dependency visitor not specified" );
53 }
54 this.visitor = visitor;
55 this.filter = filter;
56 this.accepts = new Stack<Boolean>();
57 this.parents = new Stack<DependencyNode>();
58 }
59
60 /**
61 * Gets the visitor to which this visitor delegates to.
62 *
63 * @return The visitor being delegated to, never {@code null}.
64 */
65 public DependencyVisitor getVisitor()
66 {
67 return visitor;
68 }
69
70 /**
71 * Gets the filter being applied before delegation.
72 *
73 * @return The filter being applied or {@code null} if none.
74 */
75 public DependencyFilter getFilter()
76 {
77 return filter;
78 }
79
80 public boolean visitEnter( DependencyNode node )
81 {
82 boolean accept = filter == null || filter.accept( node, parents );
83
84 accepts.push( accept );
85
86 parents.push( node );
87
88 if ( accept )
89 {
90 return visitor.visitEnter( node );
91 }
92 else
93 {
94 return true;
95 }
96 }
97
98 public boolean visitLeave( DependencyNode node )
99 {
100 parents.pop();
101
102 Boolean accept = accepts.pop();
103
104 if ( accept )
105 {
106 return visitor.visitLeave( node );
107 }
108 else
109 {
110 return true;
111 }
112 }
113
114 }