1 20 package org.apache.cactus.internal.server.runner; 21 22 import java.text.NumberFormat ; 23 import java.util.Locale ; 24 25 import junit.framework.AssertionFailedError; 26 import junit.framework.Test; 27 import junit.framework.TestFailure; 28 import junit.framework.TestListener; 29 import junit.framework.TestResult; 30 31 import org.apache.cactus.internal.util.JUnitVersionHelper; 32 import org.apache.cactus.internal.util.StringUtil; 33 34 39 public class XMLFormatter implements XMLConstants, TestListener 40 { 41 44 private static final String [] DEFAULT_STACK_FILTER_PATTERNS = new String [] 45 { 46 "org.apache.cactus.AbstractTestCase", 47 "org.apache.cactus.AbstractWebTestCase", 48 "org.apache.cactus.FilterTestCase", 49 "org.apache.cactus.JspTestCase", 50 "org.apache.cactus.ServletTestCase", 51 "junit.framework.TestCase", 52 "junit.framework.TestResult", 53 "junit.framework.TestSuite", 54 "junit.framework.Assert.", "java.lang.reflect.Method.invoke(" 56 }; 57 58 63 private String xslFileName; 64 65 68 private String suiteClassName; 69 70 73 private long totalDuration; 74 75 78 private String encoding = "UTF-8"; 79 80 83 private long currentTestStartTime; 84 85 90 private NumberFormat durationFormat = NumberFormat.getInstance(Locale.US); 91 92 95 private StringBuffer currentTestCaseResults = new StringBuffer (); 96 97 100 private String currentTestFailure; 101 102 109 public void setXslFileName(String theXslFileName) 110 { 111 this.xslFileName = theXslFileName; 112 } 113 114 117 public void setEncoding(String theEncoding) 118 { 119 this.encoding = theEncoding; 120 } 121 122 125 public String getEncoding() 126 { 127 return this.encoding; 128 } 129 130 133 public String getSuiteClassName() 134 { 135 return this.suiteClassName; 136 } 137 138 143 public void setSuiteClassName(String theSuiteClassName) 144 { 145 this.suiteClassName = theSuiteClassName; 146 } 147 148 151 public String getTotalDurationAsString() 152 { 153 return getDurationAsString(this.totalDuration); 154 } 155 156 162 private String getDurationAsString(long theDuration) 163 { 164 return durationFormat.format((double) theDuration / 1000); 165 } 166 167 172 public void setTotalDuration(long theDuration) 173 { 174 this.totalDuration = theDuration; 175 } 176 177 183 public String toXML(TestResult theResult) 184 { 185 StringBuffer xml = new StringBuffer (); 186 187 xml.append("<?xml version=\"1.0\" encoding=\"" + getEncoding() 188 + "\"?>"); 189 190 if (this.xslFileName != null) 191 { 192 xml.append("<?xml-stylesheet type=\"text/xsl\" " + "href=\"" 193 + this.xslFileName + "\"?>"); 194 } 195 196 xml.append("<" + TESTSUITES + ">"); 197 198 xml.append("<" + TESTSUITE + " " + ATTR_NAME + "=\"" 199 + getSuiteClassName() + "\" " + ATTR_TESTS + "=\"" 200 + theResult.runCount() + "\" " + ATTR_FAILURES + "=\"" 201 + theResult.failureCount() + "\" " + ATTR_ERRORS + "=\"" 202 + theResult.errorCount() + "\" " + ATTR_TIME + "=\"" 203 + getTotalDurationAsString() + "\">"); 204 205 xml.append(this.currentTestCaseResults.toString()); 206 207 xml.append("</" + TESTSUITE + ">"); 208 xml.append("</" + TESTSUITES + ">"); 209 210 return xml.toString(); 211 } 212 213 218 public void startTest(Test theTest) 219 { 220 this.currentTestStartTime = System.currentTimeMillis(); 221 this.currentTestFailure = null; 222 } 223 224 230 public void addError(Test theTest, Throwable theThrowable) 231 { 232 TestFailure failure = new TestFailure(theTest, theThrowable); 233 StringBuffer xml = new StringBuffer (); 234 235 xml.append("<" + ERROR + " " + ATTR_MESSAGE + "=\"" 236 + xmlEncode(failure.thrownException().getMessage()) + "\" " 237 + ATTR_TYPE + "=\"" 238 + failure.thrownException().getClass().getName() + "\">"); 239 xml.append(xmlEncode(StringUtil.exceptionToString( 240 failure.thrownException(), DEFAULT_STACK_FILTER_PATTERNS))); 241 xml.append("</" + ERROR + ">"); 242 243 this.currentTestFailure = xml.toString(); 244 } 245 246 252 public void addFailure(Test theTest, AssertionFailedError theError) 253 { 254 TestFailure failure = new TestFailure(theTest, theError); 255 StringBuffer xml = new StringBuffer (); 256 257 xml.append("<" + FAILURE + " " + ATTR_MESSAGE + "=\"" 258 + xmlEncode(failure.thrownException().getMessage()) + "\" " 259 + ATTR_TYPE + "=\"" 260 + failure.thrownException().getClass().getName() + "\">"); 261 xml.append(xmlEncode(StringUtil.exceptionToString( 262 failure.thrownException(), DEFAULT_STACK_FILTER_PATTERNS))); 263 xml.append("</" + FAILURE + ">"); 264 265 this.currentTestFailure = xml.toString(); 266 } 267 268 273 public void endTest(Test theTest) 274 { 275 StringBuffer xml = new StringBuffer (); 276 String duration = getDurationAsString(System.currentTimeMillis() 277 - this.currentTestStartTime); 278 279 xml.append("<" + TESTCASE + " " + ATTR_NAME + "=\"" 280 + JUnitVersionHelper.getTestCaseName(theTest) + "\" " 281 + ATTR_TIME + "=\"" + duration + "\">"); 282 283 if (this.currentTestFailure != null) 284 { 285 xml.append(this.currentTestFailure); 286 } 287 288 xml.append("</" + TESTCASE + ">"); 289 290 this.currentTestCaseResults.append(xml.toString()); 291 } 292 293 299 private String xmlEncode(String theString) 300 { 301 String newString; 302 303 newString = XMLFormatter.replace(theString, '&', "&"); 306 307 newString = XMLFormatter.replace(newString, '<', "<"); 308 newString = XMLFormatter.replace(newString, '>', ">"); 309 newString = XMLFormatter.replace(newString, '\"', """); 310 311 return newString; 312 } 313 314 323 private static String replace(String theBaseString, char theChar, 324 String theNewString) 325 { 326 if (theBaseString == null) 327 { 328 return null; 329 } 330 331 final int len = theBaseString.length() - 1; 332 int pos = -1; 333 334 while ((pos = theBaseString.indexOf(theChar, pos + 1)) > -1) 335 { 336 if (pos == 0) 337 { 338 final String after = theBaseString.substring(1); 339 340 theBaseString = theNewString + after; 341 } 342 else if (pos == len) 343 { 344 final String before = theBaseString.substring(0, pos); 345 346 theBaseString = before + theNewString; 347 } 348 else 349 { 350 final String before = theBaseString.substring(0, pos); 351 final String after = theBaseString.substring(pos + 1); 352 353 theBaseString = before + theNewString + after; 354 } 355 } 356 357 return theBaseString; 358 } 359 360 } 361 | Popular Tags |