2011/08/05 - Jakarta Cactus has been retired.

For more information, please explore the Attic.

Clover coverage report - Cactus 1.8dev for J2EE API 1.3
Coverage timestamp: Sun Mar 26 2006 18:50:18 BRT
file stats: LOC: 314   Methods: 14
NCLOC: 143   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
XMLFormatter.java 0% 0% 0% 0%
coverage
 1   
 /* 
 2   
  * ========================================================================
 3   
  * 
 4   
  * Copyright 2001-2005 The Apache Software Foundation.
 5   
  *
 6   
  * Licensed under the Apache License, Version 2.0 (the "License");
 7   
  * you may not use this file except in compliance with the License.
 8   
  * You may obtain a copy of the License at
 9   
  * 
 10   
  *   http://www.apache.org/licenses/LICENSE-2.0
 11   
  * 
 12   
  * Unless required by applicable law or agreed to in writing, software
 13   
  * distributed under the License is distributed on an "AS IS" BASIS,
 14   
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15   
  * See the License for the specific language governing permissions and
 16   
  * limitations under the License.
 17   
  * 
 18   
  * ========================================================================
 19   
  */
 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   
 /**
 35   
  * Format the test results in XML.
 36   
  *
 37   
  * @version $Id: XMLFormatter.java 239169 2005-05-05 09:21:54Z vmassol $
 38   
  */
 39   
 public class XMLFormatter implements XMLConstants, TestListener
 40   
 {
 41   
     /**
 42   
      * Default stack filter patterns.
 43   
      */
 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.", // don't filter AssertionFailure
 55   
             "java.lang.reflect.Method.invoke("
 56   
         };
 57   
 
 58   
     /**
 59   
      * (optional) Name of the XSL stylesheet to put in the returned XML string
 60   
      * so that the browser will try to apply it (IE at least, I don't know
 61   
      * about the others).
 62   
      */
 63   
     private String xslFileName;
 64   
 
 65   
     /**
 66   
      * The name of the test suite class.
 67   
      */
 68   
     private String suiteClassName;
 69   
 
 70   
     /**
 71   
      * Duration it took to execute all the tests.
 72   
      */
 73   
     private long totalDuration;
 74   
 
 75   
     /**
 76   
      * Encoding to use for the returned XML. Defaults to "UTF-8". 
 77   
      */
 78   
     private String encoding = "UTF-8";
 79   
     
 80   
     /**
 81   
      * Time current test was started
 82   
      */
 83   
     private long currentTestStartTime;
 84   
 
 85   
     /**
 86   
      * The number format used to convert durations into strings. Don't use the
 87   
      * default locale for that, because the resulting string needs to use 
 88   
      * dotted decimal notation for an XSLT transformation to work correctly.
 89   
      */
 90   
     private NumberFormat durationFormat = NumberFormat.getInstance(Locale.US);
 91   
 
 92   
     /**
 93   
      * XML string containing executed test case results
 94   
      */
 95   
     private StringBuffer currentTestCaseResults = new StringBuffer();
 96   
 
 97   
     /**
 98   
      * Current test failure (XML string) : failure or error.
 99   
      */
 100   
     private String currentTestFailure;
 101   
 
 102   
     /**
 103   
      * Sets the XSL stylesheet file name to put in the returned XML string
 104   
      * so that the browser will try to apply it (IE at least, I don't know
 105   
      * about the others).
 106   
      *
 107   
      * @param theXslFileName the file name (relative to the webapp root)
 108   
      */
 109  0
     public void setXslFileName(String theXslFileName)
 110   
     {
 111  0
         this.xslFileName = theXslFileName;
 112   
     }
 113   
 
 114   
     /**
 115   
      * @param theEncoding the encoding to use for the returned XML.
 116   
      */
 117  0
     public void setEncoding(String theEncoding)
 118   
     {
 119  0
         this.encoding = theEncoding;
 120   
     }
 121   
 
 122   
     /**
 123   
      * @return the encoding to use for the returned XML
 124   
      */
 125  0
     public String getEncoding()
 126   
     {
 127  0
         return this.encoding;
 128   
     }
 129   
     
 130   
     /**
 131   
      * @return the suite class name
 132   
      */
 133  0
     public String getSuiteClassName()
 134   
     {
 135  0
         return this.suiteClassName;
 136   
     }
 137   
 
 138   
     /**
 139   
      * Sets the suite class name that was executed.
 140   
      *
 141   
      * @param theSuiteClassName the suite class name
 142   
      */
 143  0
     public void setSuiteClassName(String theSuiteClassName)
 144   
     {
 145  0
         this.suiteClassName = theSuiteClassName;
 146   
     }
 147   
 
 148   
     /**
 149   
      * @return the total duration as a string
 150   
      */
 151  0
     public String getTotalDurationAsString()
 152   
     {
 153  0
         return getDurationAsString(this.totalDuration);
 154   
     }
 155   
 
 156   
     /**
 157   
      * Comvert a duration expressed as a long into a string.
 158   
      *
 159   
      * @param theDuration the duration to convert to string
 160   
      * @return the total duration as a string
 161   
      */
 162  0
     private String getDurationAsString(long theDuration)
 163   
     {
 164  0
         return durationFormat.format((double) theDuration / 1000);
 165   
     }
 166   
 
 167   
     /**
 168   
      * Sets the duration it took to execute all the tests.
 169   
      *
 170   
      * @param theDuration the time it took
 171   
      */
 172  0
     public void setTotalDuration(long theDuration)
 173   
     {
 174  0
         this.totalDuration = theDuration;
 175   
     }
 176   
 
 177   
     /**
 178   
      * Formats the test result as an XML string.
 179   
      *
 180   
      * @param theResult the test result object
 181   
      * @return the XML string representation of the test results
 182   
      */
 183  0
     public String toXML(TestResult theResult)
 184   
     {
 185  0
         StringBuffer xml = new StringBuffer();
 186   
 
 187  0
         xml.append("<?xml version=\"1.0\" encoding=\"" + getEncoding()
 188   
             + "\"?>");
 189   
 
 190  0
         if (this.xslFileName != null)
 191   
         {
 192  0
             xml.append("<?xml-stylesheet type=\"text/xsl\" " + "href=\""
 193   
                 + this.xslFileName + "\"?>");
 194   
         }
 195   
 
 196  0
         xml.append("<" + TESTSUITES + ">");
 197   
 
 198  0
         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  0
         xml.append(this.currentTestCaseResults.toString());
 206   
 
 207  0
         xml.append("</" + TESTSUITE + ">");
 208  0
         xml.append("</" + TESTSUITES + ">");
 209   
 
 210  0
         return xml.toString();
 211   
     }
 212   
 
 213   
     /**
 214   
      * Event called by the base test runner when the test starts.
 215   
      *
 216   
      * @param theTest the test object being executed
 217   
      */
 218  0
     public void startTest(Test theTest)
 219   
     {
 220  0
         this.currentTestStartTime = System.currentTimeMillis();
 221  0
         this.currentTestFailure = null;
 222   
     }
 223   
 
 224   
     /**
 225   
      * Event called by the base test runner when the test fails with an error.
 226   
      *
 227   
      * @param theTest the test object that failed
 228   
      * @param theThrowable the exception that was thrown
 229   
      */
 230  0
     public void addError(Test theTest, Throwable theThrowable)
 231   
     {
 232  0
         TestFailure failure = new TestFailure(theTest, theThrowable);
 233  0
         StringBuffer xml = new StringBuffer();
 234   
 
 235  0
         xml.append("<" + ERROR + " " + ATTR_MESSAGE + "=\""
 236   
             + xmlEncode(failure.thrownException().getMessage()) + "\" "
 237   
             + ATTR_TYPE + "=\""
 238   
             + failure.thrownException().getClass().getName() + "\">");
 239  0
         xml.append(xmlEncode(StringUtil.exceptionToString(
 240   
             failure.thrownException(), DEFAULT_STACK_FILTER_PATTERNS)));
 241  0
         xml.append("</" + ERROR + ">");
 242   
 
 243  0
         this.currentTestFailure = xml.toString();
 244   
     }
 245   
 
 246   
     /**
 247   
      * Event called by the base test runner when the test fails with a failure.
 248   
      *
 249   
      * @param theTest the test object that failed
 250   
      * @param theError the exception that was thrown
 251   
      */
 252  0
     public void addFailure(Test theTest, AssertionFailedError theError)
 253   
     {
 254  0
         TestFailure failure = new TestFailure(theTest, theError);
 255  0
         StringBuffer xml = new StringBuffer();
 256   
 
 257  0
         xml.append("<" + FAILURE + " " + ATTR_MESSAGE + "=\""
 258   
             + xmlEncode(failure.thrownException().getMessage()) + "\" "
 259   
             + ATTR_TYPE + "=\""
 260   
             + failure.thrownException().getClass().getName() + "\">");
 261  0
         xml.append(xmlEncode(StringUtil.exceptionToString(
 262   
             failure.thrownException(), DEFAULT_STACK_FILTER_PATTERNS)));
 263  0
         xml.append("</" + FAILURE + ">");
 264   
 
 265  0
         this.currentTestFailure = xml.toString();
 266   
     }
 267   
 
 268   
     /**
 269   
      * Event called by the base test runner when the test ends.
 270   
      *
 271   
      * @param theTest the test object being executed
 272   
      */
 273  0
     public void endTest(Test theTest)
 274   
     {
 275  0
         StringBuffer xml = new StringBuffer();
 276  0
         String duration = getDurationAsString(System.currentTimeMillis()
 277   
             - this.currentTestStartTime);
 278   
 
 279  0
         xml.append("<" + TESTCASE + " " + ATTR_NAME + "=\""
 280   
             + JUnitVersionHelper.getTestCaseName(theTest) + "\" "
 281   
             + ATTR_TIME + "=\"" + duration + "\">");
 282   
 
 283  0
         if (this.currentTestFailure != null)
 284   
         {
 285  0
             xml.append(this.currentTestFailure);
 286   
         }
 287   
 
 288  0
         xml.append("</" + TESTCASE + ">");
 289   
 
 290  0
         this.currentTestCaseResults.append(xml.toString());
 291   
     }
 292   
 
 293   
     /**
 294   
      * Escapes reserved XML characters.
 295   
      *
 296   
      * @param theString the string to escape
 297   
      * @return the escaped string
 298   
      */
 299  0
     private String xmlEncode(String theString)
 300   
     {
 301  0
         String newString;
 302   
 
 303   
         // It is important to replace the "&" first as the other replacements
 304   
         // also introduces "&" chars ...
 305  0
         newString = StringUtil.replace(theString, '&', "&amp;");
 306   
 
 307  0
         newString = StringUtil.replace(newString, '<', "&lt;");
 308  0
         newString = StringUtil.replace(newString, '>', "&gt;");
 309  0
         newString = StringUtil.replace(newString, '\"', "&quot;");
 310   
 
 311  0
         return newString;
 312   
     }
 313   
 }
 314