summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTarun Gupta <tarun1995gupta@gmail.com>2015-06-20 12:10:51 (GMT)
committerTarun Gupta <tarun1995gupta@gmail.com>2015-06-30 13:23:04 (GMT)
commitba7342e593920595af36fcd8e8e44ec206f8b561 (patch)
treefa8921599a20d85845d23d9a97bbc1cf230c7a51
parenta673d269487fd86efe7f9c5f9b4cd1c00cab556d (diff)
downloadstroke-ba7342e593920595af36fcd8e8e44ec206f8b561.zip
stroke-ba7342e593920595af36fcd8e8e44ec206f8b561.tar.bz2
Add StreamInitiation Elements.
Adds StreamInitiationFileInfo Element, its Parser and Serializer. Adds StreamInitiation Element, its Parser and Serializer. Adds StreamError Parser and Serializer. Updates StreamManagementEnabled Element. License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details. Test-Information: Tests added for StreamInitiation Parser and Serializer, which passes. Change-Id: I21a7de3f6a5ac0955b6e5aaae3c2607a30eae002
-rw-r--r--src/com/isode/stroke/elements/StreamInitiation.java106
-rw-r--r--src/com/isode/stroke/elements/StreamInitiationFileInfo.java227
-rw-r--r--src/com/isode/stroke/elements/StreamManagementEnabled.java4
-rw-r--r--src/com/isode/stroke/parser/StreamErrorParser.java141
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java3
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/StreamInitiationFileInfoParser.java130
-rw-r--r--src/com/isode/stroke/parser/payloadparsers/StreamInitiationParser.java152
-rw-r--r--src/com/isode/stroke/serializer/StreamErrorSerializer.java65
-rw-r--r--src/com/isode/stroke/serializer/payloadserializers/FullPayloadSerializerCollection.java4
-rw-r--r--src/com/isode/stroke/serializer/payloadserializers/StreamInitiationFileInfoSerializer.java57
-rw-r--r--src/com/isode/stroke/serializer/payloadserializers/StreamInitiationSerializer.java79
-rw-r--r--test/com/isode/stroke/parser/payloadparsers/StreamInitiationParserTest.java80
-rw-r--r--test/com/isode/stroke/serializer/payloadserializers/StreamInitiationSerializerTest.java73
13 files changed, 1118 insertions, 3 deletions
diff --git a/src/com/isode/stroke/elements/StreamInitiation.java b/src/com/isode/stroke/elements/StreamInitiation.java
new file mode 100644
index 0000000..466139c
--- /dev/null
+++ b/src/com/isode/stroke/elements/StreamInitiation.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2010-2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.elements;
+
+import com.isode.stroke.elements.Payload;
+import com.isode.stroke.elements.StreamInitiationFileInfo;
+import com.isode.stroke.base.NotNull;
+import java.util.Vector;
+
+public class StreamInitiation extends Payload {
+
+ private boolean isFileTransfer;
+ private String id = "";
+ private StreamInitiationFileInfo fileInfo;
+ private Vector<String> providedMethods = new Vector<String>();
+ private String requestedMethod = "";
+
+ /**
+ * Default Constructor.
+ */
+ public StreamInitiation() {
+ this.isFileTransfer = true;
+ }
+
+ /**
+ * @return id, NotNull.
+ */
+ public String getID() {
+ return id;
+ }
+
+ /**
+ * @param id, NotNull.
+ */
+ public void setID(String id) {
+ NotNull.exceptIfNull(id, "id");
+ this.id = id;
+ }
+
+ /**
+ * @return fileInfo.
+ */
+ public StreamInitiationFileInfo getFileInfo() {
+ return fileInfo;
+ }
+
+ /**
+ * @param fileInfo.
+ */
+ public void setFileInfo(StreamInitiationFileInfo info) {
+ fileInfo = info;
+ }
+
+ /**
+ * @return providedMethods.
+ */
+ public Vector<String> getProvidedMethods() {
+ return providedMethods;
+ }
+
+ /**
+ * @param method, Not Null.
+ */
+ public void addProvidedMethod(String method) {
+ NotNull.exceptIfNull(method, "method");
+ providedMethods.add(method);
+ }
+
+ /**
+ * @param method, Not Null.
+ */
+ public void setRequestedMethod(String method) {
+ NotNull.exceptIfNull(method, "method");
+ requestedMethod = method;
+ }
+
+ /**
+ * @return method, Not Null.
+ */
+ public String getRequestedMethod() {
+ return requestedMethod;
+ }
+
+ /**
+ * @return isFileTransfer.
+ */
+ public boolean getIsFileTransfer() {
+ return isFileTransfer;
+ }
+
+ /**
+ * @param isFileTransfer.
+ */
+ public void setIsFileTransfer(boolean b) {
+ isFileTransfer = b;
+ }
+} \ No newline at end of file
diff --git a/src/com/isode/stroke/elements/StreamInitiationFileInfo.java b/src/com/isode/stroke/elements/StreamInitiationFileInfo.java
new file mode 100644
index 0000000..1f9f3a4
--- /dev/null
+++ b/src/com/isode/stroke/elements/StreamInitiationFileInfo.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2011-2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.elements;
+
+import com.isode.stroke.elements.Payload;
+import com.isode.stroke.base.NotNull;
+import com.isode.stroke.base.DateTime;
+import java.util.Date;
+
+public class StreamInitiationFileInfo extends Payload {
+
+ private String name = "";
+ private String description;
+ private long size;
+ private String hash = "";
+ private Date date;
+ private String algo = "";
+ private boolean supportsRangeRequests;
+ private long rangeOffset;
+
+ /**
+ * Default Constructor.
+ */
+ public StreamInitiationFileInfo() {
+ this("", "", 0, "", null, "md5");
+ }
+
+ /**
+ * Parameterized Constructor.
+ * @param name, NotNull.
+ */
+ public StreamInitiationFileInfo(String name) {
+ this(name, "", 0, "", null, "md5");
+ }
+
+ /**
+ * Parameterized Constructor.
+ * @param name, NotNull.
+ * @param description, NotNull.
+ */
+ public StreamInitiationFileInfo(String name, String description) {
+ this(name, description, 0, "", null, "md5");
+ }
+
+ /**
+ * Parameterized Constructor.
+ * @param name, NotNull.
+ * @param description, NotNull.
+ * @param size.
+ */
+ public StreamInitiationFileInfo(String name, String description, long size) {
+ this(name, description, size, "", null, "md5");
+ }
+
+ /**
+ * Parameterized Constructor.
+ * @param name, NotNull.
+ * @param description, NotNull.
+ * @param size.
+ * @param hash, NotNull.
+ */
+ public StreamInitiationFileInfo(String name, String description, long size, String hash) {
+ this(name, description, size, hash, null, "md5");
+ }
+
+ /**
+ * Parameterized Constructor.
+ * @param name, NotNull.
+ * @param description, NotNull.
+ * @param size.
+ * @param hash, NotNull.
+ * @param date. Null means invalid date.
+ */
+ public StreamInitiationFileInfo(String name, String description, long size, String hash, Date date) {
+ this(name, description, size, hash, date, "md5");
+ }
+
+ /**
+ * Parameterized Constructor.
+ * @param name, NotNull.
+ * @param description, NotNull.
+ * @param size.
+ * @param hash, NotNull.
+ * @param date. Null means invalid date.
+ * @param algo, NotNull.
+ */
+ public StreamInitiationFileInfo(String name, String description, long size, String hash, Date date, String algo) {
+ NotNull.exceptIfNull(name, "name");
+ NotNull.exceptIfNull(description, "description");
+ NotNull.exceptIfNull(hash, "hash");
+ NotNull.exceptIfNull(algo, "algo");
+ this.name = name;
+ this.description = description;
+ this.size = size;
+ this.hash = hash;
+ this.date = date;
+ this.algo = algo;
+ this.supportsRangeRequests = false;
+ this.rangeOffset = 0L;
+ }
+
+ /**
+ * @param name, NotNull.
+ */
+ public void setName(String name) {
+ NotNull.exceptIfNull(name, "name");
+ this.name = name;
+ }
+
+ /**
+ * @return name, NotNull.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param description, NotNull.
+ */
+ public void setDescription(String description) {
+ NotNull.exceptIfNull(description, "description");
+ this.description = description;
+ }
+
+ /**
+ * @return description, NotNull.
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * @param size.
+ */
+ public void setSize(long size) {
+ this.size = size;
+ }
+
+ /**
+ * @return size.
+ */
+ public long getSize() {
+ return size;
+ }
+
+ /**
+ * @param hash, NotNull.
+ */
+ public void setHash(String hash) {
+ NotNull.exceptIfNull(hash, "hash");
+ this.hash = hash;
+ }
+
+ /**
+ * @return hash, NotNull.
+ */
+ public String getHash() {
+ return this.hash;
+ }
+
+ /**
+ * @param date. Null means invalid date.
+ */
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ /**
+ * @return date, which may be null for an invalid date.
+ */
+ public Date getDate() {
+ return date;
+ }
+
+ /**
+ * @param algo, NotNull.
+ */
+ public void setAlgo(String algo) {
+ NotNull.exceptIfNull(algo, "algo");
+ this.algo = algo;
+ }
+
+ /**
+ * @return algo, NotNull.
+ */
+ public String getAlgo() {
+ return this.algo;
+ }
+
+ /**
+ * @param supportsRangeRequests.
+ */
+ public void setSupportsRangeRequests(boolean supportsIt) {
+ this.supportsRangeRequests = supportsIt;
+ }
+
+ /**
+ * @return supportsRangeRequests.
+ */
+ public boolean getSupportsRangeRequests() {
+ return supportsRangeRequests;
+ }
+
+ /**
+ * @param offset.
+ */
+ public void setRangeOffset(long offset) {
+ this.supportsRangeRequests = true;
+ this.rangeOffset = offset;
+ }
+
+ /**
+ * @return offset.
+ */
+ public long getRangeOffset() {
+ return rangeOffset;
+ }
+}
diff --git a/src/com/isode/stroke/elements/StreamManagementEnabled.java b/src/com/isode/stroke/elements/StreamManagementEnabled.java
index f0de583..56883ca 100644
--- a/src/com/isode/stroke/elements/StreamManagementEnabled.java
+++ b/src/com/isode/stroke/elements/StreamManagementEnabled.java
@@ -10,6 +10,10 @@ package com.isode.stroke.elements;
public class StreamManagementEnabled implements Element {
+ public StreamManagementEnabled() {
+ this.resumeSupported = false;
+ }
+
public void setResumeSupported() {
resumeSupported = true;
}
diff --git a/src/com/isode/stroke/parser/StreamErrorParser.java b/src/com/isode/stroke/parser/StreamErrorParser.java
new file mode 100644
index 0000000..5d18d33
--- /dev/null
+++ b/src/com/isode/stroke/parser/StreamErrorParser.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2010-2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.parser;
+
+import com.isode.stroke.parser.GenericElementParser;
+import com.isode.stroke.parser.AttributeMap;
+import com.isode.stroke.elements.StreamError;
+import com.isode.stroke.base.NotNull;
+
+public class StreamErrorParser extends GenericElementParser<StreamError> {
+
+ private final int TopLevel = 0;
+ private final int ElementLevel = 1;
+ private int level = 0;
+ private String currentText = "";
+
+ public StreamErrorParser() {
+ super(StreamError.class);
+ }
+
+ /**
+ * @param element, NotNull.
+ * @param ns.
+ * @param attributes.
+ */
+ @Override
+ public void handleStartElement(String element, String ns, AttributeMap attributes) {
+ ++level;
+ }
+
+ /**
+ * @param element, NotNull.
+ * @param ns.
+ */
+ @Override
+ public void handleEndElement(String element, String ns) {
+ NotNull.exceptIfNull(element, "element");
+ --level;
+ if (level == ElementLevel && ns.equals("urn:ietf:params:xml:ns:xmpp-streams")) {
+ if (element.equals("text")) {
+ getElementGeneric().setText(currentText);
+ }
+ else if (element.equals("bad-format")) {
+ getElementGeneric().setType(StreamError.Type.BadFormat);
+ }
+ else if(element.equals("bad-namespace-prefix")) {
+ getElementGeneric().setType(StreamError.Type.BadNamespacePrefix);
+ }
+ else if(element.equals("conflict")) {
+ getElementGeneric().setType(StreamError.Type.Conflict);
+ }
+ else if(element.equals("connection-timeout")) {
+ getElementGeneric().setType(StreamError.Type.ConnectionTimeout);
+ }
+ else if(element.equals("host-gone")) {
+ getElementGeneric().setType(StreamError.Type.HostGone);
+ }
+ else if(element.equals("host-unknown")) {
+ getElementGeneric().setType(StreamError.Type.HostUnknown);
+ }
+ else if(element.equals("improper-addressing")) {
+ getElementGeneric().setType(StreamError.Type.ImproperAddressing);
+ }
+ else if(element.equals("internal-server-error")) {
+ getElementGeneric().setType(StreamError.Type.InternalServerError);
+ }
+ else if(element.equals("invalid-from")) {
+ getElementGeneric().setType(StreamError.Type.InvalidFrom);
+ }
+ else if(element.equals("invalid-id")) {
+ getElementGeneric().setType(StreamError.Type.InvalidID);
+ }
+ else if(element.equals("invalid-namespace")) {
+ getElementGeneric().setType(StreamError.Type.InvalidNamespace);
+ }
+ else if(element.equals("invalid-xml")) {
+ getElementGeneric().setType(StreamError.Type.InvalidXML);
+ }
+ else if(element.equals("not-authorized")) {
+ getElementGeneric().setType(StreamError.Type.NotAuthorized);
+ }
+ else if(element.equals("not-well-formed")) {
+ getElementGeneric().setType(StreamError.Type.NotWellFormed);
+ }
+ else if(element.equals("policy-violation")) {
+ getElementGeneric().setType(StreamError.Type.PolicyViolation);
+ }
+ else if(element.equals("remote-connection-failed")) {
+ getElementGeneric().setType(StreamError.Type.RemoteConnectionFailed);
+ }
+ else if(element.equals("reset")) {
+ getElementGeneric().setType(StreamError.Type.Reset);
+ }
+ else if(element.equals("resource-constraint")) {
+ getElementGeneric().setType(StreamError.Type.ResourceConstraint);
+ }
+ else if(element.equals("restricted-xml")) {
+ getElementGeneric().setType(StreamError.Type.RestrictedXML);
+ }
+ else if(element.equals("see-other-host")) {
+ getElementGeneric().setType(StreamError.Type.SeeOtherHost);
+ }
+ else if(element.equals("system-shutdown")) {
+ getElementGeneric().setType(StreamError.Type.SystemShutdown);
+ }
+ else if(element.equals("undefined-condition")) {
+ getElementGeneric().setType(StreamError.Type.UndefinedCondition);
+ }
+ else if(element.equals("unsupported-encoding")) {
+ getElementGeneric().setType(StreamError.Type.UnsupportedEncoding);
+ }
+ else if(element.equals("unsupported-stanza-type")) {
+ getElementGeneric().setType(StreamError.Type.UnsupportedStanzaType);
+ }
+ else if(element.equals("unsupported-version")) {
+ getElementGeneric().setType(StreamError.Type.UnsupportedVersion);
+ }
+ else {
+ getElementGeneric().setType(StreamError.Type.UndefinedCondition);
+ }
+ }
+ }
+
+ /**
+ * @param data, NotNull.
+ */
+ @Override
+ public void handleCharacterData(String data) {
+ NotNull.exceptIfNull(data, "data");
+ currentText += data;
+ }
+} \ No newline at end of file
diff --git a/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java b/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java
index d6d6483..b1afefd 100644
--- a/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java
+++ b/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java
@@ -54,7 +54,8 @@ public class FullPayloadParserFactoryCollection extends PayloadParserFactoryColl
"http://jabber.org/protocol/commands", CommandParser.class));
addFactory(new GenericPayloadParserFactory<InBandRegistrationPayloadParser>("query", "jabber:iq:register", InBandRegistrationPayloadParser.class));
addFactory(new SearchPayloadParserFactory());
- //addFactory(new StreamInitiationParserFactory());
+ addFactory(new GenericPayloadParserFactory<StreamInitiationFileInfoParser>("file", "http://jabber.org/protocol/si/profile/file-transfer", StreamInitiationFileInfoParser.class));
+ addFactory(new GenericPayloadParserFactory<StreamInitiationParser>("si", "http://jabber.org/protocol/si", StreamInitiationParser.class));
addFactory(new GenericPayloadParserFactory<ThreadParser>("thread", ThreadParser.class));
addFactory(new GenericPayloadParserFactory<BytestreamsParser>("query", "http://jabber.org/protocol/bytestreams", BytestreamsParser.class));
addFactory(new GenericPayloadParserFactory<VCardUpdateParser>("x", "vcard-temp:x:update", VCardUpdateParser.class));
diff --git a/src/com/isode/stroke/parser/payloadparsers/StreamInitiationFileInfoParser.java b/src/com/isode/stroke/parser/payloadparsers/StreamInitiationFileInfoParser.java
new file mode 100644
index 0000000..403ab4c
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/StreamInitiationFileInfoParser.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+/*
+ * Copyright (c) 2014 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.parser.payloadparsers;
+
+import com.isode.stroke.parser.GenericPayloadParser;
+import com.isode.stroke.parser.AttributeMap;
+import com.isode.stroke.elements.StreamInitiationFileInfo;
+import com.isode.stroke.base.NotNull;
+import com.isode.stroke.base.DateTime;
+
+public class StreamInitiationFileInfoParser extends GenericPayloadParser<StreamInitiationFileInfo> {
+
+ private int level = 0;
+ private boolean parseDescription;
+ private String desc = "";
+
+ public StreamInitiationFileInfoParser() {
+ super(new StreamInitiationFileInfo());
+ }
+
+ /**
+ * @param element, NotNull.
+ * @param ns.
+ * @param attributes, NotNull.
+ */
+ @Override
+ public void handleStartElement(String element, String ns, AttributeMap attributes) {
+ NotNull.exceptIfNull(element, "element");
+ NotNull.exceptIfNull(attributes, "attributes");
+ if (level == 0) {
+ if(attributes.getAttributeValue("name") != null) {
+ getPayloadInternal().setName(attributes.getAttributeValue("name"));
+ } else {
+ getPayloadInternal().setName("");
+ }
+
+ if(attributes.getAttributeValue("hash") != null) {
+ getPayloadInternal().setHash(attributes.getAttributeValue("hash"));
+ } else {
+ getPayloadInternal().setHash("");
+ }
+
+ if(attributes.getAttributeValue("algo") != null) {
+ getPayloadInternal().setAlgo(attributes.getAttributeValue("algo"));
+ } else {
+ getPayloadInternal().setAlgo("md5");
+ }
+
+ if(attributes.getAttributeValue("size") != null) {
+ try {
+ getPayloadInternal().setSize(Long.parseLong(attributes.getAttributeValue("size")));
+ } catch (NumberFormatException e) {
+ getPayloadInternal().setSize(0L);
+ }
+ } else {
+ getPayloadInternal().setSize(0L);
+ }
+
+ if(attributes.getAttributeValue("date") != null) {
+ getPayloadInternal().setDate(DateTime.stringToDate(attributes.getAttributeValue("date")));
+ } else {
+ getPayloadInternal().setDate(DateTime.stringToDate(""));
+ }
+
+ } else if (level == 1) {
+ if (element.equals("desc")) {
+ parseDescription = true;
+ } else {
+ parseDescription = false;
+ if (element.equals("range")) {
+ long offset = 0;
+ if (attributes.getAttributeValue("offset") != null) {
+ try {
+ offset = Long.parseLong(attributes.getAttributeValue("offset"));
+ } catch (NumberFormatException e) {
+ offset = 0;
+ }
+ } else {
+ offset = 0;
+ }
+ if (offset == 0) {
+ getPayloadInternal().setSupportsRangeRequests(true);
+ } else {
+ getPayloadInternal().setRangeOffset(offset);
+ }
+ }
+ }
+ }
+ ++level;
+ }
+
+ /**
+ * @param element, NotNull.
+ * @param ns.
+ */
+ @Override
+ public void handleEndElement(String element, String ns) {
+ NotNull.exceptIfNull(element, "element");
+ --level;
+ if (parseDescription && element.equals("desc")) {
+ parseDescription = false;
+ getPayloadInternal().setDescription(desc);
+ }
+ }
+
+ /**
+ * @param data, NotNull.
+ */
+ @Override
+ public void handleCharacterData(String data) {
+ NotNull.exceptIfNull(data, "data");
+ if (parseDescription) {
+ desc += data;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/isode/stroke/parser/payloadparsers/StreamInitiationParser.java b/src/com/isode/stroke/parser/payloadparsers/StreamInitiationParser.java
new file mode 100644
index 0000000..daab4d6
--- /dev/null
+++ b/src/com/isode/stroke/parser/payloadparsers/StreamInitiationParser.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2010-2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.parser.payloadparsers;
+
+import com.isode.stroke.parser.GenericPayloadParser;
+import com.isode.stroke.parser.AttributeMap;
+import com.isode.stroke.parser.payloadparsers.FormParser;
+import com.isode.stroke.parser.payloadparsers.FormParserFactory;
+import com.isode.stroke.elements.StreamInitiation;
+import com.isode.stroke.elements.StreamInitiationFileInfo;
+import com.isode.stroke.elements.Form;
+import com.isode.stroke.elements.FormField;
+import com.isode.stroke.base.NotNull;
+
+public class StreamInitiationParser extends GenericPayloadParser<StreamInitiation> {
+
+ private static final String FILE_TRANSFER_NS = "http://jabber.org/protocol/si/profile/file-transfer";
+ private static final String FEATURE_NEG_NS = "http://jabber.org/protocol/feature-neg";
+ private final int TopLevel = 0;
+ private final int PayloadLevel = 1;
+ private final int FileOrFeatureLevel = 2;
+ private final int FormOrDescriptionLevel = 3;
+ private int level = 0;
+ private FormParserFactory formParserFactory = new FormParserFactory();
+ private FormParser formParser;
+ private boolean inFile;
+ private boolean inFeature;
+ private StreamInitiationFileInfo currentFile;
+ private String currentText = "";
+
+ public StreamInitiationParser() {
+ super(new StreamInitiation());
+ }
+
+ /**
+ * @param element, NotNull.
+ * @param ns, NotNull.
+ * @param attributes, NotNull.
+ */
+ @Override
+ public void handleStartElement(String element, String ns, AttributeMap attributes) {
+ NotNull.exceptIfNull(element, "element");
+ NotNull.exceptIfNull(ns, "ns");
+ NotNull.exceptIfNull(attributes, "attributes");
+ if (level == TopLevel) {
+ getPayloadInternal().setID(attributes.getAttribute("id"));
+ if (attributes.getAttribute("profile").length() != 0) {
+ getPayloadInternal().setIsFileTransfer(attributes.getAttribute("profile").equals(FILE_TRANSFER_NS));
+ }
+ }
+ else if (level == PayloadLevel) {
+ if (element.equals("file")) {
+ inFile = true;
+ currentFile = new StreamInitiationFileInfo();
+ currentFile.setName(attributes.getAttribute("name"));
+ try {
+ currentFile.setSize(Long.parseLong(attributes.getAttribute("size")));
+ }
+ catch (NumberFormatException e) {
+ }
+ }
+ else if (element.equals("feature") && ns.equals(FEATURE_NEG_NS)) {
+ inFeature = true;
+ }
+ }
+ else if (level == FileOrFeatureLevel) {
+ if (inFile && element.equals("desc")) {
+ currentText = "";
+ }
+ else if (inFeature && formParserFactory.canParse(element, ns, attributes)) {
+ assert(formParser == null);
+ formParser = (FormParser)(formParserFactory.createPayloadParser());
+ }
+ }
+
+ if (formParser != null) {
+ formParser.handleStartElement(element, ns, attributes);
+ }
+ ++level;
+ }
+
+ /**
+ * @param element, NotNull.
+ * @param ns.
+ */
+ @Override
+ public void handleEndElement(String element, String ns) {
+ NotNull.exceptIfNull(element, "element");
+ --level;
+ if (formParser != null) {
+ formParser.handleEndElement(element, ns);
+ }
+ if (level == TopLevel) {
+ }
+ else if (level == PayloadLevel) {
+ if (element.equals("file")) {
+ getPayloadInternal().setFileInfo(currentFile);
+ inFile = false;
+ }
+ else if (element.equals("feature") && ns.equals(FEATURE_NEG_NS)) {
+ inFeature = false;
+ }
+ }
+ else if (level == FileOrFeatureLevel) {
+ if (inFile && element.equals("desc")) {
+ currentFile.setDescription(currentText);
+ }
+ else if (formParser != null) {
+ Form form = formParser.getPayloadInternal();
+ if (form != null) {
+ FormField field = (FormField)(form.getField("stream-method"));
+ if (field != null) {
+ if (form.getType().equals(Form.Type.FORM_TYPE)) {
+ for (FormField.Option option : field.getOptions()) {
+ getPayloadInternal().addProvidedMethod(option.value_);
+ }
+ }
+ else if (form.getType().equals(Form.Type.SUBMIT_TYPE)) {
+ if (!field.getValues().isEmpty()) {
+ getPayloadInternal().setRequestedMethod(field.getValues().get(0));
+ }
+ }
+ }
+ }
+ formParser = null;
+ }
+ }
+ }
+
+ /**
+ * @param data, NotNull.
+ */
+ @Override
+ public void handleCharacterData(String data) {
+ NotNull.exceptIfNull(data, "data");
+ if (formParser != null) {
+ formParser.handleCharacterData(data);
+ }
+ else {
+ currentText += data;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/isode/stroke/serializer/StreamErrorSerializer.java b/src/com/isode/stroke/serializer/StreamErrorSerializer.java
new file mode 100644
index 0000000..2455efe
--- /dev/null
+++ b/src/com/isode/stroke/serializer/StreamErrorSerializer.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010-2014 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.serializer;
+
+import com.isode.stroke.serializer.GenericElementSerializer;
+import com.isode.stroke.serializer.xml.XMLElement;
+import com.isode.stroke.elements.StreamError;
+import com.isode.stroke.elements.Element;
+
+public class StreamErrorSerializer extends GenericElementSerializer<StreamError> {
+
+ public StreamErrorSerializer() {
+ super(StreamError.class);
+ }
+
+ public String serialize(Element element) {
+ StreamError error = (StreamError)element;
+ XMLElement errorElement = new XMLElement("error", "http://etherx.jabber.org/streams");
+
+ String typeTag = "";
+ switch (error.getType()) {
+ case BadFormat: typeTag = "bad-format"; break;
+ case BadNamespacePrefix: typeTag = "bad-namespace-prefix"; break;
+ case Conflict: typeTag = "conflict"; break;
+ case ConnectionTimeout: typeTag = "connection-timeout"; break;
+ case HostGone: typeTag = "host-gone"; break;
+ case HostUnknown: typeTag = "host-unknown"; break;
+ case ImproperAddressing: typeTag = "improper-addressing"; break;
+ case InternalServerError: typeTag = "internal-server-error"; break;
+ case InvalidFrom: typeTag = "invalid-from"; break;
+ case InvalidID: typeTag = "invalid-id"; break;
+ case InvalidNamespace: typeTag = "invalid-namespace"; break;
+ case InvalidXML: typeTag = "invalid-xml"; break;
+ case NotAuthorized: typeTag = "not-authorized"; break;
+ case NotWellFormed: typeTag = "not-well-formed"; break;
+ case PolicyViolation: typeTag = "policy-violation"; break;
+ case RemoteConnectionFailed: typeTag = "remote-connection-failed"; break;
+ case Reset: typeTag = "reset"; break;
+ case ResourceConstraint: typeTag = "resource-constraint"; break;
+ case RestrictedXML: typeTag = "restricted-xml"; break;
+ case SeeOtherHost: typeTag = "see-other-host"; break;
+ case SystemShutdown: typeTag = "system-shutdown"; break;
+ case UndefinedCondition: typeTag = "undefined-condition"; break;
+ case UnsupportedEncoding: typeTag = "unsupported-encoding"; break;
+ case UnsupportedStanzaType: typeTag = "unsupported-stanza-type"; break;
+ case UnsupportedVersion: typeTag = "unsupported-version"; break;
+ }
+ errorElement.addNode(new XMLElement(typeTag, "urn:ietf:params:xml:ns:xmpp-streams"));
+
+ if (!error.getText().isEmpty()) {
+ errorElement.addNode(new XMLElement("text", "urn:ietf:params:xml:ns:xmpp-streams", error.getText()));
+ }
+
+ return errorElement.serialize();
+ }
+} \ No newline at end of file
diff --git a/src/com/isode/stroke/serializer/payloadserializers/FullPayloadSerializerCollection.java b/src/com/isode/stroke/serializer/payloadserializers/FullPayloadSerializerCollection.java
index 64b17d1..ba0d4e9 100644
--- a/src/com/isode/stroke/serializer/payloadserializers/FullPayloadSerializerCollection.java
+++ b/src/com/isode/stroke/serializer/payloadserializers/FullPayloadSerializerCollection.java
@@ -53,8 +53,8 @@ public class FullPayloadSerializerCollection extends PayloadSerializerCollection
addSerializer(new StartSessionSerializer());
addSerializer(new SecurityLabelSerializer());
addSerializer(new SecurityLabelsCatalogSerializer());
- //addSerializer(new StreamInitiationFileInfoSerializer());
- //addSerializer(new StreamInitiationSerializer());
+ addSerializer(new StreamInitiationFileInfoSerializer());
+ addSerializer(new StreamInitiationSerializer());
addSerializer(new ThreadSerializer());
addSerializer(new BytestreamsSerializer());
addSerializer(new VCardSerializer());
diff --git a/src/com/isode/stroke/serializer/payloadserializers/StreamInitiationFileInfoSerializer.java b/src/com/isode/stroke/serializer/payloadserializers/StreamInitiationFileInfoSerializer.java
new file mode 100644
index 0000000..1823dba
--- /dev/null
+++ b/src/com/isode/stroke/serializer/payloadserializers/StreamInitiationFileInfoSerializer.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.serializer.payloadserializers;
+
+import com.isode.stroke.serializer.GenericPayloadSerializer;
+import com.isode.stroke.serializer.xml.XMLTextNode;
+import com.isode.stroke.serializer.xml.XMLElement;
+import com.isode.stroke.elements.StreamInitiationFileInfo;
+import com.isode.stroke.base.NotNull;
+import com.isode.stroke.base.DateTime;
+
+public class StreamInitiationFileInfoSerializer extends GenericPayloadSerializer<StreamInitiationFileInfo> {
+
+ public StreamInitiationFileInfoSerializer() {
+ super(StreamInitiationFileInfo.class);
+ }
+
+ public String serializePayload(StreamInitiationFileInfo fileInfo) {
+ XMLElement fileElement = new XMLElement("file", "http://jabber.org/protocol/si/profile/file-transfer");
+
+ if (fileInfo.getDate() != null) {
+ fileElement.setAttribute("date", DateTime.dateToString(fileInfo.getDate()));
+ }
+ fileElement.setAttribute("hash", fileInfo.getHash());
+ if (!fileInfo.getAlgo().equals("md5")) {
+ fileElement.setAttribute("algo", fileInfo.getAlgo());
+ }
+ if (fileInfo.getName().length() != 0) {
+ fileElement.setAttribute("name", fileInfo.getName());
+ }
+ if (fileInfo.getSize() != 0) {
+ fileElement.setAttribute("size", Long.toString(fileInfo.getSize()));
+ }
+ if (fileInfo.getDescription().length() != 0) {
+ XMLElement desc = new XMLElement("desc", "", fileInfo.getDescription());
+ fileElement.addNode(desc);
+ }
+ if (fileInfo.getSupportsRangeRequests()) {
+ XMLElement range = new XMLElement("range");
+ if (fileInfo.getRangeOffset() != 0) {
+ range.setAttribute("offset", Long.toString(fileInfo.getRangeOffset()));
+ }
+ fileElement.addNode(range);
+ }
+ return fileElement.serialize();
+ }
+} \ No newline at end of file
diff --git a/src/com/isode/stroke/serializer/payloadserializers/StreamInitiationSerializer.java b/src/com/isode/stroke/serializer/payloadserializers/StreamInitiationSerializer.java
new file mode 100644
index 0000000..64c608c
--- /dev/null
+++ b/src/com/isode/stroke/serializer/payloadserializers/StreamInitiationSerializer.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010-2013 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.serializer.payloadserializers;
+
+import com.isode.stroke.serializer.GenericPayloadSerializer;
+import com.isode.stroke.serializer.xml.XMLTextNode;
+import com.isode.stroke.serializer.xml.XMLRawTextNode;
+import com.isode.stroke.serializer.xml.XMLElement;
+import com.isode.stroke.elements.StreamInitiation;
+import com.isode.stroke.elements.StreamInitiationFileInfo;
+import com.isode.stroke.elements.Form;
+import com.isode.stroke.elements.FormField;
+import com.isode.stroke.base.NotNull;
+
+public class StreamInitiationSerializer extends GenericPayloadSerializer<StreamInitiation> {
+
+ private static final String FILE_TRANSFER_NS = "http://jabber.org/protocol/si/profile/file-transfer";
+ private static final String FEATURE_NEG_NS = "http://jabber.org/protocol/feature-neg";
+
+ public StreamInitiationSerializer() {
+ super(StreamInitiation.class);
+ }
+
+ public String serializePayload(StreamInitiation streamInitiation) {
+ assert(streamInitiation.getIsFileTransfer() == true);
+
+ XMLElement siElement = new XMLElement("si", "http://jabber.org/protocol/si");
+ if (streamInitiation.getID().length() != 0) {
+ siElement.setAttribute("id", streamInitiation.getID());
+ }
+ siElement.setAttribute("profile", FILE_TRANSFER_NS);
+
+ if (streamInitiation.getFileInfo() != null) {
+ StreamInitiationFileInfo file = streamInitiation.getFileInfo();
+ XMLElement fileElement = new XMLElement("file", "http://jabber.org/protocol/si/profile/file-transfer");
+ fileElement.setAttribute("name", file.getName());
+ if (file.getSize() != 0) {
+ fileElement.setAttribute("size", Long.toString(file.getSize()));
+ }
+ if (file.getDescription().length() != 0) {
+ XMLElement descElement = new XMLElement("desc");
+ descElement.addNode(new XMLTextNode(file.getDescription()));
+ fileElement.addNode(descElement);
+ }
+ siElement.addNode(fileElement);
+ }
+
+ XMLElement featureElement = new XMLElement("feature", FEATURE_NEG_NS);
+ if (streamInitiation.getProvidedMethods().size() > 0) {
+ Form form = new Form(Form.Type.FORM_TYPE);
+ FormField field = new FormField(FormField.Type.LIST_SINGLE_TYPE);
+ field.setName("stream-method");
+ for(String method : streamInitiation.getProvidedMethods()) {
+ field.addOption(new FormField.Option("", method));
+ }
+ form.addField(field);
+ featureElement.addNode(new XMLRawTextNode(new FormSerializer().serialize(form)));
+ }
+ else if (streamInitiation.getRequestedMethod().length() != 0) {
+ Form form = new Form(Form.Type.SUBMIT_TYPE);
+ FormField field = new FormField(FormField.Type.LIST_SINGLE_TYPE);
+ field.addValue(streamInitiation.getRequestedMethod());
+ field.setName("stream-method");
+ form.addField(field);
+ featureElement.addNode(new XMLRawTextNode(new FormSerializer().serialize(form)));
+ }
+ siElement.addNode(featureElement);
+ return siElement.serialize();
+ }
+} \ No newline at end of file
diff --git a/test/com/isode/stroke/parser/payloadparsers/StreamInitiationParserTest.java b/test/com/isode/stroke/parser/payloadparsers/StreamInitiationParserTest.java
new file mode 100644
index 0000000..ed30aeb
--- /dev/null
+++ b/test/com/isode/stroke/parser/payloadparsers/StreamInitiationParserTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.parser.payloadparsers;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+import com.isode.stroke.elements.StreamInitiation;
+import com.isode.stroke.elements.StreamInitiationFileInfo;
+import com.isode.stroke.parser.payloadparsers.StreamInitiationParser;
+import com.isode.stroke.parser.payloadparsers.PayloadsParserTester;
+import com.isode.stroke.eventloop.DummyEventLoop;
+
+public class StreamInitiationParserTest {
+
+ public StreamInitiationParserTest() {
+
+ }
+
+ @Test
+ public void testParse_Request() {
+ DummyEventLoop eventLoop = new DummyEventLoop();
+ PayloadsParserTester parser = new PayloadsParserTester(eventLoop);
+ assertNotNull(parser.parse("<si xmlns='http://jabber.org/protocol/si' id='a0' mime-type='text/plain' profile='http://jabber.org/protocol/si/profile/file-transfer'>" +
+ "<file xmlns='http://jabber.org/protocol/si/profile/file-transfer' name='test.txt' size='1022'>" +
+ "<desc>This is info about the file.</desc>" +
+ "</file>" +
+ "<feature xmlns='http://jabber.org/protocol/feature-neg'>" +
+ "<x xmlns='jabber:x:data' type='form'>" +
+ "<field var='stream-method' type='list-single'>" +
+ "<option><value>http://jabber.org/protocol/bytestreams</value></option>" +
+ "<option><value>jabber:iq:oob</value></option>" +
+ "<option><value>http://jabber.org/protocol/ibb</value></option>" +
+ "</field>" +
+ "</x>" +
+ "</feature>" +
+ "</si>"));
+
+ StreamInitiation si = (StreamInitiation)parser.getPayload();
+ assertTrue(si.getIsFileTransfer());
+ assertNotNull(si.getFileInfo());
+ assertEquals("test.txt", si.getFileInfo().getName());
+ assertEquals(1022L, si.getFileInfo().getSize());
+ assertEquals("This is info about the file.", si.getFileInfo().getDescription());
+ assertEquals(3, si.getProvidedMethods().size());
+ assertEquals("http://jabber.org/protocol/bytestreams", si.getProvidedMethods().get(0));
+ assertEquals("jabber:iq:oob", si.getProvidedMethods().get(1));
+ assertEquals("http://jabber.org/protocol/ibb", si.getProvidedMethods().get(2));
+ }
+
+ @Test
+ public void testParse_Response() {
+ DummyEventLoop eventLoop = new DummyEventLoop();
+ PayloadsParserTester parser = new PayloadsParserTester(eventLoop);
+ assertNotNull(parser.parse("<si xmlns='http://jabber.org/protocol/si'>" +
+ "<feature xmlns='http://jabber.org/protocol/feature-neg'>" +
+ "<x xmlns='jabber:x:data' type='submit'>" +
+ "<field var='stream-method'>" +
+ "<value>http://jabber.org/protocol/bytestreams</value>" +
+ "</field>" +
+ "</x>" +
+ "</feature>" +
+ "</si>"));
+
+ StreamInitiation si = (StreamInitiation)parser.getPayload();
+ assertTrue(si.getIsFileTransfer());
+ assertEquals("http://jabber.org/protocol/bytestreams", si.getRequestedMethod());
+ }
+} \ No newline at end of file
diff --git a/test/com/isode/stroke/serializer/payloadserializers/StreamInitiationSerializerTest.java b/test/com/isode/stroke/serializer/payloadserializers/StreamInitiationSerializerTest.java
new file mode 100644
index 0000000..54e7f87
--- /dev/null
+++ b/test/com/isode/stroke/serializer/payloadserializers/StreamInitiationSerializerTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2010 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.serializer.payloadserializers;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+import com.isode.stroke.serializer.payloadserializers.StreamInitiationSerializer;
+import com.isode.stroke.serializer.PayloadSerializerCollection;
+import com.isode.stroke.elements.StreamInitiation;
+import com.isode.stroke.elements.StreamInitiationFileInfo;
+
+public class StreamInitiationSerializerTest {
+
+ /**
+ * Default Constructor.
+ */
+ public StreamInitiationSerializerTest() {
+
+ }
+
+ @Test
+ public void testSerialize_Request() {
+ StreamInitiationSerializer testling = new StreamInitiationSerializer();
+ StreamInitiation streamInitiation = new StreamInitiation();
+ StreamInitiationFileInfo fileInfo = new StreamInitiationFileInfo("test.txt", "This is info about the file.", 1022);
+ streamInitiation.setID("a0");
+ streamInitiation.setFileInfo(fileInfo);
+ streamInitiation.addProvidedMethod("http://jabber.org/protocol/bytestreams");
+ streamInitiation.addProvidedMethod("jabber:iq:oob");
+ streamInitiation.addProvidedMethod("http://jabber.org/protocol/ibb");
+ String expectedResult = "<si id=\"a0\" profile=\"http://jabber.org/protocol/si/profile/file-transfer\" xmlns=\"http://jabber.org/protocol/si\">"
+ + "<file name=\"test.txt\" size=\"1022\" xmlns=\"http://jabber.org/protocol/si/profile/file-transfer\">"
+ + "<desc>This is info about the file.</desc>"
+ + "</file>"
+ + "<feature xmlns=\"http://jabber.org/protocol/feature-neg\">"
+ + "<x type=\"form\" xmlns=\"jabber:x:data\">"
+ + "<field type=\"list-single\" var=\"stream-method\">"
+ + "<option><value>http://jabber.org/protocol/bytestreams</value></option>"
+ + "<option><value>jabber:iq:oob</value></option>"
+ + "<option><value>http://jabber.org/protocol/ibb</value></option>"
+ + "</field>"
+ + "</x>"
+ + "</feature>"
+ + "</si>";
+ assertEquals(expectedResult, testling.serialize(streamInitiation));
+ }
+
+ @Test
+ public void testSerialize_Response() {
+ StreamInitiationSerializer testling = new StreamInitiationSerializer();
+ StreamInitiation streamInitiation = new StreamInitiation();
+ streamInitiation.setRequestedMethod("http://jabber.org/protocol/bytestreams");
+ String expectedResult = "<si profile=\"http://jabber.org/protocol/si/profile/file-transfer\" xmlns=\"http://jabber.org/protocol/si\">"
+ + "<feature xmlns=\"http://jabber.org/protocol/feature-neg\">"
+ + "<x type=\"submit\" xmlns=\"jabber:x:data\">"
+ + "<field type=\"list-single\" var=\"stream-method\">"
+ + "<value>http://jabber.org/protocol/bytestreams</value>"
+ + "</field>"
+ + "</x>"
+ + "</feature>"
+ + "</si>";
+ assertEquals(expectedResult, testling.serialize(streamInitiation));
+ }
+} \ No newline at end of file