From ba7342e593920595af36fcd8e8e44ec206f8b561 Mon Sep 17 00:00:00 2001 From: Tarun Gupta Date: Sat, 20 Jun 2015 17:40:51 +0530 Subject: 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 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 providedMethods = new Vector(); + 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 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 { + + 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("query", "jabber:iq:register", InBandRegistrationPayloadParser.class)); addFactory(new SearchPayloadParserFactory()); - //addFactory(new StreamInitiationParserFactory()); + addFactory(new GenericPayloadParserFactory("file", "http://jabber.org/protocol/si/profile/file-transfer", StreamInitiationFileInfoParser.class)); + addFactory(new GenericPayloadParserFactory("si", "http://jabber.org/protocol/si", StreamInitiationParser.class)); addFactory(new GenericPayloadParserFactory("thread", ThreadParser.class)); addFactory(new GenericPayloadParserFactory("query", "http://jabber.org/protocol/bytestreams", BytestreamsParser.class)); addFactory(new GenericPayloadParserFactory("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 { + + 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 { + + 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 { + + 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 { + + 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 { + + 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("" + + "" + + "This is info about the file." + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "")); + + 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("" + + "" + + "" + + "" + + "http://jabber.org/protocol/bytestreams" + + "" + + "" + + "" + + "")); + + 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 = "" + + "" + + "This is info about the file." + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + ""; + 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 = "" + + "" + + "" + + "" + + "http://jabber.org/protocol/bytestreams" + + "" + + "" + + "" + + ""; + assertEquals(expectedResult, testling.serialize(streamInitiation)); + } +} \ No newline at end of file -- cgit v0.10.2-6-g49f6