Rework Bits of Binary implementation

This commit is contained in:
Florian Schmaus 2017-01-03 10:59:56 +01:00
parent c688acaa0f
commit 9328182912
12 changed files with 166 additions and 300 deletions

View File

@ -128,8 +128,9 @@ public class PacketParserUtils {
return parser; return parser;
} }
public static Stanza parseStanza(String stanza) throws Exception { @SuppressWarnings("unchecked")
return parseStanza(getParserFor(stanza)); public static <S extends Stanza> S parseStanza(String stanza) throws Exception {
return (S) parseStanza(getParserFor(stanza));
} }
/** /**

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2016 Fernando Ramirez * Copyright 2016-2017 Fernando Ramirez, Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,34 +16,50 @@
*/ */
package org.jivesoftware.smackx.bob; package org.jivesoftware.smackx.bob;
import java.io.UnsupportedEncodingException; import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.stringencoder.Base64; import org.jivesoftware.smack.util.stringencoder.Base64;
/** /**
* Bits of Binary data class. * Bits of Binary data class.
* *
* @author Fernando Ramirez * @author Fernando Ramirez
* @author Florian Schmaus
* @see <a href="http://xmpp.org/extensions/xep-0231.html">XEP-0231: Bits of * @see <a href="http://xmpp.org/extensions/xep-0231.html">XEP-0231: Bits of
* Binary</a> * Binary</a>
*/ */
public class BoBData { public class BoBData {
private final long maxAge; private final int maxAge;
private final String type; private final String type;
private final byte[] content;
private byte[] contentBinary;
private String contentString;
public BoBData(String type, byte[] content) {
this(type, content, -1);
}
/** /**
* BoB data constructor. * BoB data constructor.
* *
* @param maxAge
* @param type * @param type
* @param content * @param content
* @param maxAge
*/ */
public BoBData(long maxAge, String type, byte[] content) { public BoBData(String type, byte[] content, int maxAge) {
this.maxAge = maxAge;
this.type = type; this.type = type;
this.content = content; this.contentBinary = content;
this.maxAge = maxAge;
}
public BoBData(String type, String content) {
this(type, content, -1);
}
public BoBData(String type, String content, int maxAge) {
this.type = type;
this.contentString = content;
this.maxAge = maxAge;
} }
/** /**
@ -51,7 +67,7 @@ public class BoBData {
* *
* @return the max age * @return the max age
*/ */
public long getMaxAge() { public int getMaxAge() {
return maxAge; return maxAge;
} }
@ -64,13 +80,21 @@ public class BoBData {
return type; return type;
} }
private void setContentBinaryIfRequired() {
if (contentBinary == null) {
assert(StringUtils.isNotEmpty(contentString));
contentBinary = Base64.decode(contentString);
}
}
/** /**
* Get the content. * Get the content.
* *
* @return the content * @return the content
*/ */
public byte[] getContent() { public byte[] getContent() {
return content; setContentBinaryIfRequired();
return contentBinary.clone();
} }
/** /**
@ -78,13 +102,20 @@ public class BoBData {
* *
* @return the content in a Base64 encoded String * @return the content in a Base64 encoded String
*/ */
public String getBase64Encoded() { public String getContentBase64Encoded() {
byte[] bytes = Base64.encode(content); if (contentString == null) {
try { contentString = Base64.encodeToString(getContent());
return new String(bytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("UTF-8 is not supported.");
} }
return contentString;
} }
/**
* Check if the data is of reasonable size. XEP-0231 suggest that the size should not be more than 8 KiB.
*
* @return true if the data if of reasonable size.
*/
public boolean isOfReasonableSize() {
setContentBinaryIfRequired();
return contentBinary.length <= 8 * 1024;
}
} }

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2016 Fernando Ramirez * Copyright 2016-2017 Fernando Ramirez, Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,10 +16,13 @@
*/ */
package org.jivesoftware.smackx.bob; package org.jivesoftware.smackx.bob;
import org.jivesoftware.smack.util.StringUtils;
/** /**
* Bits of Binary hash class. * Bits of Binary hash class.
* *
* @author Fernando Ramirez * @author Fernando Ramirez
* @author Florian Schmaus
* @see <a href="http://xmpp.org/extensions/xep-0231.html">XEP-0231: Bits of * @see <a href="http://xmpp.org/extensions/xep-0231.html">XEP-0231: Bits of
* Binary</a> * Binary</a>
*/ */
@ -27,6 +30,7 @@ public class BoBHash {
private final String hash; private final String hash;
private final String hashType; private final String hashType;
private final String cid;
/** /**
* BoB hash constructor. * BoB hash constructor.
@ -35,8 +39,9 @@ public class BoBHash {
* @param hashType * @param hashType
*/ */
public BoBHash(String hash, String hashType) { public BoBHash(String hash, String hashType) {
this.hash = hash; this.hash = StringUtils.requireNotNullOrEmpty(hash, "hash must not be null or empty");
this.hashType = hashType; this.hashType = StringUtils.requireNotNullOrEmpty(hashType, "hashType must not be null or empty");
this.cid = this.hashType + '+' + this.hash + "@bob.xmpp.org";
} }
/** /**
@ -63,7 +68,7 @@ public class BoBHash {
* @return src attribute string * @return src attribute string
*/ */
public String toSrc() { public String toSrc() {
return "cid:" + toCid(); return "cid:" + getCid();
} }
/** /**
@ -71,8 +76,22 @@ public class BoBHash {
* *
* @return cid attribute string * @return cid attribute string
*/ */
public String toCid() { public String getCid() {
return this.hashType + "+" + this.hash + "@bob.xmpp.org"; return cid;
}
@Override
public boolean equals(Object other) {
if (other instanceof BoBHash) {
BoBHash otherBob = (BoBHash) other;
return cid.equals(otherBob.cid);
}
return false;
}
@Override
public int hashCode() {
return cid.hashCode();
} }
/** /**

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2016 Fernando Ramirez * Copyright 2017 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,18 +16,23 @@
*/ */
package org.jivesoftware.smackx.bob; package org.jivesoftware.smackx.bob;
/** import java.util.Set;
* Bits of Binary Saver Manager interface.
*
* @author Fernando Ramirez
*
*/
public interface BoBSaverManager {
public void addBoB(BoBHash bobHash, BoBData bobData); public class BoBInfo {
public void removeBoB(BoBHash bobHash); private final Set<BoBHash> hashes;
private final BoBData data;
public BoBData getBoB(BoBHash bobHash); BoBInfo(Set<BoBHash> hashes, BoBData data) {
this.hashes = hashes;
this.data = data;
}
public Set<BoBHash> getHashes() {
return hashes;
}
public BoBData getData() {
return data;
}
} }

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2016 Fernando Ramirez * Copyright 2016-2017 Fernando Ramirez, Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,8 +16,11 @@
*/ */
package org.jivesoftware.smackx.bob; package org.jivesoftware.smackx.bob;
import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.Manager;
@ -31,27 +34,29 @@ import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode; import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.IQ.Type; import org.jivesoftware.smack.packet.IQ.Type;
import org.jivesoftware.smack.util.SHA1;
import org.jivesoftware.smackx.bob.element.BoBIQ; import org.jivesoftware.smackx.bob.element.BoBIQ;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jxmpp.jid.Jid; import org.jxmpp.jid.Jid;
import org.jxmpp.util.cache.LruCache;
/** /**
* Bits of Binary manager class. * Bits of Binary manager class.
* *
* @author Fernando Ramirez * @author Fernando Ramirez
* @author Florian Schmaus
* @see <a href="http://xmpp.org/extensions/xep-0231.html">XEP-0231: Bits of * @see <a href="http://xmpp.org/extensions/xep-0231.html">XEP-0231: Bits of
* Binary</a> * Binary</a>
*/ */
public final class BoBManager extends Manager { public final class BoBManager extends Manager {
public static final String NAMESPACE = "urn:xmpp:bob"; public static final String NAMESPACE = "urn:xmpp:bob";
public static BoBSaverManager bobSaverManager;
static { static {
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() { XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
@Override @Override
public void connectionCreated(XMPPConnection connection) { public void connectionCreated(XMPPConnection connection) {
getInstanceFor(connection, bobSaverManager); getInstanceFor(connection);
} }
}); });
} }
@ -62,16 +67,9 @@ public final class BoBManager extends Manager {
* Get the singleton instance of BoBManager. * Get the singleton instance of BoBManager.
* *
* @param connection * @param connection
* @param saverManager
* @return the instance of BoBManager * @return the instance of BoBManager
*/ */
public static synchronized BoBManager getInstanceFor(XMPPConnection connection, BoBSaverManager saverManager) { public static synchronized BoBManager getInstanceFor(XMPPConnection connection) {
if (saverManager == null) {
bobSaverManager = new DefaultBoBSaverManager();
} else {
bobSaverManager = saverManager;
}
BoBManager bobManager = INSTANCES.get(connection); BoBManager bobManager = INSTANCES.get(connection);
if (bobManager == null) { if (bobManager == null) {
bobManager = new BoBManager(connection); bobManager = new BoBManager(connection);
@ -81,37 +79,34 @@ public final class BoBManager extends Manager {
return bobManager; return bobManager;
} }
private static final LruCache<BoBHash, BoBData> BOB_CACHE = new LruCache<>(128);
private final Map<BoBHash, BoBInfo> bobs = new ConcurrentHashMap<>();
private BoBManager(XMPPConnection connection) { private BoBManager(XMPPConnection connection) {
super(connection); super(connection);
ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(connection); ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(connection);
serviceDiscoveryManager.addFeature(NAMESPACE); serviceDiscoveryManager.addFeature(NAMESPACE);
connection.registerIQRequestHandler( connection.registerIQRequestHandler(
new AbstractIqRequestHandler(BoBIQ.ELEMENT, BoBIQ.NAMESPACE, Type.get, Mode.sync) { new AbstractIqRequestHandler(BoBIQ.ELEMENT, BoBIQ.NAMESPACE, Type.get, Mode.async) {
@Override @Override
public IQ handleIQRequest(IQ iqRequest) { public IQ handleIQRequest(IQ iqRequest) {
BoBIQ getBoBIQ = (BoBIQ) iqRequest; BoBIQ bobIQRequest = (BoBIQ) iqRequest;
BoBData bobData = bobSaverManager.getBoB(getBoBIQ.getBoBHash()); BoBInfo bobInfo = bobs.get(bobIQRequest.getBoBHash());
BoBIQ responseBoBIQ = null; if (bobInfo == null) {
try { // TODO return item-not-found
responseBoBIQ = responseBoB(getBoBIQ, bobData); return null;
} catch (NotConnectedException | NotLoggedInException | InterruptedException e) {
} }
BoBData bobData = bobInfo.getData();
BoBIQ responseBoBIQ = new BoBIQ(bobIQRequest.getBoBHash(), bobData);
responseBoBIQ.setType(Type.result);
responseBoBIQ.setTo(bobIQRequest.getFrom());
return responseBoBIQ; return responseBoBIQ;
} }
}); });
connection.registerIQRequestHandler(
new AbstractIqRequestHandler(BoBIQ.ELEMENT, BoBIQ.NAMESPACE, Type.result, Mode.sync) {
@Override
public IQ handleIQRequest(IQ iqRequest) {
BoBIQ resultBoBIQ = (BoBIQ) iqRequest;
bobSaverManager.addBoB(resultBoBIQ.getBoBHash(), resultBoBIQ.getBoBData());
return null;
}
});
} }
/** /**
@ -142,21 +137,46 @@ public final class BoBManager extends Manager {
*/ */
public BoBData requestBoB(Jid to, BoBHash bobHash) throws NotLoggedInException, NoResponseException, public BoBData requestBoB(Jid to, BoBHash bobHash) throws NotLoggedInException, NoResponseException,
XMPPErrorException, NotConnectedException, InterruptedException { XMPPErrorException, NotConnectedException, InterruptedException {
BoBData bobData = BOB_CACHE.lookup(bobHash);
if (bobData != null) {
return bobData;
}
BoBIQ requestBoBIQ = new BoBIQ(bobHash); BoBIQ requestBoBIQ = new BoBIQ(bobHash);
requestBoBIQ.setType(Type.get); requestBoBIQ.setType(Type.get);
requestBoBIQ.setTo(to); requestBoBIQ.setTo(to);
XMPPConnection connection = getAuthenticatedConnectionOrThrow(); XMPPConnection connection = getAuthenticatedConnectionOrThrow();
BoBIQ responseBoBIQ = connection.createPacketCollectorAndSend(requestBoBIQ).nextResultOrThrow(); BoBIQ responseBoBIQ = connection.createPacketCollectorAndSend(requestBoBIQ).nextResultOrThrow();
return responseBoBIQ.getBoBData();
bobData = responseBoBIQ.getBoBData();
BOB_CACHE.put(bobHash, bobData);
return bobData;
} }
private BoBIQ responseBoB(BoBIQ requestBoBIQ, BoBData bobData) public BoBInfo addBoB(BoBData bobData) {
throws NotConnectedException, InterruptedException, NotLoggedInException { // We only support SHA-1 for now.
BoBIQ responseBoBIQ = new BoBIQ(requestBoBIQ.getBoBHash(), bobData); BoBHash bobHash = new BoBHash("sha1", SHA1.hex(bobData.getContent()));
responseBoBIQ.setType(Type.result);
responseBoBIQ.setTo(requestBoBIQ.getFrom()); Set<BoBHash> bobHashes = Collections.singleton(bobHash);
return responseBoBIQ; bobHashes = Collections.unmodifiableSet(bobHashes);
BoBInfo bobInfo = new BoBInfo(bobHashes, bobData);
bobs.put(bobHash, bobInfo);
return bobInfo;
} }
public BoBInfo removeBoB(BoBHash bobHash) {
BoBInfo bobInfo = bobs.remove(bobHash);
if (bobInfo == null) {
return null;
}
for (BoBHash otherBobHash : bobInfo.getHashes()) {
bobs.remove(otherBobHash);
}
return bobInfo;
}
} }

View File

@ -1,46 +0,0 @@
/**
*
* Copyright 2016 Fernando Ramirez
*
* 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.bob;
import java.util.HashMap;
/**
* Default Bits of Binary Saver Manager class.
*
* @author Fernando Ramirez
*
*/
public class DefaultBoBSaverManager implements BoBSaverManager {
HashMap<BoBHash, BoBData> bobs = new HashMap<>();
@Override
public void addBoB(BoBHash bobHash, BoBData bobData) {
bobs.put(bobHash, bobData);
}
@Override
public void removeBoB(BoBHash bobHash) {
bobs.remove(bobHash);
}
@Override
public BoBData getBoB(BoBHash bobHash) {
return bobs.get(bobHash);
}
}

View File

@ -84,13 +84,13 @@ public class BoBIQ extends IQ {
@Override @Override
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
xml.attribute("cid", bobHash.toCid()); xml.attribute("cid", bobHash.getCid());
if (bobData != null) { if (bobData != null) {
xml.attribute("max-age", String.valueOf(bobData.getMaxAge())); xml.optIntAttribute("max_age", bobData.getMaxAge());
xml.attribute("type", bobData.getType()); xml.attribute("type", bobData.getType());
xml.rightAngleBracket(); xml.rightAngleBracket();
xml.escape(bobData.getBase64Encoded()); xml.escape(bobData.getContentBase64Encoded());
} else { } else {
xml.setEmptyElement(); xml.setEmptyElement();
} }

View File

@ -1,65 +0,0 @@
/**
*
* Copyright 2016 Fernando Ramirez
*
* 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.bob.provider;
import org.jivesoftware.smack.provider.ExtensionElementProvider;
import org.jivesoftware.smackx.bob.BoBHash;
import org.jivesoftware.smackx.bob.element.BoBExtension;
import org.jivesoftware.smackx.xhtmlim.XHTMLText;
import org.xmlpull.v1.XmlPullParser;
/**
* Bits of Binary extension provider class.
*
* @author Fernando Ramirez
* @see <a href="http://xmpp.org/extensions/xep-0231.html">XEP-0231: Bits of
* Binary</a>
*/
public class BoBExtensionProvider extends ExtensionElementProvider<BoBExtension> {
@Override
public BoBExtension parse(XmlPullParser parser, int initialDepth) throws Exception {
BoBHash bobHash = null;
String alt = null;
outerloop: while (true) {
int eventType = parser.next();
switch (eventType) {
case XmlPullParser.START_TAG:
if (parser.getName().equals(XHTMLText.IMG)) {
alt = parser.getAttributeValue("", "alt");
String src = parser.getAttributeValue("", "src");
bobHash = BoBHash.fromSrc(src);
}
break;
case XmlPullParser.END_TAG:
if (parser.getDepth() == initialDepth) {
break outerloop;
}
break;
}
}
return new BoBExtension(bobHash, alt, null);
}
}

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2016 Fernando Ramirez * Copyright 2017 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +17,7 @@
package org.jivesoftware.smackx.bob.provider; package org.jivesoftware.smackx.bob.provider;
import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smack.util.stringencoder.Base64; import org.jivesoftware.smack.util.ParserUtils;
import org.jivesoftware.smackx.bob.BoBData; import org.jivesoftware.smackx.bob.BoBData;
import org.jivesoftware.smackx.bob.BoBHash; import org.jivesoftware.smackx.bob.BoBHash;
import org.jivesoftware.smackx.bob.element.BoBIQ; import org.jivesoftware.smackx.bob.element.BoBIQ;
@ -26,7 +26,7 @@ import org.xmlpull.v1.XmlPullParser;
/** /**
* Bits of Binary IQ provider class. * Bits of Binary IQ provider class.
* *
* @author Fernando Ramirez * @author Florian Schmaus
* @see <a href="http://xmpp.org/extensions/xep-0231.html">XEP-0231: Bits of * @see <a href="http://xmpp.org/extensions/xep-0231.html">XEP-0231: Bits of
* Binary</a> * Binary</a>
*/ */
@ -34,34 +34,19 @@ public class BoBIQProvider extends IQProvider<BoBIQ> {
@Override @Override
public BoBIQ parse(XmlPullParser parser, int initialDepth) throws Exception { public BoBIQ parse(XmlPullParser parser, int initialDepth) throws Exception {
BoBHash bobHash = null; String cid = parser.getAttributeValue("", "cid");
BoBData bobData = null; BoBHash bobHash = BoBHash.fromCid(cid);
parser.next(); String dataType = parser.getAttributeValue("", "type");
int maxAge = ParserUtils.getIntegerAttribute(parser, "max-age", -1);
if (parser.getName().equals(BoBIQ.ELEMENT)) { String base64EncodedData = parser.nextText();
String cid = parser.getAttributeValue("", "cid");
bobHash = BoBHash.fromCid(cid);
String dataType = parser.getAttributeValue("", "type");
String maxAgeString = parser.getAttributeValue("", "max-age");
long maxAge = 0;
if (maxAgeString != null) {
maxAge = Long.parseLong(maxAgeString);
}
String base64EncodedData = null;
try {
base64EncodedData = parser.nextText();
} catch (Exception e) {
}
if (base64EncodedData != null && dataType != null) {
byte[] base64EncodedDataBytes = base64EncodedData.getBytes();
bobData = new BoBData(maxAge, dataType, Base64.decode(base64EncodedDataBytes));
}
BoBData bobData;
if (dataType != null) {
bobData = new BoBData(dataType, base64EncodedData, maxAge);
} else {
bobData = null;
} }
return new BoBIQ(bobHash, bobData); return new BoBIQ(bobHash, bobData);

View File

@ -538,11 +538,6 @@
</extensionProvider> </extensionProvider>
<!-- XEP-0231: Bits of Binary --> <!-- XEP-0231: Bits of Binary -->
<extensionProvider>
<elementName>html</elementName>
<namespace>http://jabber.org/protocol/xhtml-im</namespace>
<className>org.jivesoftware.smackx.bob.provider.BoBExtensionProvider</className>
</extensionProvider>
<iqProvider> <iqProvider>
<elementName>data</elementName> <elementName>data</elementName>
<namespace>urn:xmpp:bob</namespace> <namespace>urn:xmpp:bob</namespace>

View File

@ -1,67 +0,0 @@
/**
*
* Copyright 2016 Fernando Ramirez
*
* 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.bob;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Message.Type;
import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smackx.bob.element.BoBExtension;
import org.jivesoftware.smackx.bob.provider.BoBExtensionProvider;
import org.junit.Assert;
import org.junit.Test;
import org.jxmpp.jid.impl.JidCreate;
import org.xmlpull.v1.XmlPullParser;
public class BoBExtensionTest {
String sampleMessageWithBoBExtension = "<message to='macbeth@chat.shakespeare.lit' id='sarasa' type='groupchat'>"
+ "<body>Yet here's a spot.</body>" + "<html xmlns='http://jabber.org/protocol/xhtml-im'>"
+ "<body xmlns='http://www.w3.org/1999/xhtml'>"
+ "<img alt='A spot' src='cid:sha1+8f35fef110ffc5df08d579a50083ff9308fb6242@bob.xmpp.org'/>" + "</body>"
+ "</html>" + "</message>";
String sampleBoBExtension = "<html xmlns='http://jabber.org/protocol/xhtml-im'>"
+ "<body xmlns='http://www.w3.org/1999/xhtml'>"
+ "<img alt='A spot' src='cid:sha1+8f35fef110ffc5df08d579a50083ff9308fb6242@bob.xmpp.org'/>" + "</body>"
+ "</html>";
@Test
public void checkBoBMessageExtension() throws Exception {
Message message = (Message) PacketParserUtils.parseStanza(sampleMessageWithBoBExtension);
BoBHash bobHash = new BoBHash("8f35fef110ffc5df08d579a50083ff9308fb6242", "sha1");
Message createdMessage = new Message(JidCreate.from("macbeth@chat.shakespeare.lit"));
createdMessage.setStanzaId("sarasa");
createdMessage.setType(Type.groupchat);
createdMessage.setBody("Yet here's a spot.");
createdMessage.addExtension(new BoBExtension(bobHash, "A spot", null));
Assert.assertEquals(message.toXML().toString(), createdMessage.toXML().toString());
}
@Test
public void checkBoBExtensionProvider() throws Exception {
XmlPullParser parser = PacketParserUtils.getParserFor(sampleBoBExtension);
BoBExtension bobExtension = new BoBExtensionProvider().parse(parser);
Assert.assertEquals("A spot", bobExtension.getAlt());
Assert.assertEquals("sha1", bobExtension.getBoBHash().getHashType());
Assert.assertEquals("8f35fef110ffc5df08d579a50083ff9308fb6242", bobExtension.getBoBHash().getHash());
}
}

View File

@ -20,11 +20,9 @@ import org.jivesoftware.smack.packet.IQ.Type;
import org.jivesoftware.smack.test.util.SmackTestSuite; import org.jivesoftware.smack.test.util.SmackTestSuite;
import org.jivesoftware.smack.util.PacketParserUtils; import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smackx.bob.element.BoBIQ; import org.jivesoftware.smackx.bob.element.BoBIQ;
import org.jivesoftware.smackx.bob.provider.BoBIQProvider;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.impl.JidCreate;
import org.xmlpull.v1.XmlPullParser;
public class BoBIQTest extends SmackTestSuite { public class BoBIQTest extends SmackTestSuite {
@ -37,12 +35,6 @@ public class BoBIQTest extends SmackTestSuite {
@Test @Test
public void checkBoBIQRequest() throws Exception { public void checkBoBIQRequest() throws Exception {
XmlPullParser parser = PacketParserUtils.getParserFor(sampleBoBIQRequest);
BoBIQ bobIQ = new BoBIQProvider().parse(parser);
bobIQ.setStanzaId("sarasa");
bobIQ.setTo(JidCreate.from("ladymacbeth@shakespeare.lit/castle"));
bobIQ.setType(Type.get);
BoBHash bobHash = new BoBHash("8f35fef110ffc5df08d579a50083ff9308fb6242", "sha1"); BoBHash bobHash = new BoBHash("8f35fef110ffc5df08d579a50083ff9308fb6242", "sha1");
BoBIQ createdBoBIQ = new BoBIQ(bobHash); BoBIQ createdBoBIQ = new BoBIQ(bobHash);
@ -55,14 +47,10 @@ public class BoBIQTest extends SmackTestSuite {
@Test @Test
public void checkBoBIQResponse() throws Exception { public void checkBoBIQResponse() throws Exception {
XmlPullParser parser = PacketParserUtils.getParserFor(sampleBoBIQResponse); BoBIQ bobIQ = PacketParserUtils.parseStanza(sampleBoBIQResponse);
BoBIQ bobIQ = new BoBIQProvider().parse(parser);
bobIQ.setStanzaId("sarasa");
bobIQ.setTo(JidCreate.from("doctor@shakespeare.lit/pda"));
bobIQ.setType(Type.result);
BoBHash bobHash = new BoBHash("8f35fef110ffc5df08d579a50083ff9308fb6242", "sha1"); BoBHash bobHash = new BoBHash("8f35fef110ffc5df08d579a50083ff9308fb6242", "sha1");
BoBData bobData = new BoBData(86400, "image/png", "sarasade2354j2".getBytes()); BoBData bobData = new BoBData("image/png", "sarasade2354j2".getBytes(), 86400);
BoBIQ createdBoBIQ = new BoBIQ(bobHash, bobData); BoBIQ createdBoBIQ = new BoBIQ(bobHash, bobData);
createdBoBIQ.setStanzaId("sarasa"); createdBoBIQ.setStanzaId("sarasa");
@ -73,7 +61,7 @@ public class BoBIQTest extends SmackTestSuite {
Assert.assertEquals(bobIQ.getBoBHash().getHashType(), createdBoBIQ.getBoBHash().getHashType()); Assert.assertEquals(bobIQ.getBoBHash().getHashType(), createdBoBIQ.getBoBHash().getHashType());
Assert.assertEquals(bobIQ.getBoBData().getMaxAge(), createdBoBIQ.getBoBData().getMaxAge()); Assert.assertEquals(bobIQ.getBoBData().getMaxAge(), createdBoBIQ.getBoBData().getMaxAge());
Assert.assertEquals(bobIQ.getBoBData().getType(), createdBoBIQ.getBoBData().getType()); Assert.assertEquals(bobIQ.getBoBData().getType(), createdBoBIQ.getBoBData().getType());
Assert.assertEquals(bobIQ.getBoBData().getBase64Encoded(), createdBoBIQ.getBoBData().getBase64Encoded()); Assert.assertEquals(bobIQ.getBoBData().getContentBase64Encoded(), createdBoBIQ.getBoBData().getContentBase64Encoded());
Assert.assertEquals(bobIQ.toXML().toString(), createdBoBIQ.toXML().toString()); Assert.assertEquals(bobIQ.toXML().toString(), createdBoBIQ.toXML().toString());
} }