mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-23 06:42:05 +01:00
SMACK-403 Pulling this contribution until the related specs reach a draft status
git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/branches/smack_3_3_0@13611 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
parent
3a4b05ac00
commit
9f0f676151
3 changed files with 0 additions and 477 deletions
|
@ -1,139 +0,0 @@
|
|||
/**
|
||||
* 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 + "\"/>";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,213 +0,0 @@
|
|||
/**
|
||||
* 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());
|
||||
}
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue