Add debug-log dump() function to validate that XML has been parsed correctly.
Update (C) statements.
--- /dev/null
+#!/bin/bash
+CFB_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+INSTR_DIR="${CFB_ROOT}/../instr"
+
+#####################
+echo Compiling...
+find "${CFB_ROOT}/prod" -name "*.java" | xargs javac -g -Xlint:deprecation
+find "${CFB_ROOT}/test" -name "*.java" | xargs javac -g -classpath ${CFB_ROOT}/prod:${CLASSPATH} -Xlint:deprecation
+
+#####################
+echo Cleaning old coverage files...
+for x in "${INSTR_DIR}" report
+do
+ if [ -d "${x}" ]; then
+ rm -rf "${x}"
+ fi
+ mkdir -p "${x}"
+done
+for x in result.xml template.xml
+do
+ if [ -w ${x} ]; then
+ rm ${x}
+ fi
+done
+
+#####################
+echo Instrumenting...
+java -classpath "${CLASSPATH}" -jar `pwd`/jcov/jcov.jar Instr -t template.xml -o "${INSTR_DIR}" -type all "${CFB_ROOT}/prod"
+
+#####################
+echo Running unit tests...
+
+TESTS=""
+for x in `cd ${CFB_ROOT}/test; find . -name '*Test.class'`
+do
+ #echo CANDIDATE $x
+ TEST_CLASS=`echo ${x} | sed s:\^./:: | cut -d . -f 1 | sed s:/:.:g`
+ #echo TEST_CLASS ${TEST_CLASS}
+ TESTS="${TEST_CLASS} ${TESTS}"
+done
+
+echo First run: locale es_ES, timezone Europe/Madrid
+java -Duser.language=es -Duser.country=ES -Duser.timezone=Europe/Madrid -Djcov.template=${CFB_ROOT}/template.xml -Djcov.file=${CFB_ROOT}/result.xml -classpath "${INSTR_DIR}:${CFB_ROOT}/test:${CLASSPATH}:/usr/share/java/junit.jar:${CFB_ROOT}/jcov/jcov_file_saver.jar" org.junit.runner.JUnitCore ${TESTS}
+
+echo Second run: server default locale and timezone
+java -Djcov.template=${CFB_ROOT}/template.xml -Djcov.file=${CFB_ROOT}/result.xml -classpath "${INSTR_DIR}:${CFB_ROOT}/test:${CLASSPATH}:/usr/share/java/junit.jar:${CFB_ROOT}/jcov/jcov_file_saver.jar" org.junit.runner.JUnitCore ${TESTS}
+
+#####################
+echo Generating HTML Report...
+
+java -jar "${CFB_ROOT}/jcov/jcov.jar" RepGen -sourcepath "${CFB_ROOT}/prod" -log.level FINE result.xml
package net.jaekl.cfb;
+// Comparative FindBugs
+//
+// Tool to compare successive runs of FindBugs,
+// flagging the change from one run to the next.
+//
+// Copyright (C) 2015 Christian Jaekl
+
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import net.jaekl.cfb.db.CfbSchema;
import net.jaekl.cfb.db.driver.DbDriver;
import net.jaekl.cfb.db.driver.PostgresqlDriver;
+import net.jaekl.qd.xml.XmlParseException;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.GnuParser;
if (null != findBugsDir) {
m_fbDir = new File(findBugsDir);
}
- }
+ }
- void doMain(PrintWriter pw, String[] args) throws SQLException, IOException {
+ void doMain(PrintWriter pw, String[] args) throws SQLException, IOException, XmlParseException {
initArgs(); // read environment and system properties
if ( ! parseArgs(pw, args) ) {
return;
try (PrintWriter pw = new PrintWriter(System.out)){
cfb.doMain(pw, args);
pw.flush();
- } catch (SQLException | IOException exc) {
+ } catch (SQLException | IOException | XmlParseException exc) {
exc.printStackTrace();
}
}
package net.jaekl.cfb;
+// Copyright (C) 2015 Christian Jaekl
+
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
package net.jaekl.cfb.analyze;
-public class Analysis {
+// Copyright (C) 2015 Christian Jaekl
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+import net.jaekl.cfb.xml.BugCollection;
+import net.jaekl.qd.util.InputStreamWrapper;
+import net.jaekl.qd.xml.ParseErrorHandler;
+import net.jaekl.qd.xml.ParseHandler;
+
+public class Analysis {
+ BugCollection m_bugCollection;
+
+ public Analysis() {
+ m_bugCollection = null;
+ }
+
+ public BugCollection getBugCollection() { return m_bugCollection; }
+
+ public void parse(File xml) throws FileNotFoundException, IOException, SAXException
+ {
+ m_bugCollection = new BugCollection();
+
+ try (InputStreamWrapper isw = new InputStreamWrapper(new FileInputStream(xml)))
+ {
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+ ParseHandler ph = new ParseHandler(m_bugCollection);
+ ParseErrorHandler peh = new ParseErrorHandler();
+ reader.setContentHandler(ph);
+ reader.setErrorHandler(peh);
+ reader.parse(new InputSource(isw));
+ }
+ }
+
+ public void dump(PrintWriter pw)
+ {
+ if (null != m_bugCollection) {
+ m_bugCollection.dump(pw, 2);
+ }
+ }
}
package net.jaekl.cfb.analyze;
+// Copyright (C) 2015 Christian Jaekl
+
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Locale;
import java.util.Locale.Category;
+import org.xml.sax.SAXException;
+
import net.jaekl.cfb.CfbBundle;
import net.jaekl.cfb.util.Command;
+import net.jaekl.qd.xml.XmlParseException;
public class Analyzer {
File m_findbugsDir;
m_findbugsDir = findbugsDir;
}
- public Analysis analyze(PrintWriter pw, File workDir, File fbp) throws IOException {
+ public Analysis analyze(PrintWriter pw, File workDir, File fbp) throws IOException, XmlParseException {
Analysis result = new Analysis();
File fbOutput = outputWorkFile(workDir, fbp);
}
result = parseFbOutput(fbOutput);
-
+ result.dump(pw);
return result;
}
// Parse the output.xml that resulted from a FindBugs run,
// and store its findings into an Analysis object.
- Analysis parseFbOutput(File fbOutput)
+ Analysis parseFbOutput(File fbOutput) throws XmlParseException
{
- return null;
+ Analysis result = new Analysis();
+ try {
+ result.parse(fbOutput);
+ } catch (IOException | SAXException exc) {
+ throw new XmlParseException(exc);
+ }
+ return result;
}
}
package net.jaekl.cfb.db;
+// Copyright (C) 2015 Christian Jaekl
+
import static net.jaekl.cfb.db.Column.Null.*;
import static net.jaekl.cfb.db.Column.Type.*;
import net.jaekl.cfb.db.driver.DbDriver;
package net.jaekl.cfb.db;
+// Copyright (C) 2015 Christian Jaekl
+
public class Column {
public enum Type {
CHAR, INTEGER, TIMESTAMP, TIMESTAMPTZ, VARCHAR
package net.jaekl.cfb.db;
+// Copyright (C) 2015 Christian Jaekl
+
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
package net.jaekl.cfb.db;
+// Copyright (C) 2015 Christian Jaekl
+
import java.util.ArrayList;
import java.util.Arrays;
package net.jaekl.cfb.db.driver;
+// Copyright (C) 2015 Christian Jaekl
+
import static net.jaekl.cfb.db.Column.Null.*;
import java.sql.Connection;
package net.jaekl.cfb.db.driver;
+// Copyright (C) 2015 Christian Jaekl
+
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
package net.jaekl.cfb.util;
+// Copyright (C) 2015 Christian Jaekl
+
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
package net.jaekl.cfb.util;
+// Copyright (C) 2015 Christian Jaekl
+
import java.io.PrintWriter;
import java.io.StringWriter;
package net.jaekl.cfb.xml;
+import java.io.PrintWriter;
import java.util.ArrayList;
import org.xml.sax.Attributes;
+import net.jaekl.qd.xml.MissingAttributeException;
import net.jaekl.qd.xml.ParseResult;
import net.jaekl.qd.xml.XmlParseException;
static final String CLASS_NAME = "classname";
String m_className;
- ArrayList<SourceLine> m_sourceLines;
+ ArrayList<SourceLine> m_lines;
public BugClass() {
super(TAG, INTERNAL, EXTERNAL);
m_className = "";
+ m_lines = new ArrayList<SourceLine>();
+ }
+
+ @Override
+ public void handleMainAttributes(Attributes attr) throws MissingAttributeException
+ {
+ m_className = getRequiredAttr(TAG, attr, CLASS_NAME);
}
@Override
- public void endContents(String uri, String localName, String qName, String chars, Attributes attr)
+ public void endContents(String uri, String localName, String qName, String chars)
throws XmlParseException
{
- m_className = getRequiredAttr(TAG, attr, CLASS_NAME);
}
@Override
ParseResult[] collected = collectParsedChildren(SourceLine.class);
for (ParseResult pr : collected) {
assert(pr instanceof SourceLine);
- m_sourceLines.add((SourceLine)pr);
+ m_lines.add((SourceLine)pr);
}
}
}
+
+ @Override
+ public void dump(PrintWriter pw, int indent)
+ {
+ super.dump(pw, indent);
+ String tab = String.format("%" + (indent + 2) + "s", "");
+
+ pw.println(tab + CLASS_NAME + "=" + m_className);
+ if (null != m_lines) {
+ for (SourceLine sl : m_lines) {
+ sl.dump(pw, indent + 2);
+ }
+ }
+ }
}
package net.jaekl.cfb.xml;
-import org.xml.sax.Attributes;
+import java.io.PrintWriter;
+import java.util.ArrayList;
import net.jaekl.qd.xml.ParseResult;
import net.jaekl.qd.xml.XmlParseException;
static final String[] INTERNAL = { };
static final Object[][] EXTERNAL = { { BugInstance.TAG, BugInstance.class} };
+ ArrayList<BugInstance> m_bugs;
+
public BugCollection() {
super(TAG, INTERNAL, EXTERNAL);
+ m_bugs = new ArrayList<BugInstance>();
}
@Override
- public void endContents(String uri, String localName, String qName,
- String chars, Attributes attr) throws XmlParseException {
- // TODO Auto-generated method stub
-
+ public void endContents(String uri, String localName, String qName, String chars)
+ throws XmlParseException
+ {
+ // no-op
}
@Override
public void endExternal(String uri, String localName, String qName)
- throws XmlParseException {
- // TODO Auto-generated method stub
-
+ throws XmlParseException
+ {
+ if (BugInstance.TAG.equals(localName)) {
+ ParseResult[] collected = collectParsedChildren(BugInstance.class);
+ for (ParseResult pr : collected) {
+ assert(pr instanceof BugInstance);
+ m_bugs.add((BugInstance) pr);
+ }
+ }
+ }
+
+ @Override
+ public void dump(PrintWriter pw, int indent) {
+ super.dump(pw, indent);
+ for (BugInstance bug : m_bugs) {
+ bug.dump(pw, indent + 2);
+ }
}
}
package net.jaekl.cfb.xml;
+import java.io.PrintWriter;
import java.util.ArrayList;
import org.xml.sax.Attributes;
+import net.jaekl.qd.xml.MissingAttributeException;
import net.jaekl.qd.xml.ParseResult;
import net.jaekl.qd.xml.XmlParseException;
{ BugMethod.TAG, BugMethod.class},
{ LocalVariable.TAG, LocalVariable.class},
{ SourceLine.TAG, SourceLine.class} };
+ static final String TYPE = "type";
+ String m_type;
ArrayList<BugClass> m_classes;
ArrayList<BugMethod> m_methods;
ArrayList<LocalVariable> m_locals;
public BugInstance() {
super(TAG, INTERNAL, EXTERNAL);
+ m_type = null;
m_classes = new ArrayList<BugClass>();
m_methods = new ArrayList<BugMethod>();
m_locals = new ArrayList<LocalVariable>();
}
@Override
- public void endContents(String uri, String localName, String qName, String chars, Attributes attr)
+ public void endContents(String uri, String localName, String qName, String chars)
throws XmlParseException
{
+ // no-op
}
@Override
}
}
}
+
+ @Override
+ public void handleMainAttributes(Attributes attr) throws MissingAttributeException
+ {
+ m_type = this.getRequiredAttr(TAG, attr, TYPE);
+ }
+ @Override
+ public void dump(PrintWriter pw, int indent)
+ {
+ int childIndent = indent + 2;
+ String margin = String.format("%" + indent + "s", "");
+
+ pw.println(margin + TAG + " (" + m_type + ")");
+ for (BugClass bc : m_classes) {
+ bc.dump(pw, childIndent);
+ }
+ for (BugMethod bm : m_methods) {
+ bm.dump(pw, childIndent);
+ }
+ for (LocalVariable lv : m_locals) {
+ lv.dump(pw, childIndent);
+ }
+ for (SourceLine sl : m_lines) {
+ sl.dump(pw, childIndent);
+ }
+ }
}
package net.jaekl.cfb.xml;
+import java.io.PrintWriter;
import java.util.ArrayList;
import org.xml.sax.Attributes;
+import net.jaekl.qd.xml.MissingAttributeException;
import net.jaekl.qd.xml.ParseResult;
import net.jaekl.qd.xml.XmlParseException;
m_isStatic = false;
m_sourceLines = new ArrayList<SourceLine>();
}
-
+
@Override
- public void endContents(String uri, String localName, String qName, String chars, Attributes attr)
- throws XmlParseException
+ public void handleMainAttributes(Attributes attr) throws MissingAttributeException
{
m_className = getRequiredAttr(TAG, attr, CLASS_NAME);
m_methodName = getRequiredAttr(TAG, attr, METHOD_NAME);
m_signature = getRequiredAttr(TAG, attr, SIGNATURE);
m_isStatic = getRequiredAttr(TAG, attr, IS_STATIC).equals(TRUE);
- m_role = getOptionalAttr(attr, ROLE, null);
+ m_role = getOptionalAttr(attr, ROLE, null);
+ }
+
+ @Override
+ public void endContents(String uri, String localName, String qName, String chars)
+ throws XmlParseException
+ {
+ // no-op
}
@Override
}
}
}
+
+ @Override
+ public void dump(PrintWriter pw, int indent)
+ {
+ super.dump(pw, indent);
+ String tab = String.format("%" + (indent + 2) + "s", "");
+
+ pw.println(tab
+ + (m_isStatic ? "static" : "")
+ + m_className
+ + "."
+ + m_methodName
+ + m_signature);
+ if (null != m_role) {
+ pw.println(tab + ROLE + "=" + m_role);
+ }
+ if (null != m_sourceLines) {
+ for (SourceLine sl : m_sourceLines) {
+ sl.dump(pw, indent + 2);
+ }
+ }
+ }
}
package net.jaekl.cfb.xml;
+import java.io.PrintWriter;
+
import org.xml.sax.Attributes;
+import net.jaekl.qd.xml.MissingAttributeException;
import net.jaekl.qd.xml.ParseResult;
import net.jaekl.qd.xml.XmlParseException;
}
@Override
- public void endContents(String uri, String localName, String qName, String chars, Attributes attr)
- throws XmlParseException
+ public void handleMainAttributes(Attributes attr)
+ throws MissingAttributeException
{
m_name = getRequiredAttr(TAG, attr, NAME);
m_role = getRequiredAttr(TAG, attr, ROLE);
}
+
+ @Override
+ public void endContents(String uri, String localName, String qName, String chars)
+ throws XmlParseException
+ {
+ }
@Override
public void endExternal(String uri, String localName, String qName)
{
// no-op
}
+
+ @Override
+ public void dump(PrintWriter pw, int indent)
+ {
+ super.dump(pw, indent);
+ String tab = String.format("%" + (indent + 2) + "s", "");
+
+ pw.println(tab + NAME + "=" + m_name);
+ pw.println(tab + ROLE + "=" + m_role);
+ }
}
package net.jaekl.cfb.xml;
+import java.io.PrintWriter;
+
+import net.jaekl.qd.xml.MissingAttributeException;
import net.jaekl.qd.xml.ParseResult;
import net.jaekl.qd.xml.XmlParseException;
}
@Override
- public void endContents(String uri, String localName, String qName, String chars, Attributes attr)
- throws XmlParseException
- {
+ public void handleMainAttributes(Attributes attr) throws MissingAttributeException {
String scratch;
- m_className = getRequiredAttr(localName, attr, ATTR_CLASS_NAME);
+ m_className = getRequiredAttr(TAG, attr, ATTR_CLASS_NAME);
- scratch = getRequiredAttr(localName, attr, ATTR_START);
+ scratch = getRequiredAttr(TAG, attr, ATTR_START);
m_start = Integer.parseInt(scratch);
- scratch = getRequiredAttr(localName, attr, ATTR_END);
+ scratch = getRequiredAttr(TAG, attr, ATTR_END);
m_end = Integer.parseInt(scratch);
}
+ @Override
+ public void endContents(String uri, String localName, String qName, String chars)
+ throws XmlParseException
+ {
+ // no-op
+ }
+
@Override
public void endExternal(String uri, String localName, String qName)
throws XmlParseException
{
// no-op
}
+
+ @Override
+ public void dump(PrintWriter pw, int indent)
+ {
+ super.dump(pw, indent);
+ String tab = String.format("%" + (indent + 2) + "s", "");
+
+ pw.println(tab + m_className + " (" + m_start + " .. " + m_end + ")");
+ }
}
package net.jaekl.qd.xml;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
}
}
- public abstract void endContents(String uri, String localName, String qName, String chars, Attributes attr) throws XmlParseException;
+ public abstract void endContents(String uri, String localName, String qName, String chars) throws XmlParseException;
public abstract void endExternal(String uri, String localName, String qName) throws XmlParseException;
+
+ // Called once for this tag itself
+ public void handleMainAttributes(Attributes attr) throws MissingAttributeException {
+ // Default action is to do nothing.
+ // Override this if you want to process tag attributes.
+ }
+
+ // Called once for each internally-handled subtag
+ public void handleInternalAttributes(String tagName, Attributes attr) throws MissingAttributeException {
+ // Default action is to do nothing.
+ // Override this if you want to process tag attributes.
+ }
public String getTagName() { return m_tagName; }
- public boolean haveSeenMyTag() { return m_haveSeenMyTag; }
public void characters(char[] ch, int start, int length) throws XmlParseException
{
m_chars.append(ch, start, length);
}
+ // Dump human-readable text describing this tag and its children.
+ // Default implemenation: print the tag name (only)
+ public void dump(PrintWriter pw, int indent) {
+ String margin = String.format("%"+indent+"s", "");
+ pw.println(margin + getTagName());
+ }
+
protected ParseResult[] collectParsedChildren(Class<? extends ParseResult> cls) {
ArrayList<ParseResult> collection = new ArrayList<ParseResult>();
Iterator<ParseResult> iter = m_childParsers.iterator();
}
// returns true if this ParseResult's context has ended with this endElement() call
- public boolean endElement(String uri, String localName, String qName) throws XmlParseException
+ protected boolean endElement(String uri, String localName, String qName) throws XmlParseException
{
assert (null != localName);
}
String chars = m_chars.toString();
- endContents(uri, localName, qName, chars, info.getAttributes());
+ endContents(uri, localName, qName, chars);
return false;
}
// returns either itself, or a new ParseResult-derived object, whichever should handle parsing the inside of this element
- public ParseResult startElement(String uri, String localName, String qName, Attributes attributes)
+ public ParseResult startElement(String uri, String localName, String qName, Attributes attrs)
throws XmlParseException
{
assert (null != localName);
if (m_tagName.equals(localName)) {
m_haveSeenMyTag = true;
+ handleMainAttributes(attrs);
return this;
}
else {
}
if (m_internal.contains(localName)) {
- CurrentInfo info = new CurrentInfo(localName, attributes);
+ handleInternalAttributes(localName, attrs);
+ CurrentInfo info = new CurrentInfo(localName, attrs);
m_current.push(info);
return this;
}
try {
ParseResult childParser = (ParseResult) parserClass.newInstance();
m_childParsers.add(childParser);
- return childParser.startElement(uri, localName, qName, attributes);
+ return childParser.startElement(uri, localName, qName, attrs);
}
catch (IllegalAccessException iae) {
throw new XmlParseException(iae);
}
return value;
}
+
}
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Locale;
import org.junit.Assert;
+ "<Route><RouteNo>4</RouteNo><DirectionID>1</DirectionID><Direction>Northbound</Direction>"
+ "<RouteHeading>Rideau C / Ctr Rideau</RouteHeading>"
+ "<Trips>"
- + "<Trip><TripDestination>Rideau Centre / Centre Rideau</TripDestination><TripStartTime>19:00</TripStartTime>"
+ + "<Trip ghost=\"false\"><TripDestination>Rideau Centre / Centre Rideau</TripDestination><TripStartTime>19:00</TripStartTime>"
+ "<AdjustedScheduleTime>16</AdjustedScheduleTime><AdjustmentAge>0.45</AdjustmentAge><LastTripOfSchedule/>"
+ "<BusType>4LB - IN</BusType><Latitude>45.408957</Latitude><Longitude>-75.664125</Longitude>"
+ "<GPSSpeed>66.4</GPSSpeed></Trip>"
- + "<Trip><TripDestination>Rideau Centre / Centre Rideau</TripDestination>"
+ + "<Trip ghost=\"true\"><TripDestination>Rideau Centre / Centre Rideau</TripDestination>"
+ "<TripStartTime>19:30</TripStartTime><AdjustedScheduleTime>40</AdjustedScheduleTime><AdjustmentAge>-1</AdjustmentAge>"
+ "<LastTripOfSchedule/><BusType>4LB - IN</BusType><Latitude/><Longitude/><GPSSpeed/></Trip>"
- + "<Trip><TripDestination>Rideau Centre / Centre Rideau</TripDestination><TripStartTime>20:00</TripStartTime>"
+ + "<Trip ghost=\"true\"><TripDestination>Rideau Centre / Centre Rideau</TripDestination><TripStartTime>20:00</TripStartTime>"
+ "<AdjustedScheduleTime>70</AdjustedScheduleTime><AdjustmentAge>-1</AdjustmentAge><LastTripOfSchedule/>"
+ "<BusType>4LB - IN</BusType><Latitude/><Longitude/><GPSSpeed/></Trip>"
+ "</Trips></Route></Routes></GetRouteSummaryForStopResult></GetRouteSummaryForStopResponse>"
@Override
public void endContents(String uri, String localName, String qName,
- String chars, Attributes attr) throws XmlParseException
+ String chars) throws XmlParseException
{
Assert.fail("Should not have any contents to end.");
}
@Override
public void endContents(String uri, String localName, String qName,
- String chars, Attributes attr) throws XmlParseException
+ String chars) throws XmlParseException
{
if (localName.equals(ONE)) {
m_one = chars;
public RouteParse getRoute(int idx) { return m_routes.get(idx); }
@Override
- public void endContents(String uri, String localName, String qName,
- String chars, Attributes attr) throws XmlParseException
+ public void endContents(String uri, String localName, String qName, String chars) throws XmlParseException
{
if (localName.equals(STOP_NO)) {
m_stopNo = Integer.parseInt(chars);
@Override
public void endContents(String uri, String localName, String qName,
- String chars, Attributes attr) throws XmlParseException
+ String chars) throws XmlParseException
{
if (localName.equals(ROUTE_NO)) {
m_routeNo = Integer.parseInt(chars);
}
public static class TripParse extends ParseResult {
private static final String TRIP = "Trip";
+ private static final String GHOST = "ghost";
private static final String TRIP_DEST = "TripDestination";
private static final String TRIP_START = "TripStartTime";
private static final String ADJ_SCHED_TIME = "AdjustedScheduleTime";
// Data gleaned from parsing
String m_dest;
String m_startTime;
- int m_adjSchedTime;;
+ int m_adjSchedTime;
+ boolean m_ghost;
public TripParse() {
super(TRIP, INTERNAL, EXTERNAL);
m_dest = m_startTime = null;
m_adjSchedTime = 0;
+ m_ghost = false;
}
public String getDestination() { return m_dest; }
public String getStartTime() { return m_startTime; }
public int getAdjustedScheduleTime() { return m_adjSchedTime; }
+ public boolean ghostAttrSet() { return m_ghost; }
+
+ @Override
+ public void handleMainAttributes(Attributes attr) throws MissingAttributeException
+ {
+ String scratch = this.getRequiredAttr(TRIP, attr, GHOST);
+ Assert.assertNotNull(scratch);
+ m_ghost = scratch.toLowerCase(Locale.CANADA).equals("true");
+ }
@Override
public void endContents(String uri, String localName, String qName,
- String chars, Attributes attr) throws XmlParseException
+ String chars) throws XmlParseException
{
if (localName.equals(TRIP_DEST)) {
m_dest = chars;
Assert.assertEquals("Rideau Centre / Centre Rideau", tp.getDestination());
Assert.assertEquals("19:00", tp.getStartTime());
Assert.assertEquals(16, tp.getAdjustedScheduleTime());
+ Assert.assertEquals(false, tp.ghostAttrSet());
tp = rp.getTrip(1);
Assert.assertNotNull(tp);
Assert.assertEquals("Rideau Centre / Centre Rideau", tp.getDestination());
Assert.assertEquals("19:30", tp.getStartTime());
Assert.assertEquals(40, tp.getAdjustedScheduleTime());
+ Assert.assertEquals(true, tp.ghostAttrSet());
tp = rp.getTrip(2);
Assert.assertNotNull(tp);
Assert.assertEquals("Rideau Centre / Centre Rideau", tp.getDestination());
Assert.assertEquals("20:00", tp.getStartTime());
Assert.assertEquals(70, tp.getAdjustedScheduleTime());
+ Assert.assertEquals(true, tp.ghostAttrSet());
}
finally {
if (null != bais) {