1
0
Fork 0
mirror of https://codeberg.org/Mercury-IM/Smack synced 2024-06-27 22:14:52 +02:00
Smack/experimental/src/main/java/org/jivesoftware/smackx/carbons/CarbonManager.java
Florian Schmaus 1e57f1c659 Activate checkstyle and add missing license headers
Delete also all "All rights reserved" statements, as they are
unnecessary and conflict with checkstyle's header check. Delete unused
imports.
2014-02-17 20:09:55 +01:00

219 lines
7.3 KiB
Java

/**
*
* Copyright 2013 Georg Lukas
*
* 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.lang.ref.WeakReference;
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.carbons.packet.CarbonExtension;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
/**
* Packet extension for XEP-0280: Message Carbons. This class implements
* the manager for registering {@link CarbonExtension} 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) {
getInstanceFor(connection);
}
});
}
private WeakReference<Connection> weakRefConnection;
private volatile boolean enabled_state = false;
private CarbonManager(Connection connection) {
ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
sdm.addFeature(CarbonExtension.NAMESPACE);
weakRefConnection = new WeakReference<Connection>(connection);
instances.put(connection, this);
}
/**
* Obtain the CarbonManager responsible for a connection.
*
* @param connection the connection object.
*
* @return a CarbonManager instance
*/
public static synchronized 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='" + CarbonExtension.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() {
Connection connection = weakRefConnection.get();
try {
DiscoverInfo result = ServiceDiscoveryManager
.getInstanceFor(connection).discoverInfo(connection.getServiceName());
return result.containsFeature(CarbonExtension.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) {
final Connection connection = weakRefConnection.get();
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;
Connection connection = weakRefConnection.get();
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 CarbonExtension getCarbon(Message msg) {
CarbonExtension cc = (CarbonExtension)msg.getExtension("received", CarbonExtension.NAMESPACE);
if (cc == null)
cc = (CarbonExtension)msg.getExtension("sent", CarbonExtension.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 CarbonExtension.Private());
}
}