mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-27 00:32:07 +01:00
SMACK-403 add support for
XEP-0297 Stanza Forwarding and XEP-0280 Message Carbons and XEP-0297: Stanza Forwarding implementation This patch adds Forwarded.java, a class to wrap messages forwarded from a different entity. A forwarded stanza contains of a Packet and an optional timestamp. WARNING: The current implementation only allows to forward Message packets, as there is no universal way to parse a Packet from SMACK. XEP-0280 Message Carbons implementation This patch adds Carbon.java, a class to wrap the packet extension defined in XEP-0280 to store copies of messages sent to or received by a user to his other client(s). The CarbonManager allows to register XEP-0280 support with the SDM, to enable and disable the feature and to manipulate messages accordingly. Signed-Off-By: Georg Lukas <georg@op-co.de> git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@13411 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
parent
b9fe598129
commit
2a1f4e8376
5 changed files with 665 additions and 1 deletions
|
@ -640,4 +640,23 @@
|
||||||
<namespace>urn:xmpp:attention:0</namespace>
|
<namespace>urn:xmpp:attention:0</namespace>
|
||||||
<className>org.jivesoftware.smackx.packet.AttentionExtension$Provider</className>
|
<className>org.jivesoftware.smackx.packet.AttentionExtension$Provider</className>
|
||||||
</extensionProvider>
|
</extensionProvider>
|
||||||
|
|
||||||
|
<!-- XEP-0297 Stanza Forwarding -->
|
||||||
|
<extensionProvider>
|
||||||
|
<elementName>forwarded</elementName>
|
||||||
|
<namespace>urn:xmpp:forward:0</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.packet.Forwarded$Provider</className>
|
||||||
|
</extensionProvider>
|
||||||
|
|
||||||
|
<!-- XEP-0280 Message Carbons -->
|
||||||
|
<extensionProvider>
|
||||||
|
<elementName>sent</elementName>
|
||||||
|
<namespace>urn:xmpp:carbons:2</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.carbons.Carbon$Provider</className>
|
||||||
|
</extensionProvider>
|
||||||
|
<extensionProvider>
|
||||||
|
<elementName>received</elementName>
|
||||||
|
<namespace>urn:xmpp:carbons:2</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.carbons.Carbon$Provider</className>
|
||||||
|
</extensionProvider>
|
||||||
</smackProviders>
|
</smackProviders>
|
139
source/org/jivesoftware/smackx/carbons/Carbon.java
Normal file
139
source/org/jivesoftware/smackx/carbons/Carbon.java
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2013 Georg Lukas
|
||||||
|
*
|
||||||
|
* All rights reserved. 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.carbons;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||||
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
|
import org.jivesoftware.smackx.forward.Forwarded;
|
||||||
|
import org.jivesoftware.smackx.packet.DelayInfo;
|
||||||
|
import org.jivesoftware.smackx.provider.DelayInfoProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension for XEP-0280: Message Carbons. This class implements
|
||||||
|
* the packet extension and a {@link PacketExtensionProvider} to parse
|
||||||
|
* message carbon copies from a packet. The extension
|
||||||
|
* <a href="http://xmpp.org/extensions/xep-0280.html">XEP-0280</a> is
|
||||||
|
* meant to synchronize a message flow to multiple presences of a user.
|
||||||
|
*
|
||||||
|
* <p>The {@link Carbon.Provider} must be registered in the
|
||||||
|
* <b>smack.properties</b> file for the elements <b>sent</b> and
|
||||||
|
* <b>received</b> with namespace <b>urn:xmpp:carbons:2</b></p> to be used.
|
||||||
|
*
|
||||||
|
* @author Georg Lukas
|
||||||
|
*/
|
||||||
|
public class Carbon implements PacketExtension {
|
||||||
|
public static final String NAMESPACE = "urn:xmpp:carbons:2";
|
||||||
|
|
||||||
|
private Direction dir;
|
||||||
|
private Forwarded fwd;
|
||||||
|
|
||||||
|
public Carbon(Direction dir, Forwarded fwd) {
|
||||||
|
this.dir = dir;
|
||||||
|
this.fwd = fwd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the direction (sent or received) of the carbon.
|
||||||
|
*
|
||||||
|
* @return the {@link Direction} of the carbon.
|
||||||
|
*/
|
||||||
|
public Direction getDirection() {
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the forwarded packet.
|
||||||
|
*
|
||||||
|
* @return the {@link Forwarded} message contained in this Carbon.
|
||||||
|
*/
|
||||||
|
public Forwarded getForwarded() {
|
||||||
|
return fwd;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getElementName() {
|
||||||
|
return dir.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNamespace() {
|
||||||
|
return NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append("<").append(getElementName()).append(" xmlns=\"")
|
||||||
|
.append(getNamespace()).append("\">");
|
||||||
|
|
||||||
|
buf.append(fwd.toXML());
|
||||||
|
|
||||||
|
buf.append("</").append(getElementName()).append(">");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An enum to display the direction of a {@link Carbon} message.
|
||||||
|
*/
|
||||||
|
public static enum Direction {
|
||||||
|
received,
|
||||||
|
sent
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Provider implements PacketExtensionProvider {
|
||||||
|
|
||||||
|
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
|
||||||
|
Direction dir = Direction.valueOf(parser.getName());
|
||||||
|
Forwarded fwd = null;
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if (eventType == XmlPullParser.START_TAG && parser.getName().equals("forwarded")) {
|
||||||
|
fwd = (Forwarded)new Forwarded.Provider().parseExtension(parser);
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG && dir == Direction.valueOf(parser.getName()))
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
if (fwd == null)
|
||||||
|
throw new Exception("sent/received must contain exactly one <forwarded> tag");
|
||||||
|
return new Carbon(dir, fwd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension indicating that a message may not be carbon-copied.
|
||||||
|
*/
|
||||||
|
public static class Private implements PacketExtension {
|
||||||
|
public static final String ELEMENT = "private";
|
||||||
|
|
||||||
|
public String getElementName() {
|
||||||
|
return ELEMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return Carbon.NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toXML() {
|
||||||
|
return "<" + ELEMENT + " xmlns=\"" + Carbon.NAMESPACE + "\"/>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
213
source/org/jivesoftware/smackx/carbons/CarbonManager.java
Normal file
213
source/org/jivesoftware/smackx/carbons/CarbonManager.java
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2013 Georg Lukas
|
||||||
|
*
|
||||||
|
* All rights reserved. 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.carbons;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.Connection;
|
||||||
|
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||||
|
import org.jivesoftware.smack.PacketCollector;
|
||||||
|
import org.jivesoftware.smack.PacketListener;
|
||||||
|
import org.jivesoftware.smack.SmackConfiguration;
|
||||||
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
import org.jivesoftware.smack.filter.PacketIDFilter;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.packet.Message;
|
||||||
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
|
import org.jivesoftware.smackx.ServiceDiscoveryManager;
|
||||||
|
import org.jivesoftware.smackx.packet.DiscoverInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension for XEP-0280: Message Carbons. This class implements
|
||||||
|
* the manager for registering {@link Carbon} support, enabling and disabling
|
||||||
|
* message carbons.
|
||||||
|
*
|
||||||
|
* You should call enableCarbons() before sending your first undirected
|
||||||
|
* presence.
|
||||||
|
*
|
||||||
|
* @author Georg Lukas
|
||||||
|
*/
|
||||||
|
public class CarbonManager {
|
||||||
|
|
||||||
|
private static Map<Connection, CarbonManager> instances =
|
||||||
|
Collections.synchronizedMap(new WeakHashMap<Connection, CarbonManager>());
|
||||||
|
|
||||||
|
static {
|
||||||
|
Connection.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||||
|
public void connectionCreated(Connection connection) {
|
||||||
|
new CarbonManager(connection);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Connection connection;
|
||||||
|
private volatile boolean enabled_state = false;
|
||||||
|
|
||||||
|
private CarbonManager(Connection connection) {
|
||||||
|
ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
|
||||||
|
sdm.addFeature(Carbon.NAMESPACE);
|
||||||
|
this.connection = connection;
|
||||||
|
instances.put(connection, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the CarbonManager responsible for a connection.
|
||||||
|
*
|
||||||
|
* @param connection the connection object.
|
||||||
|
*
|
||||||
|
* @return a CarbonManager instance
|
||||||
|
*/
|
||||||
|
public static CarbonManager getInstanceFor(Connection connection) {
|
||||||
|
CarbonManager carbonManager = instances.get(connection);
|
||||||
|
|
||||||
|
if (carbonManager == null) {
|
||||||
|
carbonManager = new CarbonManager(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
return carbonManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IQ carbonsEnabledIQ(final boolean new_state) {
|
||||||
|
IQ setIQ = new IQ() {
|
||||||
|
public String getChildElementXML() {
|
||||||
|
return "<" + (new_state? "enable" : "disable") + " xmlns='" + Carbon.NAMESPACE + "'/>";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
setIQ.setType(IQ.Type.SET);
|
||||||
|
return setIQ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if XMPP Carbons are supported by the server.
|
||||||
|
*
|
||||||
|
* @return true if supported
|
||||||
|
*/
|
||||||
|
public boolean isSupportedByServer() {
|
||||||
|
try {
|
||||||
|
DiscoverInfo result = ServiceDiscoveryManager
|
||||||
|
.getInstanceFor(connection).discoverInfo(connection.getServiceName());
|
||||||
|
return result.containsFeature(Carbon.NAMESPACE);
|
||||||
|
}
|
||||||
|
catch (XMPPException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify server to change the carbons state. This method returns
|
||||||
|
* immediately and changes the variable when the reply arrives.
|
||||||
|
*
|
||||||
|
* You should first check for support using isSupportedByServer().
|
||||||
|
*
|
||||||
|
* @param new_state whether carbons should be enabled or disabled
|
||||||
|
*/
|
||||||
|
public void sendCarbonsEnabled(final boolean new_state) {
|
||||||
|
IQ setIQ = carbonsEnabledIQ(new_state);
|
||||||
|
|
||||||
|
connection.addPacketListener(new PacketListener() {
|
||||||
|
public void processPacket(Packet packet) {
|
||||||
|
IQ result = (IQ)packet;
|
||||||
|
if (result.getType() == IQ.Type.RESULT) {
|
||||||
|
enabled_state = new_state;
|
||||||
|
}
|
||||||
|
connection.removePacketListener(this);
|
||||||
|
}
|
||||||
|
}, new PacketIDFilter(setIQ.getPacketID()));
|
||||||
|
|
||||||
|
connection.sendPacket(setIQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify server to change the carbons state. This method blocks
|
||||||
|
* some time until the server replies to the IQ and returns true on
|
||||||
|
* success.
|
||||||
|
*
|
||||||
|
* You should first check for support using isSupportedByServer().
|
||||||
|
*
|
||||||
|
* @param new_state whether carbons should be enabled or disabled
|
||||||
|
*
|
||||||
|
* @return true if the operation was successful
|
||||||
|
*/
|
||||||
|
public boolean setCarbonsEnabled(final boolean new_state) {
|
||||||
|
if (enabled_state == new_state)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
IQ setIQ = carbonsEnabledIQ(new_state);
|
||||||
|
|
||||||
|
PacketCollector collector =
|
||||||
|
connection.createPacketCollector(new PacketIDFilter(setIQ.getPacketID()));
|
||||||
|
connection.sendPacket(setIQ);
|
||||||
|
IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
collector.cancel();
|
||||||
|
|
||||||
|
if (result != null && result.getType() == IQ.Type.RESULT) {
|
||||||
|
enabled_state = new_state;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to enable carbons.
|
||||||
|
*
|
||||||
|
* @return true if the operation was successful
|
||||||
|
*/
|
||||||
|
public boolean enableCarbons() {
|
||||||
|
return setCarbonsEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to disable carbons.
|
||||||
|
*
|
||||||
|
* @return true if the operation was successful
|
||||||
|
*/
|
||||||
|
public boolean disableCarbons() {
|
||||||
|
return setCarbonsEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if carbons are enabled on this connection.
|
||||||
|
*/
|
||||||
|
public boolean getCarbonsEnabled() {
|
||||||
|
return this.enabled_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain a Carbon from a message, if available.
|
||||||
|
*
|
||||||
|
* @param msg Message object to check for carbons
|
||||||
|
*
|
||||||
|
* @return a Carbon if available, null otherwise.
|
||||||
|
*/
|
||||||
|
public static Carbon getCarbon(Message msg) {
|
||||||
|
Carbon cc = (Carbon)msg.getExtension("received", Carbon.NAMESPACE);
|
||||||
|
if (cc == null)
|
||||||
|
cc = (Carbon)msg.getExtension("sent", Carbon.NAMESPACE);
|
||||||
|
return cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark a message as "private", so it will not be carbon-copied.
|
||||||
|
*
|
||||||
|
* @param msg Message object to mark private
|
||||||
|
*/
|
||||||
|
public static void disableCarbons(Message msg) {
|
||||||
|
msg.addExtension(new Carbon.Private());
|
||||||
|
}
|
||||||
|
}
|
125
source/org/jivesoftware/smackx/forward/Forwarded.java
Normal file
125
source/org/jivesoftware/smackx/forward/Forwarded.java
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2013 Georg Lukas
|
||||||
|
*
|
||||||
|
* All rights reserved. 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.forward;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||||
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
|
import org.jivesoftware.smackx.packet.DelayInfo;
|
||||||
|
import org.jivesoftware.smackx.provider.DelayInfoProvider;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension for XEP-0297: Stanza Forwarding. This class implements
|
||||||
|
* the packet extension and a {@link PacketExtensionProvider} to parse
|
||||||
|
* forwarded messages from a packet. The extension
|
||||||
|
* <a href="http://xmpp.org/extensions/xep-0297.html">XEP-0297</a> is
|
||||||
|
* a prerequisite for XEP-0280 (Message Carbons).
|
||||||
|
*
|
||||||
|
* <p>The {@link Forwarded.Provider} must be registered in the
|
||||||
|
* <b>smack.properties</b> file for the element <b>forwarded</b> with
|
||||||
|
* namespace <b>urn:xmpp:forwarded:0</b></p> to be used.
|
||||||
|
*
|
||||||
|
* @author Georg Lukas
|
||||||
|
*/
|
||||||
|
public class Forwarded implements PacketExtension {
|
||||||
|
public static final String NAMESPACE = "urn:xmpp:forward:0";
|
||||||
|
public static final String ELEMENT_NAME = "forwarded";
|
||||||
|
|
||||||
|
private DelayInfo delay;
|
||||||
|
private Packet forwardedPacket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Forwarded packet extension.
|
||||||
|
*
|
||||||
|
* @param delay an optional {@link DelayInfo} timestamp of the packet.
|
||||||
|
* @param fwdPacket the packet that is forwarded (required).
|
||||||
|
*/
|
||||||
|
public Forwarded(DelayInfo delay, Packet fwdPacket) {
|
||||||
|
this.delay = delay;
|
||||||
|
this.forwardedPacket = fwdPacket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getElementName() {
|
||||||
|
return ELEMENT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNamespace() {
|
||||||
|
return NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append("<").append(getElementName()).append(" xmlns=\"")
|
||||||
|
.append(getNamespace()).append("\">");
|
||||||
|
|
||||||
|
if (delay != null)
|
||||||
|
buf.append(delay.toXML());
|
||||||
|
buf.append(forwardedPacket.toXML());
|
||||||
|
|
||||||
|
buf.append("</").append(getElementName()).append(">");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the packet forwarded by this stanza.
|
||||||
|
*
|
||||||
|
* @return the {@link Packet} instance (typically a message) that was forwarded.
|
||||||
|
*/
|
||||||
|
public Packet getForwardedPacket() {
|
||||||
|
return forwardedPacket;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the timestamp of the forwarded packet.
|
||||||
|
*
|
||||||
|
* @return the {@link DelayInfo} representing the time when the original packet was sent. May be null.
|
||||||
|
*/
|
||||||
|
public DelayInfo getDelayInfo() {
|
||||||
|
return delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Provider implements PacketExtensionProvider {
|
||||||
|
DelayInfoProvider dip = new DelayInfoProvider();
|
||||||
|
|
||||||
|
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
|
||||||
|
DelayInfo di = null;
|
||||||
|
Packet packet = null;
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
if (parser.getName().equals("delay"))
|
||||||
|
di = (DelayInfo)dip.parseExtension(parser);
|
||||||
|
else if (parser.getName().equals("message"))
|
||||||
|
packet = PacketParserUtils.parseMessage(parser);
|
||||||
|
else throw new Exception("Unsupported forwarded packet type: " + parser.getName());
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG && parser.getName().equals(ELEMENT_NAME))
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
if (packet == null)
|
||||||
|
throw new Exception("forwarded extension must contain a packet");
|
||||||
|
return new Forwarded(di, packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,168 @@
|
||||||
|
/**
|
||||||
|
* All rights reserved. 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.carbons;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
|
import org.jivesoftware.smackx.packet.DelayInfo;
|
||||||
|
import org.jivesoftware.smackx.packet.DelayInformation;
|
||||||
|
import org.jivesoftware.smackx.forward.Forwarded;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.xmlpull.mxp1.MXParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
import com.jamesmurty.utils.XMLBuilder;
|
||||||
|
|
||||||
|
public class CarbonForwardedTest {
|
||||||
|
|
||||||
|
private static Properties outputProperties = new Properties();
|
||||||
|
static {
|
||||||
|
outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void forwardedTest() throws Exception {
|
||||||
|
XmlPullParser parser;
|
||||||
|
String control;
|
||||||
|
Forwarded fwd;
|
||||||
|
|
||||||
|
control = XMLBuilder.create("forwarded")
|
||||||
|
.a("xmlns", "urn:xmpp:forwarded:0")
|
||||||
|
.e("message")
|
||||||
|
.a("from", "romeo@montague.com")
|
||||||
|
.asString(outputProperties);
|
||||||
|
|
||||||
|
parser = getParser(control, "forwarded");
|
||||||
|
fwd = (Forwarded) new Forwarded.Provider().parseExtension(parser);
|
||||||
|
|
||||||
|
// no delay in packet
|
||||||
|
assertEquals(null, fwd.getDelayInfo());
|
||||||
|
|
||||||
|
// check message
|
||||||
|
assertEquals("romeo@montague.com", fwd.getForwardedPacket().getFrom());
|
||||||
|
|
||||||
|
// check end of tag
|
||||||
|
assertEquals(XmlPullParser.END_TAG, parser.getEventType());
|
||||||
|
assertEquals("forwarded", parser.getName());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=Exception.class)
|
||||||
|
public void forwardedEmptyTest() throws Exception {
|
||||||
|
XmlPullParser parser;
|
||||||
|
String control;
|
||||||
|
|
||||||
|
control = XMLBuilder.create("forwarded")
|
||||||
|
.a("xmlns", "urn:xmpp:forwarded:0")
|
||||||
|
.asString(outputProperties);
|
||||||
|
|
||||||
|
parser = getParser(control, "forwarded");
|
||||||
|
new Forwarded.Provider().parseExtension(parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void carbonSentTest() throws Exception {
|
||||||
|
XmlPullParser parser;
|
||||||
|
String control;
|
||||||
|
Carbon cc;
|
||||||
|
Forwarded fwd;
|
||||||
|
|
||||||
|
control = XMLBuilder.create("sent")
|
||||||
|
.e("forwarded")
|
||||||
|
.a("xmlns", "urn:xmpp:forwarded:0")
|
||||||
|
.e("message")
|
||||||
|
.a("from", "romeo@montague.com")
|
||||||
|
.asString(outputProperties);
|
||||||
|
|
||||||
|
parser = getParser(control, "sent");
|
||||||
|
cc = (Carbon) new Carbon.Provider().parseExtension(parser);
|
||||||
|
fwd = cc.getForwarded();
|
||||||
|
|
||||||
|
// meta
|
||||||
|
assertEquals(Carbon.Direction.sent, cc.getDirection());
|
||||||
|
|
||||||
|
// no delay in packet
|
||||||
|
assertEquals(null, fwd.getDelayInfo());
|
||||||
|
|
||||||
|
// check message
|
||||||
|
assertEquals("romeo@montague.com", fwd.getForwardedPacket().getFrom());
|
||||||
|
|
||||||
|
// check end of tag
|
||||||
|
assertEquals(XmlPullParser.END_TAG, parser.getEventType());
|
||||||
|
assertEquals("sent", parser.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void carbonReceivedTest() throws Exception {
|
||||||
|
XmlPullParser parser;
|
||||||
|
String control;
|
||||||
|
Carbon cc;
|
||||||
|
|
||||||
|
control = XMLBuilder.create("received")
|
||||||
|
.e("forwarded")
|
||||||
|
.a("xmlns", "urn:xmpp:forwarded:0")
|
||||||
|
.e("message")
|
||||||
|
.a("from", "romeo@montague.com")
|
||||||
|
.asString(outputProperties);
|
||||||
|
|
||||||
|
parser = getParser(control, "received");
|
||||||
|
cc = (Carbon) new Carbon.Provider().parseExtension(parser);
|
||||||
|
|
||||||
|
assertEquals(Carbon.Direction.received, cc.getDirection());
|
||||||
|
|
||||||
|
// check end of tag
|
||||||
|
assertEquals(XmlPullParser.END_TAG, parser.getEventType());
|
||||||
|
assertEquals("received", parser.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=Exception.class)
|
||||||
|
public void carbonEmptyTest() throws Exception {
|
||||||
|
XmlPullParser parser;
|
||||||
|
String control;
|
||||||
|
|
||||||
|
control = XMLBuilder.create("sent")
|
||||||
|
.a("xmlns", "urn:xmpp:forwarded:0")
|
||||||
|
.asString(outputProperties);
|
||||||
|
|
||||||
|
parser = getParser(control, "sent");
|
||||||
|
new Carbon.Provider().parseExtension(parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
private XmlPullParser getParser(String control, String startTag)
|
||||||
|
throws XmlPullParserException, IOException {
|
||||||
|
XmlPullParser parser = new MXParser();
|
||||||
|
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
||||||
|
parser.setInput(new StringReader(control));
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (parser.next() == XmlPullParser.START_TAG
|
||||||
|
&& parser.getName().equals(startTag)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue