1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.dependency.tree;
20
21 import java.io.Writer;
22 import java.util.HashSet;
23 import java.util.Set;
24
25 import org.apache.maven.artifact.Artifact;
26 import org.apache.maven.shared.dependency.graph.DependencyNode;
27 import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
28
29
30
31
32 public class JsonDependencyNodeVisitor extends AbstractSerializingVisitor implements DependencyNodeVisitor {
33
34 private String indentChar = " ";
35
36
37
38
39
40
41 public JsonDependencyNodeVisitor(Writer writer) {
42 super(writer);
43 }
44
45 @Override
46 public boolean visit(DependencyNode node) {
47 if (node.getParent() == null || node.getParent() == node) {
48 writeRootNode(node);
49 }
50 return true;
51 }
52
53
54
55
56
57
58 private void writeRootNode(DependencyNode node) {
59 Set<DependencyNode> visited = new HashSet<DependencyNode>();
60 int indent = 2;
61 StringBuilder sb = new StringBuilder();
62 sb.append("{").append("\n");
63 writeNode(indent, node, sb, visited);
64 sb.append("}").append("\n");
65 writer.write(sb.toString());
66 }
67
68
69
70
71
72
73
74 private void writeNode(int indent, DependencyNode node, StringBuilder sb, Set<DependencyNode> visited) {
75 if (visited.contains(node)) {
76
77
78 return;
79 }
80 visited.add(node);
81 appendNodeValues(sb, indent, node.getArtifact(), !node.getChildren().isEmpty());
82 if (!node.getChildren().isEmpty()) {
83 writeChildren(indent, node, sb, visited);
84 }
85 }
86
87
88
89
90
91
92
93 private void writeChildren(int indent, DependencyNode node, StringBuilder sb, Set<DependencyNode> visited) {
94 sb.append(indent(indent)).append("\"children\": [").append("\n");
95 indent += 2;
96 for (int i = 0; i < node.getChildren().size(); i++) {
97 DependencyNode child = node.getChildren().get(i);
98 sb.append(indent(indent));
99 sb.append("{").append("\n");
100 writeNode(indent + 2, child, sb, visited);
101 sb.append(indent(indent)).append("}");
102
103 if (i != node.getChildren().size() - 1) {
104 sb.append(",");
105 }
106 sb.append("\n");
107 }
108 sb.append(indent(indent)).append("]").append("\n");
109 }
110
111 @Override
112 public boolean endVisit(DependencyNode node) {
113 return true;
114 }
115
116
117
118
119
120
121
122
123 private void appendNodeValues(StringBuilder sb, int indent, Artifact artifact, boolean hasChildren) {
124 appendKeyValue(sb, indent, "groupId", artifact.getGroupId());
125 appendKeyValue(sb, indent, "artifactId", artifact.getArtifactId());
126 appendKeyValue(sb, indent, "version", artifact.getVersion());
127 appendKeyValue(sb, indent, "type", artifact.getType());
128 appendKeyValue(sb, indent, "scope", artifact.getScope());
129 appendKeyValue(sb, indent, "classifier", artifact.getClassifier());
130 if (hasChildren) {
131 appendKeyValue(sb, indent, "optional", String.valueOf(artifact.isOptional()));
132 } else {
133 appendKeyWithoutComma(sb, indent, "optional", String.valueOf(artifact.isOptional()));
134 }
135 }
136
137
138
139
140
141
142
143
144 private void appendKeyValue(StringBuilder sb, int indent, String key, String value) {
145 if (value == null) {
146 value = "";
147 }
148
149 sb.append(indent(indent))
150 .append("\"")
151 .append(key)
152 .append("\"")
153 .append(":")
154 .append(indentChar)
155 .append("\"")
156 .append(value)
157 .append("\"")
158 .append(",")
159 .append("\n");
160 }
161
162
163
164
165
166
167
168
169 private void appendKeyWithoutComma(StringBuilder sb, int indent, String key, String value) {
170 if (value == null) {
171 value = "";
172 }
173
174 sb.append(indent(indent))
175 .append("\"")
176 .append(key)
177 .append("\"")
178 .append(":")
179 .append(indentChar)
180 .append("\"")
181 .append(value)
182 .append("\"")
183 .append("\n");
184 }
185
186
187
188
189
190
191
192 private String indent(int indent) {
193 if (indent < 1) {
194 return "";
195 }
196
197 StringBuilder sb = new StringBuilder();
198 for (int i = 0; i < indent; i++) {
199 sb.append(indentChar);
200 }
201
202 return sb.toString();
203 }
204 }