package org.testng.xml; import static org.testng.internal.Utils.isStringBlank; import org.testng.ITestObjectFactory; import org.testng.TestNGException; import org.testng.collections.Lists; import org.testng.collections.Maps; import org.testng.internal.Utils; import org.testng.log4testng.Logger; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Stack; /** * Suite definition parser utility. * * @author Cedric Beust * @author Alexandru Popescu */ public class TestNGContentHandler extends DefaultHandler { private XmlSuite m_currentSuite = null; private XmlTest m_currentTest = null; private List m_currentDefines = null; private List m_currentRuns = null; private List m_currentClasses = null; private int m_currentTestIndex = 0; private int m_currentClassIndex = 0; private int m_currentIncludeIndex = 0; private List m_currentPackages = null; private XmlPackage m_currentPackage = null; private List m_suites = Lists.newArrayList(); private List m_currentIncludedGroups = null; private List m_currentExcludedGroups = null; private Map m_currentTestParameters = null; private Map m_currentSuiteParameters = null; private Map m_currentClassParameters = null; private Include m_currentInclude; private List m_currentMetaGroup = null; private String m_currentMetaGroupName; enum Location { SUITE, TEST, CLASS, INCLUDE, EXCLUDE } private Stack m_locations = new Stack<>(); private XmlClass m_currentClass = null; private ArrayList m_currentIncludedMethods = null; private List m_currentExcludedMethods = null; private ArrayList m_currentSelectors = null; private XmlMethodSelector m_currentSelector = null; private String m_currentLanguage = null; private String m_currentExpression = null; private List m_suiteFiles = Lists.newArrayList(); private boolean m_enabledTest; private List m_listeners; private String m_fileName; private boolean m_loadClasses; private boolean m_validate = false; private boolean m_hasWarn = false; public TestNGContentHandler(String fileName, boolean loadClasses) { m_fileName = fileName; m_loadClasses = loadClasses; } static private void ppp(String s) { System.out.println("[TestNGContentHandler] " + s); } /* * (non-Javadoc) * * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String, * java.lang.String) */ @Override public InputSource resolveEntity(String systemId, String publicId) throws IOException, SAXException { InputSource result = null; if (Parser.DEPRECATED_TESTNG_DTD_URL.equals(publicId) || Parser.TESTNG_DTD_URL.equals(publicId)) { m_validate = true; InputStream is = getClass().getClassLoader().getResourceAsStream(Parser.TESTNG_DTD); if (null == is) { is = Thread.currentThread().getContextClassLoader().getResourceAsStream(Parser.TESTNG_DTD); if (null == is) { System.out.println("WARNING: couldn't find in classpath " + publicId + "\n" + "Fetching it from the Web site."); result = super.resolveEntity(systemId, publicId); } else { result = new InputSource(is); } } else { result = new InputSource(is); } } else { result = super.resolveEntity(systemId, publicId); } return result; } /** * Parse */ private void xmlSuiteFile(boolean start, Attributes attributes) { if (start) { String path = attributes.getValue("path"); pushLocation(Location.SUITE); m_suiteFiles.add(path); } else { m_currentSuite.setSuiteFiles(m_suiteFiles); popLocation(Location.SUITE); } } /** * Parse */ private void xmlSuite(boolean start, Attributes attributes) { if (start) { pushLocation(Location.SUITE); String name = attributes.getValue("name"); if (isStringBlank(name)) { throw new TestNGException("The tag must define the name attribute"); } m_currentSuite = new XmlSuite(); m_currentSuite.setFileName(m_fileName); m_currentSuite.setName(name); m_currentSuiteParameters = Maps.newHashMap(); String verbose = attributes.getValue("verbose"); if (null != verbose) { m_currentSuite.setVerbose(Integer.parseInt(verbose)); } String jUnit = attributes.getValue("junit"); if (null != jUnit) { m_currentSuite.setJUnit(Boolean.valueOf(jUnit)); } String parallel = attributes.getValue("parallel"); if (parallel != null) { XmlSuite.ParallelMode mode = XmlSuite.ParallelMode.getValidParallel(parallel); if (mode != null) { m_currentSuite.setParallel(mode); } else { Utils.log("Parser", 1, "[WARN] Unknown value of attribute 'parallel' at suite level: '" + parallel + "'."); } } String parentModule = attributes.getValue("parent-module"); if (parentModule != null) { m_currentSuite.setParentModule(parentModule); } String guiceStage = attributes.getValue("guice-stage"); if (guiceStage != null) { m_currentSuite.setGuiceStage(guiceStage); } String configFailurePolicy = attributes.getValue("configfailurepolicy"); if (null != configFailurePolicy) { if (XmlSuite.SKIP.equals(configFailurePolicy) || XmlSuite.CONTINUE.equals(configFailurePolicy)) { m_currentSuite.setConfigFailurePolicy(configFailurePolicy); } } String groupByInstances = attributes.getValue("group-by-instances"); if (groupByInstances!= null) { m_currentSuite.setGroupByInstances(Boolean.valueOf(groupByInstances)); } String skip = attributes.getValue("skipfailedinvocationcounts"); if (skip != null) { m_currentSuite.setSkipFailedInvocationCounts(Boolean.valueOf(skip)); } String threadCount = attributes.getValue("thread-count"); if (null != threadCount) { m_currentSuite.setThreadCount(Integer.parseInt(threadCount)); } String dataProviderThreadCount = attributes.getValue("data-provider-thread-count"); if (null != dataProviderThreadCount) { m_currentSuite.setDataProviderThreadCount(Integer.parseInt(dataProviderThreadCount)); } String timeOut = attributes.getValue("time-out"); if (null != timeOut) { m_currentSuite.setTimeOut(timeOut); } String objectFactory = attributes.getValue("object-factory"); if (null != objectFactory && m_loadClasses) { try { m_currentSuite.setObjectFactory((ITestObjectFactory)Class.forName(objectFactory).newInstance()); } catch(Exception e) { Utils.log("Parser", 1, "[ERROR] Unable to create custom object factory '" + objectFactory + "' :" + e); } } String preserveOrder = attributes.getValue("preserve-order"); if (preserveOrder != null) { m_currentSuite.setPreserveOrder(preserveOrder); } String allowReturnValues = attributes.getValue("allow-return-values"); if (allowReturnValues != null) { m_currentSuite.setAllowReturnValues(Boolean.valueOf(allowReturnValues)); } } else { m_currentSuite.setParameters(m_currentSuiteParameters); m_suites.add(m_currentSuite); m_currentSuiteParameters = null; popLocation(Location.SUITE); } } /** * Parse */ private void xmlDefine(boolean start, Attributes attributes) { if (start) { String name = attributes.getValue("name"); m_currentDefines = Lists.newArrayList(); m_currentMetaGroup = Lists.newArrayList(); m_currentMetaGroupName = name; } else { m_currentTest.addMetaGroup(m_currentMetaGroupName, m_currentMetaGroup); m_currentDefines = null; } } /** * Parse