diff options
author | Kevin Smith <git@kismith.co.uk> | 2012-01-12 16:48:02 (GMT) |
---|---|---|
committer | Kevin Smith <git@kismith.co.uk> | 2012-01-16 15:54:31 (GMT) |
commit | 839db071f46d083b86996f514f5fe0f2d6aee80a (patch) | |
tree | 9f14beb42dcd82fa4deba10f516a0ba0368e57b5 /src/com/isode/stroke/parser | |
parent | 3adee817bfcbd54fd13c4d946bedadeca661e9b1 (diff) | |
download | stroke-839db071f46d083b86996f514f5fe0f2d6aee80a.zip stroke-839db071f46d083b86996f514f5fe0f2d6aee80a.tar.bz2 |
Add support for DiscoItems and DiscoInfo.
Updates requisite classes in line with Swiften.
Also fixes bugs in the EventLoops not using handleEvent.
Diffstat (limited to 'src/com/isode/stroke/parser')
8 files changed, 239 insertions, 13 deletions
diff --git a/src/com/isode/stroke/parser/Attribute.java b/src/com/isode/stroke/parser/Attribute.java new file mode 100644 index 0000000..d624550 --- /dev/null +++ b/src/com/isode/stroke/parser/Attribute.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2012, Isode Limited, London, England. + * All rights reserved. + */ +/* + * Copyright (c) 2010, Remko Tronçon. + * All rights reserved. + */ +package com.isode.stroke.parser; + +/* + * Internal parsing class. + */ +public class Attribute { + + public Attribute(String name, String ns) { + this.name = name; + this.ns = ns; + } + + public String getName() { + return name; + } + + public String getNamespace() { + return ns; + } + + @Override + public boolean equals(Object other) { + return other != null + && other instanceof Attribute + && name.equals(((Attribute) other).getName()) + && ns.equals(((Attribute) other).getNamespace()); + } + + @Override + public int hashCode() { + int hash = 3; + hash = 19 * hash + (this.name != null ? this.name.hashCode() : 0); + hash = 19 * hash + (this.ns != null ? this.ns.hashCode() : 0); + return hash; + } + private final String name; + private final String ns; +} diff --git a/src/com/isode/stroke/parser/AttributeMap.java b/src/com/isode/stroke/parser/AttributeMap.java index fb4aa68..0e43785 100644 --- a/src/com/isode/stroke/parser/AttributeMap.java +++ b/src/com/isode/stroke/parser/AttributeMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Isode Limited, London, England. + * Copyright (c) 2010-2012, Isode Limited, London, England. * All rights reserved. */ /* @@ -8,26 +8,103 @@ */ package com.isode.stroke.parser; -import java.util.HashMap; +import com.isode.stroke.base.NotNull; +import java.util.ArrayList; +import java.util.List; /** * XML element attributes. */ -public class AttributeMap extends HashMap<String, String> { +public class AttributeMap { + + /** + * Internal class. + */ + public class Entry { + + public Entry(Attribute attribute, String value) { + NotNull.exceptIfNull(attribute, "attribute"); + NotNull.exceptIfNull(value, "value"); + this.attribute = attribute; + this.value = value; + } + + public Attribute getAttribute() { + return attribute; + } + + public String getValue() { + return value; + } + private final Attribute attribute; + private final String value; + }; + + public AttributeMap() { + } + + /** Not null */ public String getAttribute(String attribute) { - return this.containsKey(attribute) ? this.get(attribute) : ""; + NotNull.exceptIfNull(attribute, "attribute"); + return getAttribute(attribute, ""); } - public String getAttributeValue(String attribute) { - return this.containsKey(attribute) ? this.get(attribute) : null; + /** Not null*/ + public String getAttribute(String attribute, String ns) { + String value = getInternal(attribute, ns); + return value != null ? value : ""; } + /** + * + * @param attribute attribute name. + * @return boolean value, defaulting to false if missing. + */ public boolean getBoolAttribute(String attribute) { return getBoolAttribute(attribute, false); } public boolean getBoolAttribute(String attribute, boolean defaultValue) { - String value = getAttribute(attribute); + String value = getInternal(attribute, ""); + if (value == null) { + return defaultValue; + } return "true".equals(value) || "1".equals(value); } + + /** @return Attribute or null if missing.*/ + public String getAttributeValue(String attribute) { + return getInternal(attribute, ""); + } + + /** + * + * @param name Attribute name (non-null). + * @param ns Attribute namespace (non-null). + * @param value Attribute value (non-null). + */ + public void addAttribute(String name, String ns, String value) { + NotNull.exceptIfNull(name, "name"); + NotNull.exceptIfNull(ns, "ns"); + NotNull.exceptIfNull(value, "value"); + attributes.add(new Entry(new Attribute(name, ns), value)); + } + + /** + * Internal method (used for unit tests). + */ + public List<Entry> getEntries() { + return new ArrayList(attributes); + } + + private String getInternal(String name, String ns) { + Attribute attribute = new Attribute(name, ns); + for (Entry entry : attributes) { + if (entry.getAttribute().equals(attribute)) { + return entry.value; + } + } + return null; + } + private final List<Entry> attributes = new ArrayList<Entry>(); } diff --git a/src/com/isode/stroke/parser/GenericPayloadParser.java b/src/com/isode/stroke/parser/GenericPayloadParser.java index 7642d91..4901537 100644 --- a/src/com/isode/stroke/parser/GenericPayloadParser.java +++ b/src/com/isode/stroke/parser/GenericPayloadParser.java @@ -22,7 +22,7 @@ public abstract class GenericPayloadParser <T extends Payload> implements Payloa return payload_; } - protected T getPayloadInternal() { + public T getPayloadInternal() { return payload_; } } diff --git a/src/com/isode/stroke/parser/PullXMLParser.java b/src/com/isode/stroke/parser/PullXMLParser.java index 8b42afe..845dfbc 100644 --- a/src/com/isode/stroke/parser/PullXMLParser.java +++ b/src/com/isode/stroke/parser/PullXMLParser.java @@ -78,7 +78,7 @@ class PullXMLParser extends XMLParser { if (eventType == XmlPullParser.START_TAG) { AttributeMap map = new AttributeMap(); for (int i = 0; i < parser_.getAttributeCount(); i++) { - map.put(parser_.getAttributeName(i), parser_.getAttributeValue(i)); + map.addAttribute(parser_.getAttributeName(i), parser_.getAttributeNamespace(i), parser_.getAttributeValue(i)); } addEvent(new Event(parser_.getName(), parser_.getNamespace(), map)); bump(); diff --git a/src/com/isode/stroke/parser/SerializingParser.java b/src/com/isode/stroke/parser/SerializingParser.java index d18b912..1b89c68 100644 --- a/src/com/isode/stroke/parser/SerializingParser.java +++ b/src/com/isode/stroke/parser/SerializingParser.java @@ -19,8 +19,9 @@ public class SerializingParser { public void handleStartElement(String tag, String ns, AttributeMap attributes) { XMLElement element = new XMLElement(tag, ns); - for (String name : attributes.keySet()) { - element.setAttribute(name, attributes.get(name)); + //FIXME: Ignoring attribute namespace + for (AttributeMap.Entry e : attributes.getEntries()) { + element.setAttribute(e.getAttribute().getName(), e.getValue()); } if (elementStack_.isEmpty()) { diff --git a/src/com/isode/stroke/parser/payloadparsers/DiscoInfoParser.java b/src/com/isode/stroke/parser/payloadparsers/DiscoInfoParser.java new file mode 100644 index 0000000..445a6de --- /dev/null +++ b/src/com/isode/stroke/parser/payloadparsers/DiscoInfoParser.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012, Isode Limited, London, England. + * All rights reserved. + */ +/* + * Copyright (c) 2010, Remko Tronçon. + * All rights reserved. + */ +package com.isode.stroke.parser.payloadparsers; + +import com.isode.stroke.elements.DiscoInfo; +import com.isode.stroke.parser.AttributeMap; +import com.isode.stroke.parser.GenericPayloadParser; + + +class DiscoInfoParser extends GenericPayloadParser<DiscoInfo> { + public DiscoInfoParser() { + super(new DiscoInfo()); + } + + public void handleStartElement(String element, String ns, AttributeMap attributes) { + if (level_ == PayloadLevel) { + if (element .equals("identity")) { + getPayloadInternal().addIdentity(new DiscoInfo.Identity(attributes.getAttribute("name"), attributes.getAttribute("category"), attributes.getAttribute("type"), attributes.getAttribute("lang", "http://www.w3.org/XML/1998/namespace"))); + } + else if (element.equals("feature")) { + getPayloadInternal().addFeature(attributes.getAttribute("var")); + } + else if (element.equals("x") && ns.equals("jabber:x:data")) { + assert(formParser_ == null); + formParser_ = new FormParser(); + } + } + if (formParser_ != null) { + formParser_.handleStartElement(element, ns, attributes); + } + ++level_; + } + + public void handleEndElement(String element, String ns) { + --level_; + if (formParser_ != null) { + formParser_.handleEndElement(element, ns); + } + if (level_ == PayloadLevel && formParser_ != null) { + getPayloadInternal().addExtension(formParser_.getPayloadInternal()); + formParser_ = null; + } + } + + public void handleCharacterData(String data) { + if (formParser_ != null) { + formParser_.handleCharacterData(data); + } + } + + private static final int TopLevel = 0; + private static final int PayloadLevel = 1; + private int level_ = 0; + private FormParser formParser_ = null; +} diff --git a/src/com/isode/stroke/parser/payloadparsers/DiscoItemsParser.java b/src/com/isode/stroke/parser/payloadparsers/DiscoItemsParser.java new file mode 100644 index 0000000..caf75cf --- /dev/null +++ b/src/com/isode/stroke/parser/payloadparsers/DiscoItemsParser.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2012, Isode Limited, London, England. + * All rights reserved. + */ +/* + * Copyright (c) 2010, Kevin Smith. + * All rights reserved. + */ +package com.isode.stroke.parser.payloadparsers; + +import com.isode.stroke.elements.DiscoItems; +import com.isode.stroke.elements.DiscoItems.Item; +import com.isode.stroke.jid.JID; +import com.isode.stroke.parser.AttributeMap; +import com.isode.stroke.parser.GenericPayloadParser; + +class DiscoItemsParser extends GenericPayloadParser<DiscoItems> { + public DiscoItemsParser() { + super(new DiscoItems()); + } + + public void handleStartElement(String element, String ns, AttributeMap attributes) { + if (level_ == PayloadLevel) { + if (element.equals("item")) { + Item item = new Item(attributes.getAttribute("name"), new JID(attributes.getAttribute("jid")), attributes.getAttribute("node")); + getPayloadInternal().addItem(item); + } + } + ++level_; + } + + public void handleEndElement(String element, String ns) { + --level_; + } + + public void handleCharacterData(String data) { + } + private static final int TopLevel = 0; + private static final int PayloadLevel = 1; + private int level_ = TopLevel; +} diff --git a/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java b/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java index 6114626..7273cf2 100644 --- a/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java +++ b/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java @@ -27,8 +27,8 @@ public class FullPayloadParserFactoryCollection extends PayloadParserFactoryColl addFactory(new SoftwareVersionParserFactory()); //addFactory(new StorageParserFactory()); addFactory(new RosterParserFactory()); - //addFactory(new DiscoInfoParserFactory()); - //addFactory(new DiscoItemsParserFactory()); + addFactory(new GenericPayloadParserFactory<DiscoInfoParser>("query", "http://jabber.org/protocol/disco#info", DiscoInfoParser.class)); + addFactory(new GenericPayloadParserFactory<DiscoItemsParser>("query", "http://jabber.org/protocol/disco#items", DiscoItemsParser.class)); //addFactory(new CapsInfoParserFactory()); addFactory(new ResourceBindParserFactory()); addFactory(new StartSessionParserFactory()); |