mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2025-09-13 12:19:40 +02:00
Merge from 3.3 branch
git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@13663 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
commit
dac68c64a9
163 changed files with 2304 additions and 2366 deletions
|
@ -299,24 +299,23 @@ public class FormField {
|
|||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (obj == this)
|
||||
return true;
|
||||
if (obj.getClass() != getClass())
|
||||
if (!(obj instanceof FormField))
|
||||
return false;
|
||||
|
||||
FormField other = (FormField) obj;
|
||||
|
||||
String thisXml = toXML();
|
||||
String otherXml = other.toXML();
|
||||
return toXML().equals(other.toXML());
|
||||
}
|
||||
|
||||
if (thisXml.equals(otherXml)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return toXML().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -356,6 +355,7 @@ public class FormField {
|
|||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getLabel();
|
||||
}
|
||||
|
@ -375,6 +375,7 @@ public class FormField {
|
|||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null)
|
||||
return false;
|
||||
|
@ -396,5 +397,13 @@ public class FormField {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
result = 37 * result + value.hashCode();
|
||||
result = 37 * result + (label == null ? 0 : label.hashCode());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public interface NodeInformationProvider {
|
|||
*
|
||||
* @return a list of the Items defined in the node.
|
||||
*/
|
||||
public abstract List<DiscoverItems.Item> getNodeItems();
|
||||
List<DiscoverItems.Item> getNodeItems();
|
||||
|
||||
/**
|
||||
* Returns a list of the features defined in the node. For
|
||||
|
@ -55,7 +55,7 @@ public interface NodeInformationProvider {
|
|||
*
|
||||
* @return a list of the feature strings defined in the node.
|
||||
*/
|
||||
public abstract List<String> getNodeFeatures();
|
||||
List<String> getNodeFeatures();
|
||||
|
||||
/**
|
||||
* Returns a list of the indentites defined in the node. For
|
||||
|
@ -64,12 +64,12 @@ public interface NodeInformationProvider {
|
|||
*
|
||||
* @return a list of the Identities defined in the node.
|
||||
*/
|
||||
public abstract List<DiscoverInfo.Identity> getNodeIdentities();
|
||||
List<DiscoverInfo.Identity> getNodeIdentities();
|
||||
|
||||
/**
|
||||
* Returns a list of the packet extensions defined in the node.
|
||||
*
|
||||
* @return a list of the packet extensions defined in the node.
|
||||
*/
|
||||
public abstract List<PacketExtension> getNodePacketExtensions();
|
||||
List<PacketExtension> getNodePacketExtensions();
|
||||
}
|
||||
|
|
|
@ -513,7 +513,7 @@ public class ServiceDiscoveryManager {
|
|||
|
||||
// If the node version is known, store the new entry.
|
||||
if (nvh != null) {
|
||||
if (EntityCapsManager.verifyDiscvoerInfoVersion(nvh.getVer(), nvh.getHash(), info))
|
||||
if (EntityCapsManager.verifyDiscoverInfoVersion(nvh.getVer(), nvh.getHash(), info))
|
||||
EntityCapsManager.addDiscoverInfoByNode(nvh.getNodeVer(), info);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
* Copyright 2005 Jive Software.
|
||||
*
|
||||
* 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.
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* 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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
* Copyright 2008 Jive Software.
|
||||
*
|
||||
* 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.
|
||||
|
|
|
@ -506,7 +506,7 @@ public class EntityCapsManager {
|
|||
* @param info
|
||||
* @return true if it's valid and should be cache, false if not
|
||||
*/
|
||||
public static boolean verifyDiscvoerInfoVersion(String ver, String hash, DiscoverInfo info) {
|
||||
public static boolean verifyDiscoverInfoVersion(String ver, String hash, DiscoverInfo info) {
|
||||
// step 3.3 check for duplicate identities
|
||||
if (info.containsDuplicateIdentities())
|
||||
return false;
|
||||
|
@ -583,7 +583,7 @@ public class EntityCapsManager {
|
|||
// NAME is not included (in accordance with XEP-0030, the category and
|
||||
// type MUST be included.
|
||||
SortedSet<DiscoverInfo.Identity> sortedIdentities = new TreeSet<DiscoverInfo.Identity>();
|
||||
;
|
||||
|
||||
for (Iterator<DiscoverInfo.Identity> it = discoverInfo.getIdentities(); it.hasNext();)
|
||||
sortedIdentities.add(it.next());
|
||||
|
||||
|
@ -616,7 +616,7 @@ public class EntityCapsManager {
|
|||
// only use the data form for calculation is it has a hidden FORM_TYPE
|
||||
// field
|
||||
// see XEP-0115 5.4 step 3.6
|
||||
if (extendedInfo != null && extendedInfo.hasHiddenFromTypeField()) {
|
||||
if (extendedInfo != null && extendedInfo.hasHiddenFormTypeField()) {
|
||||
synchronized (extendedInfo) {
|
||||
// 6. If the service discovery information response includes
|
||||
// XEP-0128 data forms, sort the forms by the FORM_TYPE (i.e.,
|
||||
|
|
|
@ -24,15 +24,15 @@ public interface EntityCapsPersistentCache {
|
|||
* @param node
|
||||
* @param info
|
||||
*/
|
||||
abstract void addDiscoverInfoByNodePersistent(String node, DiscoverInfo info);
|
||||
void addDiscoverInfoByNodePersistent(String node, DiscoverInfo info);
|
||||
|
||||
/**
|
||||
* Replay the Caches data into EntityCapsManager
|
||||
*/
|
||||
abstract void replay() throws IOException;
|
||||
void replay() throws IOException;
|
||||
|
||||
/**
|
||||
* Empty the Cache
|
||||
*/
|
||||
abstract void emptyCache();
|
||||
void emptyCache();
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import java.io.StringReader;
|
|||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
import org.jivesoftware.smack.util.Base64Encoder;
|
||||
import org.jivesoftware.smack.util.Base32Encoder;
|
||||
import org.jivesoftware.smack.util.StringEncoder;
|
||||
import org.jivesoftware.smackx.entitycaps.EntityCapsManager;
|
||||
import org.jivesoftware.smackx.packet.DiscoverInfo;
|
||||
|
@ -47,19 +47,20 @@ import org.xmlpull.v1.XmlPullParserException;
|
|||
public class SimpleDirectoryPersistentCache implements EntityCapsPersistentCache {
|
||||
|
||||
private File cacheDir;
|
||||
private StringEncoder stringEncoder;
|
||||
private StringEncoder filenameEncoder;
|
||||
|
||||
/**
|
||||
* Creates a new SimpleDirectoryPersistentCache Object. Make sure that the
|
||||
* cacheDir exists and that it's an directory.
|
||||
*
|
||||
* If your cacheDir is case insensitive then make sure to set the
|
||||
* StringEncoder to Base32.
|
||||
* <p>
|
||||
* Default filename encoder {@link Base32Encoder}, as this will work on all
|
||||
* filesystems, both case sensitive and case insensitive. It does however
|
||||
* produce longer filenames.
|
||||
*
|
||||
* @param cacheDir
|
||||
*/
|
||||
public SimpleDirectoryPersistentCache(File cacheDir) {
|
||||
this(cacheDir, Base64Encoder.getInstance());
|
||||
this(cacheDir, Base32Encoder.getInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -67,26 +68,25 @@ public class SimpleDirectoryPersistentCache implements EntityCapsPersistentCache
|
|||
* cacheDir exists and that it's an directory.
|
||||
*
|
||||
* If your cacheDir is case insensitive then make sure to set the
|
||||
* StringEncoder to Base32.
|
||||
* StringEncoder to {@link Base32Encoder} (which is the default).
|
||||
*
|
||||
* @param cacheDir
|
||||
* @param stringEncoder
|
||||
* @param cacheDir The directory where the cache will be stored.
|
||||
* @param filenameEncoder Encodes the node string into a filename.
|
||||
*/
|
||||
public SimpleDirectoryPersistentCache(File cacheDir, StringEncoder stringEncoder) {
|
||||
public SimpleDirectoryPersistentCache(File cacheDir, StringEncoder filenameEncoder) {
|
||||
if (!cacheDir.exists())
|
||||
throw new IllegalStateException("Cache directory \"" + cacheDir + "\" does not exist");
|
||||
if (!cacheDir.isDirectory())
|
||||
throw new IllegalStateException("Cache directory \"" + cacheDir + "\" is not a directory");
|
||||
|
||||
this.cacheDir = cacheDir;
|
||||
this.stringEncoder = stringEncoder;
|
||||
this.filenameEncoder = filenameEncoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDiscoverInfoByNodePersistent(String node, DiscoverInfo info) {
|
||||
String filename = stringEncoder.encode(node);
|
||||
String filename = filenameEncoder.encode(node);
|
||||
File nodeFile = new File(cacheDir, filename);
|
||||
|
||||
try {
|
||||
if (nodeFile.createNewFile())
|
||||
writeInfoToFile(nodeFile, info);
|
||||
|
@ -99,7 +99,7 @@ public class SimpleDirectoryPersistentCache implements EntityCapsPersistentCache
|
|||
public void replay() throws IOException {
|
||||
File[] files = cacheDir.listFiles();
|
||||
for (File f : files) {
|
||||
String node = stringEncoder.decode(f.getName());
|
||||
String node = filenameEncoder.decode(f.getName());
|
||||
DiscoverInfo info = restoreInfoFromFile(f);
|
||||
if (info == null)
|
||||
continue;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* Copyright 2009 Jonas Ådahl.
|
||||
* Copyright 2011-2013 Florian Schmaus
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -202,7 +202,7 @@ public class DataForm implements PacketExtension {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean hasHiddenFromTypeField() {
|
||||
public boolean hasHiddenFormTypeField() {
|
||||
boolean found = false;
|
||||
for (FormField f : fields) {
|
||||
if (f.getVariable().equals("FORM_TYPE") && f.getType() != null && f.getType().equals("hidden"))
|
||||
|
|
|
@ -257,13 +257,25 @@ public class DiscoverInfo extends IQ {
|
|||
* attributes.
|
||||
*
|
||||
*/
|
||||
public static class Identity implements Comparable<Object> {
|
||||
public static class Identity implements Comparable<Identity> {
|
||||
|
||||
private String category;
|
||||
private String name;
|
||||
private String type;
|
||||
private String lang; // 'xml:lang;
|
||||
|
||||
/**
|
||||
* Creates a new identity for an XMPP entity.
|
||||
*
|
||||
* @param category the entity's category.
|
||||
* @param name the entity's name.
|
||||
* @deprecated As per the spec, the type field is mandatory and the 3 argument constructor should be used instead.
|
||||
*/
|
||||
public Identity(String category, String name) {
|
||||
this.category = category;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new identity for an XMPP entity.
|
||||
* 'category' and 'type' are required by
|
||||
|
@ -274,6 +286,9 @@ public class DiscoverInfo extends IQ {
|
|||
* @param type the entity's type (required as per XEP-30).
|
||||
*/
|
||||
public Identity(String category, String name, String type) {
|
||||
if ((category == null) || (type == null))
|
||||
throw new IllegalArgumentException("category and type cannot be null");
|
||||
|
||||
this.category = category;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
|
@ -313,6 +328,7 @@ public class DiscoverInfo extends IQ {
|
|||
* 'type' attribute refer to <a href="http://www.jabber.org/registrar/disco-categories.html">Jabber::Registrar</a>
|
||||
*
|
||||
* @param type the identity's type.
|
||||
* @deprecated As per the spec, this field is mandatory and the 3 argument constructor should be used instead.
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
|
@ -374,11 +390,14 @@ public class DiscoverInfo extends IQ {
|
|||
|
||||
String otherLang = other.lang == null ? "" : other.lang;
|
||||
String thisLang = lang == null ? "" : lang;
|
||||
|
||||
if (!other.type.equals(type))
|
||||
return false;
|
||||
if (!otherLang.equals(thisLang))
|
||||
return false;
|
||||
|
||||
// This safeguard can be removed once the deprecated constructor is removed.
|
||||
String otherType = other.type == null ? "" : other.type;
|
||||
String thisType = type == null ? "" : type;
|
||||
if (!otherType.equals(thisType))
|
||||
return false;
|
||||
|
||||
String otherName = other.name == null ? "" : other.name;
|
||||
String thisName = name == null ? "" : other.name;
|
||||
|
@ -387,23 +406,35 @@ public class DiscoverInfo extends IQ {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
result = 37 * result + category.hashCode();
|
||||
result = 37 * result + (lang == null ? 0 : lang.hashCode());
|
||||
result = 37 * result + (type == null ? 0 : type.hashCode());
|
||||
result = 37 * result + (name == null ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares and identity with another object. The comparison order is:
|
||||
* Compares this identity with another one. The comparison order is:
|
||||
* Category, Type, Lang. If all three are identical the other Identity is considered equal.
|
||||
* Name is not used for comparision, as defined by XEP-0115
|
||||
*
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
public int compareTo(Object obj) {
|
||||
|
||||
DiscoverInfo.Identity other = (DiscoverInfo.Identity) obj;
|
||||
public int compareTo(DiscoverInfo.Identity other) {
|
||||
String otherLang = other.lang == null ? "" : other.lang;
|
||||
String thisLang = lang == null ? "" : lang;
|
||||
|
||||
// This can be removed once the deprecated constructor is removed.
|
||||
String otherType = other.type == null ? "" : other.type;
|
||||
String thisType = type == null ? "" : type;
|
||||
|
||||
if (category.equals(other.category)) {
|
||||
if (type.equals(other.type)) {
|
||||
if (thisType.equals(otherType)) {
|
||||
if (thisLang.equals(otherLang)) {
|
||||
// Don't compare on name, XEP-30 says that name SHOULD
|
||||
// be equals for all identities of an entity
|
||||
|
@ -412,7 +443,7 @@ public class DiscoverInfo extends IQ {
|
|||
return thisLang.compareTo(otherLang);
|
||||
}
|
||||
} else {
|
||||
return type.compareTo(other.type);
|
||||
return thisType.compareTo(otherType);
|
||||
}
|
||||
} else {
|
||||
return category.compareTo(other.category);
|
||||
|
@ -436,6 +467,8 @@ public class DiscoverInfo extends IQ {
|
|||
* @param variable the feature's variable.
|
||||
*/
|
||||
public Feature(String variable) {
|
||||
if (variable == null)
|
||||
throw new IllegalArgumentException("variable cannot be null");
|
||||
this.variable = variable;
|
||||
}
|
||||
|
||||
|
@ -465,5 +498,10 @@ public class DiscoverInfo extends IQ {
|
|||
DiscoverInfo.Feature other = (DiscoverInfo.Feature) obj;
|
||||
return variable.equals(other.variable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 37 * variable.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
* Copyright 2005 Jive Software.
|
||||
*
|
||||
* 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.
|
||||
|
|
|
@ -85,7 +85,8 @@ import org.jivesoftware.smack.util.StringUtils;
|
|||
* @author Kirill Maximov (kir@maxkir.com)
|
||||
*/
|
||||
public class VCard extends IQ {
|
||||
|
||||
private static final String DEFAULT_MIME_TYPE = "image/jpeg";
|
||||
|
||||
/**
|
||||
* Phone types:
|
||||
* VOICE?, FAX?, PAGER?, MSG?, CELL?, VIDEO?, BBS?, MODEM?, ISDN?, PCS?, PREF?
|
||||
|
@ -93,7 +94,6 @@ public class VCard extends IQ {
|
|||
private Map<String, String> homePhones = new HashMap<String, String>();
|
||||
private Map<String, String> workPhones = new HashMap<String, String>();
|
||||
|
||||
|
||||
/**
|
||||
* Address types:
|
||||
* POSTAL?, PARCEL?, (DOM | INTL)?, PREF?, POBOX?, EXTADR?, STREET?, LOCALITY?,
|
||||
|
@ -357,7 +357,7 @@ public class VCard extends IQ {
|
|||
* @param bytes the bytes of the avatar, or null to remove the avatar data
|
||||
*/
|
||||
public void setAvatar(byte[] bytes) {
|
||||
setAvatar(bytes, "image/jpeg");
|
||||
setAvatar(bytes, DEFAULT_MIME_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -390,6 +390,16 @@ public class VCard extends IQ {
|
|||
photoMimeType = mimeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the encoded avatar string. This is used by the provider.
|
||||
*
|
||||
* @param encodedAvatar the encoded avatar string.
|
||||
* @deprecated Use {@link #setAvatar(String, String)} instead.
|
||||
*/
|
||||
public void setEncodedImage(String encodedAvatar) {
|
||||
setAvatar(encodedAvatar, DEFAULT_MIME_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the byte representation of the avatar(if one exists), otherwise returns null if
|
||||
* no avatar could be found.
|
||||
|
|
|
@ -17,52 +17,47 @@
|
|||
package org.jivesoftware.smackx.ping;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jivesoftware.smack.Connection;
|
||||
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||
import org.jivesoftware.smack.ConnectionListener;
|
||||
import org.jivesoftware.smack.PacketCollector;
|
||||
import org.jivesoftware.smack.PacketListener;
|
||||
import org.jivesoftware.smack.SmackConfiguration;
|
||||
import org.jivesoftware.smack.SmackError;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.filter.AndFilter;
|
||||
import org.jivesoftware.smack.filter.IQTypeFilter;
|
||||
import org.jivesoftware.smack.filter.PacketFilter;
|
||||
import org.jivesoftware.smack.filter.PacketIDFilter;
|
||||
import org.jivesoftware.smack.filter.PacketTypeFilter;
|
||||
import org.jivesoftware.smack.keepalive.KeepAliveManager;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.jivesoftware.smack.packet.IQ.Type;
|
||||
import org.jivesoftware.smack.ping.packet.Ping;
|
||||
import org.jivesoftware.smack.util.SyncPacketSend;
|
||||
import org.jivesoftware.smackx.ServiceDiscoveryManager;
|
||||
import org.jivesoftware.smackx.packet.DiscoverInfo;
|
||||
import org.jivesoftware.smackx.ping.packet.Ping;
|
||||
import org.jivesoftware.smackx.ping.packet.Pong;
|
||||
|
||||
/**
|
||||
* Implements the XMPP Ping as defined by XEP-0199. This protocol offers an
|
||||
* alternative to the traditional 'white space ping' approach of determining the
|
||||
* availability of an entity. The XMPP Ping protocol allows ping messages to be
|
||||
* send in a more XML-friendly approach, which can be used over more than one
|
||||
* hop in the communication path.
|
||||
* Implements the XMPP Ping as defined by XEP-0199. The XMPP Ping protocol
|
||||
* allows one entity to 'ping' any other entity by simply sending a ping to
|
||||
* the appropriate JID.
|
||||
* <p>
|
||||
* NOTE: The {@link KeepAliveManager} already provides a keepalive functionality
|
||||
* for regularly pinging the server to keep the underlying transport connection
|
||||
* alive. This class is specifically intended to do manual pings of other
|
||||
* entities.
|
||||
*
|
||||
* @author Florian Schmaus
|
||||
* @see <a href="http://www.xmpp.org/extensions/xep-0199.html">XEP-0199:XMPP
|
||||
* Ping</a>
|
||||
*/
|
||||
public class PingManager {
|
||||
|
||||
public static final String NAMESPACE = "urn:xmpp:ping";
|
||||
public static final String ELEMENT = "ping";
|
||||
|
||||
|
||||
private static Map<Connection, PingManager> instances =
|
||||
Collections.synchronizedMap(new WeakHashMap<Connection, PingManager>());
|
||||
|
||||
private static Map<Connection, PingManager> instances = Collections
|
||||
.synchronizedMap(new WeakHashMap<Connection, PingManager>());
|
||||
|
||||
static {
|
||||
Connection.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
public void connectionCreated(Connection connection) {
|
||||
|
@ -71,273 +66,106 @@ public class PingManager {
|
|||
});
|
||||
}
|
||||
|
||||
private ScheduledExecutorService periodicPingExecutorService;
|
||||
private Connection connection;
|
||||
private int pingInterval = SmackConfiguration.getDefaultPingInterval();
|
||||
private Set<PingFailedListener> pingFailedListeners = Collections
|
||||
.synchronizedSet(new HashSet<PingFailedListener>());
|
||||
private ScheduledFuture<?> periodicPingTask;
|
||||
protected volatile long lastSuccessfulPingByTask = -1;
|
||||
|
||||
|
||||
// Ping Flood protection
|
||||
private long pingMinDelta = 100;
|
||||
private long lastPingStamp = 0; // timestamp of the last received ping
|
||||
|
||||
// Timestamp of the last pong received, either from the server or another entity
|
||||
// Note, no need to synchronize this value, it will only increase over time
|
||||
private long lastSuccessfulManualPing = -1;
|
||||
|
||||
private PingManager(Connection connection) {
|
||||
ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
|
||||
sdm.addFeature(NAMESPACE);
|
||||
this.connection = connection;
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
periodicPingExecutorService = new ScheduledThreadPoolExecutor(1);
|
||||
PacketFilter pingPacketFilter = new PacketTypeFilter(Ping.class);
|
||||
connection.addPacketListener(new PacketListener() {
|
||||
/**
|
||||
* Sends a Pong for every Ping
|
||||
*/
|
||||
public void processPacket(Packet packet) {
|
||||
if (pingMinDelta > 0) {
|
||||
// Ping flood protection enabled
|
||||
long currentMillies = System.currentTimeMillis();
|
||||
long delta = currentMillies - lastPingStamp;
|
||||
lastPingStamp = currentMillies;
|
||||
if (delta < pingMinDelta) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Pong pong = new Pong((Ping)packet);
|
||||
connection.sendPacket(pong);
|
||||
}
|
||||
}
|
||||
, pingPacketFilter);
|
||||
connection.addConnectionListener(new ConnectionListener() {
|
||||
|
||||
@Override
|
||||
public void connectionClosed() {
|
||||
maybeStopPingServerTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionClosedOnError(Exception arg0) {
|
||||
maybeStopPingServerTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconnectionSuccessful() {
|
||||
maybeSchedulePingServerTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconnectingIn(int seconds) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconnectionFailed(Exception e) {
|
||||
}
|
||||
});
|
||||
instances.put(connection, this);
|
||||
maybeSchedulePingServerTask();
|
||||
}
|
||||
|
||||
public static PingManager getInstanceFor(Connection connection) {
|
||||
/**
|
||||
* Retrieves a {@link PingManager} for the specified {@link Connection}, creating one if it doesn't already
|
||||
* exist.
|
||||
*
|
||||
* @param connection
|
||||
* The connection the manager is attached to.
|
||||
* @return The new or existing manager.
|
||||
*/
|
||||
public synchronized static PingManager getInstanceFor(Connection connection) {
|
||||
PingManager pingManager = instances.get(connection);
|
||||
|
||||
if (pingManager == null) {
|
||||
pingManager = new PingManager(connection);
|
||||
}
|
||||
|
||||
return pingManager;
|
||||
}
|
||||
|
||||
public void setPingIntervall(int pingIntervall) {
|
||||
this.pingInterval = pingIntervall;
|
||||
private PingManager(Connection con) {
|
||||
this.connection = con;
|
||||
ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
|
||||
|
||||
// The ServiceDiscoveryManager was not pre-initialized
|
||||
if (sdm == null)
|
||||
sdm = new ServiceDiscoveryManager(connection);
|
||||
|
||||
sdm.addFeature(Ping.NAMESPACE);
|
||||
|
||||
PacketFilter pingPacketFilter = new AndFilter(new PacketTypeFilter(Ping.class), new IQTypeFilter(Type.GET));
|
||||
|
||||
connection.addPacketListener(new PacketListener() {
|
||||
/**
|
||||
* Sends a Pong for every Ping
|
||||
*/
|
||||
public void processPacket(Packet packet) {
|
||||
IQ pong = IQ.createResultIQ((Ping) packet);
|
||||
connection.sendPacket(pong);
|
||||
}
|
||||
}, pingPacketFilter);
|
||||
}
|
||||
|
||||
public int getPingIntervall() {
|
||||
return pingInterval;
|
||||
}
|
||||
|
||||
public void registerPingFailedListener(PingFailedListener listener) {
|
||||
pingFailedListeners.add(listener);
|
||||
}
|
||||
|
||||
public void unregisterPingFailedListener(PingFailedListener listener) {
|
||||
pingFailedListeners.remove(listener);
|
||||
}
|
||||
|
||||
public void disablePingFloodProtection() {
|
||||
setPingMinimumInterval(-1);
|
||||
}
|
||||
|
||||
public void setPingMinimumInterval(long ms) {
|
||||
this.pingMinDelta = ms;
|
||||
}
|
||||
|
||||
public long getPingMinimumInterval() {
|
||||
return this.pingMinDelta;
|
||||
/**
|
||||
* Pings the given jid. This method will return false if an error occurs. The exception
|
||||
* to this, is a server ping, which will always return true if the server is reachable,
|
||||
* event if there is an error on the ping itself (i.e. ping not supported).
|
||||
* <p>
|
||||
* Use {@link #isPingSupported(String)} to determine if XMPP Ping is supported
|
||||
* by the entity.
|
||||
*
|
||||
* @param jid The id of the entity the ping is being sent to
|
||||
* @param pingTimeout The time to wait for a reply
|
||||
* @return true if a reply was received from the entity, false otherwise.
|
||||
*/
|
||||
public boolean ping(String jid, long pingTimeout) {
|
||||
Ping ping = new Ping(jid);
|
||||
|
||||
try {
|
||||
SyncPacketSend.getReply(connection, ping);
|
||||
}
|
||||
catch (XMPPException exc) {
|
||||
|
||||
return (jid.equals(connection.getServiceName()) && (exc.getSmackError() != SmackError.NO_RESPONSE_FROM_SERVER));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pings the given jid and returns the IQ response which is either of
|
||||
* IQ.Type.ERROR or IQ.Type.RESULT. If we are not connected or if there was
|
||||
* no reply, null is returned.
|
||||
* Same as calling {@link #ping(String, long)} with the defaultpacket reply
|
||||
* timeout.
|
||||
*
|
||||
* You should use isPingSupported(jid) to determine if XMPP Ping is
|
||||
* supported by the user.
|
||||
*
|
||||
* @param jid
|
||||
* @param pingTimeout
|
||||
* @return
|
||||
* @param jid The id of the entity the ping is being sent to
|
||||
* @return true if a reply was received from the entity, false otherwise.
|
||||
*/
|
||||
public IQ ping(String jid, long pingTimeout) {
|
||||
// Make sure we actually connected to the server
|
||||
if (!connection.isAuthenticated())
|
||||
return null;
|
||||
|
||||
Ping ping = new Ping(connection.getUser(), jid);
|
||||
|
||||
PacketCollector collector =
|
||||
connection.createPacketCollector(new PacketIDFilter(ping.getPacketID()));
|
||||
|
||||
connection.sendPacket(ping);
|
||||
|
||||
IQ result = (IQ) collector.nextResult(pingTimeout);
|
||||
|
||||
collector.cancel();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pings the given jid and returns the IQ response with the default
|
||||
* packet reply timeout
|
||||
*
|
||||
* @param jid
|
||||
* @return
|
||||
*/
|
||||
public IQ ping(String jid) {
|
||||
public boolean ping(String jid) {
|
||||
return ping(jid, SmackConfiguration.getPacketReplyTimeout());
|
||||
}
|
||||
|
||||
/**
|
||||
* Pings the given Entity.
|
||||
* Query the specified entity to see if it supports the Ping protocol (XEP-0199)
|
||||
*
|
||||
* Note that XEP-199 shows that if we receive a error response
|
||||
* service-unavailable there is no way to determine if the response was send
|
||||
* by the entity (e.g. a user JID) or from a server in between. This is
|
||||
* intended behavior to avoid presence leaks.
|
||||
*
|
||||
* Always use isPingSupported(jid) to determine if XMPP Ping is supported
|
||||
* by the entity.
|
||||
*
|
||||
* @param jid
|
||||
* @return True if a pong was received, otherwise false
|
||||
* @param jid The id of the entity the query is being sent to
|
||||
* @return true if it supports ping, false otherwise.
|
||||
* @throws XMPPException An XMPP related error occurred during the request
|
||||
*/
|
||||
public boolean pingEntity(String jid, long pingTimeout) {
|
||||
IQ result = ping(jid, pingTimeout);
|
||||
public boolean isPingSupported(String jid) throws XMPPException {
|
||||
DiscoverInfo result = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(jid);
|
||||
return result.containsFeature(Ping.NAMESPACE);
|
||||
}
|
||||
|
||||
if (result == null || result.getType() == IQ.Type.ERROR) {
|
||||
return false;
|
||||
}
|
||||
pongReceived();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean pingEntity(String jid) {
|
||||
return pingEntity(jid, SmackConfiguration.getPacketReplyTimeout());
|
||||
}
|
||||
|
||||
/**
|
||||
* Pings the user's server. Will notify the registered
|
||||
* pingFailedListeners in case of error.
|
||||
* Pings the server. This method will return true if the server is reachable. It
|
||||
* is the equivalent of calling <code>ping</code> with the XMPP domain.
|
||||
* <p>
|
||||
* Unlike the {@link #ping(String)} case, this method will return true even if
|
||||
* {@link #isPingSupported(String)} is false.
|
||||
*
|
||||
* If we receive as response, we can be sure that it came from the server.
|
||||
*
|
||||
* @return true if successful, otherwise false
|
||||
*/
|
||||
public boolean pingMyServer(long pingTimeout) {
|
||||
IQ result = ping(connection.getServiceName(), pingTimeout);
|
||||
|
||||
if (result == null) {
|
||||
for (PingFailedListener l : pingFailedListeners) {
|
||||
l.pingFailed();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Maybe not really a pong, but an answer is an answer
|
||||
pongReceived();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pings the user's server with the PacketReplyTimeout as defined
|
||||
* in SmackConfiguration.
|
||||
*
|
||||
* @return true if successful, otherwise false
|
||||
* @return true if a reply was received from the server, false otherwise.
|
||||
*/
|
||||
public boolean pingMyServer() {
|
||||
return pingMyServer(SmackConfiguration.getPacketReplyTimeout());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if XMPP Ping is supported by a given JID
|
||||
*
|
||||
* @param jid
|
||||
* @return
|
||||
*/
|
||||
public boolean isPingSupported(String jid) {
|
||||
try {
|
||||
DiscoverInfo result =
|
||||
ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(jid);
|
||||
return result.containsFeature(NAMESPACE);
|
||||
}
|
||||
catch (XMPPException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time of the last successful Ping Pong with the
|
||||
* users server. If there was no successful Ping (e.g. because this
|
||||
* feature is disabled) -1 will be returned.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public long getLastSuccessfulPing() {
|
||||
return Math.max(lastSuccessfulPingByTask, lastSuccessfulManualPing);
|
||||
}
|
||||
|
||||
protected Set<PingFailedListener> getPingFailedListeners() {
|
||||
return pingFailedListeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels any existing periodic ping task if there is one and schedules a new ping task if pingInterval is greater
|
||||
* then zero.
|
||||
*
|
||||
*/
|
||||
protected synchronized void maybeSchedulePingServerTask() {
|
||||
maybeStopPingServerTask();
|
||||
if (pingInterval > 0) {
|
||||
periodicPingTask = periodicPingExecutorService.schedule(new ServerPingTask(connection), pingInterval,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeStopPingServerTask() {
|
||||
if (periodicPingTask != null) {
|
||||
periodicPingTask.cancel(true);
|
||||
periodicPingTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void pongReceived() {
|
||||
lastSuccessfulManualPing = System.currentTimeMillis();
|
||||
return ping(connection.getServiceName());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
/**
|
||||
* Copyright 2012-2013 Florian Schmaus
|
||||
*
|
||||
* 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.ping;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jivesoftware.smack.Connection;
|
||||
|
||||
class ServerPingTask implements Runnable {
|
||||
|
||||
// This has to be a weak reference because IIRC all threads are roots
|
||||
// for objects and we have a new thread here that should hold a strong
|
||||
// reference to connection so that it can be GCed.
|
||||
private WeakReference<Connection> weakConnection;
|
||||
|
||||
private int delta = 1000; // 1 seconds
|
||||
private int tries = 3; // 3 tries
|
||||
|
||||
protected ServerPingTask(Connection connection) {
|
||||
this.weakConnection = new WeakReference<Connection>(connection);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
Connection connection = weakConnection.get();
|
||||
if (connection == null) {
|
||||
// connection has been collected by GC
|
||||
// which means we can stop the thread by breaking the loop
|
||||
return;
|
||||
}
|
||||
if (connection.isAuthenticated()) {
|
||||
PingManager pingManager = PingManager.getInstanceFor(connection);
|
||||
boolean res = false;
|
||||
|
||||
for (int i = 0; i < tries; i++) {
|
||||
if (i != 0) {
|
||||
try {
|
||||
Thread.sleep(delta);
|
||||
} catch (InterruptedException e) {
|
||||
// We received an interrupt
|
||||
// This only happens if we should stop pinging
|
||||
return;
|
||||
}
|
||||
}
|
||||
res = pingManager.pingMyServer();
|
||||
// stop when we receive a pong back
|
||||
if (res) {
|
||||
pingManager.lastSuccessfulPingByTask = System.currentTimeMillis();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!res) {
|
||||
Set<PingFailedListener> pingFailedListeners = pingManager.getPingFailedListeners();
|
||||
for (PingFailedListener l : pingFailedListeners) {
|
||||
l.pingFailed();
|
||||
}
|
||||
} else {
|
||||
// Ping was successful, wind-up the periodic task again
|
||||
pingManager.maybeSchedulePingServerTask();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/**
|
||||
* Copyright 2012 Florian Schmaus
|
||||
*
|
||||
* 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.ping.packet;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smackx.ping.PingManager;
|
||||
|
||||
public class Ping extends IQ {
|
||||
|
||||
public Ping() {
|
||||
}
|
||||
|
||||
public Ping(String from, String to) {
|
||||
setTo(to);
|
||||
setFrom(from);
|
||||
setType(IQ.Type.GET);
|
||||
setPacketID(getPacketID());
|
||||
}
|
||||
|
||||
public String getChildElementXML() {
|
||||
return "<" + PingManager.ELEMENT + " xmlns=\'" + PingManager.NAMESPACE + "\' />";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/**
|
||||
* Copyright 2012 Florian Schmaus
|
||||
*
|
||||
* 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.ping.packet;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
|
||||
public class Pong extends IQ {
|
||||
|
||||
/**
|
||||
* Composes a Pong packet from a received ping packet. This basically swaps
|
||||
* the 'from' and 'to' attributes. And sets the IQ type to result.
|
||||
*
|
||||
* @param ping
|
||||
*/
|
||||
public Pong(Ping ping) {
|
||||
setType(IQ.Type.RESULT);
|
||||
setFrom(ping.getTo());
|
||||
setTo(ping.getFrom());
|
||||
setPacketID(ping.getPacketID());
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the child element of the Pong reply, which is non-existent. This
|
||||
* is why we return 'null' here. See e.g. Example 11 from
|
||||
* http://xmpp.org/extensions/xep-0199.html#e2e
|
||||
*/
|
||||
public String getChildElementXML() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/**
|
||||
* Copyright 2012 Florian Schmaus
|
||||
*
|
||||
* 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.ping.provider;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
import org.jivesoftware.smackx.ping.packet.Ping;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
public class PingProvider implements IQProvider {
|
||||
|
||||
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||
// No need to use the ping constructor with arguments. IQ will already
|
||||
// have filled out all relevant fields ('from', 'to', 'id').
|
||||
return new Ping();
|
||||
}
|
||||
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
* Copyright 2009 Robin Collier.
|
||||
*
|
||||
* 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.
|
||||
|
@ -17,9 +17,6 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*
|
||||
* Created on 2009-07-13
|
||||
*/
|
||||
package org.jivesoftware.smackx.pubsub;
|
||||
|
||||
import org.jivesoftware.smack.Connection;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
* Copyright 2009 Robin Collier.
|
||||
*
|
||||
* 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.
|
||||
|
@ -17,9 +17,6 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*
|
||||
* Created on 2009-07-09
|
||||
*/
|
||||
package org.jivesoftware.smackx.pubsub;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
* Copyright 2009 Robin Collier.
|
||||
*
|
||||
* 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.
|
||||
|
@ -17,9 +17,6 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*
|
||||
* Created on 2009-05-12
|
||||
*/
|
||||
package org.jivesoftware.smackx.pubsub;
|
||||
|
||||
abstract public class NodeEvent
|
||||
|
|
|
@ -24,53 +24,86 @@ import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
|
|||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
* Parses an <b>item</b> element as is defined in both the {@link PubSubNamespace#BASIC} and {@link PubSubNamespace#EVENT}
|
||||
* namespaces. To parse the item contents, it will use whatever {@link PacketExtensionProvider} is registered in
|
||||
* <b>smack.providers</b> for its element name and namespace. If no provider is registered, it will return a {@link SimplePayload}.
|
||||
* Parses an <b>item</b> element as is defined in both the {@link PubSubNamespace#BASIC} and
|
||||
* {@link PubSubNamespace#EVENT} namespaces. To parse the item contents, it will use whatever
|
||||
* {@link PacketExtensionProvider} is registered in <b>smack.providers</b> for its element name and namespace. If no
|
||||
* provider is registered, it will return a {@link SimplePayload}.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
public class ItemProvider implements PacketExtensionProvider
|
||||
public class ItemProvider implements PacketExtensionProvider
|
||||
{
|
||||
public PacketExtension parseExtension(XmlPullParser parser) throws Exception
|
||||
{
|
||||
String id = parser.getAttributeValue(null, "id");
|
||||
public PacketExtension parseExtension(XmlPullParser parser) throws Exception
|
||||
{
|
||||
String id = parser.getAttributeValue(null, "id");
|
||||
String node = parser.getAttributeValue(null, "node");
|
||||
String elem = parser.getName();
|
||||
|
||||
int tag = parser.next();
|
||||
|
||||
if (tag == XmlPullParser.END_TAG)
|
||||
{
|
||||
return new Item(id, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
String payloadElemName = parser.getName();
|
||||
String payloadNS = parser.getNamespace();
|
||||
|
||||
if (ProviderManager.getInstance().getExtensionProvider(payloadElemName, payloadNS) == null)
|
||||
{
|
||||
boolean done = false;
|
||||
StringBuilder payloadText = new StringBuilder();
|
||||
|
||||
while (!done)
|
||||
{
|
||||
if (tag == XmlPullParser.END_TAG && parser.getName().equals(elem))
|
||||
done = true;
|
||||
else if (!((tag == XmlPullParser.START_TAG) && parser.isEmptyElementTag()))
|
||||
payloadText.append(parser.getText());
|
||||
|
||||
if (!done)
|
||||
tag = parser.next();
|
||||
}
|
||||
return new PayloadItem<SimplePayload>(id, node, new SimplePayload(payloadElemName, payloadNS, payloadText.toString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return new PayloadItem<PacketExtension>(id, node, PacketParserUtils.parsePacketExtension(payloadElemName, payloadNS, parser));
|
||||
}
|
||||
}
|
||||
}
|
||||
String elem = parser.getName();
|
||||
|
||||
int tag = parser.next();
|
||||
|
||||
if (tag == XmlPullParser.END_TAG)
|
||||
{
|
||||
return new Item(id, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
String payloadElemName = parser.getName();
|
||||
String payloadNS = parser.getNamespace();
|
||||
|
||||
if (ProviderManager.getInstance().getExtensionProvider(payloadElemName, payloadNS) == null)
|
||||
{
|
||||
boolean done = false;
|
||||
boolean isEmptyElement = false;
|
||||
StringBuilder payloadText = new StringBuilder();
|
||||
|
||||
while (!done)
|
||||
{
|
||||
if (tag == XmlPullParser.END_TAG && parser.getName().equals(elem))
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
else if (parser.getEventType() == XmlPullParser.START_TAG)
|
||||
{
|
||||
payloadText.append("<").append(parser.getName());
|
||||
|
||||
if (parser.getName().equals(payloadElemName) && (payloadNS.length() > 0))
|
||||
payloadText.append(" xmlns=\"").append(payloadNS).append("\"");
|
||||
int n = parser.getAttributeCount();
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
payloadText.append(" ").append(parser.getAttributeName(i)).append("=\"")
|
||||
.append(parser.getAttributeValue(i)).append("\"");
|
||||
|
||||
if (parser.isEmptyElementTag())
|
||||
{
|
||||
payloadText.append("/>");
|
||||
isEmptyElement = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
payloadText.append(">");
|
||||
}
|
||||
}
|
||||
else if (parser.getEventType() == XmlPullParser.END_TAG)
|
||||
{
|
||||
if (isEmptyElement)
|
||||
isEmptyElement = false;
|
||||
else
|
||||
payloadText.append("</").append(parser.getName()).append(">");
|
||||
}
|
||||
else if (parser.getEventType() == XmlPullParser.TEXT)
|
||||
{
|
||||
payloadText.append(parser.getText());
|
||||
}
|
||||
tag = parser.next();
|
||||
}
|
||||
return new PayloadItem<SimplePayload>(id, node, new SimplePayload(payloadElemName, payloadNS, payloadText.toString()));
|
||||
}
|
||||
else {
|
||||
return new PayloadItem<PacketExtension>(id, node, PacketParserUtils.parsePacketExtension(
|
||||
payloadElemName, payloadNS, parser));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* 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
|
||||
|
@ -42,16 +42,19 @@ public class DeliveryReceipt implements PacketExtension
|
|||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName()
|
||||
{
|
||||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace()
|
||||
{
|
||||
return NAMESPACE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toXML()
|
||||
{
|
||||
return "<received xmlns='" + NAMESPACE + "' id='" + id + "'/>";
|
||||
|
|
|
@ -24,20 +24,16 @@ 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.PacketExtensionFilter;
|
||||
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-0184: Message Delivery Receipts. This class implements
|
||||
* Manager for XEP-0184: Message Delivery Receipts. This class implements
|
||||
* the manager for {@link DeliveryReceipt} support, enabling and disabling of
|
||||
* automatic DeliveryReceipt transmission.
|
||||
*
|
||||
|
@ -167,7 +163,7 @@ public class DeliveryReceiptManager implements PacketListener {
|
|||
*
|
||||
* @param listener the listener to be informed about new receipts
|
||||
*/
|
||||
public void registerReceiptReceivedListener(ReceiptReceivedListener listener) {
|
||||
public void addReceiptReceivedListener(ReceiptReceivedListener listener) {
|
||||
receiptReceivedListeners.add(listener);
|
||||
}
|
||||
|
||||
|
@ -176,20 +172,10 @@ public class DeliveryReceiptManager implements PacketListener {
|
|||
*
|
||||
* @param listener the listener to be removed
|
||||
*/
|
||||
public void unregisterReceiptReceivedListener(ReceiptReceivedListener listener) {
|
||||
public void removeReceiptReceivedListener(ReceiptReceivedListener listener) {
|
||||
receiptReceivedListeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for received receipt notifications.
|
||||
*
|
||||
* Implement this and add a listener to get notified.
|
||||
*/
|
||||
public static interface ReceiptReceivedListener {
|
||||
void onReceiptReceived(String fromJid, String toJid, String receiptId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test if a packet requires a delivery receipt.
|
||||
*
|
||||
|
|
|
@ -1,21 +1,26 @@
|
|||
/**
|
||||
* Copyright 2012 Florian Schmaus
|
||||
*
|
||||
* 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.ping;
|
||||
|
||||
public interface PingFailedListener {
|
||||
void pingFailed();
|
||||
/**
|
||||
* 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.receipts;
|
||||
|
||||
/**
|
||||
* Interface for received receipt notifications.
|
||||
*
|
||||
* Implement this and add a listener to get notified.
|
||||
*/
|
||||
public interface ReceiptReceivedListener {
|
||||
void onReceiptReceived(String fromJid, String toJid, String receiptId);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue