summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/isode/stroke/parser/XMPPParser.java')
-rw-r--r--src/com/isode/stroke/parser/XMPPParser.java168
1 files changed, 168 insertions, 0 deletions
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();
+
+ }
+}