1 package org.testng.xml; 2 3 import org.testng.TestNGException; 4 import org.testng.collections.Lists; 5 import org.testng.collections.Maps; 6 import org.testng.collections.Objects; 7 import org.testng.internal.ClassHelper; 8 import org.testng.reporters.XMLStringBuffer; 9 10 import java.io.Serializable; 11 import java.util.List; 12 import java.util.Map; 13 import java.util.Properties; 14 15 /** 16 * This class describes the tag <class> in testng.xml. 17 * 18 * @author <a href="mailto:cedric@beust.com">Cedric Beust</a> 19 */ 20 public class XmlClass implements Serializable, Cloneable { 21 22 private static final long serialVersionUID = 8885360896966149897L; 23 private List<XmlInclude> m_includedMethods = Lists.newArrayList(); 24 private List<String> m_excludedMethods = Lists.newArrayList(); 25 private String m_name = null; 26 private Class m_class = null; 27 /** The index of this class in the <test> tag */ 28 private int m_index; 29 /** True if the classes need to be loaded */ 30 private boolean m_loadClasses = true; 31 private Map<String, String> m_parameters = Maps.newHashMap(); 32 private XmlTest m_xmlTest; 33 XmlClass()34 public XmlClass() { 35 init("", null, 0, false /* load classes */); 36 } 37 XmlClass(String name)38 public XmlClass(String name) { 39 init(name, null, 0); 40 } 41 XmlClass(String name, boolean loadClasses)42 public XmlClass(String name, boolean loadClasses) { 43 init(name, null, 0, loadClasses); 44 } 45 XmlClass(Class cls)46 public XmlClass(Class cls) { 47 init(cls.getName(), cls, 0, true); 48 } 49 XmlClass(Class cls, boolean loadClasses)50 public XmlClass(Class cls, boolean loadClasses) { 51 init(cls.getName(), cls, 0, loadClasses); 52 } 53 XmlClass(String className, int index)54 public XmlClass(String className, int index) { 55 init(className, null, index, true /* load classes */); 56 } 57 XmlClass(String className, int index, boolean loadClasses)58 public XmlClass(String className, int index, boolean loadClasses) { 59 init(className, null, index, loadClasses); 60 } 61 init(String className, Class cls, int index)62 private void init(String className, Class cls, int index) { 63 init(className, cls, index, true /* load classes */); 64 } 65 init(String className, Class cls, int index, boolean resolveClass)66 private void init(String className, Class cls, int index, 67 boolean resolveClass) { 68 m_name = className; 69 m_class = cls; 70 m_index = index; 71 72 if (null == m_class && resolveClass) { 73 loadClass(); 74 } 75 } 76 loadClass()77 private void loadClass() { 78 m_class = ClassHelper.forName(m_name); 79 80 if (null == m_class) { 81 throw new TestNGException("Cannot find class in classpath: " + m_name); 82 } 83 } 84 85 /** 86 * @return Returns the className. 87 */ getSupportClass()88 public Class getSupportClass() { 89 if (m_class == null) loadClass(); 90 return m_class; 91 } 92 93 /** 94 * @param className The className to set. 95 */ setClass(Class className)96 public void setClass(Class className) { 97 m_class = className; 98 } 99 100 /** 101 * @return Returns the excludedMethods. 102 */ getExcludedMethods()103 public List<String> getExcludedMethods() { 104 return m_excludedMethods; 105 } 106 107 /** 108 * @param excludedMethods The excludedMethods to set. 109 */ setExcludedMethods(List<String> excludedMethods)110 public void setExcludedMethods(List<String> excludedMethods) { 111 m_excludedMethods = excludedMethods; 112 } 113 114 /** 115 * @return Returns the includedMethods. 116 */ getIncludedMethods()117 public List<XmlInclude> getIncludedMethods() { 118 return m_includedMethods; 119 } 120 121 /** 122 * @param includedMethods The includedMethods to set. 123 */ setIncludedMethods(List<XmlInclude> includedMethods)124 public void setIncludedMethods(List<XmlInclude> includedMethods) { 125 m_includedMethods = includedMethods; 126 } 127 128 /** 129 * @return Returns the name. 130 */ getName()131 public String getName() { 132 return m_name; 133 } 134 135 /** 136 * @param name The name to set. 137 */ setName(String name)138 public void setName(String name) { 139 m_name = name; 140 } 141 142 /** 143 * @return true if the classes need to be loaded. 144 */ loadClasses()145 public boolean loadClasses() { 146 return m_loadClasses; 147 } 148 149 @Override toString()150 public String toString() { 151 return Objects.toStringHelper(getClass()) 152 .add("class", m_name) 153 .toString(); 154 } 155 toXml(String indent)156 public String toXml(String indent) { 157 XMLStringBuffer xsb = new XMLStringBuffer(indent); 158 Properties prop = new Properties(); 159 prop.setProperty("name", getName()); 160 161 boolean hasMethods = !m_includedMethods.isEmpty() || !m_excludedMethods.isEmpty(); 162 boolean hasParameters = !m_parameters.isEmpty(); 163 if (hasParameters || hasMethods) { 164 xsb.push("class", prop); 165 XmlUtils.dumpParameters(xsb, m_parameters); 166 167 if (hasMethods) { 168 xsb.push("methods"); 169 170 for (XmlInclude m : getIncludedMethods()) { 171 xsb.getStringBuffer().append(m.toXml(indent + " ")); 172 } 173 174 for (String m: getExcludedMethods()) { 175 Properties p= new Properties(); 176 p.setProperty("name", m); 177 xsb.addEmptyElement("exclude", p); 178 } 179 180 xsb.pop("methods"); 181 } 182 183 xsb.pop("class"); 184 } 185 else { 186 xsb.addEmptyElement("class", prop); 187 } 188 189 return xsb.toXML(); 190 191 } 192 listToString(List<Integer> invocationNumbers)193 public static String listToString(List<Integer> invocationNumbers) { 194 StringBuilder result = new StringBuilder(); 195 int i = 0; 196 for (Integer n : invocationNumbers) { 197 if (i++ > 0) { 198 result.append(" "); 199 } 200 result.append(n); 201 } 202 return result.toString(); 203 } 204 205 /** 206 * Clone an XmlClass by copying all its components. 207 */ 208 @Override clone()209 public Object clone() { 210 XmlClass result = new XmlClass(getName(), getIndex(), loadClasses()); 211 result.setExcludedMethods(getExcludedMethods()); 212 result.setIncludedMethods(getIncludedMethods()); 213 214 return result; 215 } 216 217 /** 218 * Note that this attribute does not come from the XML file, it's calculated 219 * internally and represents the order in which this class was found in its 220 * <test> tag. It's used to calculate the ordering of the classes 221 * when preserve-order is true. 222 */ getIndex()223 public int getIndex() { 224 return m_index; 225 } 226 setIndex(int index)227 public void setIndex(int index) { 228 m_index = index; 229 } 230 231 @Override hashCode()232 public int hashCode() { 233 final int prime = 31; 234 int result = 1; 235 result = prime * result + ((m_class == null) ? 0 : m_class.hashCode()); 236 result = prime * result + (m_loadClasses ? 1 : 0); 237 result = prime * result 238 + ((m_excludedMethods == null) ? 0 : m_excludedMethods.hashCode()); 239 result = prime * result 240 + ((m_includedMethods == null) ? 0 : m_includedMethods.hashCode()); 241 result = prime * result + m_index; 242 result = prime * result + ((m_name == null) ? 0 : m_name.hashCode()); 243 return result; 244 } 245 246 @Override equals(Object obj)247 public boolean equals(Object obj) { 248 if (this == obj) { 249 return true; 250 } 251 if (obj == null) 252 return XmlSuite.f(); 253 if (getClass() != obj.getClass()) 254 return XmlSuite.f(); 255 XmlClass other = (XmlClass) obj; 256 if (other.m_loadClasses != m_loadClasses) { 257 return XmlSuite.f(); 258 } else if (!m_excludedMethods.equals(other.m_excludedMethods)) { 259 return XmlSuite.f(); 260 } 261 if (m_includedMethods == null) { 262 if (other.m_includedMethods != null) 263 return XmlSuite.f(); 264 } else if (!m_includedMethods.equals(other.m_includedMethods)) 265 return XmlSuite.f(); 266 // if (m_index != other.m_index) 267 // return XmlSuite.f(); 268 if (m_name == null) { 269 if (other.m_name != null) 270 return XmlSuite.f(); 271 } else if (!m_name.equals(other.m_name)) 272 return XmlSuite.f(); 273 274 return true; 275 } 276 setParameters(Map<String, String> parameters)277 public void setParameters(Map<String, String> parameters) { 278 m_parameters.clear(); 279 m_parameters.putAll(parameters); 280 } 281 282 /** 283 * @return The parameters defined in this test tag and the tags above it. 284 */ getAllParameters()285 public Map<String, String> getAllParameters() { 286 Map<String, String> result = Maps.newHashMap(); 287 Map<String, String> parameters = m_xmlTest.getLocalParameters(); 288 result.putAll(parameters); 289 result.putAll(m_parameters); 290 return result; 291 } 292 293 /** 294 * @return The parameters defined in this tag, and only this test tag. To retrieve 295 * the inherited parameters as well, call {@code getAllParameters()}. 296 */ getLocalParameters()297 public Map<String, String> getLocalParameters() { 298 return m_parameters; 299 } 300 301 /** 302 * @deprecated Use {@code getLocalParameters()} or {@code getAllParameters()} 303 */ 304 @Deprecated getParameters()305 public Map<String, String> getParameters() { 306 return getAllParameters(); 307 } 308 setXmlTest(XmlTest test)309 public void setXmlTest(XmlTest test) { 310 m_xmlTest = test; 311 } 312 } 313