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