001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.mavenplugins.testsuite.report; 019 020 import org.xml.sax.Attributes; 021 import org.xml.sax.SAXException; 022 import org.xml.sax.helpers.DefaultHandler; 023 024 import javax.xml.parsers.ParserConfigurationException; 025 import javax.xml.parsers.SAXParser; 026 import javax.xml.parsers.SAXParserFactory; 027 import java.io.File; 028 import java.io.IOException; 029 import java.text.NumberFormat; 030 import java.text.ParseException; 031 import java.util.ArrayList; 032 import java.util.Collections; 033 import java.util.List; 034 import java.util.Map; 035 import java.util.StringTokenizer; 036 037 public class ReportTestSuite 038 extends DefaultHandler 039 { 040 private List testCases; 041 042 private int numberOfErrors; 043 044 private int numberOfFailures; 045 046 private int numberOfSkipped; 047 048 private int numberOfTests; 049 050 private String name; 051 052 private String fullClassName; 053 054 private String packageName; 055 056 private float timeElapsed; 057 058 private NumberFormat numberFormat = NumberFormat.getInstance(); 059 060 /** 061 * @noinspection StringBufferField 062 */ 063 private StringBuffer currentElement; 064 065 private ReportTestCase testCase; 066 067 public void parse( String xmlPath ) 068 throws ParserConfigurationException, SAXException, IOException 069 { 070 SAXParserFactory factory = SAXParserFactory.newInstance(); 071 072 SAXParser saxParser = factory.newSAXParser(); 073 074 saxParser.parse( new File( xmlPath ), this ); 075 } 076 077 078 private int getAttributeAsInt( Attributes attributes, String name ) 079 { 080 // may or may not exist 081 String valueAsString = attributes.getValue( name ); 082 if ( valueAsString != null ) 083 { 084 return Integer.parseInt( valueAsString ); 085 } 086 return 0; 087 } 088 089 public void startElement( String uri, String localName, String qName, Attributes attributes ) 090 throws SAXException 091 { 092 try 093 { 094 if ( "testsuite".equals( qName ) ) 095 { 096 numberOfErrors = getAttributeAsInt( attributes, "errors" ); 097 numberOfFailures = getAttributeAsInt( attributes, "failures" ); 098 numberOfSkipped = getAttributeAsInt( attributes, "skipped" ); 099 numberOfTests = getAttributeAsInt( attributes, "tests" ); 100 101 Number time = numberFormat.parse( attributes.getValue( "time" ) ); 102 103 timeElapsed = time.floatValue(); 104 105 //check if group attribute is existing 106 if ( attributes.getValue( "group" ) != null && !"".equals( attributes.getValue( "group" ) ) ) 107 { 108 packageName = attributes.getValue( "group" ); 109 110 name = attributes.getValue( "name" ); 111 112 fullClassName = packageName + "." + name; 113 } 114 else 115 { 116 fullClassName = attributes.getValue( "name" ); 117 118 name = fullClassName.substring( fullClassName.lastIndexOf( "." ) + 1, fullClassName.length() ); 119 120 int lastDotPosition = fullClassName.lastIndexOf( "." ); 121 if ( lastDotPosition < 0 ) 122 { 123 /* no package name */ 124 packageName = ""; 125 } 126 else 127 { 128 packageName = fullClassName.substring( 0, lastDotPosition ); 129 } 130 } 131 132 testCases = new ArrayList(); 133 } 134 else if ( "testcase".equals( qName ) ) 135 { 136 currentElement = new StringBuffer(); 137 138 testCase = new ReportTestCase(); 139 140 testCase.setFullClassName( fullClassName ); 141 142 testCase.setName( attributes.getValue( "name" ) ); 143 144 testCase.setClassName( name ); 145 146 String timeAsString = attributes.getValue( "time" ); 147 148 Number time = new Integer( 0 ); 149 150 if ( timeAsString != null ) 151 { 152 time = numberFormat.parse( timeAsString ); 153 } 154 155 testCase.setTime( time.floatValue() ); 156 157 testCase.setFullName( packageName + "." + name + "." + testCase.getName() ); 158 } 159 else if ( "failure".equals( qName ) ) 160 { 161 testCase.addFailure( attributes.getValue( "message" ), attributes.getValue( "type" ) ); 162 } 163 else if ( "error".equals( qName ) ) 164 { 165 testCase.addFailure( attributes.getValue( "message" ), attributes.getValue( "type" ) ); 166 } 167 } 168 catch ( ParseException e ) 169 { 170 throw new SAXException( e.getMessage(), e ); 171 } 172 } 173 174 public void endElement( String uri, String localName, String qName ) 175 throws SAXException 176 { 177 if ( "testcase".equals( qName ) ) 178 { 179 testCases.add( testCase ); 180 } 181 else if ( "failure".equals( qName ) ) 182 { 183 Map failure = testCase.getFailure(); 184 185 failure.put( "detail", parseCause( currentElement.toString() ) ); 186 } 187 else if ( "error".equals( qName ) ) 188 { 189 Map error = testCase.getFailure(); 190 191 error.put( "detail", parseCause( currentElement.toString() ) ); 192 } 193 } 194 195 public void characters( char[] ch, int start, int length ) 196 throws SAXException 197 { 198 String s = new String( ch, start, length ); 199 200 if ( ! "".equals( s.trim() ) ) 201 { 202 currentElement.append( s ); 203 } 204 } 205 206 public List getTestCases() 207 { 208 return this.testCases; 209 } 210 211 public int getNumberOfErrors() 212 { 213 return numberOfErrors; 214 } 215 216 public void setNumberOfErrors( int numberOfErrors ) 217 { 218 this.numberOfErrors = numberOfErrors; 219 } 220 221 public int getNumberOfFailures() 222 { 223 return numberOfFailures; 224 } 225 226 public void setNumberOfFailures( int numberOfFailures ) 227 { 228 this.numberOfFailures = numberOfFailures; 229 } 230 231 public int getNumberOfSkipped() 232 { 233 return numberOfSkipped; 234 } 235 236 public void setNumberOfSkipped( int numberOfSkipped ) 237 { 238 this.numberOfSkipped = numberOfSkipped; 239 } 240 241 public int getNumberOfTests() 242 { 243 return numberOfTests; 244 } 245 246 public void setNumberOfTests( int numberOfTests ) 247 { 248 this.numberOfTests = numberOfTests; 249 } 250 251 public String getName() 252 { 253 return name; 254 } 255 256 public void setName( String name ) 257 { 258 this.name = name; 259 } 260 261 public String getFName() 262 { 263 return name; 264 } 265 266 public void setFName( String name ) 267 { 268 this.name = name; 269 } 270 271 public String getPackageName() 272 { 273 return packageName; 274 } 275 276 public void setPackageName( String packageName ) 277 { 278 this.packageName = packageName; 279 } 280 281 public float getTimeElapsed() 282 { 283 return this.timeElapsed; 284 } 285 286 public void setTimeElapsed( float timeElapsed ) 287 { 288 this.timeElapsed = timeElapsed; 289 } 290 291 private List parseCause( String detail ) 292 { 293 String fullName = testCase.getFullName(); 294 String name = fullName.substring( fullName.lastIndexOf( "." ) + 1 ); 295 return parseCause( detail, name ); 296 } 297 298 private List parseCause( String detail, String compareTo ) 299 { 300 StringTokenizer stringTokenizer = new StringTokenizer( detail, "\n" ); 301 List parsedDetail = new ArrayList( stringTokenizer.countTokens() ); 302 303 while ( stringTokenizer.hasMoreTokens() ) 304 { 305 String lineString = stringTokenizer.nextToken().trim(); 306 parsedDetail.add( lineString ); 307 if ( lineString.indexOf( compareTo ) >= 0 ) 308 { 309 break; 310 } 311 } 312 313 return parsedDetail; 314 } 315 316 public void setTestCases( List testCases ) 317 { 318 this.testCases = Collections.unmodifiableList( testCases ); 319 } 320 }