org.testng.xml.dom.XDom Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of testng Show documentation
Show all versions of testng Show documentation
A testing framework for the JVM
package org.testng.xml.dom;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import org.testng.Assert;
import org.testng.collections.ListMultiMap;
import org.testng.collections.Lists;
import org.testng.collections.Maps;
import org.testng.internal.collections.Pair;
import org.testng.xml.XmlDefine;
import org.testng.xml.XmlGroups;
import org.testng.xml.XmlMethodSelector;
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class XDom {
// private static Map> m_map = Maps.newHashMap();
private Document m_document;
private ITagFactory m_tagFactory;
public XDom(ITagFactory tagFactory, Document document)
throws XPathExpressionException,
InstantiationException, IllegalAccessException {
m_tagFactory = tagFactory;
m_document = document;
}
public Object parse() throws XPathExpressionException,
InstantiationException, IllegalAccessException, SecurityException,
IllegalArgumentException, NoSuchMethodException,
InvocationTargetException {
Object result = null;
NodeList nodes = m_document.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
Node item = nodes.item(i);
if (item.getAttributes() != null) {
String nodeName = item.getNodeName();
System.out.println("Node name:" + nodeName);
Class c = m_tagFactory.getClassForTag(nodeName);
if (c == null) {
throw new RuntimeException("No class found for tag " + nodeName);
}
result = c.newInstance();
populateAttributes(item, result);
if (ITagSetter.class.isAssignableFrom(result.getClass())) {
throw new RuntimeException("TAG SETTER");
}
populateChildren(item, result);
}
}
return result;
}
public void populateChildren(Node root, Object result) throws InstantiationException,
IllegalAccessException, XPathExpressionException, SecurityException, IllegalArgumentException, NoSuchMethodException, InvocationTargetException {
p("populateChildren: " + root.getLocalName());
NodeList childNodes = root.getChildNodes();
ListMultiMap children = Maps.newListMultiMap();
for (int i = 0; i < childNodes.getLength(); i++) {
Node item = childNodes.item(i);
if (item.getAttributes() != null) {
String nodeName = item.getNodeName();
if ("suite-files".equals(nodeName)) {
System.out.println("BREAK");
}
Class c = m_tagFactory.getClassForTag(nodeName);
if (c == null) {
System.out.println("Warning: No class found for tag " + nodeName);
boolean foundSetter = invokeOnSetter(result, (Element) item, nodeName, null);
System.out.println(" found setter:" + foundSetter);
} else {
Object object = instantiateElement(c, result);
if (ITagSetter.class.isAssignableFrom(object.getClass())) {
System.out.println("Tag setter:" + result);
((ITagSetter) object).setProperty(nodeName, result, item);
} else {
children.put(nodeName, object);
populateAttributes(item, object);
populateContent(item, object);
}
boolean foundSetter = invokeOnSetter(result, (Element) item, nodeName, object);
// setProperty(result, nodeName, object);
populateChildren(item, object);
}
// boolean foundSetter = invokeOnSetter(result, (Element) item, nodeName);
// if (! foundSetter) {
// boolean foundListSetter = invokeOnListSetter(result, nodeName, item);
// if (! foundListSetter) {
// }
// }
}
}
// System.out.println("Found children:" + children);
// for (String s : children.getKeys()) {
// setCollectionProperty(result, s, children.get(s), object);
// }
}
/**
* Try to find a @ParentSetter. If this fails, try to find a constructor that takes the parent as a parameter.
* If this fails, use the default constructor.
*/
private Object instantiateElement(Class c, Object parent)
throws SecurityException, NoSuchMethodException,
IllegalArgumentException, InstantiationException, IllegalAccessException,
InvocationTargetException {
Object result = null;
Method m = findMethodAnnotatedWith(c, ParentSetter.class);
if (m != null) {
result = c.newInstance();
m.invoke(result, parent);
} else {
try {
result = c.getConstructor(parent.getClass()).newInstance(parent);
} catch(NoSuchMethodException ex) {
result = c.newInstance();
}
}
return result;
}
// private List>
// findMethodsWithAnnotation(Class c, Class ac) {
// List> result = Lists.newArrayList();
// for (Method m : c.getMethods()) {
// Annotation a = m.getAnnotation(ac);
// if (a != null) {
// result.add(Pair.of(m, a));
// }
// }
// return result;
// }
private Method findMethodAnnotatedWith(Class c, Class annotation) {
for (Method m : c.getMethods()) {
if (m.getAnnotation(annotation) != null) {
return m;
}
}
return null;
}
private void populateContent(Node item, Object object) {
for (int i = 0; i < item.getChildNodes().getLength(); i++) {
Node child = item.getChildNodes().item(i);
if (child instanceof Text) {
setText(object, (Text) child);
}
}
}
private void setText(Object bean, Text child) {
List> pairs =
Reflect.findMethodsWithAnnotation(bean.getClass(), TagContent.class, bean);
for (Pair pair : pairs) {
try {
pair.first().invoke(bean, child.getTextContent());
} catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException | DOMException e) {
e.printStackTrace();
}
}
}
private boolean invokeOnSetter(Object object, Element element, String nodeName,
Object bean) {
Pair pair =
Reflect.findSetterForTag(object.getClass(), nodeName, bean);
List