Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
SerializingDependencyNodeVisitor |
|
| 1.7;1,7 | ||||
SerializingDependencyNodeVisitor$TreeTokens |
|
| 1.7;1,7 |
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.io.PrintWriter; | |
23 | import java.io.Writer; | |
24 | import java.util.List; | |
25 | ||
26 | import org.apache.maven.shared.dependency.graph.DependencyNode; | |
27 | ||
28 | /** | |
29 | * A dependency node visitor that serializes visited nodes to a writer. | |
30 | * | |
31 | * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a> | |
32 | */ | |
33 | public class SerializingDependencyNodeVisitor | |
34 | implements DependencyNodeVisitor | |
35 | { | |
36 | // classes ---------------------------------------------------------------- | |
37 | ||
38 | /** | |
39 | * Provides tokens to use when serializing the dependency tree. | |
40 | */ | |
41 | public static class TreeTokens | |
42 | { | |
43 | private final String nodeIndent; | |
44 | ||
45 | private final String lastNodeIndent; | |
46 | ||
47 | private final String fillIndent; | |
48 | ||
49 | private final String lastFillIndent; | |
50 | ||
51 | public TreeTokens( String nodeIndent, String lastNodeIndent, String fillIndent, String lastFillIndent ) | |
52 | 0 | { |
53 | 0 | this.nodeIndent = nodeIndent; |
54 | 0 | this.lastNodeIndent = lastNodeIndent; |
55 | 0 | this.fillIndent = fillIndent; |
56 | 0 | this.lastFillIndent = lastFillIndent; |
57 | 0 | } |
58 | ||
59 | public String getNodeIndent( boolean last ) | |
60 | { | |
61 | 0 | return last ? lastNodeIndent : nodeIndent; |
62 | } | |
63 | ||
64 | public String getFillIndent( boolean last ) | |
65 | { | |
66 | 0 | return last ? lastFillIndent : fillIndent; |
67 | } | |
68 | } | |
69 | ||
70 | // constants -------------------------------------------------------------- | |
71 | ||
72 | /** | |
73 | * Whitespace tokens to use when outputing the dependency tree. | |
74 | */ | |
75 | 0 | public static final TreeTokens WHITESPACE_TOKENS = new TreeTokens( " ", " ", " ", " " ); |
76 | ||
77 | /** | |
78 | * The standard ASCII tokens to use when outputing the dependency tree. | |
79 | */ | |
80 | 0 | public static final TreeTokens STANDARD_TOKENS = new TreeTokens( "+- ", "\\- ", "| ", " " ); |
81 | ||
82 | /** | |
83 | * The extended ASCII tokens to use when outputing the dependency tree. | |
84 | */ | |
85 | 0 | public static final TreeTokens EXTENDED_TOKENS = |
86 | new TreeTokens( "\u00c3\u00c4 ", "\u00c0\u00c4 ", "\u00b3 ", " " ); | |
87 | ||
88 | // fields ----------------------------------------------------------------- | |
89 | ||
90 | /** | |
91 | * The writer to serialize to. | |
92 | */ | |
93 | private final PrintWriter writer; | |
94 | ||
95 | /** | |
96 | * The tokens to use when serializing the dependency tree. | |
97 | */ | |
98 | private final TreeTokens tokens; | |
99 | ||
100 | /** | |
101 | * The depth of the currently visited dependency node. | |
102 | */ | |
103 | private int depth; | |
104 | ||
105 | // constructors ----------------------------------------------------------- | |
106 | ||
107 | /** | |
108 | * Creates a dependency node visitor that serializes visited nodes to the specified writer using whitespace tokens. | |
109 | * | |
110 | * @param writer | |
111 | * the writer to serialize to | |
112 | */ | |
113 | public SerializingDependencyNodeVisitor( Writer writer ) | |
114 | { | |
115 | 0 | this( writer, WHITESPACE_TOKENS ); |
116 | 0 | } |
117 | ||
118 | /** | |
119 | * Creates a dependency node visitor that serializes visited nodes to the specified writer using the specified | |
120 | * tokens. | |
121 | * | |
122 | * @param writer | |
123 | * the writer to serialize to | |
124 | * @param tokens | |
125 | * the tokens to use when serializing the dependency tree | |
126 | */ | |
127 | public SerializingDependencyNodeVisitor( Writer writer, TreeTokens tokens ) | |
128 | 0 | { |
129 | 0 | if ( writer instanceof PrintWriter ) |
130 | { | |
131 | 0 | this.writer = (PrintWriter) writer; |
132 | } | |
133 | else | |
134 | { | |
135 | 0 | this.writer = new PrintWriter( writer, true ); |
136 | } | |
137 | ||
138 | 0 | this.tokens = tokens; |
139 | ||
140 | 0 | depth = 0; |
141 | 0 | } |
142 | ||
143 | // DependencyNodeVisitor methods ------------------------------------------ | |
144 | ||
145 | /** | |
146 | * {@inheritDoc} | |
147 | */ | |
148 | public boolean visit( DependencyNode node ) | |
149 | { | |
150 | 0 | indent( node ); |
151 | ||
152 | 0 | writer.println( node.toNodeString() ); |
153 | ||
154 | 0 | depth++; |
155 | ||
156 | 0 | return true; |
157 | } | |
158 | ||
159 | /** | |
160 | * {@inheritDoc} | |
161 | */ | |
162 | public boolean endVisit( DependencyNode node ) | |
163 | { | |
164 | 0 | depth--; |
165 | ||
166 | 0 | return true; |
167 | } | |
168 | ||
169 | // private methods -------------------------------------------------------- | |
170 | ||
171 | /** | |
172 | * Writes the necessary tokens to indent the specified dependency node to this visitor's writer. | |
173 | * | |
174 | * @param node | |
175 | * the dependency node to indent | |
176 | */ | |
177 | private void indent( DependencyNode node ) | |
178 | { | |
179 | 0 | for ( int i = 1; i < depth; i++ ) |
180 | { | |
181 | 0 | writer.write( tokens.getFillIndent( isLast( node, i ) ) ); |
182 | } | |
183 | ||
184 | 0 | if ( depth > 0 ) |
185 | { | |
186 | 0 | writer.write( tokens.getNodeIndent( isLast( node ) ) ); |
187 | } | |
188 | 0 | } |
189 | ||
190 | /** | |
191 | * Gets whether the specified dependency node is the last of its siblings. | |
192 | * | |
193 | * @param node | |
194 | * the dependency node to check | |
195 | * @return <code>true</code> if the specified dependency node is the last of its last siblings | |
196 | */ | |
197 | private boolean isLast( DependencyNode node ) | |
198 | { | |
199 | // TODO: remove node argument and calculate from visitor calls only | |
200 | ||
201 | 0 | DependencyNode parent = node.getParent(); |
202 | ||
203 | boolean last; | |
204 | ||
205 | 0 | if ( parent == null ) |
206 | { | |
207 | 0 | last = true; |
208 | } | |
209 | else | |
210 | { | |
211 | 0 | List<DependencyNode> siblings = parent.getChildren(); |
212 | ||
213 | 0 | last = ( siblings.indexOf( node ) == siblings.size() - 1 ); |
214 | } | |
215 | ||
216 | 0 | return last; |
217 | } | |
218 | ||
219 | /** | |
220 | * Gets whether the specified dependency node ancestor is the last of its siblings. | |
221 | * | |
222 | * @param node | |
223 | * the dependency node whose ancestor to check | |
224 | * @param ancestorDepth | |
225 | * the depth of the ancestor of the specified dependency node to check | |
226 | * @return <code>true</code> if the specified dependency node ancestor is the last of its siblings | |
227 | */ | |
228 | private boolean isLast( DependencyNode node, int ancestorDepth ) | |
229 | { | |
230 | // TODO: remove node argument and calculate from visitor calls only | |
231 | ||
232 | 0 | int distance = depth - ancestorDepth; |
233 | ||
234 | 0 | while ( distance-- > 0 ) |
235 | { | |
236 | 0 | node = node.getParent(); |
237 | } | |
238 | ||
239 | 0 | return isLast( node ); |
240 | } | |
241 | } |