diff --git a/src/org/rubyforge/debugcommons/reader/VariablesReader.java b/src/org/rubyforge/debugcommons/reader/VariablesReader.java index 122e8ef..d1d1f25 100644 --- a/src/org/rubyforge/debugcommons/reader/VariablesReader.java +++ b/src/org/rubyforge/debugcommons/reader/VariablesReader.java @@ -73,27 +73,53 @@ private void parseVariables() throws XmlPullParserException, IOException { if (Util.isEndTag(xpp, "variables")) { break; } - assert xpp.getName().equals("variable") : xpp.getName() + "(type: " + Util.getType(xpp) + ") encountered"; - String name = getAttributeValue("name"); - String value = getAttributeValue("value"); - String kind = getAttributeValue("kind"); - RubyVariableInfo newVariable; - if (value == null) { - newVariable = new RubyVariableInfo(name, kind); - } else { - String type = getAttributeValue("type"); - boolean hasChildren = getAttributeBoolValue("hasChildren"); - String objectId = getAttributeValue("objectId"); - newVariable = new RubyVariableInfo(name, kind, value, type, hasChildren, objectId); - } - _variables.add(newVariable); - ensureEndTag("variable"); + _variables.add(parseVariable()); } this.variables = _variables.toArray(new RubyVariableInfo[_variables.size()]); } + private RubyVariableInfo parseVariable() throws XmlPullParserException, IOException { + assert xpp.getName().equals("variable") : xpp.getName() + "(type: " + Util.getType(xpp) + ") encountered"; + final String name = getAttributeValue("name"); + String value = getAttributeValue("value"); + final String kind = getAttributeValue("kind"); + + if (value == null) { + ensureEndTag("variable"); + return new RubyVariableInfo(name, kind); + } + + final String type = getAttributeValue("type"); + final boolean hasChildren = getAttributeBoolValue("hasChildren"); + final String objectId = getAttributeValue("objectId"); + value = readValueFromElement(value); + ensureAtEndTag(xpp, "variable"); + + return new RubyVariableInfo(name, kind, value, type, hasChildren, objectId); + } + + /** + * Tries to read value from {@code value} sub-element, if there is no sub-element default value will be returned. + * Note: xpp moved to the next event after sub-element. + */ + private String readValueFromElement(final String defaultValue) throws IOException, XmlPullParserException { + String value = defaultValue; + final int nextTag = xpp.next(); + if (nextTag == XmlPullParser.START_TAG && "value".equals(xpp.getName())) { + xpp.next(); + if (xpp.getEventType() == XmlPullParser.TEXT) { + value = xpp.getText(); + xpp.next(); + } + ensureAtEndTag(xpp, "value"); + xpp.next(); + } + + return value; + } + private void parseProcessingException() throws XmlPullParserException, IOException { - LOGGER.severe("Processing exception occured." + + LOGGER.severe("Processing exception occurred." + " exceptionMessage: " + getAttributeValue("message") + ", exceptionType: " + getAttributeValue("type")); ensureEndTag("processingException"); diff --git a/src/org/rubyforge/debugcommons/reader/XmlStreamReader.java b/src/org/rubyforge/debugcommons/reader/XmlStreamReader.java index c1e89e0..b08fe99 100644 --- a/src/org/rubyforge/debugcommons/reader/XmlStreamReader.java +++ b/src/org/rubyforge/debugcommons/reader/XmlStreamReader.java @@ -34,15 +34,23 @@ public abstract class XmlStreamReader { public XmlStreamReader(XmlPullParser xpp) { this.xpp = xpp; } - + protected void ensureEndTag(final String name) throws XmlPullParserException, IOException { - int nextTag = xpp.next(); - if (nextTag != XmlPullParser.END_TAG && !name.equals(xpp.getName())) { + ensureEndTag(xpp, name); + } + + public static void ensureEndTag(XmlPullParser xpp, final String name) throws XmlPullParserException, IOException { + xpp.next(); + ensureAtEndTag(xpp, name); + } + + protected static void ensureAtEndTag(XmlPullParser xpp, final String name) throws XmlPullParserException, IOException { + if (xpp.getEventType() != XmlPullParser.END_TAG && !name.equals(xpp.getName())) { throw new IllegalStateException( "Unexpected event. Expecting " + name + " end tag." + xpp.getName()); } } - + /** * Works like {@link XmlPullParser#next} but skips all {@link * XmlPullParser#TEXT} events.