summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/isode')
-rw-r--r--src/com/isode/stroke/parser/GenericPayloadTreeParser.java65
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java15
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/MUCAdminPayloadParser.java36
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/MUCDestroyPayloadParser.java38
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/MUCInvitationPayloadParser.java35
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/MUCItemParser.java72
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/MUCOwnerPayloadParser.java74
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/MUCOwnerPayloadParserFactory.java41
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/MUCUserPayloadParser.java71
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/MUCUserPayloadParserFactory.java41
-rw-r--r--src/com/isode/stroke/parser/tree/NullParserElement.java29
-rw-r--r--src/com/isode/stroke/parser/tree/ParserElement.java128
-rw-r--r--src/com/isode/stroke/parser/tree/TreeReparser.java65
13 files changed, 707 insertions, 3 deletions
diff --git a/src/com/isode/stroke/parser/GenericPayloadTreeParser.java b/src/com/isode/stroke/parser/GenericPayloadTreeParser.java
new file mode 100644
index 0000000..e414ac5
--- /dev/null
+++ b/src/com/isode/stroke/parser/GenericPayloadTreeParser.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2011, Kevin Smith
+ * All rights reserved.
+ */
+package com.isode.stroke.parser;
+
+import java.util.LinkedList;
+
+import com.isode.stroke.elements.Payload;
+import com.isode.stroke.parser.tree.ParserElement;
+
+/**
+ * Generic parser offering something a bit like a DOM to work with
+ * @param <T> Payload Type to parse
+ */
+public abstract class GenericPayloadTreeParser<T extends Payload> extends GenericPayloadParser<T> {
+
+ private LinkedList<ParserElement> elementStack_ = new LinkedList<ParserElement>();
+ private ParserElement root_;
+
+ /**
+ * Create the parser for the given payload type
+ * @param payload payload type object, not null
+ */
+ public GenericPayloadTreeParser(T payload) {
+ super(payload);
+ }
+
+ @Override
+ public void handleCharacterData(String data) {
+ ParserElement current = elementStack_.getLast();
+ current.appendCharacterData(data);
+ }
+
+ @Override
+ public void handleEndElement(String element, String xmlns) {
+ elementStack_.removeLast();
+ if (elementStack_.isEmpty()) {
+ handleTree(root_);
+ }
+ }
+
+ @Override
+ public void handleStartElement(String element, String xmlns,
+ AttributeMap attributes) {
+ if (root_ == null) {
+ root_ = new ParserElement(element, xmlns, attributes);
+ elementStack_.addLast(root_);
+ }else {
+ ParserElement current = elementStack_.getLast();
+ elementStack_.addLast(current.addChild(element, xmlns, attributes));
+ }
+ }
+
+ /**
+ * Parse children of the root element. Subclasses should implement
+ * this method to extract the items from child nodes
+ * @param root root of the node whose children contains items
+ */
+ public abstract void handleTree(ParserElement root);
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java b/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java
index 6b67116..1abce76 100644
--- a/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java
+++ b/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java
@@ -46,9 +46,18 @@ public class FullPayloadParserFactoryCollection extends PayloadParserFactoryColl
//addFactory(new PrivateStorageParserFactory(this));
//addFactory(new ChatStateParserFactory());
//addFactory(new DelayParserFactory());
- //addFactory(new MUCUserPayloadParserFactory());
- //addFactory(new NicknameParserFactory());
-
+ addFactory(new MUCUserPayloadParserFactory(this));
+ addFactory(new MUCOwnerPayloadParserFactory(this));
+ addFactory(new GenericPayloadParserFactory<MUCInvitationPayloadParser>("x",
+ "jabber:x:conference",MUCInvitationPayloadParser.class));
+ addFactory(new GenericPayloadParserFactory<MUCAdminPayloadParser>("query",
+ "http://jabber.org/protocol/muc#admin",MUCAdminPayloadParser.class));
+ addFactory(new GenericPayloadParserFactory<MUCDestroyPayloadParser>("destroy",
+ "http://jabber.org/protocol/muc#user",MUCDestroyPayloadParser.class));
+ addFactory(new GenericPayloadParserFactory<MUCDestroyPayloadParser>("destroy",
+ "http://jabber.org/protocol/muc#owner",MUCDestroyPayloadParser.class));
+
+ //addFactory(new NicknameParserFactory());
PayloadParserFactory defaultFactory = new RawXMLPayloadParserFactory();
setDefaultFactory(defaultFactory);
diff --git a/src/com/isode/stroke/parser/payloadparsers/MUCAdminPayloadParser.java b/src/com/isode/stroke/parser/payloadparsers/MUCAdminPayloadParser.java
new file mode 100644
index 0000000..3c3dfb3
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/MUCAdminPayloadParser.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 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.MUCAdminPayload;
+import com.isode.stroke.elements.MUCItem;
+import com.isode.stroke.parser.GenericPayloadTreeParser;
+import com.isode.stroke.parser.tree.ParserElement;
+
+/**
+ * Class representing a parser for MUC Admin payload
+ *
+ */
+public class MUCAdminPayloadParser extends GenericPayloadTreeParser<MUCAdminPayload>{
+
+ /**
+ * Create the parser
+ */
+ public MUCAdminPayloadParser() {
+ super(new MUCAdminPayload());
+ }
+
+ @Override
+ public void handleTree(ParserElement root) {
+ for (ParserElement itemElement : root.getChildren("item", "http://jabber.org/protocol/muc#admin")) {
+ MUCItem item = MUCItemParser.itemFromTree(itemElement);
+ getPayloadInternal().addItem(item);
+ }
+ }
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/MUCDestroyPayloadParser.java b/src/com/isode/stroke/parser/payloadparsers/MUCDestroyPayloadParser.java
new file mode 100644
index 0000000..f6b7790
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/MUCDestroyPayloadParser.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, 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.MUCDestroyPayload;
+import com.isode.stroke.jid.JID;
+import com.isode.stroke.parser.GenericPayloadTreeParser;
+import com.isode.stroke.parser.tree.ParserElement;
+
+/**
+ * Class representing a parser for MUC Destroy payload
+ *
+ */
+public class MUCDestroyPayloadParser extends GenericPayloadTreeParser<MUCDestroyPayload> {
+
+ /**
+ * Create the parser
+ */
+ public MUCDestroyPayloadParser() {
+ super(new MUCDestroyPayload());
+ }
+
+ @Override
+ public void handleTree(ParserElement root) {
+ String ns = root.getNamespace();
+ String jid = root.getAttributes().getAttribute("jid");
+ if (jid != null && !jid.isEmpty()) {
+ getPayloadInternal().setNewVenue(new JID(jid));
+ }
+ getPayloadInternal().setReason(root.getChild("reason", ns).getText());
+ }
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/MUCInvitationPayloadParser.java b/src/com/isode/stroke/parser/payloadparsers/MUCInvitationPayloadParser.java
new file mode 100644
index 0000000..27ab0d8
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/MUCInvitationPayloadParser.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 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.MUCInvitationPayload;
+import com.isode.stroke.jid.JID;
+import com.isode.stroke.parser.GenericPayloadTreeParser;
+import com.isode.stroke.parser.tree.ParserElement;
+
+/**
+ * Class representing a parser for MUC Invitation payload
+ *
+ */
+public class MUCInvitationPayloadParser extends GenericPayloadTreeParser<MUCInvitationPayload> {
+
+ public MUCInvitationPayloadParser() {
+ super(new MUCInvitationPayload());
+ }
+
+ @Override
+ public void handleTree(ParserElement root) {
+ MUCInvitationPayload invite = getPayloadInternal();
+ invite.setIsContinuation(root.getAttributes().getBoolAttribute("continue", false));
+ invite.setJID(new JID(root.getAttributes().getAttribute("jid")));
+ invite.setPassword(root.getAttributes().getAttribute("password"));
+ invite.setReason(root.getAttributes().getAttribute("reason"));
+ invite.setThread(root.getAttributes().getAttribute("thread"));
+ }
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/MUCItemParser.java b/src/com/isode/stroke/parser/payloadparsers/MUCItemParser.java
new file mode 100644
index 0000000..1a1bb74
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/MUCItemParser.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2012, 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.MUCItem;
+import com.isode.stroke.elements.MUCOccupant.Affiliation;
+import com.isode.stroke.elements.MUCOccupant.Role;
+import com.isode.stroke.jid.JID;
+import com.isode.stroke.parser.tree.ParserElement;
+
+/**
+ * Class containing parser functions for MUC Item
+ *
+ */
+public class MUCItemParser {
+
+ /**
+ * Get the MUC Item from the node
+ * @param root XML node element
+ * @return MUC Item, not null
+ */
+ public static MUCItem itemFromTree(ParserElement root) {
+ MUCItem item = new MUCItem();
+ String affiliation = root.getAttributes().getAttribute("affiliation");
+ String role = root.getAttributes().getAttribute("role");
+ String nick = root.getAttributes().getAttribute("nick");
+ String jid = root.getAttributes().getAttribute("jid");
+ item.affiliation = parseAffiliation(affiliation);
+ item.role = parseRole(role);
+ if (!jid.isEmpty()) {
+ item.realJID = new JID(jid);
+ }
+ if (!nick.isEmpty()) {
+ item.nick = nick;
+ }
+ String xmlns = root.getNamespace();
+ String reason = root.getChild("reason", xmlns).getText();
+ String actor = root.getChild("actor", xmlns).getAttributes().getAttribute("jid");
+ if (!reason.isEmpty()) {
+ item.reason = reason;
+ }
+ if (!actor.isEmpty()) {
+ item.actor = new JID(actor);
+ }
+
+ return item;
+ }
+
+ private static Role parseRole(String val) {
+ for(Role role : Role.values()) {
+ if(role.nodeName.equals(val)) {
+ return role;
+ }
+ }
+ return null;
+ }
+
+ private static Affiliation parseAffiliation(String val) {
+ for(Affiliation aff : Affiliation.values()) {
+ if(aff.nodeName.equals(val)) {
+ return aff;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/MUCOwnerPayloadParser.java b/src/com/isode/stroke/parser/payloadparsers/MUCOwnerPayloadParser.java
new file mode 100644
index 0000000..dd5e186
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/MUCOwnerPayloadParser.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012, 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.MUCOwnerPayload;
+import com.isode.stroke.parser.AttributeMap;
+import com.isode.stroke.parser.GenericPayloadParser;
+import com.isode.stroke.parser.PayloadParser;
+import com.isode.stroke.parser.PayloadParserFactory;
+import com.isode.stroke.parser.PayloadParserFactoryCollection;
+
+
+/**
+ * Class representing a parser for MUC Owner payload
+ *
+ */
+public class MUCOwnerPayloadParser extends GenericPayloadParser<MUCOwnerPayload> {
+ private PayloadParserFactoryCollection factories_;
+ private int level;
+ private PayloadParser currentPayloadParser;
+
+ /**
+ * Create the parser
+ * @param factories payload parser factory collection, not null
+ */
+ public MUCOwnerPayloadParser(PayloadParserFactoryCollection factories) {
+ super(new MUCOwnerPayload());
+ this.factories_ = factories;
+ level = 0;
+ }
+
+ @Override
+ public void handleStartElement(String element, String ns, AttributeMap attributes) {
+ if (level == 1) {
+ PayloadParserFactory payloadParserFactory = factories_.getPayloadParserFactory(
+ element, ns, attributes);
+ if (payloadParserFactory != null) {
+ currentPayloadParser = payloadParserFactory.createPayloadParser();
+ }
+ }
+
+ if (level >= 1 && currentPayloadParser != null) {
+ currentPayloadParser.handleStartElement(element, ns, attributes);
+ }
+ ++level;
+ }
+
+ @Override
+ public void handleEndElement(String element, String ns) {
+ --level;
+ if (currentPayloadParser != null) {
+ if (level >= 1) {
+ currentPayloadParser.handleEndElement(element, ns);
+ }
+
+ if (level == 1) {
+ getPayloadInternal().setPayload(currentPayloadParser.getPayload());
+ }
+ }
+ }
+
+ @Override
+ public void handleCharacterData(String data) {
+ if (level > 1 && currentPayloadParser != null) {
+ currentPayloadParser.handleCharacterData(data);
+ }
+ }
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/MUCOwnerPayloadParserFactory.java b/src/com/isode/stroke/parser/payloadparsers/MUCOwnerPayloadParserFactory.java
new file mode 100644
index 0000000..6d016d9
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/MUCOwnerPayloadParserFactory.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, 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.parser.AttributeMap;
+import com.isode.stroke.parser.PayloadParser;
+import com.isode.stroke.parser.PayloadParserFactory;
+import com.isode.stroke.parser.PayloadParserFactoryCollection;
+
+/**
+ * Factory for MUC Owner Payload Parser
+ *
+ */
+public class MUCOwnerPayloadParserFactory implements PayloadParserFactory {
+
+ private PayloadParserFactoryCollection factories;
+
+ /**
+ * Create the MUC Owner Payload Parser factory
+ * @param factories reference to Payload Parser Factory Collection, not null
+ */
+ public MUCOwnerPayloadParserFactory(PayloadParserFactoryCollection factories) {
+ this.factories = factories;
+ }
+
+ @Override
+ public boolean canParse(String element, String ns, AttributeMap map) {
+ return "query".equals(element) && "http://jabber.org/protocol/muc#owner".equals(ns);
+ }
+
+ @Override
+ public PayloadParser createPayloadParser() {
+ return new MUCOwnerPayloadParser(factories);
+ }
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/MUCUserPayloadParser.java b/src/com/isode/stroke/parser/payloadparsers/MUCUserPayloadParser.java
new file mode 100644
index 0000000..170e935
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/MUCUserPayloadParser.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Kevin Smith
+ * All rights reserved.
+ */
+package com.isode.stroke.parser.payloadparsers;
+
+import com.isode.stroke.elements.MUCItem;
+import com.isode.stroke.elements.MUCUserPayload;
+import com.isode.stroke.jid.JID;
+import com.isode.stroke.parser.GenericPayloadTreeParser;
+import com.isode.stroke.parser.PayloadParserFactoryCollection;
+import com.isode.stroke.parser.tree.ParserElement;
+import com.isode.stroke.parser.tree.TreeReparser;
+
+/**
+ * Class representing a parser for MUC User payload
+ *
+ */
+public class MUCUserPayloadParser extends GenericPayloadTreeParser<MUCUserPayload> {
+
+ private PayloadParserFactoryCollection factories;
+
+ /**
+ * Create the parser
+ * @param collection reference to payload parser factory collection, not null
+ */
+ public MUCUserPayloadParser(PayloadParserFactoryCollection collection){
+ super(new MUCUserPayload());
+ this.factories = collection;
+ }
+
+ @Override
+ public void handleTree(ParserElement root) {
+ for (ParserElement child : root.getAllChildren()) {
+ if ("item".equals(child.getName()) && child.getNamespace().equals(root.getNamespace())) {
+ MUCItem item = MUCItemParser.itemFromTree(child);
+ getPayloadInternal().addItem(item);
+ } else if ("password".equals(child.getName()) && child.getNamespace().equals(root.getNamespace())) {
+ getPayloadInternal().setPassword(child.getText());
+ } else if ("invite".equals(child.getName()) && child.getNamespace().equals(root.getNamespace())) {
+ MUCUserPayload.Invite invite = new MUCUserPayload.Invite();
+ String to = child.getAttributes().getAttribute("to");
+ if (to != null && !to.isEmpty()) {
+ invite.to = JID.fromString(to);
+ }
+ String from = child.getAttributes().getAttribute("from");
+ if (from != null && !from.isEmpty()) {
+ invite.from = JID.fromString(from);
+ }
+ ParserElement reason = child.getChild("reason", root.getNamespace());
+ if (reason != null) {
+ invite.reason = reason.getText();
+ }
+ getPayloadInternal().setInvite(invite);
+ } else if ("status".equals(child.getName()) && child.getNamespace().equals(root.getNamespace())) {
+ MUCUserPayload.StatusCode status = new MUCUserPayload.StatusCode();
+ try {
+ status.code = Integer.parseInt(child.getAttributes().getAttribute("code"));
+ getPayloadInternal().addStatusCode(status);
+ }catch (NumberFormatException e) {
+ }
+ } else {
+ getPayloadInternal().setPayload(TreeReparser.parseTree(child, factories));
+ }
+ }
+ }
+}
diff --git a/src/com/isode/stroke/parser/payloadparsers/MUCUserPayloadParserFactory.java b/src/com/isode/stroke/parser/payloadparsers/MUCUserPayloadParserFactory.java
new file mode 100644
index 0000000..0712eea
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/MUCUserPayloadParserFactory.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, 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.parser.AttributeMap;
+import com.isode.stroke.parser.PayloadParser;
+import com.isode.stroke.parser.PayloadParserFactory;
+import com.isode.stroke.parser.PayloadParserFactoryCollection;
+
+/**
+ * Factory for MUC User Payload Parser
+ *
+ */
+public class MUCUserPayloadParserFactory implements PayloadParserFactory {
+
+ private PayloadParserFactoryCollection factories;
+
+ /**
+ * Create the MUC User Payload Parser factory
+ * @param factories reference to Payload Parser Factory Collection, not null
+ */
+ public MUCUserPayloadParserFactory(PayloadParserFactoryCollection factories) {
+ this.factories = factories;
+ }
+
+ @Override
+ public boolean canParse(String element, String ns, AttributeMap map) {
+ return "x".equals(element) && "http://jabber.org/protocol/muc#user".equals(ns);
+ }
+
+ @Override
+ public PayloadParser createPayloadParser() {
+ return new MUCUserPayloadParser(factories);
+ }
+}
diff --git a/src/com/isode/stroke/parser/tree/NullParserElement.java b/src/com/isode/stroke/parser/tree/NullParserElement.java
new file mode 100644
index 0000000..83f8b6f
--- /dev/null
+++ b/src/com/isode/stroke/parser/tree/NullParserElement.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2011, Kevin Smith
+ * All rights reserved.
+ */
+package com.isode.stroke.parser.tree;
+
+import com.isode.stroke.parser.AttributeMap;
+
+/**
+ * Class representing a Null Parser element
+ *
+ */
+public class NullParserElement extends ParserElement{
+ /**
+ * Create the object
+ */
+ public NullParserElement() {
+ super("", "", new AttributeMap());
+ }
+
+ /**
+ * Empty/Null Parser element
+ */
+ public static NullParserElement element = new NullParserElement();
+}
diff --git a/src/com/isode/stroke/parser/tree/ParserElement.java b/src/com/isode/stroke/parser/tree/ParserElement.java
new file mode 100644
index 0000000..1a43696
--- /dev/null
+++ b/src/com/isode/stroke/parser/tree/ParserElement.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2012, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2011, Kevin Smith
+ * All rights reserved.
+ */
+package com.isode.stroke.parser.tree;
+
+import java.util.Vector;
+import com.isode.stroke.parser.AttributeMap;
+
+/**
+ * Class representing a parser for nodes in the stanza
+ *
+ */
+public class ParserElement {
+ private Vector<ParserElement> children_ = new Vector<ParserElement>();
+ private String name_ = "";
+ private String xmlns_ ="";
+ private AttributeMap attributes_ = new AttributeMap();
+ private String text_ = "";
+
+ /**
+ * Create the parser.
+ * @param name name of the parser node, e.g. query, reason, not null
+ * @param xmlns XML namespace, e.g. http://jabber.org/protocol/muc#user, not null
+ * @param attributes attributes of the node, not null
+ */
+ public ParserElement(String name, String xmlns, AttributeMap attributes){
+ this.name_ = name;
+ this.xmlns_ = xmlns;
+ this.attributes_ = attributes;
+ }
+
+ /**
+ * Get the text data of the node
+ * @return not null, can be empty
+ */
+ public String getText() {
+ return text_;
+ }
+
+ /**
+ * Get the name of the node, not null
+ * @return name of node
+ */
+ public String getName() {
+ return name_;
+ }
+
+ /**
+ * Get the name space of the XML node, not null
+ * @return xml namespace
+ */
+ public String getNamespace() {
+ return xmlns_;
+ }
+
+ /**
+ * Get the attributes of the XML node
+ * @return XMP node attributes, not null
+ */
+ public AttributeMap getAttributes() {
+ return attributes_;
+ }
+
+ /**
+ * Add child of the XML node
+ * @param name name of child node, not null
+ * @param xmlns XML namespace, not null
+ * @param attributes attributes, not null
+ * @return child node, not null
+ */
+ public ParserElement addChild(String name, String xmlns, AttributeMap attributes){
+ ParserElement child = new ParserElement(name, xmlns, attributes);
+ children_.add(child);
+ return child;
+ }
+
+ /**
+ * Append data to the text of the node
+ * @param data data to be appended, not null
+ */
+ public void appendCharacterData(String data) {
+ text_ += data;
+ }
+
+ /**
+ * Get the children of the node which have the given name
+ * and namespace value
+ * @param name name of node, not null
+ * @param xmlns namespace of node, not null
+ * @return list of children, not null but can be empty
+ */
+ public Vector<ParserElement> getChildren(String name, String xmlns) {
+ Vector<ParserElement> result = new Vector<ParserElement>();
+ for(ParserElement child : children_) {
+ if(child.name_.equals(name) && child.xmlns_.equals(xmlns)) {
+ result.add(child);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Get all the child nodes of XML element
+ * @return list of all children, not null but can be empty
+ */
+ public Vector<ParserElement> getAllChildren() {
+ return children_;
+ }
+
+ /**
+ * Get the first child of the node which have the given name
+ * and namespace value
+ * @param name name of node, not null
+ * @param xmlns namespace of node, not null
+ * @return child node if exists or a parser element {@link NullParserElement}
+ * representing null value
+ */
+ public ParserElement getChild(String name, String xmlns) {
+ Vector<ParserElement> results = getChildren(name, xmlns);
+ ParserElement result = results.isEmpty() ? NullParserElement.element : results.get(0);
+ return result;
+ }
+}
diff --git a/src/com/isode/stroke/parser/tree/TreeReparser.java b/src/com/isode/stroke/parser/tree/TreeReparser.java
new file mode 100644
index 0000000..647ab9e
--- /dev/null
+++ b/src/com/isode/stroke/parser/tree/TreeReparser.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2011, Kevin Smith
+ * All rights reserved.
+ */
+package com.isode.stroke.parser.tree;
+
+import java.util.LinkedList;
+
+import com.isode.stroke.elements.Payload;
+import com.isode.stroke.parser.PayloadParser;
+import com.isode.stroke.parser.PayloadParserFactoryCollection;
+
+/**
+ * Class for parsing elements of a parser element
+ *
+ */
+public class TreeReparser {
+ /**
+ * Class representing an element and its handling state
+ *
+ */
+ private static class ElementState {
+ ParserElement pe;
+ boolean state;
+ public ElementState(ParserElement pe, boolean state) {
+ super();
+ this.pe = pe;
+ this.state = state;
+ }
+ }
+
+ /**
+ * Parse the elements under the given root node
+ * @param root root node, not null
+ * @param collection payload parser factories, not null
+ * @return payload created from the elements of the given node, not null
+ */
+ public static Payload parseTree(ParserElement root, PayloadParserFactoryCollection collection) {
+ PayloadParser parser = collection.getPayloadParserFactory(root.getName(), root.getNamespace(),
+ root.getAttributes()).createPayloadParser();
+ LinkedList<ElementState> stack = new LinkedList<ElementState>();
+ stack.addLast(new ElementState(root, true));
+ while (!stack.isEmpty()) {
+ ElementState current = stack.getLast();
+ stack.removeLast();
+ if (current.state) {
+ stack.addLast(new ElementState(current.pe, false));
+ parser.handleStartElement(current.pe.getName(), current.pe.getNamespace(), current.pe.getAttributes());
+ for(ParserElement child : current.pe.getAllChildren()) {
+ stack.addLast(new ElementState(child, true));
+ }
+ } else {
+ parser.handleCharacterData(current.pe.getText());
+ parser.handleEndElement(current.pe.getName(), current.pe.getNamespace());
+ }
+ }
+
+ Payload payload = parser.getPayload();
+ return payload;
+ }
+}