summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2011-07-01 09:19:49 (GMT)
committerKevin Smith <git@kismith.co.uk>2011-07-01 09:19:49 (GMT)
commit2da71a8a85486a494343f1662d64fb5ae5a2a44e (patch)
tree23992f9f2a00bac23b345e5c2cc9c1194efc25be /src/com/isode/stroke/parser
downloadstroke-2da71a8a85486a494343f1662d64fb5ae5a2a44e.zip
stroke-2da71a8a85486a494343f1662d64fb5ae5a2a44e.tar.bz2
Initial import
Diffstat (limited to 'src/com/isode/stroke/parser')
-rw-r--r--src/com/isode/stroke/parser/AttributeMap.java33
-rw-r--r--src/com/isode/stroke/parser/AuthChallengeParser.java40
-rw-r--r--src/com/isode/stroke/parser/AuthFailureParser.java21
-rw-r--r--src/com/isode/stroke/parser/AuthRequestParser.java42
-rw-r--r--src/com/isode/stroke/parser/AuthResponseParser.java40
-rw-r--r--src/com/isode/stroke/parser/AuthSuccessParser.java40
-rw-r--r--src/com/isode/stroke/parser/CompressFailureParser.java21
-rw-r--r--src/com/isode/stroke/parser/CompressParser.java46
-rw-r--r--src/com/isode/stroke/parser/CompressedParser.java21
-rw-r--r--src/com/isode/stroke/parser/ElementParser.java25
-rw-r--r--src/com/isode/stroke/parser/EnableStreamManagementParser.java21
-rw-r--r--src/com/isode/stroke/parser/GenericElementParser.java46
-rw-r--r--src/com/isode/stroke/parser/GenericPayloadParser.java28
-rw-r--r--src/com/isode/stroke/parser/GenericPayloadParserFactory.java42
-rw-r--r--src/com/isode/stroke/parser/GenericStanzaParser.java29
-rw-r--r--src/com/isode/stroke/parser/IQParser.java34
-rw-r--r--src/com/isode/stroke/parser/MessageParser.java34
-rw-r--r--src/com/isode/stroke/parser/PayloadParser.java25
-rw-r--r--src/com/isode/stroke/parser/PayloadParserFactory.java18
-rw-r--r--src/com/isode/stroke/parser/PayloadParserFactoryCollection.java41
-rw-r--r--src/com/isode/stroke/parser/PlatformXMLParserFactory.java21
-rw-r--r--src/com/isode/stroke/parser/PresenceParser.java44
-rw-r--r--src/com/isode/stroke/parser/PullXMLParser.java219
-rw-r--r--src/com/isode/stroke/parser/SerializingParser.java48
-rw-r--r--src/com/isode/stroke/parser/StanzaAckParser.java39
-rw-r--r--src/com/isode/stroke/parser/StanzaAckRequestParser.java21
-rw-r--r--src/com/isode/stroke/parser/StanzaParser.java95
-rw-r--r--src/com/isode/stroke/parser/StartTLSFailureParser.java21
-rw-r--r--src/com/isode/stroke/parser/StartTLSParser.java21
-rw-r--r--src/com/isode/stroke/parser/StreamFeaturesParser.java74
-rw-r--r--src/com/isode/stroke/parser/StreamManagementEnabledParser.java38
-rw-r--r--src/com/isode/stroke/parser/StreamManagementFailedParser.java21
-rw-r--r--src/com/isode/stroke/parser/StreamResumeParser.java42
-rw-r--r--src/com/isode/stroke/parser/StreamResumedParser.java42
-rw-r--r--src/com/isode/stroke/parser/TLSProceedParser.java20
-rw-r--r--src/com/isode/stroke/parser/UnknownElementParser.java18
-rw-r--r--src/com/isode/stroke/parser/UnknownPayloadParser.java32
-rw-r--r--src/com/isode/stroke/parser/XMLParser.java24
-rw-r--r--src/com/isode/stroke/parser/XMLParserClient.java19
-rw-r--r--src/com/isode/stroke/parser/XMPPParser.java168
-rw-r--r--src/com/isode/stroke/parser/XMPPParserClient.java19
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/BodyParser.java40
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/BodyParserFactory.java19
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java55
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/LastParser.java46
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/RawXMLPayloadParser.java45
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/RawXMLPayloadParserFactory.java26
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/ResourceBindParser.java56
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/ResourceBindParserFactory.java20
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/RosterParser.java82
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/RosterParserFactory.java19
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/SearchPayloadParser.java124
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/SearchPayloadParserFactory.java21
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/SoftwareVersionParser.java51
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/SoftwareVersionParserFactory.java20
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/StartSessionParser.java35
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/StartSessionParserFactory.java19
57 files changed, 2371 insertions, 0 deletions
diff --git a/src/com/isode/stroke/parser/AttributeMap.java b/src/com/isode/stroke/parser/AttributeMap.java
new file mode 100644
index 0000000..dc948ce
--- /dev/null
+++ b/src/com/isode/stroke/parser/AttributeMap.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import java.util.HashMap;
+
+/**
+ * XML element attributes.
+ */
+public class AttributeMap extends HashMap<String, String> {
+ public String getAttribute(String attribute) {
+ return this.get(attribute);
+ }
+
+ public String getAttributeValue(String attribute) {
+ return this.containsKey(attribute) ? this.get(attribute) : null;
+ }
+
+ public boolean getBoolAttribute(String attribute) {
+ return getBoolAttribute(attribute, false);
+ }
+
+ public boolean getBoolAttribute(String attribute, boolean defaultValue) {
+ String value = getAttribute(attribute);
+ return "true".equals(value) || "1".equals(value);
+ }
+}
diff --git a/src/com/isode/stroke/parser/AuthChallengeParser.java b/src/com/isode/stroke/parser/AuthChallengeParser.java
new file mode 100644
index 0000000..20238dd
--- /dev/null
+++ b/src/com/isode/stroke/parser/AuthChallengeParser.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2010-2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.AuthChallenge;
+import com.isode.stroke.stringcodecs.Base64;
+
+class AuthChallengeParser extends GenericElementParser<AuthChallenge> {
+
+ public AuthChallengeParser() {
+ super(AuthChallenge.class);
+ }
+
+ @Override
+ public void handleStartElement(String unused1, String unused2, AttributeMap unused3) {
+ ++depth;
+ }
+
+ @Override
+ public void handleEndElement(String unused1, String unused2) {
+ --depth;
+ if (depth == 0) {
+ getElementGeneric().setValue(Base64.decode(text));
+ }
+ }
+
+ @Override
+ public void handleCharacterData(String text) {
+ this.text += text;
+ }
+ private int depth = 0;
+ private String text = "";
+}
diff --git a/src/com/isode/stroke/parser/AuthFailureParser.java b/src/com/isode/stroke/parser/AuthFailureParser.java
new file mode 100644
index 0000000..c42abed
--- /dev/null
+++ b/src/com/isode/stroke/parser/AuthFailureParser.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.AuthFailure;
+
+class AuthFailureParser extends GenericElementParser<AuthFailure> {
+
+ public AuthFailureParser() {
+ super(AuthFailure.class);
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/AuthRequestParser.java b/src/com/isode/stroke/parser/AuthRequestParser.java
new file mode 100644
index 0000000..7f40c9c
--- /dev/null
+++ b/src/com/isode/stroke/parser/AuthRequestParser.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.AuthRequest;
+import com.isode.stroke.stringcodecs.Base64;
+
+class AuthRequestParser extends GenericElementParser<AuthRequest> {
+
+ public AuthRequestParser() {
+ super(AuthRequest.class);
+ }
+
+ @Override
+ public void handleStartElement(String a, String b, AttributeMap attribute) {
+ if (depth_ == 0) {
+ getElementGeneric().setMechanism(attribute.getAttribute("mechanism"));
+ }
+ ++depth_;
+ }
+
+ @Override
+ public void handleEndElement(String a, String b) {
+ --depth_;
+ if (depth_ == 0) {
+ getElementGeneric().setMessage(Base64.decode(text_));
+ }
+ }
+
+ @Override
+ public void handleCharacterData(String a) {
+ text_ += a;
+ }
+ String text_ = "";
+ int depth_ = 0;
+}
diff --git a/src/com/isode/stroke/parser/AuthResponseParser.java b/src/com/isode/stroke/parser/AuthResponseParser.java
new file mode 100644
index 0000000..a93249a
--- /dev/null
+++ b/src/com/isode/stroke/parser/AuthResponseParser.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2010-2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.AuthResponse;
+import com.isode.stroke.stringcodecs.Base64;
+
+class AuthResponseParser extends GenericElementParser<AuthResponse> {
+
+ public AuthResponseParser() {
+ super(AuthResponse.class);
+ }
+
+ @Override
+ public void handleStartElement(String unused1, String unused2, AttributeMap unused3) {
+ ++depth;
+ }
+
+ @Override
+ public void handleEndElement(String unused1, String unused2) {
+ --depth;
+ if (depth == 0) {
+ getElementGeneric().setValue(Base64.decode(text));
+ }
+ }
+
+ @Override
+ public void handleCharacterData(String text) {
+ this.text += text;
+ }
+ private int depth = 0;
+ private String text = "";
+}
diff --git a/src/com/isode/stroke/parser/AuthSuccessParser.java b/src/com/isode/stroke/parser/AuthSuccessParser.java
new file mode 100644
index 0000000..111d3ce
--- /dev/null
+++ b/src/com/isode/stroke/parser/AuthSuccessParser.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010-2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.AuthSuccess;
+import com.isode.stroke.stringcodecs.Base64;
+
+class AuthSuccessParser extends GenericElementParser<AuthSuccess> {
+
+ public AuthSuccessParser() {
+ super(AuthSuccess.class);
+ }
+
+ @Override
+ public void handleStartElement(String a, String b, AttributeMap attribute) {
+ ++depth_;
+ }
+
+ @Override
+ public void handleEndElement(String a, String b) {
+ --depth_;
+ if (depth_ == 0) {
+ getElementGeneric().setValue(Base64.decode(text_));
+ }
+ }
+
+ @Override
+ public void handleCharacterData(String a) {
+ text_ += a;
+ }
+ String text_ = "";
+ int depth_ = 0;
+}
diff --git a/src/com/isode/stroke/parser/CompressFailureParser.java b/src/com/isode/stroke/parser/CompressFailureParser.java
new file mode 100644
index 0000000..cbfa413
--- /dev/null
+++ b/src/com/isode/stroke/parser/CompressFailureParser.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.CompressFailure;
+
+class CompressFailureParser extends GenericElementParser<CompressFailure> {
+
+ public CompressFailureParser() {
+ super(CompressFailure.class);
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/CompressParser.java b/src/com/isode/stroke/parser/CompressParser.java
new file mode 100644
index 0000000..133b20b
--- /dev/null
+++ b/src/com/isode/stroke/parser/CompressParser.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.CompressRequest;
+
+class CompressParser extends GenericElementParser<CompressRequest> {
+
+ private int currentDepth_ = 0;
+ private String currentText_;
+ private boolean inMethod_;
+
+ public CompressParser() {
+ super(CompressRequest.class);
+ }
+
+ @Override
+ public void handleStartElement(String element, String ns, AttributeMap attributes) {
+ if (currentDepth_ == 1 && element.equals("method")) {
+ inMethod_ = true;
+ currentText_ = "";
+ }
+ ++currentDepth_;
+ }
+
+ @Override
+ public void handleEndElement(String el, String ns) {
+ --currentDepth_;
+ if (currentDepth_ == 1 && inMethod_) {
+ getElementGeneric().setMethod(currentText_);
+ inMethod_ = false;
+ }
+ }
+
+ @Override
+ public void handleCharacterData(String data) {
+ currentText_ += data;
+ }
+}
diff --git a/src/com/isode/stroke/parser/CompressedParser.java b/src/com/isode/stroke/parser/CompressedParser.java
new file mode 100644
index 0000000..77d17e4
--- /dev/null
+++ b/src/com/isode/stroke/parser/CompressedParser.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.Compressed;
+
+class CompressedParser extends GenericElementParser<Compressed> {
+
+ public CompressedParser() {
+ super(Compressed.class);
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/ElementParser.java b/src/com/isode/stroke/parser/ElementParser.java
new file mode 100644
index 0000000..eebb51a
--- /dev/null
+++ b/src/com/isode/stroke/parser/ElementParser.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.Element;
+
+/**
+ * Parse XML Elements.
+ */
+public interface ElementParser {
+
+ void handleStartElement(String element, String ns, AttributeMap attributes);
+
+ void handleEndElement(String element, String ns);
+
+ void handleCharacterData(String data);
+
+ Element getElement();
+}
diff --git a/src/com/isode/stroke/parser/EnableStreamManagementParser.java b/src/com/isode/stroke/parser/EnableStreamManagementParser.java
new file mode 100644
index 0000000..fe657dd
--- /dev/null
+++ b/src/com/isode/stroke/parser/EnableStreamManagementParser.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.EnableStreamManagement;
+
+class EnableStreamManagementParser extends GenericElementParser<EnableStreamManagement> {
+
+ public EnableStreamManagementParser() {
+ super(EnableStreamManagement.class);
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/GenericElementParser.java b/src/com/isode/stroke/parser/GenericElementParser.java
new file mode 100644
index 0000000..da961f6
--- /dev/null
+++ b/src/com/isode/stroke/parser/GenericElementParser.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.Element;
+
+public class GenericElementParser<T extends Element> implements ElementParser {
+
+ private final T element_;
+
+ public GenericElementParser(Class c) {
+ try {
+ element_ = (T) c.newInstance();
+ } catch (InstantiationException ex) {
+ /* Fatal */
+ throw new RuntimeException(ex);
+ } catch (IllegalAccessException ex) {
+ /* Fatal */
+ throw new RuntimeException(ex);
+ }
+ }
+
+
+ public Element getElement() {
+ return element_;
+ }
+
+ protected T getElementGeneric() {
+ return element_;
+ }
+
+ public void handleStartElement(String a, String b, AttributeMap c) {
+ }
+
+ public void handleEndElement(String a, String b) {
+ }
+
+ public void handleCharacterData(String a) {
+ }
+}
diff --git a/src/com/isode/stroke/parser/GenericPayloadParser.java b/src/com/isode/stroke/parser/GenericPayloadParser.java
new file mode 100644
index 0000000..7ac8337
--- /dev/null
+++ b/src/com/isode/stroke/parser/GenericPayloadParser.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.Payload;
+
+public abstract class GenericPayloadParser <T extends Payload> implements PayloadParser {
+ private T payload_;
+
+ public GenericPayloadParser(T payload) {
+ payload_ = payload;
+ }
+
+ public Payload getPayload() {
+ return payload_;
+ }
+
+ protected T getPayloadInternal() {
+ return payload_;
+ }
+}
diff --git a/src/com/isode/stroke/parser/GenericPayloadParserFactory.java b/src/com/isode/stroke/parser/GenericPayloadParserFactory.java
new file mode 100644
index 0000000..a6d7e25
--- /dev/null
+++ b/src/com/isode/stroke/parser/GenericPayloadParserFactory.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010, 2011 Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+public class GenericPayloadParserFactory<T extends PayloadParser> implements PayloadParserFactory {
+
+ private final String tag_;
+ private final String xmlns_;
+ private final Class payloadClass_;
+
+ public GenericPayloadParserFactory(final String tag, final Class<? extends PayloadParser> payloadClass) {
+ this(tag, "", payloadClass);
+ }
+
+ public GenericPayloadParserFactory(final String tag, final String xmlns, final Class<? extends PayloadParser> payloadClass) {
+ tag_ = tag;
+ xmlns_ = xmlns;
+ payloadClass_ = payloadClass;
+ }
+
+ public boolean canParse(final String element, final String ns, final AttributeMap attributes) {
+ return element.equals(tag_) && xmlns_.equals(ns);
+ }
+
+ public final PayloadParser createPayloadParser() {
+ try {
+ return (PayloadParser) payloadClass_.newInstance();
+ } catch (InstantiationException ex) {
+ /* Fatal */
+ throw new RuntimeException(ex);
+ } catch (IllegalAccessException ex) {
+ /* Fatal */
+ throw new RuntimeException(ex);
+ }
+ }
+}
diff --git a/src/com/isode/stroke/parser/GenericStanzaParser.java b/src/com/isode/stroke/parser/GenericStanzaParser.java
new file mode 100644
index 0000000..0f3c6c1
--- /dev/null
+++ b/src/com/isode/stroke/parser/GenericStanzaParser.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.Element;
+import com.isode.stroke.elements.Stanza;
+
+public class GenericStanzaParser<T extends Stanza> extends StanzaParser {
+ private final T stanza_;
+ public GenericStanzaParser(PayloadParserFactoryCollection collection, T blankStanza) {
+ super(collection);
+ stanza_ = blankStanza;
+ }
+
+ public Element getElement() {
+ return stanza_;
+ }
+
+ public T getStanzaGeneric() {
+ return stanza_;
+ }
+}
diff --git a/src/com/isode/stroke/parser/IQParser.java b/src/com/isode/stroke/parser/IQParser.java
new file mode 100644
index 0000000..3e8325a
--- /dev/null
+++ b/src/com/isode/stroke/parser/IQParser.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.IQ;
+
+public class IQParser extends GenericStanzaParser<IQ> {
+
+ public IQParser(PayloadParserFactoryCollection factories) {
+ super(factories, new IQ());
+ }
+
+ @Override
+ void handleStanzaAttributes(AttributeMap attributes) {
+ String type = attributes.getAttribute("type");
+ if ("set".equals(type)) {
+ getStanzaGeneric().setType(IQ.Type.Set);
+ } else if ("get".equals(type)) {
+ getStanzaGeneric().setType(IQ.Type.Get);
+ } else if ("result".equals(type)) {
+ getStanzaGeneric().setType(IQ.Type.Result);
+ } else if ("error".equals(type)) {
+ getStanzaGeneric().setType(IQ.Type.Error);
+ } else {
+ getStanzaGeneric().setType(IQ.Type.Get);
+ }
+ }
+}
diff --git a/src/com/isode/stroke/parser/MessageParser.java b/src/com/isode/stroke/parser/MessageParser.java
new file mode 100644
index 0000000..1294e62
--- /dev/null
+++ b/src/com/isode/stroke/parser/MessageParser.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.Message;
+
+public class MessageParser extends GenericStanzaParser<Message> {
+
+ public MessageParser(PayloadParserFactoryCollection factories) {
+ super(factories, new Message());
+ }
+
+ @Override
+ void handleStanzaAttributes(AttributeMap attributes) {
+ String type = attributes.getAttribute("type");
+ if ("chat".equals(type)) {
+ getStanzaGeneric().setType(Message.Type.Chat);
+ } else if ("error".equals(type)) {
+ getStanzaGeneric().setType(Message.Type.Error);
+ } else if ("groupchat".equals(type)) {
+ getStanzaGeneric().setType(Message.Type.Groupchat);
+ } else if ("headline".equals(type)) {
+ getStanzaGeneric().setType(Message.Type.Headline);
+ } else {
+ getStanzaGeneric().setType(Message.Type.Normal);
+ }
+ }
+}
diff --git a/src/com/isode/stroke/parser/PayloadParser.java b/src/com/isode/stroke/parser/PayloadParser.java
new file mode 100644
index 0000000..c0dfb43
--- /dev/null
+++ b/src/com/isode/stroke/parser/PayloadParser.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.Payload;
+
+/**
+ * Parse a payload.
+ */
+public interface PayloadParser {
+
+ void handleStartElement(String element, String ns, AttributeMap attributes);
+
+ void handleEndElement(String element, String ns);
+
+ void handleCharacterData(String data);
+
+ Payload getPayload();
+}
diff --git a/src/com/isode/stroke/parser/PayloadParserFactory.java b/src/com/isode/stroke/parser/PayloadParserFactory.java
new file mode 100644
index 0000000..3b07395
--- /dev/null
+++ b/src/com/isode/stroke/parser/PayloadParserFactory.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+/**
+ * Create a parser.
+ */
+public interface PayloadParserFactory {
+ boolean canParse(String element, String ns, AttributeMap attributes);
+ PayloadParser createPayloadParser();
+}
diff --git a/src/com/isode/stroke/parser/PayloadParserFactoryCollection.java b/src/com/isode/stroke/parser/PayloadParserFactoryCollection.java
new file mode 100644
index 0000000..2d3601b
--- /dev/null
+++ b/src/com/isode/stroke/parser/PayloadParserFactoryCollection.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import java.util.Vector;
+
+/**
+ * Collection of parser factories.
+ */
+public class PayloadParserFactoryCollection {
+
+ private final Vector<PayloadParserFactory> factories_ = new Vector<PayloadParserFactory>();
+ private PayloadParserFactory defaultFactory_ = null;
+
+ public void addFactory(PayloadParserFactory factory) {
+ synchronized (factories_) {
+ factories_.add(factory);
+ }
+ }
+
+ public void setDefaultFactory(PayloadParserFactory factory) {
+ defaultFactory_ = factory;
+ }
+
+ public PayloadParserFactory getPayloadParserFactory(String element, String ns, AttributeMap attributes) {
+ synchronized(factories_) {
+ for (PayloadParserFactory factory : factories_) {
+ if (factory.canParse(element, ns, attributes)) {
+ return factory;
+ }
+ }
+ }
+ return defaultFactory_;
+ }
+}
diff --git a/src/com/isode/stroke/parser/PlatformXMLParserFactory.java b/src/com/isode/stroke/parser/PlatformXMLParserFactory.java
new file mode 100644
index 0000000..85c9ae9
--- /dev/null
+++ b/src/com/isode/stroke/parser/PlatformXMLParserFactory.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+import com.isode.stroke.eventloop.EventLoop;
+
+class PlatformXMLParserFactory {
+ /**
+ * Unlike Swiften, this may be threaded, and therefore needs an eventloop.
+ */
+ public static XMLParser createXMLParser(XMLParserClient client, EventLoop eventLoop) {
+ return new PullXMLParser(client, eventLoop);
+ }
+}
diff --git a/src/com/isode/stroke/parser/PresenceParser.java b/src/com/isode/stroke/parser/PresenceParser.java
new file mode 100644
index 0000000..cca8729
--- /dev/null
+++ b/src/com/isode/stroke/parser/PresenceParser.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.Presence;
+
+public class PresenceParser extends GenericStanzaParser<Presence> {
+
+ public PresenceParser(PayloadParserFactoryCollection factories) {
+ super(factories, new Presence());
+ }
+
+ @Override
+ void handleStanzaAttributes(AttributeMap attributes) {
+ String type = attributes.getAttribute("type");
+ if (type != null) {
+ if (type.equals("unavailable")) {
+ getStanzaGeneric().setType(Presence.Type.Unavailable);
+ } else if (type.equals("probe")) {
+ getStanzaGeneric().setType(Presence.Type.Probe);
+ } else if (type.equals("subscribe")) {
+ getStanzaGeneric().setType(Presence.Type.Subscribe);
+ } else if (type.equals("subscribed")) {
+ getStanzaGeneric().setType(Presence.Type.Subscribed);
+ } else if (type.equals("unsubscribe")) {
+ getStanzaGeneric().setType(Presence.Type.Unsubscribe);
+ } else if (type.equals("unsubscribed")) {
+ getStanzaGeneric().setType(Presence.Type.Unsubscribed);
+ } else if (type.equals("error")) {
+ getStanzaGeneric().setType(Presence.Type.Error);
+ } else {
+ getStanzaGeneric().setType(Presence.Type.Available);
+ }
+ } else {
+ getStanzaGeneric().setType(Presence.Type.Available);
+ }
+ }
+}
diff --git a/src/com/isode/stroke/parser/PullXMLParser.java b/src/com/isode/stroke/parser/PullXMLParser.java
new file mode 100644
index 0000000..8b42afe
--- /dev/null
+++ b/src/com/isode/stroke/parser/PullXMLParser.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.eventloop.Event.Callback;
+import com.isode.stroke.eventloop.EventLoop;
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.xmlpull.mxp1.MXParser;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+/**
+ * Parser based around the XmlPullParser
+ */
+class PullXMLParser extends XMLParser {
+
+ private final Logger logger_ = Logger.getLogger(this.getClass().getName());
+ private final XmlPullParser parser_ = new MXParser();
+ private final PipedInputStream reader_;
+ private final PipedOutputStream writer_;
+ private final ArrayBlockingQueue<Event> events_ = new ArrayBlockingQueue<Event>(20);
+ private final Thread parserThread_;
+ private boolean error_ = false;
+ private final EventLoop eventLoop_;
+
+
+ private enum EventType {Start, End, Text};
+
+ /**
+ * XML Event struct.
+ */
+ private class Event {
+ private final EventType type;
+ private final String name;
+ private final String namespace;
+ private final AttributeMap attributes;
+ public Event(EventType type, String name, String namespace, AttributeMap attributes) {
+ this.type = type;
+ this.name = name;
+ this.namespace = namespace;
+ this.attributes = attributes;
+ }
+
+ public Event(String name) {
+ this(EventType.Text, name, null, null);
+ }
+
+
+ public Event(String name, String namespace) {
+ this(EventType.End, name, namespace, null);
+ }
+
+ public Event(String name, String namespace, AttributeMap attributes) {
+ this(EventType.Start, name, namespace, attributes);
+ }
+
+ }
+
+ /**
+ * Put an XML event onto the queue ready for the main thread to pick up later.
+ */
+ private void addEvent(Event event) throws InterruptedException {
+ events_.put(event);
+ }
+
+ /**
+ * Deal with whatever was just read out of the parser_.
+ */
+ private void handleEvent(int eventType) throws XmlPullParserException, InterruptedException {
+ 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));
+ }
+ addEvent(new Event(parser_.getName(), parser_.getNamespace(), map));
+ bump();
+ } else if (eventType == XmlPullParser.END_TAG) {
+ addEvent(new Event(parser_.getName(), parser_.getNamespace()));
+ bump();
+ } else if (eventType == XmlPullParser.TEXT) {
+ StringBuilder text = new StringBuilder();
+ int holderForStartAndLength[] = new int[2];
+ char ch[] = parser_.getTextCharacters(holderForStartAndLength);
+ int start = holderForStartAndLength[0];
+ int length = holderForStartAndLength[1];
+ for (int i = start; i < start + length; i++) {
+ text.append(ch[i]);
+ }
+ addEvent(new Event(text.toString()));
+ bump();
+ } else if (eventType == XmlPullParser.START_DOCUMENT) {
+ //System.out.println("Starting document");
+ } else if (eventType == XmlPullParser.END_DOCUMENT) {
+ //System.out.println("Ending document");
+
+ } else {
+ //System.out.println("Unhandled event");
+ }
+ }
+
+ /**
+ * Cause the main thread to process any outstanding events.
+ */
+ private void bump() {
+ eventLoop_.postEvent(new Callback() {
+ public void run() {
+ processEvents();
+ }
+ });
+ }
+
+ public PullXMLParser(XMLParserClient client, EventLoop eventLoop) {
+ super(client);
+ eventLoop_ = eventLoop;
+ writer_ = new PipedOutputStream();
+ try {
+ reader_ = new PipedInputStream(writer_, 128000);
+ } catch (IOException ex) {
+ Logger.getLogger(PullXMLParser.class.getName()).log(Level.SEVERE, null, ex);
+ throw new IllegalStateException(ex);
+ }
+ try {
+ parser_.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
+ parser_.setInput(reader_, "UTF-8");
+ } catch (XmlPullParserException ex) {
+ Logger.getLogger(PullXMLParser.class.getName()).log(Level.SEVERE, null, ex);
+ throw new IllegalStateException(ex);
+ }
+ Runnable parserRunnable = new Runnable() {
+ public void run() {
+ int eventType = XmlPullParser.END_DOCUMENT - 1; /* Anything to make the following not true*/
+ while (eventType != XmlPullParser.END_DOCUMENT) {
+ try {
+ parser_.next();
+ eventType = parser_.getEventType();
+ handleEvent(eventType);
+ } catch (XmlPullParserException ex) {
+ error_ = true;
+ Logger.getLogger(PullXMLParser.class.getName()).log(Level.SEVERE, null, ex);
+ break;
+ } catch (IOException ex) {
+ error_ = true;
+ Logger.getLogger(PullXMLParser.class.getName()).log(Level.SEVERE, null, ex);
+ break;
+ } catch (InterruptedException ex) {
+ /* The thread was interrupted while trying to process an event - presumably this is because we're shutting down.*/
+ error_ = true;
+ Logger.getLogger(PullXMLParser.class.getName()).log(Level.SEVERE, null, ex);
+ break;
+ }
+ }
+ }
+ };
+ parserThread_ = new Thread(parserRunnable);
+ parserThread_.setDaemon(true);
+ parserThread_.start();
+ }
+
+ /**
+ * Do not do this!
+ * This is only to allow the unit tests to join onto it.
+ * @return
+ */
+ Thread getParserThread() {
+ return parserThread_;
+ }
+
+ /**
+ * Process outstanding events.
+ * Call in the main thread only.
+ */
+ private void processEvents() {
+ while (events_.size() > 0) {
+ processEvent(events_.poll());
+ }
+ }
+
+ /**
+ * Main thread only.
+ */
+ private void processEvent(Event event) {
+ String name = event.name;
+ String namespace = event.namespace;
+ AttributeMap attributes = event.attributes;
+ switch (event.type) {
+ case Start: getClient().handleStartElement(name, namespace, attributes); break;
+ case End: getClient().handleEndElement(name, namespace); break;
+ case Text: getClient().handleCharacterData(name); break;
+ }
+ }
+
+ /**
+ * Cause the parser thread to parse these data later.
+ * Note that the return code is a best guess based on previous parsing,
+ * and will almost always give a false negative on a stanza before a
+ * true negative. True negatives will always mean an error in the stream.
+ */
+ @Override
+ public boolean parse(String data) {
+ try {
+ writer_.write(new ByteArray(data).getData());
+ writer_.flush();
+ } catch (IOException ex) {
+ error_ = true;
+ Logger.getLogger(PullXMLParser.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ return !error_;
+ }
+
+
+}
diff --git a/src/com/isode/stroke/parser/SerializingParser.java b/src/com/isode/stroke/parser/SerializingParser.java
new file mode 100644
index 0000000..1346dc8
--- /dev/null
+++ b/src/com/isode/stroke/parser/SerializingParser.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.serializer.xml.XMLElement;
+import com.isode.stroke.serializer.xml.XMLTextNode;
+import java.util.Vector;
+
+public class SerializingParser {
+
+ private final Vector<XMLElement> elementStack_ = new Vector<XMLElement>();
+ private XMLElement rootElement_;
+
+ 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));
+ }
+
+ if (elementStack_.isEmpty()) {
+ rootElement_ = element;
+ } else {
+ elementStack_.lastElement().addNode(element);
+ }
+ elementStack_.add(element);
+ }
+
+ public void handleEndElement(String tag, String ns) {
+ assert (!elementStack_.isEmpty());
+ elementStack_.remove(elementStack_.size() - 1);
+ }
+
+ public void handleCharacterData(String data) {
+ if (!elementStack_.isEmpty()) {
+ elementStack_.lastElement().addNode(new XMLTextNode(data));
+ }
+ }
+
+ public String getResult() {
+ return (rootElement_ != null ? rootElement_.serialize() : "");
+ }
+}
diff --git a/src/com/isode/stroke/parser/StanzaAckParser.java b/src/com/isode/stroke/parser/StanzaAckParser.java
new file mode 100644
index 0000000..40fab80
--- /dev/null
+++ b/src/com/isode/stroke/parser/StanzaAckParser.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.StanzaAck;
+
+class StanzaAckParser extends GenericElementParser<StanzaAck> {
+
+ private int depth = 0;
+
+ public StanzaAckParser() {
+ super(StanzaAck.class);
+ }
+
+ @Override
+ public void handleStartElement(String el, String ns, AttributeMap attributes) {
+ if (depth == 0) {
+ String handledStanzasString = attributes.getAttribute("h");
+ try {
+ getElementGeneric().setHandledStanzasCount(Long.parseLong(handledStanzasString));
+ } catch (NumberFormatException e) {
+
+ }
+ }
+ ++depth;
+ }
+
+ @Override
+ public void handleEndElement(String el, String ns) {
+ --depth;
+ }
+}
diff --git a/src/com/isode/stroke/parser/StanzaAckRequestParser.java b/src/com/isode/stroke/parser/StanzaAckRequestParser.java
new file mode 100644
index 0000000..9a61d7f
--- /dev/null
+++ b/src/com/isode/stroke/parser/StanzaAckRequestParser.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.StanzaAckRequest;
+
+class StanzaAckRequestParser extends GenericElementParser<StanzaAckRequest> {
+
+ public StanzaAckRequestParser() {
+ super(StanzaAckRequest.class);
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/StanzaParser.java b/src/com/isode/stroke/parser/StanzaParser.java
new file mode 100644
index 0000000..2aa865e
--- /dev/null
+++ b/src/com/isode/stroke/parser/StanzaParser.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.Element;
+import com.isode.stroke.elements.Payload;
+import com.isode.stroke.elements.Stanza;
+import com.isode.stroke.jid.JID;
+
+public abstract class StanzaParser implements ElementParser {
+
+ protected int currentDepth_ = 0;
+ protected final PayloadParserFactoryCollection factories_;
+ protected PayloadParser currentPayloadParser_;
+
+ public StanzaParser(PayloadParserFactoryCollection factories) {
+ factories_ = factories;
+ }
+
+ void handleStanzaAttributes(AttributeMap map) {
+ }
+
+ Stanza getStanza() {
+ return (Stanza) getElement();
+ }
+
+ private boolean inPayload() {
+ return currentDepth_ > 1;
+ }
+
+ private boolean inStanza() {
+ return currentDepth_ > 0;
+ }
+
+ public void handleStartElement(String element, String ns, AttributeMap attributes) {
+ if (inStanza()) {
+ if (!inPayload()) {
+ assert currentPayloadParser_ == null;
+ PayloadParserFactory payloadParserFactory = factories_.getPayloadParserFactory(element, ns, attributes);
+ if (payloadParserFactory != null) {
+ currentPayloadParser_ = payloadParserFactory.createPayloadParser();
+ } else {
+ currentPayloadParser_ = new UnknownPayloadParser();
+ }
+ }
+ assert currentPayloadParser_ != null;
+ currentPayloadParser_.handleStartElement(element, ns, attributes);
+ } else {
+ String from = attributes.getAttribute("from");
+ if (from != null) {
+ getStanza().setFrom(JID.fromString(from));
+ }
+ String to = attributes.getAttribute("to");
+ if (to != null) {
+ getStanza().setTo(JID.fromString(to));
+ }
+ String id = attributes.getAttribute("id");
+ if (id != null) {
+ getStanza().setID(id);
+ }
+ handleStanzaAttributes(attributes);
+ }
+ ++currentDepth_;
+ }
+
+ public void handleEndElement(String element, String ns) {
+ assert (inStanza());
+ if (inPayload()) {
+ assert currentPayloadParser_ != null;
+ currentPayloadParser_.handleEndElement(element, ns);
+ --currentDepth_;
+ if (!inPayload()) {
+ Payload payload = currentPayloadParser_.getPayload();
+ if (payload != null) {
+ getStanza().addPayload(payload);
+ }
+ currentPayloadParser_ = null;
+ }
+ } else {
+ --currentDepth_;
+ }
+ }
+
+ public void handleCharacterData(String data) {
+ if (currentPayloadParser_ != null) {
+ currentPayloadParser_.handleCharacterData(data);
+ }
+ }
+}
diff --git a/src/com/isode/stroke/parser/StartTLSFailureParser.java b/src/com/isode/stroke/parser/StartTLSFailureParser.java
new file mode 100644
index 0000000..e1a858c
--- /dev/null
+++ b/src/com/isode/stroke/parser/StartTLSFailureParser.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.StartTLSFailure;
+
+class StartTLSFailureParser extends GenericElementParser<StartTLSFailure>{
+
+ public StartTLSFailureParser() {
+ super(StartTLSFailure.class);
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/StartTLSParser.java b/src/com/isode/stroke/parser/StartTLSParser.java
new file mode 100644
index 0000000..c2f3e5d
--- /dev/null
+++ b/src/com/isode/stroke/parser/StartTLSParser.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2010-2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.StartTLSRequest;
+
+class StartTLSParser extends GenericElementParser<StartTLSRequest> {
+
+ public StartTLSParser() {
+ super(StartTLSRequest.class);
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/StreamFeaturesParser.java b/src/com/isode/stroke/parser/StreamFeaturesParser.java
new file mode 100644
index 0000000..7181659
--- /dev/null
+++ b/src/com/isode/stroke/parser/StreamFeaturesParser.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2010-2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.StreamFeatures;
+
+class StreamFeaturesParser extends GenericElementParser<StreamFeatures> {
+
+ public StreamFeaturesParser() {
+ super(StreamFeatures.class);
+ }
+
+ @Override
+ public void handleStartElement(String element, String ns, AttributeMap unused) {
+ if (currentDepth_ == 1) {
+ if (element.equals("starttls") && ns.equals("urn:ietf:params:xml:ns:xmpp-tls")) {
+ getElementGeneric().setHasStartTLS();
+ } else if (element.equals("session") && ns.equals("urn:ietf:params:xml:ns:xmpp-session")) {
+ getElementGeneric().setHasSession();
+ } else if (element.equals("bind") && ns.equals("urn:ietf:params:xml:ns:xmpp-bind")) {
+ getElementGeneric().setHasResourceBind();
+ } else if (element.equals("sm") && ns.equals("urn:xmpp:sm:2")) {
+ getElementGeneric().setHasStreamManagement();
+ } else if (element.equals("mechanisms") && ns.equals("urn:ietf:params:xml:ns:xmpp-sasl")) {
+ inMechanisms_ = true;
+ } else if (element.equals("compression") && ns.equals("http://jabber.org/features/compress")) {
+ inCompression_ = true;
+ }
+ } else if (currentDepth_ == 2) {
+ if (inCompression_ && element.equals("method")) {
+ inCompressionMethod_ = true;
+ currentText_ = "";
+ } else if (inMechanisms_ && element.equals("mechanism")) {
+ inMechanism_ = true;
+ currentText_ = "";
+ }
+ }
+ ++currentDepth_;
+ }
+
+ @Override
+ public void handleEndElement(String unused1, String unused2) {
+ --currentDepth_;
+ if (currentDepth_ == 1) {
+ inCompression_ = false;
+ inMechanisms_ = false;
+ } else if (currentDepth_ == 2) {
+ if (inCompressionMethod_) {
+ getElementGeneric().addCompressionMethod(currentText_);
+ inCompressionMethod_ = false;
+ } else if (inMechanism_) {
+ getElementGeneric().addAuthenticationMechanism(currentText_);
+ inMechanism_ = false;
+ }
+ }
+ }
+
+ @Override
+ public void handleCharacterData(String data) {
+ currentText_ = currentText_ + data;
+ }
+ private int currentDepth_ = 0;
+ private String currentText_ = "";
+ private boolean inMechanisms_ = false;
+ private boolean inMechanism_ = false;
+ private boolean inCompression_ = false;
+ private boolean inCompressionMethod_ = false;
+}
diff --git a/src/com/isode/stroke/parser/StreamManagementEnabledParser.java b/src/com/isode/stroke/parser/StreamManagementEnabledParser.java
new file mode 100644
index 0000000..a2d12b0
--- /dev/null
+++ b/src/com/isode/stroke/parser/StreamManagementEnabledParser.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.StreamManagementEnabled;
+
+class StreamManagementEnabledParser extends GenericElementParser<StreamManagementEnabled> {
+
+ private int level = 0;
+ private final static int TopLevel = 0;
+
+ public StreamManagementEnabledParser() {
+ super(StreamManagementEnabled.class);
+ }
+
+ @Override
+ public void handleStartElement(String el, String ns, AttributeMap attributes) {
+ if (level == TopLevel) {
+ if (attributes.getBoolAttribute("resume", false)) {
+ getElementGeneric().setResumeSupported();
+ }
+ getElementGeneric().setResumeID(attributes.getAttribute("id"));
+ }
+ ++level;
+ }
+
+ @Override
+ public void handleEndElement(String el, String ns) {
+ --level;
+ }
+}
diff --git a/src/com/isode/stroke/parser/StreamManagementFailedParser.java b/src/com/isode/stroke/parser/StreamManagementFailedParser.java
new file mode 100644
index 0000000..f8c63e7
--- /dev/null
+++ b/src/com/isode/stroke/parser/StreamManagementFailedParser.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.StreamManagementFailed;
+
+class StreamManagementFailedParser extends GenericElementParser<StreamManagementFailed> {
+
+ public StreamManagementFailedParser() {
+ super(StreamManagementFailed.class);
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/StreamResumeParser.java b/src/com/isode/stroke/parser/StreamResumeParser.java
new file mode 100644
index 0000000..924e865
--- /dev/null
+++ b/src/com/isode/stroke/parser/StreamResumeParser.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.StreamResume;
+
+class StreamResumeParser extends GenericElementParser<StreamResume> {
+
+ private int level = 0;
+ private final static int TopLevel = 0;
+
+ public StreamResumeParser() {
+ super(StreamResume.class);
+ }
+
+ @Override
+ public void handleStartElement(String el, String ns, AttributeMap attributes) {
+ if (level == TopLevel) {
+ String handledStanzasCount = attributes.getAttributeValue("h");
+ if (handledStanzasCount != null) {
+ try {
+ getElementGeneric().setHandledStanzasCount(Long.parseLong(handledStanzasCount));
+ } catch (NumberFormatException e) {
+ }
+ }
+ getElementGeneric().setResumeID(attributes.getAttribute("previd"));
+ }
+ ++level;
+ }
+
+ @Override
+ public void handleEndElement(String el, String ns) {
+ --level;
+ }
+}
diff --git a/src/com/isode/stroke/parser/StreamResumedParser.java b/src/com/isode/stroke/parser/StreamResumedParser.java
new file mode 100644
index 0000000..2a874a2
--- /dev/null
+++ b/src/com/isode/stroke/parser/StreamResumedParser.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.StreamResumed;
+
+class StreamResumedParser extends GenericElementParser<StreamResumed> {
+
+ private int level = 0;
+ private final static int TopLevel = 0;
+
+ public StreamResumedParser() {
+ super(StreamResumed.class);
+ }
+
+ @Override
+ public void handleStartElement(String el, String ns, AttributeMap attributes) {
+ if (level == TopLevel) {
+ String handledStanzasCount = attributes.getAttributeValue("h");
+ if (handledStanzasCount != null) {
+ try {
+ getElementGeneric().setHandledStanzasCount(Long.parseLong(handledStanzasCount));
+ } catch (NumberFormatException e) {
+ }
+ }
+ getElementGeneric().setResumeID(attributes.getAttribute("previd"));
+ }
+ ++level;
+ }
+
+ @Override
+ public void handleEndElement(String el, String ns) {
+ --level;
+ }
+}
diff --git a/src/com/isode/stroke/parser/TLSProceedParser.java b/src/com/isode/stroke/parser/TLSProceedParser.java
new file mode 100644
index 0000000..b6f196d
--- /dev/null
+++ b/src/com/isode/stroke/parser/TLSProceedParser.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2010-2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.TLSProceed;
+
+class TLSProceedParser extends GenericElementParser<TLSProceed>{
+
+ public TLSProceedParser() {
+ super(TLSProceed.class);
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/UnknownElementParser.java b/src/com/isode/stroke/parser/UnknownElementParser.java
new file mode 100644
index 0000000..cf70dd6
--- /dev/null
+++ b/src/com/isode/stroke/parser/UnknownElementParser.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2010-2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.UnknownElement;
+
+public class UnknownElementParser extends GenericElementParser<UnknownElement> {
+ public UnknownElementParser() {
+ super(UnknownElement.class);
+ }
+}
diff --git a/src/com/isode/stroke/parser/UnknownPayloadParser.java b/src/com/isode/stroke/parser/UnknownPayloadParser.java
new file mode 100644
index 0000000..2bdfbae
--- /dev/null
+++ b/src/com/isode/stroke/parser/UnknownPayloadParser.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.Payload;
+
+public class UnknownPayloadParser implements PayloadParser {
+
+ public void handleStartElement(String element, String ns, AttributeMap attributes) {
+
+ }
+
+ public void handleEndElement(String element, String ns) {
+
+ }
+
+ public void handleCharacterData(String data) {
+
+ }
+
+ public Payload getPayload() {
+ return null;
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/XMLParser.java b/src/com/isode/stroke/parser/XMLParser.java
new file mode 100644
index 0000000..a564b12
--- /dev/null
+++ b/src/com/isode/stroke/parser/XMLParser.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+public abstract class XMLParser {
+ private final XMLParserClient client_;
+
+ public XMLParser(XMLParserClient client) {
+ client_ = client;
+ }
+
+ public abstract boolean parse(String data);
+
+ protected XMLParserClient getClient() {
+ return client_;
+ }
+}
diff --git a/src/com/isode/stroke/parser/XMLParserClient.java b/src/com/isode/stroke/parser/XMLParserClient.java
new file mode 100644
index 0000000..5fb7071
--- /dev/null
+++ b/src/com/isode/stroke/parser/XMLParserClient.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+
+public interface XMLParserClient {
+ void handleStartElement(String element, String ns, AttributeMap attributes);
+
+ void handleEndElement(String element, String ns);
+
+ void handleCharacterData(String data);
+}
diff --git a/src/com/isode/stroke/parser/XMPPParser.java b/src/com/isode/stroke/parser/XMPPParser.java
new file mode 100644
index 0000000..c16a250
--- /dev/null
+++ b/src/com/isode/stroke/parser/XMPPParser.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.ProtocolHeader;
+import com.isode.stroke.eventloop.EventLoop;
+import java.util.logging.Logger;
+
+
+public class XMPPParser implements XMLParserClient {
+
+ private final XMLParser xmlParser_ ;
+ private final XMPPParserClient client_;
+ private final PayloadParserFactoryCollection payloadParserFactories_;
+ private int currentDepth_ = 0;
+ private ElementParser currentElementParser_ = null;
+ private boolean parseErrorOccurred_ = false;
+ private Logger logger_ = Logger.getLogger(this.getClass().getName());
+
+ public XMPPParser(XMPPParserClient parserClient, PayloadParserFactoryCollection payloadParserFactories, EventLoop eventLoop) {
+ client_ = parserClient;
+ payloadParserFactories_ = payloadParserFactories;
+ xmlParser_ = PlatformXMLParserFactory.createXMLParser(this, eventLoop);
+ }
+
+ public boolean parse(String data) {
+ parseErrorOccurred_ = false;
+ boolean xmlParseResult = xmlParser_.parse(data);
+ if (parseErrorOccurred_ || !xmlParseResult) {
+ logger_.warning(String.format("When parsing, %b and %b", parseErrorOccurred_, xmlParseResult));
+ }
+ return xmlParseResult && !parseErrorOccurred_;
+ }
+
+ public void handleStartElement(
+ String element,
+ String ns,
+ AttributeMap attributes) {
+ if (!inStream()) {
+ logger_.warning("Not in stream");
+ if (element.equals("stream") && ns.equals("http://etherx.jabber.org/streams")) {
+ ProtocolHeader header = new ProtocolHeader();
+ header.setFrom(attributes.getAttribute("from"));
+ header.setTo(attributes.getAttribute("to"));
+ header.setID(attributes.getAttribute("id"));
+ header.setVersion(attributes.getAttribute("version"));
+ client_.handleStreamStart(header);
+ } else {
+ parseErrorOccurred_ = true;
+ }
+ } else {
+ if (!inElement()) {
+ assert currentElementParser_ == null;
+ currentElementParser_ = createElementParser(element, ns);
+ }
+ currentElementParser_.handleStartElement(element, ns, attributes);
+ }
+ ++currentDepth_;
+ }
+
+ public void handleEndElement(String element, String ns) {
+ assert (inStream());
+ if (inElement()) {
+ assert currentElementParser_ != null;
+ currentElementParser_.handleEndElement(element, ns);
+ --currentDepth_;
+ if (!inElement()) {
+ client_.handleElement(currentElementParser_.getElement());
+ currentElementParser_ = null;
+ }
+ } else {
+ assert (element.equals("stream"));
+ --currentDepth_;
+ client_.handleStreamEnd();
+ }
+ }
+
+ public void handleCharacterData(String data) {
+ if (currentElementParser_ != null) {
+ currentElementParser_.handleCharacterData(data);
+ }
+ }
+
+ private boolean inStream() {
+ return currentDepth_ > 0;
+ }
+
+ private boolean inElement() {
+ return currentDepth_ > 1;
+ }
+
+ private ElementParser createElementParser(String element, String xmlns) {
+ if (element.equals("presence")) {
+ return new PresenceParser(payloadParserFactories_);
+ }
+ else if (element.equals("iq")) {
+ return new IQParser(payloadParserFactories_);
+ }
+ else if (element.equals("message")) {
+ return new MessageParser(payloadParserFactories_);
+ }
+ else if (element.equals("features") && xmlns.equals("http://etherx.jabber.org/streams")) {
+ return new StreamFeaturesParser();
+ }
+ else if (element.equals("auth")) {
+ return new AuthRequestParser();
+ }
+ else if (element.equals("success")) {
+ return new AuthSuccessParser();
+ }
+ else if (element.equals("failure") && xmlns.equals("urn:ietf:params:xml:ns:xmpp-sasl")) {
+ return new AuthFailureParser();
+ }
+ else if (element.equals("challenge") && xmlns.equals("urn:ietf:params:xml:ns:xmpp-sasl")) {
+ return new AuthChallengeParser();
+ }
+ else if (element.equals("response") && xmlns.equals("urn:ietf:params:xml:ns:xmpp-sasl")) {
+ return new AuthResponseParser();
+ }
+ else if (element.equals("starttls")) {
+ return new StartTLSParser();
+ }
+ else if (element.equals("failure") && xmlns.equals("urn:ietf:params:xml:ns:xmpp-tls")) {
+ return new StartTLSFailureParser();
+ }
+ else if (element.equals("compress")) {
+ return new CompressParser();
+ }
+ else if (element.equals("compressed")) {
+ return new CompressedParser();
+ }
+ else if (element.equals("failure") && xmlns.equals("http://jabber.org/protocol/compress")) {
+ return new CompressFailureParser();
+ }
+ else if (element.equals("proceed")) {
+ return new TLSProceedParser();
+ }
+ else if (element.equals("enable") && xmlns.equals("urn:xmpp:sm:2")) {
+ return new EnableStreamManagementParser();
+ }
+ else if (element.equals("enabled") && xmlns.equals("urn:xmpp:sm:2")) {
+ return new StreamManagementEnabledParser();
+ }
+ else if (element.equals("failed") && xmlns.equals("urn:xmpp:sm:2")) {
+ return new StreamManagementFailedParser();
+ }
+ else if (element.equals("resume") && xmlns.equals("urn:xmpp:sm:2")) {
+ return new StreamResumeParser();
+ }
+ else if (element.equals("resumed") && xmlns.equals("urn:xmpp:sm:2")) {
+ return new StreamResumedParser();
+ }
+ else if (element.equals("a") && xmlns.equals("urn:xmpp:sm:2")) {
+ return new StanzaAckParser();
+ }
+ else if (element.equals("r") && xmlns.equals("urn:xmpp:sm:2")) {
+ return new StanzaAckRequestParser();
+ }
+ return new UnknownElementParser();
+
+ }
+}
diff --git a/src/com/isode/stroke/parser/XMPPParserClient.java b/src/com/isode/stroke/parser/XMPPParserClient.java
new file mode 100644
index 0000000..c4499cd
--- /dev/null
+++ b/src/com/isode/stroke/parser/XMPPParserClient.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser;
+
+import com.isode.stroke.elements.Element;
+import com.isode.stroke.elements.ProtocolHeader;
+
+public interface XMPPParserClient {
+ void handleStreamStart(ProtocolHeader header);
+ void handleElement(Element element);
+ void handleStreamEnd();
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/BodyParser.java b/src/com/isode/stroke/parser/payloadparsers/BodyParser.java
new file mode 100644
index 0000000..3672c56
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/BodyParser.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 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.Body;
+import com.isode.stroke.parser.AttributeMap;
+import com.isode.stroke.parser.GenericPayloadParser;
+
+public class BodyParser extends GenericPayloadParser<Body> {
+
+ private int level_ = 0;
+ private String text_ = "";
+
+ public BodyParser() {
+ super(new Body());
+ }
+
+ public void handleStartElement(String element, String ns, AttributeMap attributes) {
+ ++level_;
+ }
+
+ public void handleEndElement(String element, String ns) {
+ --level_;
+ if (level_ == 0) {
+ getPayloadInternal().setText(text_);
+ }
+ }
+
+ public void handleCharacterData(String data) {
+ text_ += data;
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/BodyParserFactory.java b/src/com/isode/stroke/parser/payloadparsers/BodyParserFactory.java
new file mode 100644
index 0000000..154281b
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/BodyParserFactory.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2010, 2011 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.parser.GenericPayloadParserFactory;
+
+public class BodyParserFactory extends GenericPayloadParserFactory<BodyParser> {
+
+ public BodyParserFactory() {
+ super("body", BodyParser.class);
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java b/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java
new file mode 100644
index 0000000..dfc1b61
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010, 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.parser.GenericPayloadParserFactory;
+import com.isode.stroke.parser.PayloadParserFactory;
+import com.isode.stroke.parser.PayloadParserFactoryCollection;
+
+public class FullPayloadParserFactoryCollection extends PayloadParserFactoryCollection {
+ public FullPayloadParserFactoryCollection() {
+ /* TODO: Port more */
+ //addFactory(new GenericPayloadParserFactory<IBBParser>("", "http://jabber.org/protocol/ibb"));
+ //addFactory(new GenericPayloadParserFactory<StatusShowParser>("show", StatusShowParser.class));
+ //addFactory(new GenericPayloadParserFactory<StatusParser>("status", StatusParser.class));
+ //addFactory(new GenericPayloadParserFactory<ReplaceParser>("replace", "http://swift.im/protocol/replace"));
+ addFactory(new GenericPayloadParserFactory<LastParser>("query", "jabber:iq:last", LastParser.class));
+ addFactory(new GenericPayloadParserFactory<BodyParser>("body", BodyParser.class));
+ //addFactory(new GenericPayloadParserFactory<SubjectParser>("subject", SubjectParser.class));
+ //addFactory(new GenericPayloadParserFactory<PriorityParser>("priority", PriorityParser.class));
+ //addFactory(new ErrorParserFactory(this)));
+ addFactory(new SoftwareVersionParserFactory());
+ //addFactory(new StorageParserFactory());
+ addFactory(new RosterParserFactory());
+ //addFactory(new DiscoInfoParserFactory());
+ //addFactory(new DiscoItemsParserFactory());
+ //addFactory(new CapsInfoParserFactory());
+ addFactory(new ResourceBindParserFactory());
+ addFactory(new StartSessionParserFactory());
+ //addFactory(new SecurityLabelParserFactory());
+ //addFactory(new SecurityLabelsCatalogParserFactory());
+ //addFactory(new FormParserFactory());
+ //addFactory(new CommandParserFactory());
+ //addFactery(new InBandRegistrationPayloadParserFactory());
+ addFactory(new SearchPayloadParserFactory());
+ //addFactory(new StreamInitiationParserFactory());
+ //addFactory(new BytestreamsParserFactory());
+ //addFactory(new VCardUpdateParserFactory());
+ //addFactory(new VCardParserFactory());
+ //addFactory(new PrivateStorageParserFactory(this));
+ //addFactory(new ChatStateParserFactory());
+ //addFactory(new DelayParserFactory());
+ //addFactory(new MUCUserPayloadParserFactory());
+ //addFactory(new NicknameParserFactory());
+
+
+ PayloadParserFactory defaultFactory = new RawXMLPayloadParserFactory();
+ setDefaultFactory(defaultFactory);
+ }
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/LastParser.java b/src/com/isode/stroke/parser/payloadparsers/LastParser.java
new file mode 100644
index 0000000..d2c2a82
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/LastParser.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2011, Kevin Smith.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser.payloadparsers;
+
+import com.isode.stroke.elements.Last;
+import com.isode.stroke.parser.AttributeMap;
+import com.isode.stroke.parser.GenericPayloadParser;
+
+public class LastParser extends GenericPayloadParser<Last> {
+
+ private int level_ = 0;
+
+ public LastParser() {
+ super(new Last());
+ }
+
+ public void handleStartElement(String element, String ns, AttributeMap attributes) {
+ if (level_ == 0) {
+ int seconds = 0;
+
+ try {
+ seconds = Integer.parseInt(attributes.getAttribute("seconds"));
+ }
+ catch (NumberFormatException ex) {
+ }
+ getPayloadInternal().setSeconds(seconds);
+ }
+ ++level_;
+ }
+
+ public void handleEndElement(String element, String ns) {
+
+ }
+
+ public void handleCharacterData(String data) {
+
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/RawXMLPayloadParser.java b/src/com/isode/stroke/parser/payloadparsers/RawXMLPayloadParser.java
new file mode 100644
index 0000000..2a97fed
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/RawXMLPayloadParser.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010, 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.RawXMLPayload;
+import com.isode.stroke.parser.AttributeMap;
+import com.isode.stroke.parser.GenericPayloadParser;
+import com.isode.stroke.parser.SerializingParser;
+
+public class RawXMLPayloadParser extends GenericPayloadParser<RawXMLPayload> {
+
+ private int level_;
+ private final SerializingParser serializingParser_ = new SerializingParser();
+
+ public RawXMLPayloadParser() {
+ super(new RawXMLPayload());
+ }
+
+
+
+ public void handleStartElement(String element, String ns, AttributeMap attributes) {
+ ++level_;
+ serializingParser_.handleStartElement(element, ns, attributes);
+ }
+
+ public void handleEndElement(String element, String ns) {
+ serializingParser_.handleEndElement(element, ns);
+ --level_;
+ if (level_ == 0) {
+ getPayloadInternal().setRawXML(serializingParser_.getResult());
+ }
+ }
+
+ public void handleCharacterData(String data) {
+ serializingParser_.handleCharacterData(data);
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/RawXMLPayloadParserFactory.java b/src/com/isode/stroke/parser/payloadparsers/RawXMLPayloadParserFactory.java
new file mode 100644
index 0000000..e0914e1
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/RawXMLPayloadParserFactory.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010, 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.parser.AttributeMap;
+import com.isode.stroke.parser.PayloadParser;
+import com.isode.stroke.parser.PayloadParserFactory;
+
+public class RawXMLPayloadParserFactory implements PayloadParserFactory {
+
+ public boolean canParse(String element, String ns, AttributeMap attributes) {
+ return true;
+ }
+
+ public PayloadParser createPayloadParser() {
+ return new RawXMLPayloadParser();
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/ResourceBindParser.java b/src/com/isode/stroke/parser/payloadparsers/ResourceBindParser.java
new file mode 100644
index 0000000..be409f4
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/ResourceBindParser.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010, 2011 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.ResourceBind;
+import com.isode.stroke.jid.JID;
+import com.isode.stroke.parser.AttributeMap;
+import com.isode.stroke.parser.GenericPayloadParser;
+
+public class ResourceBindParser extends GenericPayloadParser<ResourceBind> {
+
+ public ResourceBindParser() {
+ super(new ResourceBind());
+ level_ = 0;
+ inJID_ = false;
+ inResource_ = false;
+ }
+
+ public void handleStartElement(String element, String ns, AttributeMap attributes) {
+ if (level_ == 1) {
+ text_ = "";
+ if (element.equals("resource")) {
+ inResource_ = true;
+ }
+ if (element.equals("jid")) {
+ inJID_ = true;
+ }
+ }
+ ++level_;
+ }
+
+ public void handleEndElement(String element, String ns) {
+ --level_;
+ if (level_ == 1) {
+ if (inJID_) {
+ getPayloadInternal().setJID(JID.fromString(text_));
+ } else if (inResource_) {
+ getPayloadInternal().setResource(text_);
+ }
+ }
+ }
+
+ public void handleCharacterData(String data) {
+ text_ += data;
+ }
+ private int level_;
+ private boolean inJID_;
+ private boolean inResource_;
+ private String text_ = "";
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/ResourceBindParserFactory.java b/src/com/isode/stroke/parser/payloadparsers/ResourceBindParserFactory.java
new file mode 100644
index 0000000..a6b644d
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/ResourceBindParserFactory.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2010, 2011 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.parser.GenericPayloadParserFactory;
+
+class ResourceBindParserFactory extends GenericPayloadParserFactory<ResourceBindParser> {
+
+ public ResourceBindParserFactory() {
+ super("bind", "urn:ietf:params:xml:ns:xmpp-bind", ResourceBindParser.class);
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/RosterParser.java b/src/com/isode/stroke/parser/payloadparsers/RosterParser.java
new file mode 100644
index 0000000..fa115c2
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/RosterParser.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2010, 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.Payload;
+import com.isode.stroke.elements.RosterItemPayload;
+import com.isode.stroke.elements.RosterPayload;
+import com.isode.stroke.jid.JID;
+import com.isode.stroke.parser.AttributeMap;
+import com.isode.stroke.parser.GenericPayloadParser;
+
+public class RosterParser extends GenericPayloadParser<RosterPayload> {
+
+ public RosterParser() {
+ super(new RosterPayload());
+ }
+
+ public void handleStartElement(String element, String ns, AttributeMap attributes) {
+ if (level_ == PayloadLevel) {
+ if (element.equals("item")) {
+ inItem_ = true;
+ currentItem_ = new RosterItemPayload();
+
+ currentItem_.setJID(JID.fromString(attributes.getAttribute("jid")));
+ currentItem_.setName(attributes.getAttribute("name"));
+
+ String subscription = attributes.getAttribute("subscription");
+ if ("both".equals(subscription)) {
+ currentItem_.setSubscription(RosterItemPayload.Subscription.Both);
+ } else if ("to".equals(subscription)) {
+ currentItem_.setSubscription(RosterItemPayload.Subscription.To);
+ } else if ("frome".equals(subscription)) {
+ currentItem_.setSubscription(RosterItemPayload.Subscription.From);
+ } else if ("remove".equals(subscription)) {
+ currentItem_.setSubscription(RosterItemPayload.Subscription.Remove);
+ } else {
+ currentItem_.setSubscription(RosterItemPayload.Subscription.None);
+ }
+
+ if ("subscribe".equals(attributes.getAttribute("ask"))) {
+ currentItem_.setSubscriptionRequested();
+ }
+ }
+ } else if (level_ == ItemLevel) {
+ if (element.equals("group")) {
+ currentText_ = "";
+ }
+ }
+ ++level_;
+ }
+
+ public void handleEndElement(String element, String ns) {
+ --level_;
+ if (level_ == PayloadLevel) {
+ if (inItem_) {
+ getPayloadInternal().addItem(currentItem_);
+ inItem_ = false;
+ }
+ } else if (level_ == ItemLevel) {
+ if (element.equals("group")) {
+ currentItem_.addGroup(currentText_);
+ }
+ }
+ }
+
+ public void handleCharacterData(String data) {
+ currentText_ += data;
+ }
+ private final int TopLevel = 0;
+ private final int PayloadLevel = 1;
+ private final int ItemLevel = 2;
+ private int level_ = TopLevel;
+ private boolean inItem_ = false;
+ private RosterItemPayload currentItem_;
+ private String currentText_;
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/RosterParserFactory.java b/src/com/isode/stroke/parser/payloadparsers/RosterParserFactory.java
new file mode 100644
index 0000000..ad690e1
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/RosterParserFactory.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2010, 2011 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.parser.GenericPayloadParserFactory;
+
+public class RosterParserFactory extends GenericPayloadParserFactory<RosterParser> {
+
+ public RosterParserFactory() {
+ super("query", "jabber:iq:roster", RosterParser.class);
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/SearchPayloadParser.java b/src/com/isode/stroke/parser/payloadparsers/SearchPayloadParser.java
new file mode 100644
index 0000000..0ee1499
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/SearchPayloadParser.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2010, 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.SearchPayload;
+import com.isode.stroke.jid.JID;
+import com.isode.stroke.parser.AttributeMap;
+import com.isode.stroke.parser.GenericPayloadParser;
+
+public class SearchPayloadParser extends GenericPayloadParser<SearchPayload> {
+
+ private static final int TopLevel = 0;
+ private static final int PayloadLevel = 1;
+ private static final int ItemLevel = 2;
+
+ private int level = 0;
+ private String currentText = "";
+ //private FormParserFactory formParserFactory = new FormParserFactory(); /* Not ported yet*/
+ //private FormParser formParser;
+ SearchPayload.Item currentItem;
+
+ public SearchPayloadParser() {
+ super(new SearchPayload());
+ }
+
+ public void handleStartElement(String element, String ns, AttributeMap attributes) {
+ if (level == TopLevel) {
+ }
+ else if (level == PayloadLevel) {
+ //if (element.equals("x") && ns.equals("jabber:x:data")) {
+ // assert formParser == null;
+ // formParser = dynamic_cast<FormParser*>(formParserFactory->createPayloadParser());
+ //} /* Not ported yet */
+ //else
+ if (element.equals("item")) {
+ assert currentItem == null;
+ currentItem = new SearchPayload.Item();
+ currentItem.jid = JID.fromString(attributes.getAttribute("jid"));
+ }
+ else {
+ currentText = "";
+ }
+ }
+ else if (level == ItemLevel && currentItem != null) {
+ currentText = "";
+ }
+
+ //if (formParser) {
+ // formParser->handleStartElement(element, ns, attributes);
+ //} /* Not ported yet */
+
+ ++level;
+ }
+
+ public void handleEndElement(String element, String ns) {
+ --level;
+
+ //if (formParser) {
+ // formParser->handleEndElement(element, ns);
+ //} /*Not Ported yet*/
+
+ if (level == TopLevel) {
+ }
+ else if (level == PayloadLevel) {
+ //if (formParser) {
+ // getPayloadInternal()->setForm(formParser->getPayloadInternal());
+ // delete formParser;
+ // formParser = NULL;
+ //}
+ //else /*Not ported yet*/
+ if (element.equals("item")) {
+ assert currentItem != null;
+ getPayloadInternal().addItem(currentItem);
+ currentItem = null;
+ }
+ else if (element.equals("instructions")) {
+ getPayloadInternal().setInstructions(currentText);
+ }
+ else if (element.equals("nick")) {
+ getPayloadInternal().setNick(currentText);
+ }
+ else if (element.equals("first")) {
+ getPayloadInternal().setFirst(currentText);
+ }
+ else if (element.equals("last")) {
+ getPayloadInternal().setLast(currentText);
+ }
+ else if (element.equals("email")) {
+ getPayloadInternal().setEMail(currentText);
+ }
+ }
+ else if (level == ItemLevel && currentItem != null) {
+ if (element.equals("nick")) {
+ currentItem.nick = currentText;
+ }
+ else if (element.equals("first")) {
+ currentItem.first = currentText;
+ }
+ else if (element.equals("last")) {
+ currentItem.last = currentText;
+ }
+ else if (element.equals("email")) {
+ currentItem.email = currentText;
+ }
+ }
+ }
+
+ public void handleCharacterData(String data) {
+ //if (formParser) {
+ // formParser->handleCharacterData(data);
+ //}
+ //else { /*Not ported yet*/
+ currentText += data;
+ //}
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/SearchPayloadParserFactory.java b/src/com/isode/stroke/parser/payloadparsers/SearchPayloadParserFactory.java
new file mode 100644
index 0000000..4add0a1
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/SearchPayloadParserFactory.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, 2011 Isode Limited, London, England.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser.payloadparsers;
+
+import com.isode.stroke.parser.GenericPayloadParserFactory;
+import com.isode.stroke.parser.PayloadParser;
+
+public class SearchPayloadParserFactory extends GenericPayloadParserFactory<SearchPayloadParser> {
+
+ public SearchPayloadParserFactory() {
+ super("query", "jabber:iq:search", SearchPayloadParser.class);
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/SoftwareVersionParser.java b/src/com/isode/stroke/parser/payloadparsers/SoftwareVersionParser.java
new file mode 100644
index 0000000..93563a3
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/SoftwareVersionParser.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010 Isode Limited, London, England.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser.payloadparsers;
+
+import com.isode.stroke.elements.Version;
+import com.isode.stroke.parser.AttributeMap;
+import com.isode.stroke.parser.GenericPayloadParser;
+
+public class SoftwareVersionParser extends GenericPayloadParser<Version> {
+
+ public SoftwareVersionParser() {
+ super(new Version());
+ }
+
+ public void handleStartElement(String element, String ns, AttributeMap attributes) {
+ level_++;
+ }
+
+ public void handleEndElement(String element, String ns) {
+ --level_;
+ if (level_ == PayloadLevel) {
+ if (element.equals("name")) {
+ getPayloadInternal().setName(currentText_);
+ } else if (element.equals("version")) {
+ getPayloadInternal().setVersion(currentText_);
+ } else if (element.equals("os")) {
+ getPayloadInternal().setOS(currentText_);
+ }
+ currentText_ = "";
+ }
+
+ }
+
+ public void handleCharacterData(String data) {
+ currentText_ += data;
+ }
+
+ private static final int TopLevel = 0;
+ private static final int PayloadLevel = 1;
+ private int level_ = TopLevel;
+ private String currentText_ = "";
+
+
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/SoftwareVersionParserFactory.java b/src/com/isode/stroke/parser/payloadparsers/SoftwareVersionParserFactory.java
new file mode 100644
index 0000000..e2180f5
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/SoftwareVersionParserFactory.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, 2011 Isode Limited, London, England.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.parser.payloadparsers;
+
+import com.isode.stroke.parser.GenericPayloadParserFactory;
+
+public class SoftwareVersionParserFactory extends GenericPayloadParserFactory<SoftwareVersionParser> {
+
+ public SoftwareVersionParserFactory() {
+ super("query", "jabber:iq:version", SoftwareVersionParser.class);
+ }
+
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/StartSessionParser.java b/src/com/isode/stroke/parser/payloadparsers/StartSessionParser.java
new file mode 100644
index 0000000..ba7804c
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/StartSessionParser.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2011 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.StartSession;
+import com.isode.stroke.parser.AttributeMap;
+import com.isode.stroke.parser.GenericPayloadParser;
+
+public class StartSessionParser extends GenericPayloadParser<StartSession> {
+
+ public StartSessionParser() {
+ super(new StartSession());
+ }
+
+ public void handleStartElement(String element, String ns, AttributeMap attributes) {
+
+ }
+
+ public void handleEndElement(String element, String ns) {
+
+ }
+
+ public void handleCharacterData(String data) {
+
+ }
+
+
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/StartSessionParserFactory.java b/src/com/isode/stroke/parser/payloadparsers/StartSessionParserFactory.java
new file mode 100644
index 0000000..c2c9777
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/StartSessionParserFactory.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2010, 2011 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.parser.GenericPayloadParserFactory;
+
+class StartSessionParserFactory extends GenericPayloadParserFactory<StartSessionParser> {
+
+ public StartSessionParserFactory() {
+ super("session", "urn:ietf:params:xml:ns:xmpp-session", StartSessionParser.class);
+ }
+
+}