1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.themis.lethe.analysis;
18
19 import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
20 import io.github.tonywasher.joceanus.themis.exc.ThemisDataException;
21 import io.github.tonywasher.joceanus.themis.exc.ThemisIOException;
22 import org.w3c.dom.Document;
23 import org.w3c.dom.Element;
24 import org.w3c.dom.Node;
25 import org.xml.sax.SAXException;
26
27 import javax.xml.XMLConstants;
28 import javax.xml.parsers.DocumentBuilder;
29 import javax.xml.parsers.DocumentBuilderFactory;
30 import javax.xml.parsers.ParserConfigurationException;
31 import java.io.BufferedInputStream;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.Objects;
37
38
39
40
41 public class ThemisAnalysisMaven {
42
43
44
45 public static final String POM = "pom.xml";
46
47
48
49
50 private static final String DOC_NAME = "project";
51
52
53
54
55 private static final String EL_PARENT = "parent";
56
57
58
59
60 private static final String EL_MODULES = "modules";
61
62
63
64
65 private static final String EL_MODULE = "module";
66
67
68
69
70 private static final String EL_DEPENDENCIES = "dependencies";
71
72
73
74
75 private static final String EL_DEPENDENCY = "dependency";
76
77
78
79
80 private final ThemisAnalysisMavenId theId;
81
82
83
84
85 private final List<String> theModules;
86
87
88
89
90 private final List<ThemisAnalysisMavenId> theDependencies;
91
92
93
94
95
96
97
98 public ThemisAnalysisMaven(final InputStream pInputStream) throws OceanusException {
99
100 theModules = new ArrayList<>();
101 theDependencies = new ArrayList<>();
102
103
104 try (BufferedInputStream myInBuffer = new BufferedInputStream(pInputStream)) {
105 final DocumentBuilderFactory myFactory = DocumentBuilderFactory.newInstance();
106 myFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
107 myFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
108 myFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
109 final DocumentBuilder myBuilder = myFactory.newDocumentBuilder();
110
111
112 final Document myDocument = myBuilder.parse(myInBuffer);
113 theId = parseProjectFile(myDocument);
114
115
116 } catch (IOException
117 | ParserConfigurationException
118 | SAXException e) {
119 throw new ThemisIOException("Exception accessing Pom file", e);
120 }
121 }
122
123 @Override
124 public String toString() {
125 return theId.toString();
126 }
127
128
129
130
131
132
133 public ThemisAnalysisMavenId getMavenId() {
134 return theId;
135 }
136
137
138
139
140
141
142 public List<String> getModules() {
143 return theModules;
144 }
145
146
147
148
149
150
151
152
153 public ThemisAnalysisMavenId parseProjectFile(final Document pDocument) throws OceanusException {
154
155 final Element myDoc = pDocument.getDocumentElement();
156
157
158 if (!Objects.equals(myDoc.getNodeName(), DOC_NAME)) {
159 throw new ThemisDataException("Invalid document type");
160 }
161
162
163 final Element myParentEl = getElement(myDoc, EL_PARENT);
164 final ThemisAnalysisMavenId myParent = myParentEl == null
165 ? null
166 : new ThemisAnalysisMavenId(myParentEl);
167
168
169 final ThemisAnalysisMavenId myId = new ThemisAnalysisMavenId(myDoc, myParent);
170
171
172 final Element myModules = getElement(myDoc, EL_MODULES);
173 processModules(myModules);
174
175
176 final Element myDependencies = getElement(myDoc, EL_DEPENDENCIES);
177 processDependencies(myDependencies, myId);
178
179
180 return myId;
181 }
182
183
184
185
186
187
188
189
190 static String getElementValue(final Element pElement,
191 final String pValue) {
192
193 if (pElement == null) {
194 return null;
195 }
196
197
198 for (Node myChild = pElement.getFirstChild();
199 myChild != null;
200 myChild = myChild.getNextSibling()) {
201
202 if (myChild instanceof Element
203 && pValue.equals(myChild.getNodeName())) {
204 return myChild.getTextContent();
205 }
206 }
207
208
209 return null;
210 }
211
212
213
214
215
216
217
218
219 static Element getElement(final Element pElement,
220 final String pValue) {
221
222 if (pElement == null) {
223 return null;
224 }
225
226
227 for (Node myChild = pElement.getFirstChild();
228 myChild != null;
229 myChild = myChild.getNextSibling()) {
230
231 if (myChild instanceof Element myElement
232 && pValue.equals(myChild.getNodeName())) {
233 return myElement;
234 }
235 }
236
237
238 return null;
239 }
240
241
242
243
244
245
246 private void processModules(final Element pModules) {
247
248 if (pModules == null) {
249 return;
250 }
251
252
253 for (Node myChild = pModules.getFirstChild();
254 myChild != null;
255 myChild = myChild.getNextSibling()) {
256
257 if (myChild instanceof Element
258 && EL_MODULE.equals(myChild.getNodeName())) {
259 theModules.add(myChild.getTextContent());
260 }
261 }
262 }
263
264
265
266
267
268
269
270 private void processDependencies(final Element pDependencies,
271 final ThemisAnalysisMavenId pParent) {
272
273 if (pDependencies == null) {
274 return;
275 }
276
277
278 for (Node myChild = pDependencies.getFirstChild();
279 myChild != null;
280 myChild = myChild.getNextSibling()) {
281
282 if (myChild instanceof Element myElement
283 && EL_DEPENDENCY.equals(myChild.getNodeName())) {
284 theDependencies.add(new ThemisAnalysisMavenId(myElement, pParent));
285 }
286 }
287 }
288 }