/*
* Copyright (C) 2008 Digital Sundhed (SDSD)
*
* All source code and information supplied as part of chronos
* is copyright to its contributers.
*
* The source code has been released under a dual license - meaning you can
* use either licensed version of the library with your code.
*
* It is released under the Common Public License 1.0, a copy of which can
* be found at the link below.
* http://www.opensource.org/licenses/cpl.php
*
* It is released under the LGPL (GNU Lesser General Public License), either
* version 2.1 of the License, or (at your option) any later version. A copy
* of which can be found at the link below.
* http://www.gnu.org/copyleft/lesser.html
*/
package org.codehaus.mojo.chronos.jmeter;
import java.util.Properties;
import org.codehaus.mojo.chronos.responsetime.GroupedResponsetimeSamples;
import org.codehaus.mojo.chronos.responsetime.ResponsetimeSample;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* SAXHandler for JMeter xml logs.
*
* @author ksr@lakeside.dk
*/
public final class JMeterSAXFileHandler extends DefaultHandler {
private final GroupedResponsetimeSamples samples = new GroupedResponsetimeSamples();
private Properties sampleAttributes;
private boolean inProperty = false;
private boolean insideSample = false;
private StringBuffer testMethodNameSB = new StringBuffer();
private Properties parentSampleAttributes;
/**
* @see DefaultHandler#startElement(String, String, String, Attributes)
*/
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if("sampleResult".equals(qName)) {
// jtl20
Properties props = new Properties();
for (int i = 0; i < attributes.getLength(); i++) {
props.put(attributes.getQName(i), attributes.getValue(i));
}
sampleAttributes = props;
insideSample = true;
} else if("property".equals(qName)) {
// jtl20
// TODO be sure that log cannot contain other types of character
// data under junitSamples properties
inProperty = true;
} else if("httpSample".equals(qName) || "sample".equals(qName)) {
// jtl21
if(insideSample) {
parentSampleAttributes = sampleAttributes;
}
Properties props = new Properties();
for (int i = 0; i < attributes.getLength(); i++) {
props.put(attributes.getQName(i), attributes.getValue(i));
}
sampleAttributes = props;
insideSample = true;
}
}
/**
* this method can be called multiple times in one element if there's enough chars.
*
* @see DefaultHandler#characters(char[], int, int)
*/
public void characters(char[] ch, int start, int length) {
if(insideSample && inProperty) {
testMethodNameSB.append(new String(ch, start, length));
}
}
/**
* @see DefaultHandler#endElement(String, String, String)
*/
public void endElement(String uri, String localName, String qName) throws SAXException {
if("property".equals(qName)) {
inProperty = false;
} else if("sampleResult".equals(qName)) {
// jtl20
ResponsetimeSample sample = new Jtl20Sample(sampleAttributes);
String sampleName = Jtl20Sample.getSampleName(sampleAttributes, testMethodNameSB.toString());
samples.add(sample, sampleName);
testMethodNameSB.setLength(0);
insideSample = false;
sampleAttributes = null;
} else if("httpSample".equals(qName) || "sample".equals(qName)) {
// jtl21
if(!insideSample) {
sampleAttributes = parentSampleAttributes;
}
String sampleName = Jtl21Sample.getSampleName(sampleAttributes);
ResponsetimeSample sample = new Jtl21Sample(sampleAttributes);
samples.add(sample, sampleName);
testMethodNameSB.setLength(0);
sampleAttributes = null;
insideSample = false;
}
}
/**
* @return the generated samples obtained by parsing the logfile
*/
public GroupedResponsetimeSamples getJMeterSamples() {
return samples;
}
}