Add JingleContentDescriptionFileTransfer and tests

This commit is contained in:
vanitasvitae 2017-05-31 13:27:23 +02:00
parent 7319998bb9
commit f0e6521360
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
12 changed files with 375 additions and 13 deletions

View File

@ -1,3 +1,19 @@
/**
*
* Copyright © 2017 Paul Schaub
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.hash;
import org.bouncycastle.jcajce.provider.digest.Blake2b;
@ -122,7 +138,7 @@ public final class HashManager extends Manager {
}
/**
* Compensational method for static 'valueOf' function
* Compensational method for static 'valueOf' function.
* @param s
* @return
*/

View File

@ -114,4 +114,17 @@ public class HashElement implements ExtensionElement {
public String getNamespace() {
return HashManager.NAMESPACE_V2;
}
@Override
public boolean equals(Object other) {
if (other == null || !(other instanceof HashElement)) {
return false;
}
return this.hashCode() == other.hashCode();
}
@Override
public int hashCode() {
return toXML().toString().hashCode();
}
}

View File

@ -22,7 +22,7 @@ import org.jivesoftware.smackx.hash.element.HashElement;
import org.xmlpull.v1.XmlPullParser;
/**
* Provider for HashElements
* Provider for HashElements.
*/
public class HashElementProvider extends ExtensionElementProvider<HashElement> {

View File

@ -16,16 +16,16 @@
*/
package org.jivesoftware.smackx.jingle_filetransfer.element;
import org.jivesoftware.smack.packet.NamedElement;
import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jivesoftware.smackx.hash.element.HashElement;
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionPayloadType;
import java.util.Date;
/**
* Content of type File.
*/
public class FileTransfer implements NamedElement {
public class FileTransferPayload extends JingleContentDescriptionPayloadType {
public static final String ELEMENT = "file";
public static final String ELEM_DATE = "date";
public static final String ELEM_DESC = "desc";
@ -41,7 +41,7 @@ public class FileTransfer implements NamedElement {
private final int size;
private final Range range;
public FileTransfer(Date date, String desc, HashElement hash, String mediaType, String name, int size, Range range) {
public FileTransferPayload(Date date, String desc, HashElement hash, String mediaType, String name, int size, Range range) {
this.date = date;
this.desc = desc;
this.hash = hash;
@ -51,6 +51,34 @@ public class FileTransfer implements NamedElement {
this.range = range;
}
public Date getDate() {
return date;
}
public String getDescription() {
return desc;
}
public HashElement getHash() {
return hash;
}
public String getMediaType() {
return mediaType;
}
public String getName() {
return name;
}
public int getSize() {
return size;
}
public Range getRange() {
return range;
}
@Override
public String getElementName() {
return ELEMENT;

View File

@ -27,11 +27,8 @@ import java.util.List;
*/
public class JingleContentDescriptionFileTransfer extends JingleContentDescription {
private FileTransfer fileTransfer;
protected JingleContentDescriptionFileTransfer(List<JingleContentDescriptionPayloadType> payloadTypes, FileTransfer fileTransfer) {
public JingleContentDescriptionFileTransfer(List<JingleContentDescriptionPayloadType> payloadTypes) {
super(payloadTypes);
this.fileTransfer = fileTransfer;
}
@Override

View File

@ -1,3 +1,19 @@
/**
*
* Copyright © 2017 Paul Schaub
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.jingle_filetransfer.element;
import org.jivesoftware.smack.packet.NamedElement;
@ -102,4 +118,18 @@ public class Range implements NamedElement {
}
return sb;
}
@Override
public boolean equals(Object other) {
if (other == null || !(other instanceof Range)) {
return false;
}
return this.hashCode() == other.hashCode();
}
@Override
public int hashCode() {
return toXML().toString().hashCode();
}
}

View File

@ -0,0 +1,138 @@
/**
*
* Copyright 2017 Paul Schaub
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.jingle_filetransfer.provider;
import org.jivesoftware.smackx.hash.element.HashElement;
import org.jivesoftware.smackx.hash.provider.HashElementProvider;
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionPayloadType;
import org.jivesoftware.smackx.jingle.provider.JingleContentDescriptionProvider;
import org.jivesoftware.smackx.jingle_filetransfer.element.FileTransferPayload;
import org.jivesoftware.smackx.jingle_filetransfer.element.JingleContentDescriptionFileTransfer;
import org.jivesoftware.smackx.jingle_filetransfer.element.Range;
import org.jxmpp.util.XmppDateTime;
import org.xmlpull.v1.XmlPullParser;
import java.util.ArrayList;
import java.util.Date;
import static org.xmlpull.v1.XmlPullParser.END_TAG;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
/**
* Provider for JingleContentDescriptionFileTransfer elements.
*/
public class JingleContentDescriptionFileTransferProvider
extends JingleContentDescriptionProvider<JingleContentDescriptionFileTransfer> {
@Override
public JingleContentDescriptionFileTransfer parse(XmlPullParser parser, int initialDepth) throws Exception {
boolean inRange = false;
Date date = null;
String desc = null;
String mediaType = null;
String name = null;
int size = -1;
Range range = null;
HashElement inRangeHash = null;
HashElement hash = null;
ArrayList<JingleContentDescriptionPayloadType> payloads = new ArrayList<>();
int offset = 0;
int length = -1;
while (true) {
int tag = parser.nextTag();
String elem = parser.getName();
if (tag == START_TAG) {
switch (elem) {
case FileTransferPayload.ELEMENT:
date = null;
desc = null;
mediaType = null;
name = null;
size = -1;
range = null;
inRangeHash = null;
hash = null;
break;
case FileTransferPayload.ELEM_DATE:
date = XmppDateTime.parseXEP0082Date(parser.nextText());
break;
case FileTransferPayload.ELEM_DESC:
desc = parser.nextText();
break;
case FileTransferPayload.ELEM_MEDIA_TYPE:
mediaType = parser.nextText();
break;
case FileTransferPayload.ELEM_NAME:
name = parser.nextText();
break;
case FileTransferPayload.ELEM_SIZE:
size = Integer.parseInt(parser.nextText());
break;
case Range.ELEMENT:
inRange = true;
String offsetString = parser.getAttributeValue(null, Range.ATTR_OFFSET);
String lengthString = parser.getAttributeValue(null, Range.ATTR_LENGTH);
offset = (offsetString != null ? Integer.parseInt(offsetString) : 0);
length = (lengthString != null ? Integer.parseInt(lengthString) : -1);
if (parser.isEmptyElementTag()) {
range = new Range(offset, length);
inRange = false;
}
break;
case HashElement.ELEMENT:
if (inRange) {
inRangeHash = new HashElementProvider().parse(parser);
} else {
hash = new HashElementProvider().parse(parser);
}
break;
}
} else if (tag == END_TAG) {
switch (elem) {
case Range.ELEMENT:
inRange = false;
range = new Range(offset, length, inRangeHash);
break;
case FileTransferPayload.ELEMENT:
payloads.add(new FileTransferPayload(date, desc, hash, mediaType, name, size, range));
break;
case JingleContentDescriptionFileTransfer.ELEMENT:
return new JingleContentDescriptionFileTransfer(payloads);
}
}
}
}
}

View File

@ -26,6 +26,8 @@ import org.junit.Test;
import static junit.framework.TestCase.assertEquals;
import static org.jivesoftware.smackx.hash.HashManager.ALGORITHM.SHA_256;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* Test toXML and parse of HashElement and HashElementProvider.
@ -44,6 +46,11 @@ public class HashElementTest extends SmackTestSuite {
assertEquals(SHA_256, parsed.getAlgorithm());
assertEquals("f4OxZX/x/FO5LcGBSKHWXfwtSx+j1ncoSt3SABJtkGk=", parsed.getHashB64());
assertArrayEquals(HashManager.sha_256(message.getBytes(StringUtils.UTF8)), parsed.getHash());
assertFalse(parsed.equals(expected));
assertFalse(parsed.equals(null));
assertEquals(element, parsed);
assertTrue(element.equals(parsed));
}
}

View File

@ -26,8 +26,8 @@ import static junit.framework.TestCase.assertEquals;
/**
* Test HashManager functionality.
* The test sums got calculated using 'echo "Hello World!" | {md5sum, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum,
* sha3-224sum -l, sha3-256sum -l, sha3-384sum -l, sha3-512sum -l, b2sum -l 160, b2sum -l 256, b2sum -l 384, b2sum -l 512}
* The test sums got calculated using 'echo "Hello World!" | { md5sum, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum,
* sha3-224sum -l, sha3-256sum -l, sha3-384sum -l, sha3-512sum -l, b2sum -l 160, b2sum -l 256, b2sum -l 384, b2sum -l 512 }
*/
public class HashTest extends SmackTestSuite {
@ -48,7 +48,7 @@ public class HashTest extends SmackTestSuite {
private static final String b2_512sum = "54b113f499799d2f3c0711da174e3bc724737ad18f63feb286184f0597e1466436705d6c8e8c7d3d3b88f5a22e83496e0043c44a3c2b1700e0e02259f8ac468e";
private byte[] array() {
if(testArray == null) {
if (testArray == null) {
try {
testArray = testString.getBytes(StringUtils.UTF8);
} catch (UnsupportedEncodingException e) {

View File

@ -1,3 +1,19 @@
/**
*
* Copyright © 2017 Paul Schaub
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.jingle_filetransfer;
import org.jivesoftware.smack.test.util.SmackTestSuite;
@ -13,7 +29,7 @@ import static junit.framework.TestCase.assertNull;
/**
* Test the JingleContentFile class.
*/
public class FileTransferTest extends SmackTestSuite {
public class FileTransferPayloadTest extends SmackTestSuite {
@Test
public void rangeTest() throws Exception {

View File

@ -0,0 +1,116 @@
/**
*
* Copyright © 2017 Paul Schaub
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.jingle_filetransfer;
import org.jivesoftware.smack.test.util.SmackTestSuite;
import org.jivesoftware.smack.test.util.TestUtils;
import org.jivesoftware.smackx.hash.HashManager;
import org.jivesoftware.smackx.hash.element.HashElement;
import org.jivesoftware.smackx.jingle.element.JingleContentDescription;
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionPayloadType;
import org.jivesoftware.smackx.jingle_filetransfer.element.FileTransferPayload;
import org.jivesoftware.smackx.jingle_filetransfer.element.JingleContentDescriptionFileTransfer;
import org.jivesoftware.smackx.jingle_filetransfer.element.Range;
import org.jivesoftware.smackx.jingle_filetransfer.provider.JingleContentDescriptionFileTransferProvider;
import org.junit.Test;
import org.jxmpp.util.XmppDateTime;
import java.util.ArrayList;
import java.util.Date;
import static org.junit.Assert.assertEquals;
/**
* Test the JingleContentDescriptionFileTransfer element and provider.
*/
public class JingleContentDescriptionFileTransferTest extends SmackTestSuite {
@Test
public void parserTest() throws Exception {
String dateString = "2012-01-02T03:04:05.000+00:00";
String descriptionString = "The Description";
String mediaTypeString = "text/plain";
String nameString = "the-file.txt";
int sizeInt = 4096;
HashManager.ALGORITHM algorithm = HashManager.ALGORITHM.SHA_256;
String hashB64 = "f4OxZX/x/FO5LcGBSKHWXfwtSx+j1ncoSt3SABJtkGk=";
String xml =
"<description xmlns='urn:xmpp:jingle:apps:file-transfer:5'>" +
"<file>" +
"<date>" + dateString + "</date>" +
"<desc>" + descriptionString + "</desc>" +
"<media-type>" + mediaTypeString + "</media-type>" +
"<name>" + nameString + "</name>" +
"<range/>" +
"<size>" + sizeInt + "</size>" +
"<hash xmlns='urn:xmpp:hashes:2' algo='" + algorithm + "'>" +
hashB64 +
"</hash>" +
"</file>" +
"</description>";
HashElement hashElement = new HashElement(algorithm, hashB64);
Range range = new Range();
Date date = XmppDateTime.parseDate(dateString);
FileTransferPayload fileTransferPayload = new FileTransferPayload(date, descriptionString, hashElement, mediaTypeString, nameString, sizeInt, range);
ArrayList<JingleContentDescriptionPayloadType> payloads = new ArrayList<>();
payloads.add(fileTransferPayload);
JingleContentDescriptionFileTransfer descriptionFileTransfer =
new JingleContentDescriptionFileTransfer(payloads);
assertEquals(xml, descriptionFileTransfer.toXML().toString());
JingleContentDescription parsed = new JingleContentDescriptionFileTransferProvider()
.parse(TestUtils.getParser(xml));
assertEquals(xml, parsed.toXML().toString());
FileTransferPayload payload = (FileTransferPayload) parsed.getJinglePayloadTypes().get(0);
assertEquals(date, payload.getDate());
assertEquals(descriptionString, payload.getDescription());
assertEquals(mediaTypeString, payload.getMediaType());
assertEquals(nameString, payload.getName());
assertEquals(sizeInt, payload.getSize());
assertEquals(range, payload.getRange());
assertEquals(hashElement, payload.getHash());
}
@Test
public void parserTest2() throws Exception {
HashManager.ALGORITHM algorithm = HashManager.ALGORITHM.SHA_256;
String hashB64 = "f4OxZX/x/FO5LcGBSKHWXfwtSx+j1ncoSt3SABJtkGk=";
HashElement hashElement = new HashElement(algorithm, hashB64);
Range range = new Range(2048, 1024, hashElement);
String xml =
"<description xmlns='urn:xmpp:jingle:apps:file-transfer:5'>" +
"<file>" +
"<range offset='2048' length='1024'>" +
"<hash xmlns='urn:xmpp:hashes:2' algo='" + algorithm + "'>" +
hashB64 +
"</hash>" +
"</range>" +
"</file>" +
"</description>";
FileTransferPayload payload = new FileTransferPayload(null, null, null, null, null, -1, range);
ArrayList<JingleContentDescriptionPayloadType> list = new ArrayList<>();
list.add(payload);
JingleContentDescriptionFileTransfer fileTransfer = new JingleContentDescriptionFileTransfer(list);
assertEquals(xml, fileTransfer.toXML().toString());
JingleContentDescriptionFileTransfer parsed = new JingleContentDescriptionFileTransferProvider()
.parse(TestUtils.getParser(xml));
assertEquals(xml, parsed.toXML().toString());
}
}

View File

@ -62,6 +62,7 @@ public abstract class JingleContentDescription implements ExtensionElement {
xml.append(payloads);
xml.closeElement(this);
return xml;
}