1 package org.testng.xml.dom; 2 3 import org.testng.collections.Lists; 4 import org.testng.collections.Maps; 5 import org.testng.xml.XmlClass; 6 import org.testng.xml.XmlSuite; 7 import org.testng.xml.XmlTest; 8 import org.w3c.dom.Document; 9 import org.w3c.dom.Element; 10 import org.w3c.dom.Node; 11 import org.w3c.dom.NodeList; 12 13 import javax.xml.xpath.XPath; 14 import javax.xml.xpath.XPathExpressionException; 15 import javax.xml.xpath.XPathFactory; 16 17 import java.lang.reflect.InvocationTargetException; 18 import java.lang.reflect.Method; 19 import java.util.Iterator; 20 import java.util.List; 21 import java.util.Map; 22 23 public class DomUtil { 24 25 private XPath m_xpath; 26 private Document m_document; 27 DomUtil(Document doc)28 public DomUtil(Document doc) { 29 XPathFactory xpathFactory = XPathFactory.newInstance(); 30 m_xpath = xpathFactory.newXPath(); 31 m_document = doc; 32 } 33 populate(final XmlSuite xmlSuite)34 public void populate(final XmlSuite xmlSuite) throws XPathExpressionException { 35 NodeList nodes = m_document.getChildNodes(); 36 final Map<String, String> parameters = Maps.newHashMap(); 37 for (int i = 0; i < nodes.getLength(); i++) { 38 Node item1 = nodes.item(i); 39 40 Map<String, NodeProcessor> map = Maps.newHashMap(); 41 map.put("parameter", new NodeProcessor() { 42 @Override 43 public void process(Node node) { 44 Element e = (Element) node; 45 parameters.put(e.getAttribute("name"), e.getAttribute("value")); 46 } 47 }); 48 map.put("test", new NodeProcessor() { 49 @Override 50 public void process(Node node) { 51 XmlTest xmlTest = new XmlTest(xmlSuite); 52 populateTest(xmlTest, node); 53 } 54 }); 55 map.put("suite-files", new NodeProcessor() { 56 @Override 57 public void process(Node node) { 58 NodeList item2Children = node.getChildNodes(); 59 List<String> suiteFiles = Lists.newArrayList(); 60 for (int k = 0; k < item2Children.getLength(); k++) { 61 Node item3 = item2Children.item(k); 62 if (item3 instanceof Element) { 63 Element e = (Element) item3; 64 if ("suite-file".equals(item3.getNodeName())) { 65 suiteFiles.add(e.getAttribute("path")); 66 } 67 } 68 } 69 xmlSuite.setSuiteFiles(suiteFiles); 70 } 71 }); 72 parseNodeAndChildren("suite", item1, xmlSuite, map); 73 74 // if ("suite".equals(item1.getNodeName()) && item1.getAttributes() != null) { 75 // populateAttributes(item1, xmlSuite); 76 // NodeList item1Children = item1.getChildNodes(); 77 // for (int j = 0; j < item1Children.getLength(); j++) { 78 // Node item2 = item1Children.item(j); 79 // if ("parameter".equals(item2.getNodeName())) { 80 // Element e = (Element) item2; 81 // parameters.put(e.getAttribute("name"), e.getAttribute("value")); 82 // } else if ("test".equals(item2.getNodeName())) { 83 // XmlTest xmlTest = new XmlTest(xmlSuite); 84 // populateTest(xmlTest, item2); 85 // } else if ("suite-files".equals(item2.getNodeName())) { 86 // NodeList item2Children = item2.getChildNodes(); 87 // List<String> suiteFiles = Lists.newArrayList(); 88 // for (int k = 0; k < item2Children.getLength(); k++) { 89 // Node item3 = item2Children.item(k); 90 // if (item3 instanceof Element) { 91 // Element e = (Element) item3; 92 // if ("suite-file".equals(item3.getNodeName())) { 93 // suiteFiles.add(e.getAttribute("path")); 94 // } 95 // } 96 // } 97 // xmlSuite.setSuiteFiles(suiteFiles); 98 // } 99 // } 100 // } 101 } 102 103 xmlSuite.setParameters(parameters); 104 // XPathExpression expr = m_xpath.compile("//suite/test"); 105 // NodeList tests = (NodeList) expr.evaluate(m_document, XPathConstants.NODESET); 106 // for (int i = 0; i < tests.getLength(); i++) { 107 // Node node = tests.item(i); 108 // System.out.println("<test>:" + node); 109 // } 110 } 111 112 public static interface NodeProcessor { process(Node node)113 void process(Node node); 114 } 115 parseNodeAndChildren(String name, Node root, Object object, Map<String, NodeProcessor> processors)116 private void parseNodeAndChildren(String name, Node root, Object object, 117 Map<String, NodeProcessor> processors) throws XPathExpressionException { 118 if (name.equals(root.getNodeName()) && root.getAttributes() != null) { 119 populateAttributes(root, object); 120 NodeList children = root.getChildNodes(); 121 for (int j = 0; j < children.getLength(); j++) { 122 Node item2 = children.item(j); 123 String nodeName = item2.getNodeName(); 124 NodeProcessor proc = processors.get(nodeName); 125 if (proc != null) { 126 proc.process(item2); 127 } else if (! nodeName.startsWith("#")){ 128 throw new RuntimeException("No processor found for " + nodeName); 129 } 130 // if ("parameter".equals(item2.getNodeName())) { 131 // Element e = (Element) item2; 132 // parameters.put(e.getAttribute("name"), e.getAttribute("value")); 133 // } 134 } 135 } 136 } 137 findChildren(Node node, String name)138 public static Iterator<Node> findChildren(Node node, String name) { 139 List<Node> result = Lists.newArrayList(); 140 NodeList children = node.getChildNodes(); 141 for (int i = 0; i < children.getLength(); i++) { 142 Node n = children.item(i); 143 if (name.equals(n.getNodeName())) { 144 result.add(n); 145 } 146 } 147 return result.iterator(); 148 } 149 populateTest(XmlTest xmlTest, Node item)150 private void populateTest(XmlTest xmlTest, Node item) { 151 Map<String, String> testParameters = Maps.newHashMap(); 152 populateAttributes(item, xmlTest); 153 NodeList itemChildren = item.getChildNodes(); 154 for (int k = 0; k < itemChildren.getLength(); k++) { 155 Node item2 = itemChildren.item(k); 156 if ("parameter".equals(item2.getNodeName())) { 157 Element e = (Element) item2; 158 testParameters.put(e.getAttribute("name"), e.getAttribute("value")); 159 } else if ("classes".equals(item2.getNodeName())) { 160 NodeList item2Children = item2.getChildNodes(); 161 for (int l = 0; l < item2Children.getLength(); l++) { 162 Node item4 = item2Children.item(l); 163 if ("class".equals(item4.getNodeName())) { 164 XmlClass xmlClass = new XmlClass(); 165 populateAttributes(item4, xmlClass); 166 xmlTest.getClasses().add(xmlClass); 167 168 // TODO: excluded/included methods 169 } 170 } 171 } else if ("groups".equals(item2.getNodeName())) { 172 NodeList item2Children = item2.getChildNodes(); 173 List<String> includes = Lists.newArrayList(); 174 List<String> excludes = Lists.newArrayList(); 175 for (int l = 0; l < item2Children.getLength(); l++) { 176 Node item3 = item2Children.item(l); 177 if ("run".equals(item3.getNodeName())) { 178 NodeList item3Children = item3.getChildNodes(); 179 for (int m = 0; m < item3Children.getLength(); m++) { 180 Node item4 = item3Children.item(m); 181 if ("include".equals(item4.getNodeName())) { 182 includes.add(((Element) item4).getAttribute("name")); 183 } else if ("exclude".equals(item4.getNodeName())) { 184 excludes.add(((Element) item4).getAttribute("name")); 185 } 186 } 187 } else if ("dependencies".equals(item3.getNodeName())) { 188 NodeList item3Children = item3.getChildNodes(); 189 for (int m = 0; m < item3Children.getLength(); m++) { 190 Node item4 = item3Children.item(m); 191 if ("group".equals(item4.getNodeName())) { 192 Element e = (Element) item4; 193 xmlTest.addXmlDependencyGroup(e.getAttribute("name"), e.getAttribute("depends-on")); 194 } 195 } 196 } else if ("define".equals(item3.getNodeName())) { 197 xmlDefine(xmlTest, item3); 198 } 199 } 200 xmlTest.setIncludedGroups(includes); 201 xmlTest.setExcludedGroups(excludes); 202 } // TODO: (method-selectors?,packages?) > 203 } 204 205 xmlTest.setParameters(testParameters); 206 } 207 208 /** 209 * Parse the <define> tag. 210 */ xmlDefine(XmlTest xmlTest, Node item)211 private void xmlDefine(XmlTest xmlTest, Node item) { 212 NodeList item3Children = item.getChildNodes(); 213 List<String> groups = Lists.newArrayList(); 214 for (int m = 0; m < item3Children.getLength(); m++) { 215 Node item4 = item3Children.item(m); 216 if ("include".equals(item4.getNodeName())) { 217 Element e = (Element) item4; 218 groups.add(e.getAttribute("name")); 219 } 220 } 221 xmlTest.addMetaGroup(((Element) item).getAttribute("name"), groups); 222 } 223 populateAttributes(Node node, Object object)224 private void populateAttributes(Node node, Object object) { 225 for (int j = 0; j < node.getAttributes().getLength(); j++) { 226 Node item = node.getAttributes().item(j); 227 p(node.getAttributes().item(j).toString()); 228 setProperty(object, item.getLocalName(), item.getNodeValue()); 229 } 230 } 231 setProperty(Object object, String name, Object value)232 private void setProperty(Object object, String name, Object value) { 233 String methodName = toCamelCaseSetter(name); 234 Method foundMethod = null; 235 for (Method m : object.getClass().getDeclaredMethods()) { 236 if (m.getName().equals(methodName)) { 237 foundMethod = m; 238 break; 239 } 240 } 241 242 if (foundMethod == null) { 243 p("Warning: couldn't find setter method " + methodName); 244 } else { 245 try { 246 p("Invoking " + methodName + " with " + value); 247 Class<?> type = foundMethod.getParameterTypes()[0]; 248 if (type == Boolean.class || type == boolean.class) { 249 foundMethod.invoke(object, Boolean.parseBoolean(value.toString())); 250 } else if (type == Integer.class || type == int.class) { 251 foundMethod.invoke(object, Integer.parseInt(value.toString())); 252 } else { 253 foundMethod.invoke(object, value.toString()); 254 } 255 } catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException e) { 256 e.printStackTrace(); 257 } 258 } 259 } 260 p(String string)261 private void p(String string) { 262 // System.out.println("[XPathUtil] " + string); 263 } 264 toCamelCaseSetter(String name)265 private String toCamelCaseSetter(String name) { 266 StringBuilder result = new StringBuilder("set" + name.substring(0, 1).toUpperCase()); 267 for (int i = 1; i < name.length(); i++) { 268 if (name.charAt(i) == '-') { 269 result.append(Character.toUpperCase(name.charAt(i + 1))); 270 i++; 271 } else { 272 result.append(name.charAt(i)); 273 } 274 } 275 return result.toString(); 276 } 277 } 278