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 }