diff options
author | Kevin Smith <git@kismith.co.uk> | 2011-07-01 09:19:49 (GMT) |
---|---|---|
committer | Kevin Smith <git@kismith.co.uk> | 2011-07-01 09:19:49 (GMT) |
commit | 2da71a8a85486a494343f1662d64fb5ae5a2a44e (patch) | |
tree | 23992f9f2a00bac23b345e5c2cc9c1194efc25be /src/com/isode/stroke/parser | |
download | stroke-2da71a8a85486a494343f1662d64fb5ae5a2a44e.zip stroke-2da71a8a85486a494343f1662d64fb5ae5a2a44e.tar.bz2 |
Initial import
Diffstat (limited to 'src/com/isode/stroke/parser')
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); + } + +} |