1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.sw4j.tool.annotation.jpa.test.util;
18
19 import java.io.File;
20 import java.io.IOException;
21 import java.io.StringWriter;
22 import java.io.Writer;
23 import java.nio.charset.Charset;
24 import java.util.Arrays;
25 import java.util.HashSet;
26 import java.util.LinkedList;
27 import java.util.List;
28 import java.util.Set;
29 import javax.tools.JavaCompiler;
30 import javax.tools.JavaFileObject;
31 import javax.tools.StandardJavaFileManager;
32 import javax.tools.ToolProvider;
33 import javax.xml.parsers.DocumentBuilder;
34 import javax.xml.parsers.DocumentBuilderFactory;
35 import javax.xml.parsers.ParserConfigurationException;
36 import javax.xml.xpath.XPath;
37 import javax.xml.xpath.XPathConstants;
38 import javax.xml.xpath.XPathExpressionException;
39 import javax.xml.xpath.XPathFactory;
40 import org.testng.Assert;
41 import org.w3c.dom.Attr;
42 import org.w3c.dom.Document;
43 import org.w3c.dom.Element;
44 import org.w3c.dom.NamedNodeMap;
45 import org.w3c.dom.Node;
46 import org.w3c.dom.NodeList;
47 import org.xml.sax.SAXException;
48
49
50
51
52
53
54 public class ITUtil {
55
56
57 private static final String TARGET_FOLDER = "target/jpa-classes/";
58
59
60 private Document resultDocument;
61
62
63 private final Set<Node> visitedNodes;
64
65 public ITUtil() {
66 visitedNodes = new HashSet<>();
67 }
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 public void compileClasses(String folder, String resultFileName, String[] options)
83 throws ParserConfigurationException, SAXException, IOException {
84 try {
85 File entityFolder = new File(folder);
86 List<File> files = new LinkedList<>();
87 getFiles(entityFolder, files);
88
89 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
90 Assert.assertNotNull(compiler, "Need a java compiler for executing the tests.");
91 StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, Charset.forName("UTF-8"));
92
93 File classesFolder = new File(TARGET_FOLDER);
94 classesFolder.mkdirs();
95
96 Iterable<? extends JavaFileObject> entities = fileManager.getJavaFileObjectsFromFiles(files);
97 List<String> opts = new LinkedList<>();
98 opts.add("-d");
99 opts.add(TARGET_FOLDER);
100 opts.addAll(Arrays.asList(options));
101 Writer writer = new StringWriter();
102 compiler.getTask(writer, fileManager, null, opts, null, entities).call();
103
104 if (resultFileName != null) {
105 File resultFile = new File(resultFileName);
106 if (resultFile.exists()) {
107 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
108 resultDocument = builder.parse(resultFile);
109 }
110 }
111 } catch (Exception ex) {
112 ex.printStackTrace();
113 }
114 }
115
116
117
118
119
120
121
122
123 private void getFiles(File folder, List<File> javaFiles) {
124 if (folder.isDirectory()) {
125 File[] files = folder.listFiles();
126 for (File file: files) {
127 getFiles(file, javaFiles);
128 }
129 } else if (folder.getName().endsWith(".java")) {
130 javaFiles.add(folder);
131 }
132 }
133
134
135
136
137
138 public void checkVisitedNodes() {
139 StringBuilder sb = new StringBuilder();
140 if (this.resultDocument != null) {
141 checkVisitedNodes(resultDocument.getDocumentElement(), sb);
142 if (sb.length() > 0) {
143 Assert.fail(sb.toString());
144 }
145 }
146 }
147
148
149
150
151
152
153
154 private void checkVisitedNodes(final Element node, final StringBuilder sb) {
155 if (!visitedNodes.contains(node)) {
156 sb.append("Expected the element \"").append(getPathToNode(node)).append("\" to be tested.\n");
157 }
158 NamedNodeMap attributes = node.getAttributes();
159 for (int i = 0; i < attributes.getLength(); i++) {
160 Attr attr = (Attr)attributes.item(i);
161 if (!visitedNodes.contains(attr)) {
162 sb.append("Expected the attribute \"").append(getPathToNode(attr)).append("\" to be tested.\n");
163 }
164 }
165 NodeList children = node.getChildNodes();
166 for (int i = 0; i < children.getLength(); i++) {
167 Node child = children.item(i);
168 if (child.getNodeType() == Node.ELEMENT_NODE) {
169 checkVisitedNodes((Element)child, sb);
170 }
171 }
172 }
173
174
175
176
177
178
179
180 private String getPathToNode(final Node node) {
181 StringBuilder path = new StringBuilder();
182 Node parent;
183 if (node.getNodeType() == Node.ELEMENT_NODE) {
184 parent = node;
185 } else {
186 parent = ((Attr)node).getOwnerElement();
187 path.append("/@").append(node.getNodeName());
188 }
189 while (parent != null) {
190 if (parent.getNodeType() != Node.DOCUMENT_NODE) {
191 path.insert(0, handleElementAttributes(parent));
192 path.insert(0, parent.getNodeName());
193 path.insert(0, "/");
194 }
195 parent = parent.getParentNode();
196 }
197 return path.toString();
198 }
199
200
201
202
203
204
205
206 private StringBuilder handleElementAttributes(Node node) {
207 StringBuilder attributePath = new StringBuilder();
208 if (node.hasAttributes()) {
209 NamedNodeMap attributes = node.getAttributes();
210 if (attributes.getLength() > 0) {
211 attributePath.append("[");
212 for (int i = 0; i < attributes.getLength(); i++) {
213 if (i > 0) {
214 attributePath.append(" and ");
215 }
216 Node attribute = attributes.item(i);
217 attributePath.append("@").append(attribute.getNodeName()).append("='")
218 .append(attribute.getNodeValue()).append("'");
219 }
220 attributePath.append("]");
221 }
222 }
223 return attributePath;
224 }
225
226
227
228
229
230
231 public Element getRootElement() {
232 Element root = resultDocument.getDocumentElement();
233 visitedNodes.add(root);
234 getAttribute("xmlns:xsi", root);
235 getAttribute("xsi:schemaLocation", root);
236 return root;
237 }
238
239
240
241
242
243
244
245
246 public Node getNode(String path) throws XPathExpressionException {
247 XPath xpath = XPathFactory.newInstance().newXPath();
248 Node result = (Node)xpath.evaluate(path, resultDocument, XPathConstants.NODE);
249 visitedNodes.add(result);
250 return result;
251 }
252
253
254
255
256
257
258
259
260 public Node getAttribute(String name, Node node) {
261 Node attribute = node.getAttributes().getNamedItem(name);
262 if (attribute != null) {
263 visitedNodes.add(attribute);
264 }
265 return attribute;
266 }
267
268 }