1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.shared.dependency.graph.traversal;
20
21 import java.io.PrintWriter;
22 import java.io.Writer;
23 import java.util.List;
24
25 import org.apache.maven.shared.dependency.graph.DependencyNode;
26
27
28
29
30
31
32 public class SerializingDependencyNodeVisitor implements DependencyNodeVisitor {
33
34
35
36
37
38 public static class GraphTokens {
39 private final String nodeIndent;
40
41 private final String lastNodeIndent;
42
43 private final String fillIndent;
44
45 private final String lastFillIndent;
46
47 public GraphTokens(String nodeIndent, String lastNodeIndent, String fillIndent, String lastFillIndent) {
48 this.nodeIndent = nodeIndent;
49 this.lastNodeIndent = lastNodeIndent;
50 this.fillIndent = fillIndent;
51 this.lastFillIndent = lastFillIndent;
52 }
53
54 public String getNodeIndent(boolean last) {
55 return last ? lastNodeIndent : nodeIndent;
56 }
57
58 public String getFillIndent(boolean last) {
59 return last ? lastFillIndent : fillIndent;
60 }
61 }
62
63
64
65
66
67
68 public static final GraphTokens WHITESPACE_TOKENS = new GraphTokens(" ", " ", " ", " ");
69
70
71
72
73 public static final GraphTokens STANDARD_TOKENS = new GraphTokens("+- ", "\\- ", "| ", " ");
74
75
76
77
78 public static final GraphTokens EXTENDED_TOKENS =
79 new GraphTokens("\u251C\u2500 ", "\u2514\u2500 ", "\u2502 ", " ");
80
81
82
83
84
85
86 private final PrintWriter writer;
87
88
89
90
91 private final GraphTokens tokens;
92
93
94
95
96 private int depth;
97
98
99
100
101
102
103
104
105 public SerializingDependencyNodeVisitor(Writer writer) {
106 this(writer, WHITESPACE_TOKENS);
107 }
108
109
110
111
112
113
114
115
116 public SerializingDependencyNodeVisitor(Writer writer, GraphTokens tokens) {
117 if (writer instanceof PrintWriter) {
118 this.writer = (PrintWriter) writer;
119 } else {
120 this.writer = new PrintWriter(writer, true);
121 }
122
123 this.tokens = tokens;
124
125 depth = 0;
126 }
127
128
129
130
131
132
133 @Override
134 public boolean visit(DependencyNode node) {
135 indent(node);
136
137 writer.println(node.toNodeString());
138
139 depth++;
140
141 return true;
142 }
143
144
145
146
147 @Override
148 public boolean endVisit(DependencyNode node) {
149 depth--;
150
151 return true;
152 }
153
154
155
156
157
158
159
160
161 private void indent(DependencyNode node) {
162 for (int i = 1; i < depth; i++) {
163 writer.write(tokens.getFillIndent(isLast(node, i)));
164 }
165
166 if (depth > 0) {
167 writer.write(tokens.getNodeIndent(isLast(node)));
168 }
169 }
170
171
172
173
174
175
176
177 private boolean isLast(DependencyNode node) {
178
179
180 DependencyNode parent = node.getParent();
181
182 boolean last;
183
184 if (parent == null) {
185 last = true;
186 } else {
187 List<DependencyNode> siblings = parent.getChildren();
188
189 last = (siblings.indexOf(node) == siblings.size() - 1);
190 }
191
192 return last;
193 }
194
195
196
197
198
199
200
201
202 private boolean isLast(DependencyNode node, int ancestorDepth) {
203
204
205 int distance = depth - ancestorDepth;
206
207 while (distance-- > 0) {
208 node = node.getParent();
209 }
210
211 return isLast(node);
212 }
213 }