mirror of
https://github.com/vanitasvitae/Smack.git
synced 2025-06-21 03:14:41 +02:00
Enfore spaces for indentation
Although I'm in the tabs camp, Smack uses mostly spaces. Therefore it is the logical choice for the indentation style.
This commit is contained in:
parent
ffe9397e66
commit
ef0af66b21
125 changed files with 5336 additions and 5344 deletions
|
@ -35,10 +35,6 @@
|
|||
<property name="format" value="^\s+$"/>
|
||||
<property name="message" value="Line containing only whitespace character(s)"/>
|
||||
</module>
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="^ +\t+"/>
|
||||
<property name="message" value="Line containing tab(s) after space"/>
|
||||
</module>
|
||||
<module name="RegexpSingleline">
|
||||
<!-- We use {2,} instead of + here to address the typical case where a file was written
|
||||
with tabs but javadoc is causing '\t *' -->
|
||||
|
@ -89,6 +85,10 @@
|
|||
<property name="message" value="Usage of println"/>
|
||||
<property name="ignoreComments" value="true"/>
|
||||
</module>
|
||||
<module name="RegexpSinglelineJava">
|
||||
<property name="format" value="^\t+"/>
|
||||
<property name="message" value="Indent must not use tab characters. Use space instead."/>
|
||||
</module>
|
||||
<module name="JavadocMethod">
|
||||
<!-- TODO stricten those checks -->
|
||||
<property name="scope" value="public"/>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2014 Florian Schmaus
|
||||
* Copyright © 2014-2017 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -63,116 +63,116 @@ import android.os.SystemClock;
|
|||
*/
|
||||
public final class ServerPingWithAlarmManager extends Manager {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(ServerPingWithAlarmManager.class
|
||||
.getName());
|
||||
private static final Logger LOGGER = Logger.getLogger(ServerPingWithAlarmManager.class
|
||||
.getName());
|
||||
|
||||
private static final String PING_ALARM_ACTION = "org.igniterealtime.smackx.ping.ACTION";
|
||||
private static final String PING_ALARM_ACTION = "org.igniterealtime.smackx.ping.ACTION";
|
||||
|
||||
private static final Map<XMPPConnection, ServerPingWithAlarmManager> INSTANCES = new WeakHashMap<XMPPConnection, ServerPingWithAlarmManager>();
|
||||
private static final Map<XMPPConnection, ServerPingWithAlarmManager> INSTANCES = new WeakHashMap<XMPPConnection, ServerPingWithAlarmManager>();
|
||||
|
||||
static {
|
||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
@Override
|
||||
public void connectionCreated(XMPPConnection connection) {
|
||||
getInstanceFor(connection);
|
||||
}
|
||||
});
|
||||
}
|
||||
static {
|
||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
@Override
|
||||
public void connectionCreated(XMPPConnection connection) {
|
||||
getInstanceFor(connection);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static synchronized ServerPingWithAlarmManager getInstanceFor(XMPPConnection connection) {
|
||||
ServerPingWithAlarmManager serverPingWithAlarmManager = INSTANCES.get(connection);
|
||||
if (serverPingWithAlarmManager == null) {
|
||||
serverPingWithAlarmManager = new ServerPingWithAlarmManager(connection);
|
||||
INSTANCES.put(connection, serverPingWithAlarmManager);
|
||||
}
|
||||
return serverPingWithAlarmManager;
|
||||
}
|
||||
public static synchronized ServerPingWithAlarmManager getInstanceFor(XMPPConnection connection) {
|
||||
ServerPingWithAlarmManager serverPingWithAlarmManager = INSTANCES.get(connection);
|
||||
if (serverPingWithAlarmManager == null) {
|
||||
serverPingWithAlarmManager = new ServerPingWithAlarmManager(connection);
|
||||
INSTANCES.put(connection, serverPingWithAlarmManager);
|
||||
}
|
||||
return serverPingWithAlarmManager;
|
||||
}
|
||||
|
||||
private boolean mEnabled = true;
|
||||
private boolean mEnabled = true;
|
||||
|
||||
private ServerPingWithAlarmManager(XMPPConnection connection) {
|
||||
super(connection);
|
||||
}
|
||||
private ServerPingWithAlarmManager(XMPPConnection connection) {
|
||||
super(connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* If enabled, ServerPingWithAlarmManager will call {@link PingManager#pingServerIfNecessary()}
|
||||
* for the connection of this instance every half hour.
|
||||
*
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public void setEnabled(boolean enabled) {
|
||||
mEnabled = enabled;
|
||||
}
|
||||
public void setEnabled(boolean enabled) {
|
||||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return mEnabled;
|
||||
}
|
||||
public boolean isEnabled() {
|
||||
return mEnabled;
|
||||
}
|
||||
|
||||
private static final BroadcastReceiver ALARM_BROADCAST_RECEIVER = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
LOGGER.fine("Ping Alarm broadcast received");
|
||||
Set<Entry<XMPPConnection, ServerPingWithAlarmManager>> managers;
|
||||
synchronized (ServerPingWithAlarmManager.class) {
|
||||
// Make a copy to avoid ConcurrentModificationException when
|
||||
// iterating directly over INSTANCES and the Set is modified
|
||||
// concurrently by creating a new ServerPingWithAlarmManager.
|
||||
managers = new HashSet<>(INSTANCES.entrySet());
|
||||
}
|
||||
for (Entry<XMPPConnection, ServerPingWithAlarmManager> entry : managers) {
|
||||
XMPPConnection connection = entry.getKey();
|
||||
if (entry.getValue().isEnabled()) {
|
||||
LOGGER.fine("Calling pingServerIfNecessary for connection "
|
||||
+ connection);
|
||||
final PingManager pingManager = PingManager.getInstanceFor(connection);
|
||||
// Android BroadcastReceivers have a timeout of 60 seconds.
|
||||
// The connections reply timeout may be higher, which causes
|
||||
// timeouts of the broadcast receiver and a subsequent ANR
|
||||
// of the App of the broadcast receiver. We therefore need
|
||||
// to call pingServerIfNecessary() in a new thread to avoid
|
||||
// this. It could happen that the device gets back to sleep
|
||||
// until the Thread runs, but that's a risk we are willing
|
||||
// to take into account as it's unlikely.
|
||||
Async.go(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
pingManager.pingServerIfNecessary();
|
||||
}
|
||||
}, "PingServerIfNecessary (" + connection.getConnectionCounter() + ')');
|
||||
} else {
|
||||
LOGGER.fine("NOT calling pingServerIfNecessary (disabled) on connection "
|
||||
+ connection.getConnectionCounter());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
private static final BroadcastReceiver ALARM_BROADCAST_RECEIVER = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
LOGGER.fine("Ping Alarm broadcast received");
|
||||
Set<Entry<XMPPConnection, ServerPingWithAlarmManager>> managers;
|
||||
synchronized (ServerPingWithAlarmManager.class) {
|
||||
// Make a copy to avoid ConcurrentModificationException when
|
||||
// iterating directly over INSTANCES and the Set is modified
|
||||
// concurrently by creating a new ServerPingWithAlarmManager.
|
||||
managers = new HashSet<>(INSTANCES.entrySet());
|
||||
}
|
||||
for (Entry<XMPPConnection, ServerPingWithAlarmManager> entry : managers) {
|
||||
XMPPConnection connection = entry.getKey();
|
||||
if (entry.getValue().isEnabled()) {
|
||||
LOGGER.fine("Calling pingServerIfNecessary for connection "
|
||||
+ connection);
|
||||
final PingManager pingManager = PingManager.getInstanceFor(connection);
|
||||
// Android BroadcastReceivers have a timeout of 60 seconds.
|
||||
// The connections reply timeout may be higher, which causes
|
||||
// timeouts of the broadcast receiver and a subsequent ANR
|
||||
// of the App of the broadcast receiver. We therefore need
|
||||
// to call pingServerIfNecessary() in a new thread to avoid
|
||||
// this. It could happen that the device gets back to sleep
|
||||
// until the Thread runs, but that's a risk we are willing
|
||||
// to take into account as it's unlikely.
|
||||
Async.go(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
pingManager.pingServerIfNecessary();
|
||||
}
|
||||
}, "PingServerIfNecessary (" + connection.getConnectionCounter() + ')');
|
||||
} else {
|
||||
LOGGER.fine("NOT calling pingServerIfNecessary (disabled) on connection "
|
||||
+ connection.getConnectionCounter());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static Context sContext;
|
||||
private static PendingIntent sPendingIntent;
|
||||
private static AlarmManager sAlarmManager;
|
||||
private static Context sContext;
|
||||
private static PendingIntent sPendingIntent;
|
||||
private static AlarmManager sAlarmManager;
|
||||
|
||||
/**
|
||||
* Register a pending intent with the AlarmManager to be broadcasted every half hour and
|
||||
* register the alarm broadcast receiver to receive this intent. The receiver will check all
|
||||
* known questions if a ping is Necessary when invoked by the alarm intent.
|
||||
*
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public static void onCreate(Context context) {
|
||||
sContext = context;
|
||||
context.registerReceiver(ALARM_BROADCAST_RECEIVER, new IntentFilter(PING_ALARM_ACTION));
|
||||
sAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
sPendingIntent = PendingIntent.getBroadcast(context, 0, new Intent(PING_ALARM_ACTION), 0);
|
||||
sAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
||||
SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR,
|
||||
AlarmManager.INTERVAL_HALF_HOUR, sPendingIntent);
|
||||
}
|
||||
public static void onCreate(Context context) {
|
||||
sContext = context;
|
||||
context.registerReceiver(ALARM_BROADCAST_RECEIVER, new IntentFilter(PING_ALARM_ACTION));
|
||||
sAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
sPendingIntent = PendingIntent.getBroadcast(context, 0, new Intent(PING_ALARM_ACTION), 0);
|
||||
sAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
||||
SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR,
|
||||
AlarmManager.INTERVAL_HALF_HOUR, sPendingIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister the alarm broadcast receiver and cancel the alarm.
|
||||
*/
|
||||
public static void onDestroy() {
|
||||
sContext.unregisterReceiver(ALARM_BROADCAST_RECEIVER);
|
||||
sAlarmManager.cancel(sPendingIntent);
|
||||
}
|
||||
public static void onDestroy() {
|
||||
sContext.unregisterReceiver(ALARM_BROADCAST_RECEIVER);
|
||||
sAlarmManager.cancel(sPendingIntent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2014 Florian Schmaus
|
||||
* Copyright © 2014-2017 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -28,12 +28,12 @@ import org.jivesoftware.smack.util.stringencoder.android.AndroidBase64UrlSafeEnc
|
|||
|
||||
public class AndroidSmackInitializer implements SmackInitializer {
|
||||
|
||||
@Override
|
||||
public List<Exception> initialize() {
|
||||
SmackConfiguration.setDefaultHostnameVerifier(new StrictHostnameVerifier());
|
||||
Base64.setEncoder(AndroidBase64Encoder.getInstance());
|
||||
Base64UrlSafeEncoder.setEncoder(AndroidBase64UrlSafeEncoder.getInstance());
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public List<Exception> initialize() {
|
||||
SmackConfiguration.setDefaultHostnameVerifier(new StrictHostnameVerifier());
|
||||
Base64.setEncoder(AndroidBase64Encoder.getInstance());
|
||||
Base64UrlSafeEncoder.setEncoder(AndroidBase64UrlSafeEncoder.getInstance());
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,12 +35,12 @@ public final class IQTypeFilter extends FlexibleStanzaTypeFilter<IQ> {
|
|||
public static final StanzaFilter ERROR = new IQTypeFilter(Type.error);
|
||||
public static final StanzaFilter GET_OR_SET = new OrFilter(GET, SET);
|
||||
|
||||
private final IQ.Type type;
|
||||
private final IQ.Type type;
|
||||
|
||||
private IQTypeFilter(IQ.Type type) {
|
||||
private IQTypeFilter(IQ.Type type) {
|
||||
super(IQ.class);
|
||||
this.type = Objects.requireNonNull(type, "Type must not be null");
|
||||
}
|
||||
this.type = Objects.requireNonNull(type, "Type must not be null");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean acceptSpecific(IQ iq) {
|
||||
|
|
|
@ -26,190 +26,190 @@ import org.junit.Test;
|
|||
public class StanzaCollectorTest
|
||||
{
|
||||
|
||||
@Test
|
||||
public void verifyRollover() throws InterruptedException
|
||||
{
|
||||
TestStanzaCollector collector = new TestStanzaCollector(null, new OKEverything(), 5);
|
||||
@Test
|
||||
public void verifyRollover() throws InterruptedException
|
||||
{
|
||||
TestStanzaCollector collector = new TestStanzaCollector(null, new OKEverything(), 5);
|
||||
|
||||
for (int i=0; i<6; i++)
|
||||
{
|
||||
Stanza testPacket = new TestPacket(i);
|
||||
collector.processStanza(testPacket);
|
||||
}
|
||||
for (int i=0; i<6; i++)
|
||||
{
|
||||
Stanza testPacket = new TestPacket(i);
|
||||
collector.processStanza(testPacket);
|
||||
}
|
||||
|
||||
// Assert that '0' has rolled off
|
||||
assertEquals("1", collector.nextResultBlockForever().getStanzaId());
|
||||
assertEquals("2", collector.nextResultBlockForever().getStanzaId());
|
||||
assertEquals("3", collector.nextResultBlockForever().getStanzaId());
|
||||
assertEquals("4", collector.nextResultBlockForever().getStanzaId());
|
||||
assertEquals("5", collector.pollResult().getStanzaId());
|
||||
assertNull(collector.pollResult());
|
||||
// Assert that '0' has rolled off
|
||||
assertEquals("1", collector.nextResultBlockForever().getStanzaId());
|
||||
assertEquals("2", collector.nextResultBlockForever().getStanzaId());
|
||||
assertEquals("3", collector.nextResultBlockForever().getStanzaId());
|
||||
assertEquals("4", collector.nextResultBlockForever().getStanzaId());
|
||||
assertEquals("5", collector.pollResult().getStanzaId());
|
||||
assertNull(collector.pollResult());
|
||||
|
||||
for (int i=10; i<15; i++)
|
||||
{
|
||||
Stanza testPacket = new TestPacket(i);
|
||||
collector.processStanza(testPacket);
|
||||
}
|
||||
for (int i=10; i<15; i++)
|
||||
{
|
||||
Stanza testPacket = new TestPacket(i);
|
||||
collector.processStanza(testPacket);
|
||||
}
|
||||
|
||||
assertEquals("10", collector.nextResultBlockForever().getStanzaId());
|
||||
assertEquals("11", collector.nextResultBlockForever().getStanzaId());
|
||||
assertEquals("12", collector.nextResultBlockForever().getStanzaId());
|
||||
assertEquals("13", collector.nextResultBlockForever().getStanzaId());
|
||||
assertEquals("14", collector.pollResult().getStanzaId());
|
||||
assertNull(collector.pollResult());
|
||||
assertEquals("10", collector.nextResultBlockForever().getStanzaId());
|
||||
assertEquals("11", collector.nextResultBlockForever().getStanzaId());
|
||||
assertEquals("12", collector.nextResultBlockForever().getStanzaId());
|
||||
assertEquals("13", collector.nextResultBlockForever().getStanzaId());
|
||||
assertEquals("14", collector.pollResult().getStanzaId());
|
||||
assertNull(collector.pollResult());
|
||||
|
||||
assertNull(collector.nextResult(1000));
|
||||
}
|
||||
assertNull(collector.nextResult(1000));
|
||||
}
|
||||
|
||||
/**
|
||||
* Although this doesn't guarentee anything due to the nature of threading, it can potentially
|
||||
* catch problems.
|
||||
*/
|
||||
@Test
|
||||
public void verifyThreadSafety()
|
||||
{
|
||||
int insertCount = 500;
|
||||
final TestStanzaCollector collector = new TestStanzaCollector(null, new OKEverything(), insertCount);
|
||||
@Test
|
||||
public void verifyThreadSafety()
|
||||
{
|
||||
int insertCount = 500;
|
||||
final TestStanzaCollector collector = new TestStanzaCollector(null, new OKEverything(), insertCount);
|
||||
|
||||
Thread consumer1 = new Thread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(3);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
Stanza packet = collector.nextResultBlockForever();
|
||||
// System.out.println(Thread.currentThread().getName() + " packet: " + packet);
|
||||
}
|
||||
}
|
||||
Thread consumer1 = new Thread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(3);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
Stanza packet = collector.nextResultBlockForever();
|
||||
// System.out.println(Thread.currentThread().getName() + " packet: " + packet);
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
consumer1.setName("consumer 1");
|
||||
}
|
||||
});
|
||||
consumer1.setName("consumer 1");
|
||||
|
||||
Thread consumer2 = new Thread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Stanza p = null;
|
||||
Thread consumer2 = new Thread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Stanza p = null;
|
||||
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(3);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
try {
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(3);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
try {
|
||||
p = collector.nextResult(1);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// System.out.println(Thread.currentThread().getName() + " packet: " + p);
|
||||
}
|
||||
while (p != null);
|
||||
}
|
||||
});
|
||||
consumer2.setName("consumer 2");
|
||||
// System.out.println(Thread.currentThread().getName() + " packet: " + p);
|
||||
}
|
||||
while (p != null);
|
||||
}
|
||||
});
|
||||
consumer2.setName("consumer 2");
|
||||
|
||||
Thread consumer3 = new Thread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Stanza p = null;
|
||||
Thread consumer3 = new Thread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Stanza p = null;
|
||||
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(3);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
p = collector.pollResult();
|
||||
// System.out.println(Thread.currentThread().getName() + " packet: " + p);
|
||||
}
|
||||
while (p != null);
|
||||
}
|
||||
});
|
||||
consumer3.setName("consumer 3");
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(3);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
p = collector.pollResult();
|
||||
// System.out.println(Thread.currentThread().getName() + " packet: " + p);
|
||||
}
|
||||
while (p != null);
|
||||
}
|
||||
});
|
||||
consumer3.setName("consumer 3");
|
||||
|
||||
consumer1.start();
|
||||
consumer2.start();
|
||||
consumer3.start();
|
||||
consumer1.start();
|
||||
consumer2.start();
|
||||
consumer3.start();
|
||||
|
||||
for(int i=0; i<insertCount; i++)
|
||||
{
|
||||
collector.processStanza(new TestPacket(i));
|
||||
}
|
||||
for(int i=0; i<insertCount; i++)
|
||||
{
|
||||
collector.processStanza(new TestPacket(i));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Thread.sleep(5000);
|
||||
consumer3.join();
|
||||
consumer2.join();
|
||||
consumer1.interrupt();
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
//We cannot guarantee that this is going to pass due to the possible issue of timing between consumer 1
|
||||
// and main, but the probability is extremely remote.
|
||||
assertNull(collector.pollResult());
|
||||
}
|
||||
try
|
||||
{
|
||||
Thread.sleep(5000);
|
||||
consumer3.join();
|
||||
consumer2.join();
|
||||
consumer1.interrupt();
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
//We cannot guarantee that this is going to pass due to the possible issue of timing between consumer 1
|
||||
// and main, but the probability is extremely remote.
|
||||
assertNull(collector.pollResult());
|
||||
}
|
||||
|
||||
class OKEverything implements StanzaFilter
|
||||
{
|
||||
@Override
|
||||
public boolean accept(Stanza packet)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
class OKEverything implements StanzaFilter
|
||||
{
|
||||
@Override
|
||||
public boolean accept(Stanza packet)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class TestStanzaCollector extends StanzaCollector
|
||||
{
|
||||
protected TestStanzaCollector(XMPPConnection conection, StanzaFilter packetFilter, int size)
|
||||
{
|
||||
super(conection, StanzaCollector.newConfiguration().setStanzaFilter(packetFilter).setSize(size));
|
||||
}
|
||||
}
|
||||
class TestStanzaCollector extends StanzaCollector
|
||||
{
|
||||
protected TestStanzaCollector(XMPPConnection conection, StanzaFilter packetFilter, int size)
|
||||
{
|
||||
super(conection, StanzaCollector.newConfiguration().setStanzaFilter(packetFilter).setSize(size));
|
||||
}
|
||||
}
|
||||
|
||||
class TestPacket extends Stanza
|
||||
{
|
||||
public TestPacket(int i)
|
||||
{
|
||||
setStanzaId(String.valueOf(i));
|
||||
}
|
||||
class TestPacket extends Stanza
|
||||
{
|
||||
public TestPacket(int i)
|
||||
{
|
||||
setStanzaId(String.valueOf(i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toXML()
|
||||
{
|
||||
return "<packetId>" + getStanzaId() + "</packetId>";
|
||||
}
|
||||
@Override
|
||||
public String toXML()
|
||||
{
|
||||
return "<packetId>" + getStanzaId() + "</packetId>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toXML();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.junit.Test;
|
|||
*/
|
||||
public class SHA1Test {
|
||||
|
||||
@Test
|
||||
@Test
|
||||
public void testHash() {
|
||||
// Test null
|
||||
// @TODO - should the StringUtils.hash(String) method be fixed to handle null input?
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.junit.Test;
|
|||
* A test case for the StringUtils class.
|
||||
*/
|
||||
public class StringUtilsTest {
|
||||
@Test
|
||||
@Test
|
||||
public void testEscapeForXml() {
|
||||
String input = null;
|
||||
|
||||
|
@ -67,11 +67,11 @@ public class StringUtilsTest {
|
|||
assertCharSequenceEquals("It's a good day today", StringUtils.escapeForXml(input));
|
||||
}
|
||||
|
||||
public static void assertCharSequenceEquals(CharSequence expected, CharSequence actual) {
|
||||
public static void assertCharSequenceEquals(CharSequence expected, CharSequence actual) {
|
||||
assertEquals(expected.toString(), actual.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test
|
||||
public void testEncodeHex() {
|
||||
String input = "";
|
||||
String output = "";
|
||||
|
@ -84,7 +84,7 @@ public class StringUtilsTest {
|
|||
new String(output.getBytes()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test
|
||||
public void testRandomString() {
|
||||
// Boundary test
|
||||
String result = StringUtils.randomString(-1);
|
||||
|
|
|
@ -203,7 +203,7 @@ public final class EnhancedDebuggerWindow {
|
|||
* a tab panel for each connection that is being debugged.
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private void createDebug() {
|
||||
private void createDebug() {
|
||||
|
||||
frame = new JFrame("Smack Debug Window");
|
||||
|
||||
|
|
|
@ -18,6 +18,6 @@ package org.jivesoftware.smackx.blocking;
|
|||
|
||||
public interface AllJidsUnblockedListener {
|
||||
|
||||
void onAllJidsUnblocked();
|
||||
void onAllJidsUnblocked();
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,6 @@ import org.jxmpp.jid.Jid;
|
|||
|
||||
public interface JidsBlockedListener {
|
||||
|
||||
void onJidsBlocked(List<Jid> blockedJids);
|
||||
void onJidsBlocked(List<Jid> blockedJids);
|
||||
|
||||
}
|
||||
|
|
|
@ -31,27 +31,27 @@ import org.jxmpp.jid.Jid;
|
|||
*/
|
||||
public abstract class FileTransfer {
|
||||
|
||||
private String fileName;
|
||||
private String fileName;
|
||||
|
||||
private String filePath;
|
||||
private String filePath;
|
||||
|
||||
private long fileSize;
|
||||
private long fileSize;
|
||||
|
||||
private Jid peer;
|
||||
private Jid peer;
|
||||
|
||||
private Status status = Status.initial;
|
||||
private Status status = Status.initial;
|
||||
|
||||
private final Object statusMonitor = new Object();
|
||||
|
||||
protected FileTransferNegotiator negotiator;
|
||||
protected FileTransferNegotiator negotiator;
|
||||
|
||||
protected String streamID;
|
||||
protected String streamID;
|
||||
|
||||
protected long amountWritten = -1;
|
||||
protected long amountWritten = -1;
|
||||
|
||||
private Error error;
|
||||
private Error error;
|
||||
|
||||
private Exception exception;
|
||||
private Exception exception;
|
||||
|
||||
/**
|
||||
* Buffer size between input and output
|
||||
|
@ -59,137 +59,137 @@ public abstract class FileTransfer {
|
|||
private static final int BUFFER_SIZE = 8192;
|
||||
|
||||
protected FileTransfer(Jid peer, String streamID,
|
||||
FileTransferNegotiator negotiator) {
|
||||
this.peer = peer;
|
||||
this.streamID = streamID;
|
||||
this.negotiator = negotiator;
|
||||
}
|
||||
FileTransferNegotiator negotiator) {
|
||||
this.peer = peer;
|
||||
this.streamID = streamID;
|
||||
this.negotiator = negotiator;
|
||||
}
|
||||
|
||||
protected void setFileInfo(String fileName, long fileSize) {
|
||||
this.fileName = fileName;
|
||||
this.fileSize = fileSize;
|
||||
}
|
||||
protected void setFileInfo(String fileName, long fileSize) {
|
||||
this.fileName = fileName;
|
||||
this.fileSize = fileSize;
|
||||
}
|
||||
|
||||
protected void setFileInfo(String path, String fileName, long fileSize) {
|
||||
this.filePath = path;
|
||||
this.fileName = fileName;
|
||||
this.fileSize = fileSize;
|
||||
}
|
||||
protected void setFileInfo(String path, String fileName, long fileSize) {
|
||||
this.filePath = path;
|
||||
this.fileName = fileName;
|
||||
this.fileSize = fileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the file being transfered.
|
||||
*
|
||||
* @return Returns the size of the file being transfered.
|
||||
*/
|
||||
public long getFileSize() {
|
||||
return fileSize;
|
||||
}
|
||||
/**
|
||||
* Returns the size of the file being transfered.
|
||||
*
|
||||
* @return Returns the size of the file being transfered.
|
||||
*/
|
||||
public long getFileSize() {
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the file being transfered.
|
||||
*
|
||||
* @return Returns the name of the file being transfered.
|
||||
*/
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
/**
|
||||
* Returns the name of the file being transfered.
|
||||
*
|
||||
* @return Returns the name of the file being transfered.
|
||||
*/
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the local path of the file.
|
||||
*
|
||||
* @return Returns the local path of the file.
|
||||
*/
|
||||
public String getFilePath() {
|
||||
return filePath;
|
||||
}
|
||||
/**
|
||||
* Returns the local path of the file.
|
||||
*
|
||||
* @return Returns the local path of the file.
|
||||
*/
|
||||
public String getFilePath() {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the JID of the peer for this file transfer.
|
||||
*
|
||||
* @return Returns the JID of the peer for this file transfer.
|
||||
*/
|
||||
public Jid getPeer() {
|
||||
return peer;
|
||||
}
|
||||
/**
|
||||
* Returns the JID of the peer for this file transfer.
|
||||
*
|
||||
* @return Returns the JID of the peer for this file transfer.
|
||||
*/
|
||||
public Jid getPeer() {
|
||||
return peer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the progress of the file transfer as a number between 0 and 1.
|
||||
*
|
||||
* @return Returns the progress of the file transfer as a number between 0
|
||||
* and 1.
|
||||
*/
|
||||
public double getProgress() {
|
||||
/**
|
||||
* Returns the progress of the file transfer as a number between 0 and 1.
|
||||
*
|
||||
* @return Returns the progress of the file transfer as a number between 0
|
||||
* and 1.
|
||||
*/
|
||||
public double getProgress() {
|
||||
if (amountWritten <= 0 || fileSize <= 0) {
|
||||
return 0;
|
||||
}
|
||||
return (double) amountWritten / (double) fileSize;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the transfer has been cancelled, if it has stopped because
|
||||
* of a an error, or the transfer completed successfully.
|
||||
*
|
||||
* @return Returns true if the transfer has been cancelled, if it has stopped
|
||||
* because of a an error, or the transfer completed successfully.
|
||||
*/
|
||||
public boolean isDone() {
|
||||
return status == Status.cancelled || status == Status.error
|
||||
|| status == Status.complete || status == Status.refused;
|
||||
}
|
||||
/**
|
||||
* Returns true if the transfer has been cancelled, if it has stopped because
|
||||
* of a an error, or the transfer completed successfully.
|
||||
*
|
||||
* @return Returns true if the transfer has been cancelled, if it has stopped
|
||||
* because of a an error, or the transfer completed successfully.
|
||||
*/
|
||||
public boolean isDone() {
|
||||
return status == Status.cancelled || status == Status.error
|
||||
|| status == Status.complete || status == Status.refused;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current status of the file transfer.
|
||||
*
|
||||
* @return Returns the current status of the file transfer.
|
||||
*/
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
/**
|
||||
* Returns the current status of the file transfer.
|
||||
*
|
||||
* @return Returns the current status of the file transfer.
|
||||
*/
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
protected void setError(Error type) {
|
||||
this.error = type;
|
||||
}
|
||||
protected void setError(Error type) {
|
||||
this.error = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* When {@link #getStatus()} returns that there was an {@link Status#error}
|
||||
* during the transfer, the type of error can be retrieved through this
|
||||
* method.
|
||||
*
|
||||
* @return Returns the type of error that occurred if one has occurred.
|
||||
*/
|
||||
public Error getError() {
|
||||
return error;
|
||||
}
|
||||
/**
|
||||
* When {@link #getStatus()} returns that there was an {@link Status#error}
|
||||
* during the transfer, the type of error can be retrieved through this
|
||||
* method.
|
||||
*
|
||||
* @return Returns the type of error that occurred if one has occurred.
|
||||
*/
|
||||
public Error getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* If an exception occurs asynchronously it will be stored for later
|
||||
* retrieval. If there is an error there maybe an exception set.
|
||||
*
|
||||
* @return The exception that occurred or null if there was no exception.
|
||||
* @see #getError()
|
||||
*/
|
||||
public Exception getException() {
|
||||
return exception;
|
||||
}
|
||||
/**
|
||||
* If an exception occurs asynchronously it will be stored for later
|
||||
* retrieval. If there is an error there maybe an exception set.
|
||||
*
|
||||
* @return The exception that occurred or null if there was no exception.
|
||||
* @see #getError()
|
||||
*/
|
||||
public Exception getException() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
public String getStreamID() {
|
||||
return streamID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the file transfer.
|
||||
*/
|
||||
public abstract void cancel();
|
||||
/**
|
||||
* Cancels the file transfer.
|
||||
*/
|
||||
public abstract void cancel();
|
||||
|
||||
protected void setException(Exception exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
protected void setException(Exception exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
protected void setStatus(Status status) {
|
||||
protected void setStatus(Status status) {
|
||||
synchronized (statusMonitor) {
|
||||
// CHECKSTYLE:OFF
|
||||
this.status = status;
|
||||
}
|
||||
this.status = status;
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
|
||||
|
@ -206,91 +206,91 @@ public abstract class FileTransfer {
|
|||
protected void writeToStream(final InputStream in, final OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
final byte[] b = new byte[BUFFER_SIZE];
|
||||
int count = 0;
|
||||
amountWritten = 0;
|
||||
final byte[] b = new byte[BUFFER_SIZE];
|
||||
int count = 0;
|
||||
amountWritten = 0;
|
||||
|
||||
while ((count = in.read(b)) > 0 && !getStatus().equals(Status.cancelled)) {
|
||||
out.write(b, 0, count);
|
||||
amountWritten += count;
|
||||
}
|
||||
|
||||
// the connection was likely terminated abruptly if these are not equal
|
||||
if (!getStatus().equals(Status.cancelled) && getError() == Error.none
|
||||
&& amountWritten != fileSize) {
|
||||
// the connection was likely terminated abruptly if these are not equal
|
||||
if (!getStatus().equals(Status.cancelled) && getError() == Error.none
|
||||
&& amountWritten != fileSize) {
|
||||
setStatus(Status.error);
|
||||
this.error = Error.connection;
|
||||
}
|
||||
}
|
||||
this.error = Error.connection;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class to represent the current status of the file transfer.
|
||||
*
|
||||
* @author Alexander Wenckus
|
||||
*
|
||||
*/
|
||||
public enum Status {
|
||||
/**
|
||||
* A class to represent the current status of the file transfer.
|
||||
*
|
||||
* @author Alexander Wenckus
|
||||
*
|
||||
*/
|
||||
public enum Status {
|
||||
|
||||
/**
|
||||
* An error occurred during the transfer.
|
||||
*
|
||||
* @see FileTransfer#getError()
|
||||
*/
|
||||
error("Error"),
|
||||
/**
|
||||
* An error occurred during the transfer.
|
||||
*
|
||||
* @see FileTransfer#getError()
|
||||
*/
|
||||
error("Error"),
|
||||
|
||||
/**
|
||||
/**
|
||||
* The initial status of the file transfer.
|
||||
*/
|
||||
initial("Initial"),
|
||||
|
||||
/**
|
||||
* The file transfer is being negotiated with the peer. The party
|
||||
* Receiving the file has the option to accept or refuse a file transfer
|
||||
* request. If they accept, then the process of stream negotiation will
|
||||
* begin. If they refuse the file will not be transfered.
|
||||
*
|
||||
* @see #negotiating_stream
|
||||
*/
|
||||
negotiating_transfer("Negotiating Transfer"),
|
||||
* The file transfer is being negotiated with the peer. The party
|
||||
* Receiving the file has the option to accept or refuse a file transfer
|
||||
* request. If they accept, then the process of stream negotiation will
|
||||
* begin. If they refuse the file will not be transfered.
|
||||
*
|
||||
* @see #negotiating_stream
|
||||
*/
|
||||
negotiating_transfer("Negotiating Transfer"),
|
||||
|
||||
/**
|
||||
* The peer has refused the file transfer request halting the file
|
||||
* transfer negotiation process.
|
||||
*/
|
||||
refused("Refused"),
|
||||
/**
|
||||
* The peer has refused the file transfer request halting the file
|
||||
* transfer negotiation process.
|
||||
*/
|
||||
refused("Refused"),
|
||||
|
||||
/**
|
||||
* The stream to transfer the file is being negotiated over the chosen
|
||||
* stream type. After the stream negotiating process is complete the
|
||||
* status becomes negotiated.
|
||||
*
|
||||
* @see #negotiated
|
||||
*/
|
||||
negotiating_stream("Negotiating Stream"),
|
||||
/**
|
||||
* The stream to transfer the file is being negotiated over the chosen
|
||||
* stream type. After the stream negotiating process is complete the
|
||||
* status becomes negotiated.
|
||||
*
|
||||
* @see #negotiated
|
||||
*/
|
||||
negotiating_stream("Negotiating Stream"),
|
||||
|
||||
/**
|
||||
* After the stream negotiation has completed the intermediate state
|
||||
* between the time when the negotiation is finished and the actual
|
||||
* transfer begins.
|
||||
*/
|
||||
negotiated("Negotiated"),
|
||||
/**
|
||||
* After the stream negotiation has completed the intermediate state
|
||||
* between the time when the negotiation is finished and the actual
|
||||
* transfer begins.
|
||||
*/
|
||||
negotiated("Negotiated"),
|
||||
|
||||
/**
|
||||
* The transfer is in progress.
|
||||
*
|
||||
* @see FileTransfer#getProgress()
|
||||
*/
|
||||
in_progress("In Progress"),
|
||||
/**
|
||||
* The transfer is in progress.
|
||||
*
|
||||
* @see FileTransfer#getProgress()
|
||||
*/
|
||||
in_progress("In Progress"),
|
||||
|
||||
/**
|
||||
* The transfer has completed successfully.
|
||||
*/
|
||||
complete("Complete"),
|
||||
/**
|
||||
* The transfer has completed successfully.
|
||||
*/
|
||||
complete("Complete"),
|
||||
|
||||
/**
|
||||
* The file transfer was cancelled.
|
||||
*/
|
||||
cancelled("Cancelled");
|
||||
/**
|
||||
* The file transfer was cancelled.
|
||||
*/
|
||||
cancelled("Cancelled");
|
||||
|
||||
private String status;
|
||||
|
||||
|
@ -312,55 +312,55 @@ public abstract class FileTransfer {
|
|||
}
|
||||
|
||||
public enum Error {
|
||||
/**
|
||||
* No error.
|
||||
*/
|
||||
none("No error"),
|
||||
/**
|
||||
* No error.
|
||||
*/
|
||||
none("No error"),
|
||||
|
||||
/**
|
||||
* The peer did not find any of the provided stream mechanisms
|
||||
* acceptable.
|
||||
*/
|
||||
not_acceptable("The peer did not find any of the provided stream mechanisms acceptable."),
|
||||
/**
|
||||
* The peer did not find any of the provided stream mechanisms
|
||||
* acceptable.
|
||||
*/
|
||||
not_acceptable("The peer did not find any of the provided stream mechanisms acceptable."),
|
||||
|
||||
/**
|
||||
* The provided file to transfer does not exist or could not be read.
|
||||
*/
|
||||
bad_file("The provided file to transfer does not exist or could not be read."),
|
||||
/**
|
||||
* The provided file to transfer does not exist or could not be read.
|
||||
*/
|
||||
bad_file("The provided file to transfer does not exist or could not be read."),
|
||||
|
||||
/**
|
||||
* The remote user did not respond or the connection timed out.
|
||||
*/
|
||||
no_response("The remote user did not respond or the connection timed out."),
|
||||
/**
|
||||
* The remote user did not respond or the connection timed out.
|
||||
*/
|
||||
no_response("The remote user did not respond or the connection timed out."),
|
||||
|
||||
/**
|
||||
* An error occurred over the socket connected to send the file.
|
||||
*/
|
||||
connection("An error occured over the socket connected to send the file."),
|
||||
/**
|
||||
* An error occurred over the socket connected to send the file.
|
||||
*/
|
||||
connection("An error occured over the socket connected to send the file."),
|
||||
|
||||
/**
|
||||
* An error occurred while sending or receiving the file.
|
||||
*/
|
||||
stream("An error occured while sending or recieving the file.");
|
||||
/**
|
||||
* An error occurred while sending or receiving the file.
|
||||
*/
|
||||
stream("An error occured while sending or recieving the file.");
|
||||
|
||||
private final String msg;
|
||||
private final String msg;
|
||||
|
||||
private Error(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
private Error(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a String representation of this error.
|
||||
*
|
||||
* @return Returns a String representation of this error.
|
||||
*/
|
||||
public String getMessage() {
|
||||
return msg;
|
||||
}
|
||||
/**
|
||||
* Returns a String representation of this error.
|
||||
*
|
||||
* @return Returns a String representation of this error.
|
||||
*/
|
||||
public String getMessage() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
public String toString() {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,11 +23,11 @@ package org.jivesoftware.smackx.filetransfer;
|
|||
* @author Alexander Wenckus
|
||||
*/
|
||||
public interface FileTransferListener {
|
||||
/**
|
||||
* A request to send a file has been recieved from another user.
|
||||
*
|
||||
* @param request
|
||||
* The request from the other user.
|
||||
*/
|
||||
public void fileTransferRequest(final FileTransferRequest request);
|
||||
/**
|
||||
* A request to send a file has been recieved from another user.
|
||||
*
|
||||
* @param request
|
||||
* The request from the other user.
|
||||
*/
|
||||
public void fileTransferRequest(final FileTransferRequest request);
|
||||
}
|
||||
|
|
|
@ -56,20 +56,20 @@ public final class FileTransferManager extends Manager {
|
|||
return fileTransferManager;
|
||||
}
|
||||
|
||||
private final FileTransferNegotiator fileTransferNegotiator;
|
||||
private final FileTransferNegotiator fileTransferNegotiator;
|
||||
|
||||
private final List<FileTransferListener> listeners = new CopyOnWriteArrayList<FileTransferListener>();
|
||||
private final List<FileTransferListener> listeners = new CopyOnWriteArrayList<FileTransferListener>();
|
||||
|
||||
/**
|
||||
* Creates a file transfer manager to initiate and receive file transfers.
|
||||
*
|
||||
* @param connection
|
||||
* The XMPPConnection that the file transfers will use.
|
||||
*/
|
||||
private FileTransferManager(XMPPConnection connection) {
|
||||
super(connection);
|
||||
this.fileTransferNegotiator = FileTransferNegotiator
|
||||
.getInstanceFor(connection);
|
||||
/**
|
||||
* Creates a file transfer manager to initiate and receive file transfers.
|
||||
*
|
||||
* @param connection
|
||||
* The XMPPConnection that the file transfers will use.
|
||||
*/
|
||||
private FileTransferManager(XMPPConnection connection) {
|
||||
super(connection);
|
||||
this.fileTransferNegotiator = FileTransferNegotiator
|
||||
.getInstanceFor(connection);
|
||||
connection.registerIQRequestHandler(new AbstractIqRequestHandler(StreamInitiation.ELEMENT,
|
||||
StreamInitiation.NAMESPACE, IQ.Type.set, Mode.async) {
|
||||
@Override
|
||||
|
@ -82,42 +82,42 @@ public final class FileTransferManager extends Manager {
|
|||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a file transfer listener to listen to incoming file transfer
|
||||
* requests.
|
||||
*
|
||||
* @param li
|
||||
* The listener
|
||||
* @see #removeFileTransferListener(FileTransferListener)
|
||||
* @see FileTransferListener
|
||||
*/
|
||||
public void addFileTransferListener(final FileTransferListener li) {
|
||||
listeners.add(li);
|
||||
}
|
||||
/**
|
||||
* Add a file transfer listener to listen to incoming file transfer
|
||||
* requests.
|
||||
*
|
||||
* @param li
|
||||
* The listener
|
||||
* @see #removeFileTransferListener(FileTransferListener)
|
||||
* @see FileTransferListener
|
||||
*/
|
||||
public void addFileTransferListener(final FileTransferListener li) {
|
||||
listeners.add(li);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a file transfer listener.
|
||||
*
|
||||
* @param li
|
||||
* The file transfer listener to be removed
|
||||
* @see FileTransferListener
|
||||
*/
|
||||
public void removeFileTransferListener(final FileTransferListener li) {
|
||||
listeners.remove(li);
|
||||
}
|
||||
/**
|
||||
* Removes a file transfer listener.
|
||||
*
|
||||
* @param li
|
||||
* The file transfer listener to be removed
|
||||
* @see FileTransferListener
|
||||
*/
|
||||
public void removeFileTransferListener(final FileTransferListener li) {
|
||||
listeners.remove(li);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an OutgoingFileTransfer to send a file to another user.
|
||||
*
|
||||
* @param userID
|
||||
* The fully qualified jabber ID (i.e. full JID) with resource of the user to
|
||||
* send the file to.
|
||||
* @return The send file object on which the negotiated transfer can be run.
|
||||
* @exception IllegalArgumentException if userID is null or not a full JID
|
||||
*/
|
||||
public OutgoingFileTransfer createOutgoingFileTransfer(EntityFullJid userID) {
|
||||
/**
|
||||
* Creates an OutgoingFileTransfer to send a file to another user.
|
||||
*
|
||||
* @param userID
|
||||
* The fully qualified jabber ID (i.e. full JID) with resource of the user to
|
||||
* send the file to.
|
||||
* @return The send file object on which the negotiated transfer can be run.
|
||||
* @exception IllegalArgumentException if userID is null or not a full JID
|
||||
*/
|
||||
public OutgoingFileTransfer createOutgoingFileTransfer(EntityFullJid userID) {
|
||||
// We need to create outgoing file transfers with a full JID since this method will later
|
||||
// use XEP-0095 to negotiate the stream. This is done with IQ stanzas that need to be addressed to a full JID
|
||||
// in order to reach an client entity.
|
||||
|
@ -125,45 +125,45 @@ public final class FileTransferManager extends Manager {
|
|||
throw new IllegalArgumentException("userID was null");
|
||||
}
|
||||
|
||||
return new OutgoingFileTransfer(connection().getUser(), userID,
|
||||
FileTransferNegotiator.getNextStreamID(),
|
||||
fileTransferNegotiator);
|
||||
}
|
||||
|
||||
/**
|
||||
* When the file transfer request is acceptable, this method should be
|
||||
* invoked. It will create an IncomingFileTransfer which allows the
|
||||
* transmission of the file to procede.
|
||||
*
|
||||
* @param request
|
||||
* The remote request that is being accepted.
|
||||
* @return The IncomingFileTransfer which manages the download of the file
|
||||
* from the transfer initiator.
|
||||
*/
|
||||
protected IncomingFileTransfer createIncomingFileTransfer(
|
||||
FileTransferRequest request) {
|
||||
if (request == null) {
|
||||
throw new NullPointerException("RecieveRequest cannot be null");
|
||||
}
|
||||
|
||||
IncomingFileTransfer transfer = new IncomingFileTransfer(request,
|
||||
return new OutgoingFileTransfer(connection().getUser(), userID,
|
||||
FileTransferNegotiator.getNextStreamID(),
|
||||
fileTransferNegotiator);
|
||||
transfer.setFileInfo(request.getFileName(), request.getFileSize());
|
||||
}
|
||||
|
||||
return transfer;
|
||||
}
|
||||
/**
|
||||
* When the file transfer request is acceptable, this method should be
|
||||
* invoked. It will create an IncomingFileTransfer which allows the
|
||||
* transmission of the file to procede.
|
||||
*
|
||||
* @param request
|
||||
* The remote request that is being accepted.
|
||||
* @return The IncomingFileTransfer which manages the download of the file
|
||||
* from the transfer initiator.
|
||||
*/
|
||||
protected IncomingFileTransfer createIncomingFileTransfer(
|
||||
FileTransferRequest request) {
|
||||
if (request == null) {
|
||||
throw new NullPointerException("RecieveRequest cannot be null");
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject an incoming file transfer.
|
||||
* <p>
|
||||
* Specified in XEP-95 4.2 and 3.2 Example 8
|
||||
* </p>
|
||||
* @param request
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
protected void rejectIncomingFileTransfer(FileTransferRequest request) throws NotConnectedException, InterruptedException {
|
||||
StreamInitiation initiation = request.getStreamInitiation();
|
||||
IncomingFileTransfer transfer = new IncomingFileTransfer(request,
|
||||
fileTransferNegotiator);
|
||||
transfer.setFileInfo(request.getFileName(), request.getFileSize());
|
||||
|
||||
return transfer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject an incoming file transfer.
|
||||
* <p>
|
||||
* Specified in XEP-95 4.2 and 3.2 Example 8
|
||||
* </p>
|
||||
* @param request
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
protected void rejectIncomingFileTransfer(FileTransferRequest request) throws NotConnectedException, InterruptedException {
|
||||
StreamInitiation initiation = request.getStreamInitiation();
|
||||
|
||||
// Reject as specified in XEP-95 4.2. Note that this is not to be confused with the Socks 5
|
||||
// Bytestream rejection as specified in XEP-65 5.3.1 Example 13, which says that
|
||||
|
@ -172,5 +172,5 @@ public final class FileTransferManager extends Manager {
|
|||
IQ rejection = IQ.createErrorResponse(initiation, XMPPError.getBuilder(
|
||||
XMPPError.Condition.forbidden));
|
||||
connection().sendStanza(rejection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,113 +27,113 @@ import org.jxmpp.jid.Jid;
|
|||
*
|
||||
*/
|
||||
public class FileTransferRequest {
|
||||
private final StreamInitiation streamInitiation;
|
||||
private final StreamInitiation streamInitiation;
|
||||
|
||||
private final FileTransferManager manager;
|
||||
private final FileTransferManager manager;
|
||||
|
||||
/**
|
||||
* A recieve request is constructed from the Stream Initiation request
|
||||
* received from the initator.
|
||||
*
|
||||
* @param manager
|
||||
* The manager handling this file transfer
|
||||
*
|
||||
* @param si
|
||||
* The Stream initiaton recieved from the initiator.
|
||||
*/
|
||||
public FileTransferRequest(FileTransferManager manager, StreamInitiation si) {
|
||||
this.streamInitiation = si;
|
||||
this.manager = manager;
|
||||
}
|
||||
/**
|
||||
* A recieve request is constructed from the Stream Initiation request
|
||||
* received from the initator.
|
||||
*
|
||||
* @param manager
|
||||
* The manager handling this file transfer
|
||||
*
|
||||
* @param si
|
||||
* The Stream initiaton recieved from the initiator.
|
||||
*/
|
||||
public FileTransferRequest(FileTransferManager manager, StreamInitiation si) {
|
||||
this.streamInitiation = si;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the file.
|
||||
*
|
||||
* @return Returns the name of the file.
|
||||
*/
|
||||
public String getFileName() {
|
||||
return streamInitiation.getFile().getName();
|
||||
}
|
||||
/**
|
||||
* Returns the name of the file.
|
||||
*
|
||||
* @return Returns the name of the file.
|
||||
*/
|
||||
public String getFileName() {
|
||||
return streamInitiation.getFile().getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size in bytes of the file.
|
||||
*
|
||||
* @return Returns the size in bytes of the file.
|
||||
*/
|
||||
public long getFileSize() {
|
||||
return streamInitiation.getFile().getSize();
|
||||
}
|
||||
/**
|
||||
* Returns the size in bytes of the file.
|
||||
*
|
||||
* @return Returns the size in bytes of the file.
|
||||
*/
|
||||
public long getFileSize() {
|
||||
return streamInitiation.getFile().getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the description of the file provided by the requestor.
|
||||
*
|
||||
* @return Returns the description of the file provided by the requestor.
|
||||
*/
|
||||
public String getDescription() {
|
||||
return streamInitiation.getFile().getDesc();
|
||||
}
|
||||
/**
|
||||
* Returns the description of the file provided by the requestor.
|
||||
*
|
||||
* @return Returns the description of the file provided by the requestor.
|
||||
*/
|
||||
public String getDescription() {
|
||||
return streamInitiation.getFile().getDesc();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mime-type of the file.
|
||||
*
|
||||
* @return Returns the mime-type of the file.
|
||||
*/
|
||||
public String getMimeType() {
|
||||
return streamInitiation.getMimeType();
|
||||
}
|
||||
/**
|
||||
* Returns the mime-type of the file.
|
||||
*
|
||||
* @return Returns the mime-type of the file.
|
||||
*/
|
||||
public String getMimeType() {
|
||||
return streamInitiation.getMimeType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fully-qualified jabber ID of the user that requested this
|
||||
* file transfer.
|
||||
*
|
||||
* @return Returns the fully-qualified jabber ID of the user that requested
|
||||
* this file transfer.
|
||||
*/
|
||||
public Jid getRequestor() {
|
||||
return streamInitiation.getFrom();
|
||||
}
|
||||
/**
|
||||
* Returns the fully-qualified jabber ID of the user that requested this
|
||||
* file transfer.
|
||||
*
|
||||
* @return Returns the fully-qualified jabber ID of the user that requested
|
||||
* this file transfer.
|
||||
*/
|
||||
public Jid getRequestor() {
|
||||
return streamInitiation.getFrom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stream ID that uniquely identifies this file transfer.
|
||||
*
|
||||
* @return Returns the stream ID that uniquely identifies this file
|
||||
* transfer.
|
||||
*/
|
||||
public String getStreamID() {
|
||||
return streamInitiation.getSessionID();
|
||||
}
|
||||
/**
|
||||
* Returns the stream ID that uniquely identifies this file transfer.
|
||||
*
|
||||
* @return Returns the stream ID that uniquely identifies this file
|
||||
* transfer.
|
||||
*/
|
||||
public String getStreamID() {
|
||||
return streamInitiation.getSessionID();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stream initiation stanza(/packet) that was sent by the requestor which
|
||||
* contains the parameters of the file transfer being transfer and also the
|
||||
* methods available to transfer the file.
|
||||
*
|
||||
* @return Returns the stream initiation stanza(/packet) that was sent by the
|
||||
* requestor which contains the parameters of the file transfer
|
||||
* being transfer and also the methods available to transfer the
|
||||
* file.
|
||||
*/
|
||||
protected StreamInitiation getStreamInitiation() {
|
||||
return streamInitiation;
|
||||
}
|
||||
/**
|
||||
* Returns the stream initiation stanza(/packet) that was sent by the requestor which
|
||||
* contains the parameters of the file transfer being transfer and also the
|
||||
* methods available to transfer the file.
|
||||
*
|
||||
* @return Returns the stream initiation stanza(/packet) that was sent by the
|
||||
* requestor which contains the parameters of the file transfer
|
||||
* being transfer and also the methods available to transfer the
|
||||
* file.
|
||||
*/
|
||||
protected StreamInitiation getStreamInitiation() {
|
||||
return streamInitiation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts this file transfer and creates the incoming file transfer.
|
||||
*
|
||||
* @return Returns the <b><i>IncomingFileTransfer</b></i> on which the
|
||||
* file transfer can be carried out.
|
||||
*/
|
||||
public IncomingFileTransfer accept() {
|
||||
return manager.createIncomingFileTransfer(this);
|
||||
}
|
||||
/**
|
||||
* Accepts this file transfer and creates the incoming file transfer.
|
||||
*
|
||||
* @return Returns the <b><i>IncomingFileTransfer</b></i> on which the
|
||||
* file transfer can be carried out.
|
||||
*/
|
||||
public IncomingFileTransfer accept() {
|
||||
return manager.createIncomingFileTransfer(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rejects the file transfer request.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void reject() throws NotConnectedException, InterruptedException {
|
||||
manager.rejectIncomingFileTransfer(this);
|
||||
}
|
||||
/**
|
||||
* Rejects the file transfer request.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void reject() throws NotConnectedException, InterruptedException {
|
||||
manager.rejectIncomingFileTransfer(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ import org.jxmpp.jid.Jid;
|
|||
public class OutgoingFileTransfer extends FileTransfer {
|
||||
private static final Logger LOGGER = Logger.getLogger(OutgoingFileTransfer.class.getName());
|
||||
|
||||
private static int RESPONSE_TIMEOUT = 60 * 1000;
|
||||
private static int RESPONSE_TIMEOUT = 60 * 1000;
|
||||
private NegotiationProgress callback;
|
||||
|
||||
/**
|
||||
|
@ -58,349 +58,349 @@ public class OutgoingFileTransfer extends FileTransfer {
|
|||
return RESPONSE_TIMEOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time in milliseconds after which the file transfer negotiation
|
||||
* process will timeout if the other user has not responded.
|
||||
*
|
||||
* @param responseTimeout
|
||||
* The timeout time in milliseconds.
|
||||
*/
|
||||
public static void setResponseTimeout(int responseTimeout) {
|
||||
RESPONSE_TIMEOUT = responseTimeout;
|
||||
}
|
||||
/**
|
||||
* Sets the time in milliseconds after which the file transfer negotiation
|
||||
* process will timeout if the other user has not responded.
|
||||
*
|
||||
* @param responseTimeout
|
||||
* The timeout time in milliseconds.
|
||||
*/
|
||||
public static void setResponseTimeout(int responseTimeout) {
|
||||
RESPONSE_TIMEOUT = responseTimeout;
|
||||
}
|
||||
|
||||
private OutputStream outputStream;
|
||||
private OutputStream outputStream;
|
||||
|
||||
private Jid initiator;
|
||||
private Jid initiator;
|
||||
|
||||
private Thread transferThread;
|
||||
private Thread transferThread;
|
||||
|
||||
protected OutgoingFileTransfer(Jid initiator, Jid target,
|
||||
String streamID, FileTransferNegotiator transferNegotiator) {
|
||||
super(target, streamID, transferNegotiator);
|
||||
this.initiator = initiator;
|
||||
}
|
||||
protected OutgoingFileTransfer(Jid initiator, Jid target,
|
||||
String streamID, FileTransferNegotiator transferNegotiator) {
|
||||
super(target, streamID, transferNegotiator);
|
||||
this.initiator = initiator;
|
||||
}
|
||||
|
||||
protected void setOutputStream(OutputStream stream) {
|
||||
if (outputStream == null) {
|
||||
this.outputStream = stream;
|
||||
}
|
||||
}
|
||||
protected void setOutputStream(OutputStream stream) {
|
||||
if (outputStream == null) {
|
||||
this.outputStream = stream;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the output stream connected to the peer to transfer the file. It
|
||||
* is only available after it has been successfully negotiated by the
|
||||
* {@link StreamNegotiator}.
|
||||
*
|
||||
* @return Returns the output stream connected to the peer to transfer the
|
||||
* file.
|
||||
*/
|
||||
protected OutputStream getOutputStream() {
|
||||
if (getStatus().equals(FileTransfer.Status.negotiated)) {
|
||||
return outputStream;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns the output stream connected to the peer to transfer the file. It
|
||||
* is only available after it has been successfully negotiated by the
|
||||
* {@link StreamNegotiator}.
|
||||
*
|
||||
* @return Returns the output stream connected to the peer to transfer the
|
||||
* file.
|
||||
*/
|
||||
protected OutputStream getOutputStream() {
|
||||
if (getStatus().equals(FileTransfer.Status.negotiated)) {
|
||||
return outputStream;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method handles the negotiation of the file transfer and the stream,
|
||||
* it only returns the created stream after the negotiation has been completed.
|
||||
*
|
||||
* @param fileName
|
||||
* The name of the file that will be transmitted. It is
|
||||
* preferable for this name to have an extension as it will be
|
||||
* used to determine the type of file it is.
|
||||
* @param fileSize
|
||||
* The size in bytes of the file that will be transmitted.
|
||||
* @param description
|
||||
* A description of the file that will be transmitted.
|
||||
* @return The OutputStream that is connected to the peer to transmit the
|
||||
* file.
|
||||
* @throws XMPPException
|
||||
* Thrown if an error occurs during the file transfer
|
||||
* negotiation process.
|
||||
* @throws SmackException if there was no response from the server.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public synchronized OutputStream sendFile(String fileName, long fileSize,
|
||||
String description) throws XMPPException, SmackException, InterruptedException {
|
||||
if (isDone() || outputStream != null) {
|
||||
throw new IllegalStateException(
|
||||
"The negotation process has already"
|
||||
+ " been attempted on this file transfer");
|
||||
}
|
||||
try {
|
||||
setFileInfo(fileName, fileSize);
|
||||
this.outputStream = negotiateStream(fileName, fileSize, description);
|
||||
} catch (XMPPErrorException e) {
|
||||
handleXMPPException(e);
|
||||
throw e;
|
||||
}
|
||||
return outputStream;
|
||||
}
|
||||
/**
|
||||
* This method handles the negotiation of the file transfer and the stream,
|
||||
* it only returns the created stream after the negotiation has been completed.
|
||||
*
|
||||
* @param fileName
|
||||
* The name of the file that will be transmitted. It is
|
||||
* preferable for this name to have an extension as it will be
|
||||
* used to determine the type of file it is.
|
||||
* @param fileSize
|
||||
* The size in bytes of the file that will be transmitted.
|
||||
* @param description
|
||||
* A description of the file that will be transmitted.
|
||||
* @return The OutputStream that is connected to the peer to transmit the
|
||||
* file.
|
||||
* @throws XMPPException
|
||||
* Thrown if an error occurs during the file transfer
|
||||
* negotiation process.
|
||||
* @throws SmackException if there was no response from the server.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public synchronized OutputStream sendFile(String fileName, long fileSize,
|
||||
String description) throws XMPPException, SmackException, InterruptedException {
|
||||
if (isDone() || outputStream != null) {
|
||||
throw new IllegalStateException(
|
||||
"The negotation process has already"
|
||||
+ " been attempted on this file transfer");
|
||||
}
|
||||
try {
|
||||
setFileInfo(fileName, fileSize);
|
||||
this.outputStream = negotiateStream(fileName, fileSize, description);
|
||||
} catch (XMPPErrorException e) {
|
||||
handleXMPPException(e);
|
||||
throw e;
|
||||
}
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* This methods handles the transfer and stream negotiation process. It
|
||||
* returns immediately and its progress will be updated through the
|
||||
* {@link NegotiationProgress} callback.
|
||||
*
|
||||
* @param fileName
|
||||
* The name of the file that will be transmitted. It is
|
||||
* preferable for this name to have an extension as it will be
|
||||
* used to determine the type of file it is.
|
||||
* @param fileSize
|
||||
* The size in bytes of the file that will be transmitted.
|
||||
* @param description
|
||||
* A description of the file that will be transmitted.
|
||||
* @param progress
|
||||
* A callback to monitor the progress of the file transfer
|
||||
* negotiation process and to retrieve the OutputStream when it
|
||||
* is complete.
|
||||
*/
|
||||
public synchronized void sendFile(final String fileName,
|
||||
final long fileSize, final String description,
|
||||
final NegotiationProgress progress)
|
||||
/**
|
||||
* This methods handles the transfer and stream negotiation process. It
|
||||
* returns immediately and its progress will be updated through the
|
||||
* {@link NegotiationProgress} callback.
|
||||
*
|
||||
* @param fileName
|
||||
* The name of the file that will be transmitted. It is
|
||||
* preferable for this name to have an extension as it will be
|
||||
* used to determine the type of file it is.
|
||||
* @param fileSize
|
||||
* The size in bytes of the file that will be transmitted.
|
||||
* @param description
|
||||
* A description of the file that will be transmitted.
|
||||
* @param progress
|
||||
* A callback to monitor the progress of the file transfer
|
||||
* negotiation process and to retrieve the OutputStream when it
|
||||
* is complete.
|
||||
*/
|
||||
public synchronized void sendFile(final String fileName,
|
||||
final long fileSize, final String description,
|
||||
final NegotiationProgress progress)
|
||||
{
|
||||
if(progress == null) {
|
||||
throw new IllegalArgumentException("Callback progress cannot be null.");
|
||||
}
|
||||
checkTransferThread();
|
||||
if (isDone() || outputStream != null) {
|
||||
throw new IllegalStateException(
|
||||
"The negotation process has already"
|
||||
+ " been attempted for this file transfer");
|
||||
}
|
||||
if (isDone() || outputStream != null) {
|
||||
throw new IllegalStateException(
|
||||
"The negotation process has already"
|
||||
+ " been attempted for this file transfer");
|
||||
}
|
||||
setFileInfo(fileName, fileSize);
|
||||
this.callback = progress;
|
||||
transferThread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
OutgoingFileTransfer.this.outputStream = negotiateStream(
|
||||
fileName, fileSize, description);
|
||||
public void run() {
|
||||
try {
|
||||
OutgoingFileTransfer.this.outputStream = negotiateStream(
|
||||
fileName, fileSize, description);
|
||||
progress.outputStreamEstablished(OutgoingFileTransfer.this.outputStream);
|
||||
}
|
||||
catch (XMPPErrorException e) {
|
||||
handleXMPPException(e);
|
||||
}
|
||||
handleXMPPException(e);
|
||||
}
|
||||
catch (Exception e) {
|
||||
setException(e);
|
||||
}
|
||||
}
|
||||
}, "File Transfer Negotiation " + streamID);
|
||||
transferThread.start();
|
||||
}
|
||||
}
|
||||
}, "File Transfer Negotiation " + streamID);
|
||||
transferThread.start();
|
||||
}
|
||||
|
||||
private void checkTransferThread() {
|
||||
if (transferThread != null && transferThread.isAlive() || isDone()) {
|
||||
throw new IllegalStateException(
|
||||
"File transfer in progress or has already completed.");
|
||||
}
|
||||
}
|
||||
private void checkTransferThread() {
|
||||
if (transferThread != null && transferThread.isAlive() || isDone()) {
|
||||
throw new IllegalStateException(
|
||||
"File transfer in progress or has already completed.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method handles the stream negotiation process and transmits the file
|
||||
* to the remote user. It returns immediately and the progress of the file
|
||||
* transfer can be monitored through several methods:
|
||||
*
|
||||
* <UL>
|
||||
* <LI>{@link FileTransfer#getStatus()}
|
||||
* <LI>{@link FileTransfer#getProgress()}
|
||||
* <LI>{@link FileTransfer#isDone()}
|
||||
* </UL>
|
||||
*
|
||||
* This method handles the stream negotiation process and transmits the file
|
||||
* to the remote user. It returns immediately and the progress of the file
|
||||
* transfer can be monitored through several methods:
|
||||
*
|
||||
* <UL>
|
||||
* <LI>{@link FileTransfer#getStatus()}
|
||||
* <LI>{@link FileTransfer#getProgress()}
|
||||
* <LI>{@link FileTransfer#isDone()}
|
||||
* </UL>
|
||||
*
|
||||
* @param file the file to transfer to the remote entity.
|
||||
* @param description a description for the file to transfer.
|
||||
* @throws SmackException
|
||||
* If there is an error during the negotiation process or the
|
||||
* sending of the file.
|
||||
*/
|
||||
public synchronized void sendFile(final File file, final String description)
|
||||
throws SmackException {
|
||||
checkTransferThread();
|
||||
if (file == null || !file.exists() || !file.canRead()) {
|
||||
throw new IllegalArgumentException("Could not read file");
|
||||
} else {
|
||||
setFileInfo(file.getAbsolutePath(), file.getName(), file.length());
|
||||
}
|
||||
* @throws SmackException
|
||||
* If there is an error during the negotiation process or the
|
||||
* sending of the file.
|
||||
*/
|
||||
public synchronized void sendFile(final File file, final String description)
|
||||
throws SmackException {
|
||||
checkTransferThread();
|
||||
if (file == null || !file.exists() || !file.canRead()) {
|
||||
throw new IllegalArgumentException("Could not read file");
|
||||
} else {
|
||||
setFileInfo(file.getAbsolutePath(), file.getName(), file.length());
|
||||
}
|
||||
|
||||
transferThread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
outputStream = negotiateStream(file.getName(), file
|
||||
.length(), description);
|
||||
} catch (XMPPErrorException e) {
|
||||
handleXMPPException(e);
|
||||
return;
|
||||
}
|
||||
transferThread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
outputStream = negotiateStream(file.getName(), file
|
||||
.length(), description);
|
||||
} catch (XMPPErrorException e) {
|
||||
handleXMPPException(e);
|
||||
return;
|
||||
}
|
||||
catch (Exception e) {
|
||||
setException(e);
|
||||
}
|
||||
if (outputStream == null) {
|
||||
return;
|
||||
}
|
||||
if (outputStream == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!updateStatus(Status.negotiated, Status.in_progress)) {
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = new FileInputStream(file);
|
||||
writeToStream(inputStream, outputStream);
|
||||
} catch (FileNotFoundException e) {
|
||||
setStatus(FileTransfer.Status.error);
|
||||
setError(Error.bad_file);
|
||||
setException(e);
|
||||
} catch (IOException e) {
|
||||
setStatus(FileTransfer.Status.error);
|
||||
setException(e);
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = new FileInputStream(file);
|
||||
writeToStream(inputStream, outputStream);
|
||||
} catch (FileNotFoundException e) {
|
||||
setStatus(FileTransfer.Status.error);
|
||||
setError(Error.bad_file);
|
||||
setException(e);
|
||||
} catch (IOException e) {
|
||||
setStatus(FileTransfer.Status.error);
|
||||
setException(e);
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.WARNING, "Closing input stream", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.WARNING, "Closing output stream", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
updateStatus(Status.in_progress, FileTransfer.Status.complete);
|
||||
}
|
||||
}
|
||||
|
||||
}, "File Transfer " + streamID);
|
||||
transferThread.start();
|
||||
}
|
||||
}, "File Transfer " + streamID);
|
||||
transferThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method handles the stream negotiation process and transmits the file
|
||||
* to the remote user. It returns immediately and the progress of the file
|
||||
* transfer can be monitored through several methods:
|
||||
*
|
||||
* <UL>
|
||||
* <LI>{@link FileTransfer#getStatus()}
|
||||
* <LI>{@link FileTransfer#getProgress()}
|
||||
* <LI>{@link FileTransfer#isDone()}
|
||||
* </UL>
|
||||
*
|
||||
* This method handles the stream negotiation process and transmits the file
|
||||
* to the remote user. It returns immediately and the progress of the file
|
||||
* transfer can be monitored through several methods:
|
||||
*
|
||||
* <UL>
|
||||
* <LI>{@link FileTransfer#getStatus()}
|
||||
* <LI>{@link FileTransfer#getProgress()}
|
||||
* <LI>{@link FileTransfer#isDone()}
|
||||
* </UL>
|
||||
*
|
||||
* @param in the stream to transfer to the remote entity.
|
||||
* @param fileName the name of the file that is transferred
|
||||
* @param fileSize the size of the file that is transferred
|
||||
* @param description a description for the file to transfer.
|
||||
*/
|
||||
public synchronized void sendStream(final InputStream in, final String fileName, final long fileSize, final String description){
|
||||
checkTransferThread();
|
||||
*/
|
||||
public synchronized void sendStream(final InputStream in, final String fileName, final long fileSize, final String description){
|
||||
checkTransferThread();
|
||||
|
||||
setFileInfo(fileName, fileSize);
|
||||
transferThread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
setFileInfo(fileName, fileSize);
|
||||
transferThread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
//Create packet filter
|
||||
try {
|
||||
outputStream = negotiateStream(fileName, fileSize, description);
|
||||
} catch (XMPPErrorException e) {
|
||||
handleXMPPException(e);
|
||||
return;
|
||||
}
|
||||
outputStream = negotiateStream(fileName, fileSize, description);
|
||||
} catch (XMPPErrorException e) {
|
||||
handleXMPPException(e);
|
||||
return;
|
||||
}
|
||||
catch (Exception e) {
|
||||
setException(e);
|
||||
}
|
||||
if (outputStream == null) {
|
||||
return;
|
||||
}
|
||||
if (outputStream == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!updateStatus(Status.negotiated, Status.in_progress)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
writeToStream(in, outputStream);
|
||||
} catch (IOException e) {
|
||||
setStatus(FileTransfer.Status.error);
|
||||
setException(e);
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
writeToStream(in, outputStream);
|
||||
} catch (IOException e) {
|
||||
setStatus(FileTransfer.Status.error);
|
||||
setException(e);
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
/* Do Nothing */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
updateStatus(Status.in_progress, FileTransfer.Status.complete);
|
||||
}
|
||||
}
|
||||
|
||||
}, "File Transfer " + streamID);
|
||||
transferThread.start();
|
||||
}
|
||||
}, "File Transfer " + streamID);
|
||||
transferThread.start();
|
||||
}
|
||||
|
||||
private void handleXMPPException(XMPPErrorException e) {
|
||||
XMPPError error = e.getXMPPError();
|
||||
if (error != null) {
|
||||
switch (error.getCondition()) {
|
||||
case forbidden:
|
||||
setStatus(Status.refused);
|
||||
return;
|
||||
case bad_request:
|
||||
setStatus(Status.error);
|
||||
setError(Error.not_acceptable);
|
||||
break;
|
||||
private void handleXMPPException(XMPPErrorException e) {
|
||||
XMPPError error = e.getXMPPError();
|
||||
if (error != null) {
|
||||
switch (error.getCondition()) {
|
||||
case forbidden:
|
||||
setStatus(Status.refused);
|
||||
return;
|
||||
case bad_request:
|
||||
setStatus(Status.error);
|
||||
setError(Error.not_acceptable);
|
||||
break;
|
||||
default:
|
||||
setStatus(FileTransfer.Status.error);
|
||||
}
|
||||
}
|
||||
|
||||
setException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of bytes that have been sent for the file transfer. Or
|
||||
* -1 if the file transfer has not started.
|
||||
* <p>
|
||||
* Note: This method is only useful when the {@link #sendFile(File, String)}
|
||||
* method is called, as it is the only method that actually transmits the
|
||||
* file.
|
||||
*
|
||||
* @return Returns the amount of bytes that have been sent for the file
|
||||
* transfer. Or -1 if the file transfer has not started.
|
||||
*/
|
||||
public long getBytesSent() {
|
||||
return amountWritten;
|
||||
}
|
||||
/**
|
||||
* Returns the amount of bytes that have been sent for the file transfer. Or
|
||||
* -1 if the file transfer has not started.
|
||||
* <p>
|
||||
* Note: This method is only useful when the {@link #sendFile(File, String)}
|
||||
* method is called, as it is the only method that actually transmits the
|
||||
* file.
|
||||
*
|
||||
* @return Returns the amount of bytes that have been sent for the file
|
||||
* transfer. Or -1 if the file transfer has not started.
|
||||
*/
|
||||
public long getBytesSent() {
|
||||
return amountWritten;
|
||||
}
|
||||
|
||||
private OutputStream negotiateStream(String fileName, long fileSize,
|
||||
String description) throws SmackException, XMPPException, InterruptedException {
|
||||
// Negotiate the file transfer profile
|
||||
private OutputStream negotiateStream(String fileName, long fileSize,
|
||||
String description) throws SmackException, XMPPException, InterruptedException {
|
||||
// Negotiate the file transfer profile
|
||||
|
||||
if (!updateStatus(Status.initial, Status.negotiating_transfer)) {
|
||||
throw new IllegalStateChangeException();
|
||||
}
|
||||
StreamNegotiator streamNegotiator = negotiator.negotiateOutgoingTransfer(
|
||||
getPeer(), streamID, fileName, fileSize, description,
|
||||
RESPONSE_TIMEOUT);
|
||||
StreamNegotiator streamNegotiator = negotiator.negotiateOutgoingTransfer(
|
||||
getPeer(), streamID, fileName, fileSize, description,
|
||||
RESPONSE_TIMEOUT);
|
||||
|
||||
// Negotiate the stream
|
||||
if (!updateStatus(Status.negotiating_transfer, Status.negotiating_stream)) {
|
||||
throw new IllegalStateChangeException();
|
||||
}
|
||||
outputStream = streamNegotiator.createOutgoingStream(streamID,
|
||||
outputStream = streamNegotiator.createOutgoingStream(streamID,
|
||||
initiator, getPeer());
|
||||
|
||||
if (!updateStatus(Status.negotiating_stream, Status.negotiated)) {
|
||||
throw new IllegalStateChangeException();
|
||||
}
|
||||
return outputStream;
|
||||
}
|
||||
}
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
setStatus(Status.cancelled);
|
||||
}
|
||||
public void cancel() {
|
||||
setStatus(Status.cancelled);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateStatus(Status oldStatus, Status newStatus) {
|
||||
|
@ -429,30 +429,30 @@ public class OutgoingFileTransfer extends FileTransfer {
|
|||
}
|
||||
|
||||
/**
|
||||
* A callback class to retrieve the status of an outgoing transfer
|
||||
* negotiation process.
|
||||
*
|
||||
* @author Alexander Wenckus
|
||||
*
|
||||
*/
|
||||
public interface NegotiationProgress {
|
||||
* A callback class to retrieve the status of an outgoing transfer
|
||||
* negotiation process.
|
||||
*
|
||||
* @author Alexander Wenckus
|
||||
*
|
||||
*/
|
||||
public interface NegotiationProgress {
|
||||
|
||||
/**
|
||||
* Called when the status changes.
|
||||
/**
|
||||
* Called when the status changes.
|
||||
*
|
||||
* @param oldStatus the previous status of the file transfer.
|
||||
* @param newStatus the new status of the file transfer.
|
||||
*/
|
||||
void statusUpdated(Status oldStatus, Status newStatus);
|
||||
void statusUpdated(Status oldStatus, Status newStatus);
|
||||
|
||||
/**
|
||||
* Once the negotiation process is completed the output stream can be
|
||||
* retrieved.
|
||||
/**
|
||||
* Once the negotiation process is completed the output stream can be
|
||||
* retrieved.
|
||||
*
|
||||
* @param stream the established stream which can be used to transfer the file to the remote
|
||||
* entity
|
||||
*/
|
||||
void outputStreamEstablished(OutputStream stream);
|
||||
*/
|
||||
void outputStreamEstablished(OutputStream stream);
|
||||
|
||||
/**
|
||||
* Called when an exception occurs during the negotiation progress.
|
||||
|
|
|
@ -71,6 +71,6 @@ public class RegistrationProvider extends IQProvider<Registration> {
|
|||
Registration registration = new Registration(instruction, fields);
|
||||
registration.addExtensions(packetExtensions);
|
||||
return registration;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,77 +31,77 @@ import org.xmlpull.v1.XmlPullParserException;
|
|||
*/
|
||||
public class Nick implements ExtensionElement {
|
||||
|
||||
public static final String NAMESPACE = "http://jabber.org/protocol/nick";
|
||||
public static final String NAMESPACE = "http://jabber.org/protocol/nick";
|
||||
|
||||
public static final String ELEMENT_NAME = "nick";
|
||||
public static final String ELEMENT_NAME = "nick";
|
||||
|
||||
private String name = null;
|
||||
private String name = null;
|
||||
|
||||
public Nick(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public Nick(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of this nickname.
|
||||
*
|
||||
* @return the nickname
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
/**
|
||||
* The value of this nickname.
|
||||
*
|
||||
* @return the nickname
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this nickname.
|
||||
*
|
||||
* @param name
|
||||
* the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
/**
|
||||
* Sets the value of this nickname.
|
||||
*
|
||||
* @param name
|
||||
* the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.jivesoftware.smack.packet.PacketExtension#getElementName()
|
||||
*/
|
||||
public String getElementName() {
|
||||
return ELEMENT_NAME;
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.jivesoftware.smack.packet.PacketExtension#getElementName()
|
||||
*/
|
||||
public String getElementName() {
|
||||
return ELEMENT_NAME;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.jivesoftware.smack.packet.PacketExtension#getNamespace()
|
||||
*/
|
||||
public String getNamespace() {
|
||||
return NAMESPACE;
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.jivesoftware.smack.packet.PacketExtension#getNamespace()
|
||||
*/
|
||||
public String getNamespace() {
|
||||
return NAMESPACE;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.jivesoftware.smack.packet.PacketExtension#toXML()
|
||||
*/
|
||||
public String toXML() {
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.jivesoftware.smack.packet.PacketExtension#toXML()
|
||||
*/
|
||||
public String toXML() {
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
|
||||
buf.append('<').append(ELEMENT_NAME).append(" xmlns=\"").append(
|
||||
NAMESPACE).append("\">");
|
||||
buf.append(getName());
|
||||
buf.append("</").append(ELEMENT_NAME).append('>');
|
||||
buf.append('<').append(ELEMENT_NAME).append(" xmlns=\"").append(
|
||||
NAMESPACE).append("\">");
|
||||
buf.append(getName());
|
||||
buf.append("</").append(ELEMENT_NAME).append('>');
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static class Provider extends ExtensionElementProvider<Nick> {
|
||||
public static class Provider extends ExtensionElementProvider<Nick> {
|
||||
|
||||
@Override
|
||||
public Nick parse(XmlPullParser parser, int initialDepth)
|
||||
throws XmlPullParserException, IOException {
|
||||
final String name = parser.nextText();
|
||||
final String name = parser.nextText();
|
||||
|
||||
return new Nick(name);
|
||||
}
|
||||
}
|
||||
return new Nick(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ public final class PrivacyListManager extends Manager {
|
|||
*
|
||||
* @param connection the XMPP connection.
|
||||
*/
|
||||
private PrivacyListManager(XMPPConnection connection) {
|
||||
private PrivacyListManager(XMPPConnection connection) {
|
||||
super(connection);
|
||||
|
||||
connection.registerIQRequestHandler(new AbstractIqRequestHandler(Privacy.ELEMENT, Privacy.NAMESPACE,
|
||||
|
@ -215,24 +215,24 @@ public final class PrivacyListManager extends Manager {
|
|||
return plm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the {@link Privacy} stanza(/packet) to the server in order to know some privacy content and then
|
||||
* waits for the answer.
|
||||
*
|
||||
* @param requestPrivacy is the {@link Privacy} stanza(/packet) configured properly whose XML
|
||||
/**
|
||||
* Send the {@link Privacy} stanza(/packet) to the server in order to know some privacy content and then
|
||||
* waits for the answer.
|
||||
*
|
||||
* @param requestPrivacy is the {@link Privacy} stanza(/packet) configured properly whose XML
|
||||
* will be sent to the server.
|
||||
* @return a new {@link Privacy} with the data received from the server.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
private Privacy getRequest(Privacy requestPrivacy) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request is a get iq type
|
||||
requestPrivacy.setType(Privacy.Type.get);
|
||||
* @return a new {@link Privacy} with the data received from the server.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
private Privacy getRequest(Privacy requestPrivacy) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request is a get iq type
|
||||
requestPrivacy.setType(Privacy.Type.get);
|
||||
|
||||
return connection().createStanzaCollectorAndSend(requestPrivacy).nextResultOrThrow();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the {@link Privacy} stanza(/packet) to the server in order to modify the server privacy and waits
|
||||
|
@ -253,22 +253,22 @@ public final class PrivacyListManager extends Manager {
|
|||
return connection().createStanzaCollectorAndSend(requestPrivacy).nextResultOrThrow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer a privacy containing the list structure without {@link PrivacyItem}.
|
||||
*
|
||||
* @return a Privacy with the list names.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
private Privacy getPrivacyWithListNames() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an empty privacy message
|
||||
Privacy request = new Privacy();
|
||||
/**
|
||||
* Answer a privacy containing the list structure without {@link PrivacyItem}.
|
||||
*
|
||||
* @return a Privacy with the list names.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
private Privacy getPrivacyWithListNames() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an empty privacy message
|
||||
Privacy request = new Privacy();
|
||||
|
||||
// Send the package to the server and get the answer
|
||||
return getRequest(request);
|
||||
}
|
||||
// Send the package to the server and get the answer
|
||||
return getRequest(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer the active privacy list. Returns <code>null</code> if there is no active list.
|
||||
|
@ -386,20 +386,20 @@ public final class PrivacyListManager extends Manager {
|
|||
return privacyAnswer.getPrivacyList(listName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer the privacy list items under listName with the allowed and blocked permissions.
|
||||
*
|
||||
* @param listName the name of the list to get the allowed and blocked permissions.
|
||||
* @return a privacy list under the list listName.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public PrivacyList getPrivacyList(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
/**
|
||||
* Answer the privacy list items under listName with the allowed and blocked permissions.
|
||||
*
|
||||
* @param listName the name of the list to get the allowed and blocked permissions.
|
||||
* @return a privacy list under the list listName.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public PrivacyList getPrivacyList(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
listName = StringUtils.requireNotNullOrEmpty(listName, "List name must not be null");
|
||||
return new PrivacyList(false, false, listName, getPrivacyListItems(listName));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer every privacy list with the allowed and blocked permissions.
|
||||
|
@ -423,87 +423,87 @@ public final class PrivacyListManager extends Manager {
|
|||
return lists;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or change the active list to listName.
|
||||
*
|
||||
* @param listName the list name to set as the active one.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void setActiveListName(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setActiveName(listName);
|
||||
/**
|
||||
* Set or change the active list to listName.
|
||||
*
|
||||
* @param listName the list name to set as the active one.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void setActiveListName(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setActiveName(listName);
|
||||
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Client declines the use of active lists.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void declineActiveList() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setDeclineActiveList(true);
|
||||
/**
|
||||
* Client declines the use of active lists.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void declineActiveList() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setDeclineActiveList(true);
|
||||
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or change the default list to listName.
|
||||
*
|
||||
* @param listName the list name to set as the default one.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void setDefaultListName(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setDefaultName(listName);
|
||||
/**
|
||||
* Set or change the default list to listName.
|
||||
*
|
||||
* @param listName the list name to set as the default one.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void setDefaultListName(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setDefaultName(listName);
|
||||
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Client declines the use of default lists.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void declineDefaultList() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setDeclineDefaultList(true);
|
||||
/**
|
||||
* Client declines the use of default lists.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void declineDefaultList() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setDeclineDefaultList(true);
|
||||
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* The client has created a new list. It send the new one to the server.
|
||||
*
|
||||
/**
|
||||
* The client has created a new list. It send the new one to the server.
|
||||
*
|
||||
* @param listName the list that has changed its content.
|
||||
* @param privacyItems a List with every privacy item in the list.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void createPrivacyList(String listName, List<PrivacyItem> privacyItems) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
updatePrivacyList(listName, privacyItems);
|
||||
}
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void createPrivacyList(String listName, List<PrivacyItem> privacyItems) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
updatePrivacyList(listName, privacyItems);
|
||||
}
|
||||
|
||||
/**
|
||||
* The client has edited an existing list. It updates the server content with the resulting
|
||||
|
@ -526,23 +526,23 @@ public final class PrivacyListManager extends Manager {
|
|||
setRequest(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a privacy list.
|
||||
*
|
||||
/**
|
||||
* Remove a privacy list.
|
||||
*
|
||||
* @param listName the list that has changed its content.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void deletePrivacyList(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setPrivacyList(listName, new ArrayList<PrivacyItem>());
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void deletePrivacyList(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setPrivacyList(listName, new ArrayList<PrivacyItem>());
|
||||
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a privacy list listener that will be notified of any new update in the user
|
||||
|
|
|
@ -45,17 +45,17 @@ public class Privacy extends IQ {
|
|||
public static final String ELEMENT = QUERY_ELEMENT;
|
||||
public static final String NAMESPACE = "jabber:iq:privacy";
|
||||
|
||||
/** declineActiveList is true when the user declines the use of the active list **/
|
||||
private boolean declineActiveList=false;
|
||||
/** activeName is the name associated with the active list set for the session **/
|
||||
private String activeName;
|
||||
/** declineDefaultList is true when the user declines the use of the default list **/
|
||||
private boolean declineDefaultList=false;
|
||||
/** defaultName is the name of the default list that applies to the user as a whole **/
|
||||
private String defaultName;
|
||||
/** itemLists holds the set of privacy items classified in lists. It is a map where the
|
||||
* key is the name of the list and the value a collection with privacy items. **/
|
||||
private Map<String, List<PrivacyItem>> itemLists = new HashMap<String, List<PrivacyItem>>();
|
||||
/** declineActiveList is true when the user declines the use of the active list **/
|
||||
private boolean declineActiveList=false;
|
||||
/** activeName is the name associated with the active list set for the session **/
|
||||
private String activeName;
|
||||
/** declineDefaultList is true when the user declines the use of the default list **/
|
||||
private boolean declineDefaultList=false;
|
||||
/** defaultName is the name of the default list that applies to the user as a whole **/
|
||||
private String defaultName;
|
||||
/** itemLists holds the set of privacy items classified in lists. It is a map where the
|
||||
* key is the name of the list and the value a collection with privacy items. **/
|
||||
private Map<String, List<PrivacyItem>> itemLists = new HashMap<String, List<PrivacyItem>>();
|
||||
|
||||
public Privacy() {
|
||||
super(ELEMENT, NAMESPACE);
|
||||
|
@ -94,13 +94,13 @@ public class Privacy extends IQ {
|
|||
public void deletePrivacyList(String listName) {
|
||||
// Remove the list from the cache
|
||||
// CHECKSTYLE:OFF
|
||||
this.getItemLists().remove(listName);
|
||||
this.getItemLists().remove(listName);
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
// Check if deleted list was the default list
|
||||
if (this.getDefaultName() != null && listName.equals(this.getDefaultName())) {
|
||||
// CHECKSTYLE:OFF
|
||||
this.setDefaultName(null);
|
||||
this.setDefaultName(null);
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
}
|
||||
|
@ -114,9 +114,9 @@ public class Privacy extends IQ {
|
|||
// Check if we have the default list
|
||||
// CHECKSTYLE:OFF
|
||||
if (this.getActiveName() == null) {
|
||||
return null;
|
||||
return null;
|
||||
} else {
|
||||
return this.getItemLists().get(this.getActiveName());
|
||||
return this.getItemLists().get(this.getActiveName());
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
|
@ -130,9 +130,9 @@ public class Privacy extends IQ {
|
|||
// Check if we have the default list
|
||||
// CHECKSTYLE:OFF
|
||||
if (this.getDefaultName() == null) {
|
||||
return null;
|
||||
return null;
|
||||
} else {
|
||||
return this.getItemLists().get(this.getDefaultName());
|
||||
return this.getItemLists().get(this.getDefaultName());
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
|
@ -156,15 +156,15 @@ public class Privacy extends IQ {
|
|||
*/
|
||||
public PrivacyItem getItem(String listName, int order) {
|
||||
// CHECKSTYLE:OFF
|
||||
Iterator<PrivacyItem> values = getPrivacyList(listName).iterator();
|
||||
PrivacyItem itemFound = null;
|
||||
while (itemFound == null && values.hasNext()) {
|
||||
PrivacyItem element = values.next();
|
||||
if (element.getOrder() == order) {
|
||||
itemFound = element;
|
||||
}
|
||||
}
|
||||
return itemFound;
|
||||
Iterator<PrivacyItem> values = getPrivacyList(listName).iterator();
|
||||
PrivacyItem itemFound = null;
|
||||
while (itemFound == null && values.hasNext()) {
|
||||
PrivacyItem element = values.next();
|
||||
if (element.getOrder() == order) {
|
||||
itemFound = element;
|
||||
}
|
||||
}
|
||||
return itemFound;
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ public class Privacy extends IQ {
|
|||
return true;
|
||||
} else {
|
||||
// CHECKSTYLE:OFF
|
||||
return false;
|
||||
return false;
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ public class Privacy extends IQ {
|
|||
*/
|
||||
public void deleteList(String listName) {
|
||||
// CHECKSTYLE:OFF
|
||||
this.getItemLists().remove(listName);
|
||||
this.getItemLists().remove(listName);
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
|
||||
|
@ -203,9 +203,9 @@ public class Privacy extends IQ {
|
|||
* @return the name of the active list.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public String getActiveName() {
|
||||
return activeName;
|
||||
}
|
||||
public String getActiveName() {
|
||||
return activeName;
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
/**
|
||||
|
@ -215,9 +215,9 @@ public class Privacy extends IQ {
|
|||
* @param activeName is the name of the active list.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public void setActiveName(String activeName) {
|
||||
this.activeName = activeName;
|
||||
}
|
||||
public void setActiveName(String activeName) {
|
||||
this.activeName = activeName;
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
/**
|
||||
|
@ -228,9 +228,9 @@ public class Privacy extends IQ {
|
|||
* @return the name of the default list.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public String getDefaultName() {
|
||||
return defaultName;
|
||||
}
|
||||
public String getDefaultName() {
|
||||
return defaultName;
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
/**
|
||||
|
@ -243,9 +243,9 @@ public class Privacy extends IQ {
|
|||
* @param defaultName is the name of the default list.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public void setDefaultName(String defaultName) {
|
||||
this.defaultName = defaultName;
|
||||
}
|
||||
public void setDefaultName(String defaultName) {
|
||||
this.defaultName = defaultName;
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
/**
|
||||
|
@ -257,9 +257,9 @@ public class Privacy extends IQ {
|
|||
* collection of privacy items.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public Map<String, List<PrivacyItem>> getItemLists() {
|
||||
return itemLists;
|
||||
}
|
||||
public Map<String, List<PrivacyItem>> getItemLists() {
|
||||
return itemLists;
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
/**
|
||||
|
@ -268,9 +268,9 @@ public class Privacy extends IQ {
|
|||
* @return the decline status of the list.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public boolean isDeclineActiveList() {
|
||||
return declineActiveList;
|
||||
}
|
||||
public boolean isDeclineActiveList() {
|
||||
return declineActiveList;
|
||||
}
|
||||
// CHECKSYTLE:ON
|
||||
|
||||
/**
|
||||
|
@ -279,9 +279,9 @@ public class Privacy extends IQ {
|
|||
* @param declineActiveList indicates if the receiver declines the use of an active list.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public void setDeclineActiveList(boolean declineActiveList) {
|
||||
this.declineActiveList = declineActiveList;
|
||||
}
|
||||
public void setDeclineActiveList(boolean declineActiveList) {
|
||||
this.declineActiveList = declineActiveList;
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
/**
|
||||
|
@ -290,9 +290,9 @@ public class Privacy extends IQ {
|
|||
* @return the decline status of the list.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public boolean isDeclineDefaultList() {
|
||||
return declineDefaultList;
|
||||
}
|
||||
public boolean isDeclineDefaultList() {
|
||||
return declineDefaultList;
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
/**
|
||||
|
@ -301,18 +301,18 @@ public class Privacy extends IQ {
|
|||
* @param declineDefaultList indicates if the receiver declines the use of a default list.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public void setDeclineDefaultList(boolean declineDefaultList) {
|
||||
this.declineDefaultList = declineDefaultList;
|
||||
}
|
||||
public void setDeclineDefaultList(boolean declineDefaultList) {
|
||||
this.declineDefaultList = declineDefaultList;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns all the list names the user has defined to group restrictions.
|
||||
*
|
||||
* @return a Set with Strings containing every list names.
|
||||
*/
|
||||
public Set<String> getPrivacyListNames() {
|
||||
return this.itemLists.keySet();
|
||||
}
|
||||
public Set<String> getPrivacyListNames() {
|
||||
return this.itemLists.keySet();
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
@Override
|
||||
|
@ -322,40 +322,40 @@ public class Privacy extends IQ {
|
|||
|
||||
// Add the active tag
|
||||
if (this.isDeclineActiveList()) {
|
||||
buf.append("<active/>");
|
||||
buf.append("<active/>");
|
||||
} else {
|
||||
if (this.getActiveName() != null) {
|
||||
if (this.getActiveName() != null) {
|
||||
buf.append("<active name=\"").escape(getActiveName()).append("\"/>");
|
||||
}
|
||||
}
|
||||
// Add the default tag
|
||||
if (this.isDeclineDefaultList()) {
|
||||
buf.append("<default/>");
|
||||
buf.append("<default/>");
|
||||
} else {
|
||||
if (this.getDefaultName() != null) {
|
||||
if (this.getDefaultName() != null) {
|
||||
buf.append("<default name=\"").escape(getDefaultName()).append("\"/>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the list with their privacy items
|
||||
for (Map.Entry<String, List<PrivacyItem>> entry : this.getItemLists().entrySet()) {
|
||||
String listName = entry.getKey();
|
||||
List<PrivacyItem> items = entry.getValue();
|
||||
// Begin the list tag
|
||||
if (items.isEmpty()) {
|
||||
// Begin the list tag
|
||||
if (items.isEmpty()) {
|
||||
buf.append("<list name=\"").escape(listName).append("\"/>");
|
||||
} else {
|
||||
} else {
|
||||
buf.append("<list name=\"").escape(listName).append("\">");
|
||||
}
|
||||
for (PrivacyItem item : items) {
|
||||
// Append the item xml representation
|
||||
buf.append(item.toXML());
|
||||
}
|
||||
// Close the list tag
|
||||
if (!items.isEmpty()) {
|
||||
buf.append("</list>");
|
||||
}
|
||||
}
|
||||
}
|
||||
for (PrivacyItem item : items) {
|
||||
// Append the item xml representation
|
||||
buf.append(item.toXML());
|
||||
}
|
||||
// Close the list tag
|
||||
if (!items.isEmpty()) {
|
||||
buf.append("</list>");
|
||||
}
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
return buf;
|
||||
}
|
||||
|
|
|
@ -47,20 +47,20 @@ public class PrivacyProvider extends IQProvider<Privacy> {
|
|||
if (eventType == XmlPullParser.START_TAG) {
|
||||
// CHECKSTYLE:OFF
|
||||
if (parser.getName().equals("active")) {
|
||||
String activeName = parser.getAttributeValue("", "name");
|
||||
if (activeName == null) {
|
||||
privacy.setDeclineActiveList(true);
|
||||
} else {
|
||||
privacy.setActiveName(activeName);
|
||||
}
|
||||
String activeName = parser.getAttributeValue("", "name");
|
||||
if (activeName == null) {
|
||||
privacy.setDeclineActiveList(true);
|
||||
} else {
|
||||
privacy.setActiveName(activeName);
|
||||
}
|
||||
}
|
||||
else if (parser.getName().equals("default")) {
|
||||
String defaultName = parser.getAttributeValue("", "name");
|
||||
if (defaultName == null) {
|
||||
privacy.setDeclineDefaultList(true);
|
||||
} else {
|
||||
privacy.setDefaultName(defaultName);
|
||||
}
|
||||
String defaultName = parser.getAttributeValue("", "name");
|
||||
if (defaultName == null) {
|
||||
privacy.setDeclineDefaultList(true);
|
||||
} else {
|
||||
privacy.setDefaultName(defaultName);
|
||||
}
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
else if (parser.getName().equals("list")) {
|
||||
|
@ -75,10 +75,10 @@ public class PrivacyProvider extends IQProvider<Privacy> {
|
|||
}
|
||||
|
||||
return privacy;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the list complex type
|
||||
private static void parseList(XmlPullParser parser, Privacy privacy) throws XmlPullParserException, IOException, SmackException {
|
||||
// Parse the list complex type
|
||||
private static void parseList(XmlPullParser parser, Privacy privacy) throws XmlPullParserException, IOException, SmackException {
|
||||
boolean done = false;
|
||||
String listName = parser.getAttributeValue("", "name");
|
||||
ArrayList<PrivacyItem> items = new ArrayList<PrivacyItem>();
|
||||
|
@ -87,7 +87,7 @@ public class PrivacyProvider extends IQProvider<Privacy> {
|
|||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("item")) {
|
||||
// CHECKSTYLE:OFF
|
||||
items.add(parseItem(parser));
|
||||
items.add(parseItem(parser));
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
}
|
||||
|
@ -100,10 +100,10 @@ public class PrivacyProvider extends IQProvider<Privacy> {
|
|||
|
||||
privacy.setPrivacyList(listName, items);
|
||||
// CHECKSTYLE:OFF
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the list complex type
|
||||
private static PrivacyItem parseItem(XmlPullParser parser) throws XmlPullParserException, IOException, SmackException {
|
||||
// Parse the list complex type
|
||||
private static PrivacyItem parseItem(XmlPullParser parser) throws XmlPullParserException, IOException, SmackException {
|
||||
// CHECKSTYLE:ON
|
||||
// Retrieves the required attributes
|
||||
String actionValue = parser.getAttributeValue("", "action");
|
||||
|
@ -142,7 +142,7 @@ public class PrivacyProvider extends IQProvider<Privacy> {
|
|||
parseItemChildElements(parser, item);
|
||||
return item;
|
||||
// CHECKSTYLE:OFF
|
||||
}
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
private static void parseItemChildElements(XmlPullParser parser, PrivacyItem privacyItem) throws XmlPullParserException, IOException {
|
||||
|
|
|
@ -24,18 +24,18 @@ package org.jivesoftware.smackx.pubsub;
|
|||
*/
|
||||
public enum AccessModel
|
||||
{
|
||||
/** Anyone may subscribe and retrieve items. */
|
||||
open,
|
||||
/** Anyone may subscribe and retrieve items. */
|
||||
open,
|
||||
|
||||
/** Subscription request must be approved and only subscribers may retrieve items. */
|
||||
authorize,
|
||||
/** Subscription request must be approved and only subscribers may retrieve items. */
|
||||
authorize,
|
||||
|
||||
/** Anyone with a presence subscription of both or from may subscribe and retrieve items. */
|
||||
presence,
|
||||
/** Anyone with a presence subscription of both or from may subscribe and retrieve items. */
|
||||
presence,
|
||||
|
||||
/** Anyone in the specified roster group(s) may subscribe and retrieve items. */
|
||||
roster,
|
||||
/** Anyone in the specified roster group(s) may subscribe and retrieve items. */
|
||||
roster,
|
||||
|
||||
/** Only those on a whitelist may subscribe and retrieve items. */
|
||||
whitelist;
|
||||
/** Only those on a whitelist may subscribe and retrieve items. */
|
||||
whitelist;
|
||||
}
|
||||
|
|
|
@ -42,17 +42,17 @@ public class Affiliation implements ExtensionElement
|
|||
private final Type affiliation;
|
||||
private final PubSubNamespace namespace;
|
||||
|
||||
public enum Type
|
||||
{
|
||||
member, none, outcast, owner, publisher
|
||||
}
|
||||
public enum Type
|
||||
{
|
||||
member, none, outcast, owner, publisher
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an affiliation.
|
||||
*
|
||||
* @param node The node the user is affiliated with.
|
||||
* @param affiliation the optional affiliation.
|
||||
*/
|
||||
/**
|
||||
* Constructs an affiliation.
|
||||
*
|
||||
* @param node The node the user is affiliated with.
|
||||
* @param affiliation the optional affiliation.
|
||||
*/
|
||||
public Affiliation(String node, Type affiliation) {
|
||||
this.node = StringUtils.requireNotNullOrEmpty(node, "node must not be null or empty");
|
||||
this.affiliation = affiliation;
|
||||
|
|
|
@ -30,8 +30,8 @@ import org.jivesoftware.smack.util.XmlStringBuilder;
|
|||
*/
|
||||
public class AffiliationsExtension extends NodeExtension
|
||||
{
|
||||
protected List<Affiliation> items = Collections.emptyList();
|
||||
private final String node;
|
||||
protected List<Affiliation> items = Collections.emptyList();
|
||||
private final String node;
|
||||
|
||||
public AffiliationsExtension() {
|
||||
this(null, null);
|
||||
|
@ -47,20 +47,20 @@ public class AffiliationsExtension extends NodeExtension
|
|||
this.node = node;
|
||||
}
|
||||
|
||||
public List<Affiliation> getAffiliations()
|
||||
{
|
||||
return items;
|
||||
}
|
||||
public List<Affiliation> getAffiliations()
|
||||
{
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence toXML()
|
||||
{
|
||||
if ((items == null) || (items.size() == 0))
|
||||
{
|
||||
return super.toXML();
|
||||
}
|
||||
else
|
||||
{
|
||||
@Override
|
||||
public CharSequence toXML()
|
||||
{
|
||||
if ((items == null) || (items.size() == 0))
|
||||
{
|
||||
return super.toXML();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can't use XmlStringBuilder(this), because we don't want the namespace to be included
|
||||
XmlStringBuilder xml = new XmlStringBuilder();
|
||||
xml.openElement(getElementName());
|
||||
|
@ -69,6 +69,6 @@ public class AffiliationsExtension extends NodeExtension
|
|||
xml.append(items);
|
||||
xml.closeElement(this);
|
||||
return xml;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,12 +24,12 @@ package org.jivesoftware.smackx.pubsub;
|
|||
*/
|
||||
public enum ChildrenAssociationPolicy
|
||||
{
|
||||
/** Anyone may associate leaf nodes with the collection. */
|
||||
all,
|
||||
/** Anyone may associate leaf nodes with the collection. */
|
||||
all,
|
||||
|
||||
/** Only collection node owners may associate leaf nodes with the collection. */
|
||||
owners,
|
||||
/** Only collection node owners may associate leaf nodes with the collection. */
|
||||
owners,
|
||||
|
||||
/** Only those on a whitelist may associate leaf nodes with the collection. */
|
||||
whitelist;
|
||||
/** Only those on a whitelist may associate leaf nodes with the collection. */
|
||||
whitelist;
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@ package org.jivesoftware.smackx.pubsub;
|
|||
|
||||
public class CollectionNode extends Node
|
||||
{
|
||||
CollectionNode(PubSubManager pubSubManager, String nodeId)
|
||||
{
|
||||
super(pubSubManager, nodeId);
|
||||
}
|
||||
CollectionNode(PubSubManager pubSubManager, String nodeId)
|
||||
{
|
||||
super(pubSubManager, nodeId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,29 +31,29 @@ import org.jivesoftware.smack.packet.ExtensionElement;
|
|||
*/
|
||||
public class ConfigurationEvent extends NodeExtension implements EmbeddedPacketExtension
|
||||
{
|
||||
private ConfigureForm form;
|
||||
private ConfigureForm form;
|
||||
|
||||
public ConfigurationEvent(String nodeId)
|
||||
{
|
||||
super(PubSubElementType.CONFIGURATION, nodeId);
|
||||
}
|
||||
public ConfigurationEvent(String nodeId)
|
||||
{
|
||||
super(PubSubElementType.CONFIGURATION, nodeId);
|
||||
}
|
||||
|
||||
public ConfigurationEvent(String nodeId, ConfigureForm configForm)
|
||||
{
|
||||
super(PubSubElementType.CONFIGURATION, nodeId);
|
||||
form = configForm;
|
||||
}
|
||||
public ConfigurationEvent(String nodeId, ConfigureForm configForm)
|
||||
{
|
||||
super(PubSubElementType.CONFIGURATION, nodeId);
|
||||
form = configForm;
|
||||
}
|
||||
|
||||
public ConfigureForm getConfiguration()
|
||||
{
|
||||
return form;
|
||||
}
|
||||
public ConfigureForm getConfiguration()
|
||||
{
|
||||
return form;
|
||||
}
|
||||
|
||||
public List<ExtensionElement> getExtensions()
|
||||
{
|
||||
if (getConfiguration() == null)
|
||||
return Collections.emptyList();
|
||||
else
|
||||
return Arrays.asList(((ExtensionElement)getConfiguration().getDataFormToSend()));
|
||||
}
|
||||
public List<ExtensionElement> getExtensions()
|
||||
{
|
||||
if (getConfiguration() == null)
|
||||
return Collections.emptyList();
|
||||
else
|
||||
return Arrays.asList(((ExtensionElement)getConfiguration().getDataFormToSend()));
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -29,193 +29,193 @@ import org.jivesoftware.smackx.xdata.Form;
|
|||
*/
|
||||
public enum ConfigureNodeFields
|
||||
{
|
||||
/**
|
||||
* Determines who may subscribe and retrieve items.
|
||||
*
|
||||
* <p><b>Value: {@link AccessModel}</b></p>
|
||||
*/
|
||||
access_model,
|
||||
/**
|
||||
* Determines who may subscribe and retrieve items.
|
||||
*
|
||||
* <p><b>Value: {@link AccessModel}</b></p>
|
||||
*/
|
||||
access_model,
|
||||
|
||||
/**
|
||||
* The URL of an XSL transformation which can be applied to
|
||||
* payloads in order to generate an appropriate message
|
||||
* body element.
|
||||
*
|
||||
* <p><b>Value: {@link URL}</b></p>
|
||||
*/
|
||||
body_xslt,
|
||||
/**
|
||||
* The URL of an XSL transformation which can be applied to
|
||||
* payloads in order to generate an appropriate message
|
||||
* body element.
|
||||
*
|
||||
* <p><b>Value: {@link URL}</b></p>
|
||||
*/
|
||||
body_xslt,
|
||||
|
||||
/**
|
||||
* The collection with which a node is affiliated.
|
||||
*
|
||||
* <p><b>Value: String</b></p>
|
||||
*/
|
||||
collection,
|
||||
/**
|
||||
* The collection with which a node is affiliated.
|
||||
*
|
||||
* <p><b>Value: String</b></p>
|
||||
*/
|
||||
collection,
|
||||
|
||||
/**
|
||||
* The URL of an XSL transformation which can be applied to
|
||||
* payload format in order to generate a valid Data Forms result
|
||||
* that the client could display using a generic Data Forms
|
||||
* rendering engine body element.
|
||||
*
|
||||
* <p><b>Value: {@link URL}</b></p>
|
||||
*/
|
||||
dataform_xslt,
|
||||
/**
|
||||
* The URL of an XSL transformation which can be applied to
|
||||
* payload format in order to generate a valid Data Forms result
|
||||
* that the client could display using a generic Data Forms
|
||||
* rendering engine body element.
|
||||
*
|
||||
* <p><b>Value: {@link URL}</b></p>
|
||||
*/
|
||||
dataform_xslt,
|
||||
|
||||
/**
|
||||
* Whether to deliver payloads with event notifications.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
deliver_payloads,
|
||||
/**
|
||||
* Whether to deliver payloads with event notifications.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
deliver_payloads,
|
||||
|
||||
/**
|
||||
* Whether owners or publisher should receive replies to items.
|
||||
*
|
||||
* <p><b>Value: {@link ItemReply}</b></p>
|
||||
*/
|
||||
itemreply,
|
||||
/**
|
||||
* Whether owners or publisher should receive replies to items.
|
||||
*
|
||||
* <p><b>Value: {@link ItemReply}</b></p>
|
||||
*/
|
||||
itemreply,
|
||||
|
||||
/**
|
||||
* Who may associate leaf nodes with a collection.
|
||||
*
|
||||
* <p><b>Value: {@link ChildrenAssociationPolicy}</b></p>
|
||||
*/
|
||||
children_association_policy,
|
||||
/**
|
||||
* Who may associate leaf nodes with a collection.
|
||||
*
|
||||
* <p><b>Value: {@link ChildrenAssociationPolicy}</b></p>
|
||||
*/
|
||||
children_association_policy,
|
||||
|
||||
/**
|
||||
* The list of JIDs that may associate leaf nodes with a
|
||||
* collection.
|
||||
*
|
||||
* <p><b>Value: List of JIDs as Strings</b></p>
|
||||
*/
|
||||
children_association_whitelist,
|
||||
/**
|
||||
* The list of JIDs that may associate leaf nodes with a
|
||||
* collection.
|
||||
*
|
||||
* <p><b>Value: List of JIDs as Strings</b></p>
|
||||
*/
|
||||
children_association_whitelist,
|
||||
|
||||
/**
|
||||
* The child nodes (leaf or collection) associated with a collection.
|
||||
*
|
||||
* <p><b>Value: List of Strings</b></p>
|
||||
*/
|
||||
children,
|
||||
/**
|
||||
* The child nodes (leaf or collection) associated with a collection.
|
||||
*
|
||||
* <p><b>Value: List of Strings</b></p>
|
||||
*/
|
||||
children,
|
||||
|
||||
/**
|
||||
* The maximum number of child nodes that can be associated with a
|
||||
* collection.
|
||||
*
|
||||
* <p><b>Value: int</b></p>
|
||||
*/
|
||||
children_max,
|
||||
/**
|
||||
* The maximum number of child nodes that can be associated with a
|
||||
* collection.
|
||||
*
|
||||
* <p><b>Value: int</b></p>
|
||||
*/
|
||||
children_max,
|
||||
|
||||
/**
|
||||
* The maximum number of items to persist.
|
||||
*
|
||||
* <p><b>Value: int</b></p>
|
||||
*/
|
||||
max_items,
|
||||
/**
|
||||
* The maximum number of items to persist.
|
||||
*
|
||||
* <p><b>Value: int</b></p>
|
||||
*/
|
||||
max_items,
|
||||
|
||||
/**
|
||||
* The maximum payload size in bytes.
|
||||
*
|
||||
* <p><b>Value: int</b></p>
|
||||
*/
|
||||
max_payload_size,
|
||||
/**
|
||||
* The maximum payload size in bytes.
|
||||
*
|
||||
* <p><b>Value: int</b></p>
|
||||
*/
|
||||
max_payload_size,
|
||||
|
||||
/**
|
||||
* Whether the node is a leaf (default) or collection.
|
||||
*
|
||||
* <p><b>Value: {@link NodeType}</b></p>
|
||||
*/
|
||||
node_type,
|
||||
/**
|
||||
* Whether the node is a leaf (default) or collection.
|
||||
*
|
||||
* <p><b>Value: {@link NodeType}</b></p>
|
||||
*/
|
||||
node_type,
|
||||
|
||||
/**
|
||||
* Whether to notify subscribers when the node configuration changes.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
notify_config,
|
||||
/**
|
||||
* Whether to notify subscribers when the node configuration changes.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
notify_config,
|
||||
|
||||
/**
|
||||
* Whether to notify subscribers when the node is deleted.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
notify_delete,
|
||||
/**
|
||||
* Whether to notify subscribers when the node is deleted.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
notify_delete,
|
||||
|
||||
/**
|
||||
* Whether to notify subscribers when items are removed from the node.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
notify_retract,
|
||||
/**
|
||||
* Whether to notify subscribers when items are removed from the node.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
notify_retract,
|
||||
|
||||
/**
|
||||
* Whether to persist items to storage. This is required to have. multiple
|
||||
* items in the node.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
persist_items,
|
||||
/**
|
||||
* Whether to persist items to storage. This is required to have. multiple
|
||||
* items in the node.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
persist_items,
|
||||
|
||||
/**
|
||||
* Whether to deliver notifications to available users only.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
presence_based_delivery,
|
||||
/**
|
||||
* Whether to deliver notifications to available users only.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
presence_based_delivery,
|
||||
|
||||
/**
|
||||
* Defines who can publish to the node.
|
||||
*
|
||||
* <p><b>Value: {@link PublishModel}</b></p>
|
||||
*/
|
||||
publish_model,
|
||||
/**
|
||||
* Defines who can publish to the node.
|
||||
*
|
||||
* <p><b>Value: {@link PublishModel}</b></p>
|
||||
*/
|
||||
publish_model,
|
||||
|
||||
/**
|
||||
* The specific multi-user chat rooms to specify for replyroom.
|
||||
*
|
||||
* <p><b>Value: List of JIDs as Strings</b></p>
|
||||
*/
|
||||
replyroom,
|
||||
/**
|
||||
* The specific multi-user chat rooms to specify for replyroom.
|
||||
*
|
||||
* <p><b>Value: List of JIDs as Strings</b></p>
|
||||
*/
|
||||
replyroom,
|
||||
|
||||
/**
|
||||
* The specific JID(s) to specify for replyto.
|
||||
*
|
||||
* <p><b>Value: List of JIDs as Strings</b></p>
|
||||
*/
|
||||
replyto,
|
||||
/**
|
||||
* The specific JID(s) to specify for replyto.
|
||||
*
|
||||
* <p><b>Value: List of JIDs as Strings</b></p>
|
||||
*/
|
||||
replyto,
|
||||
|
||||
/**
|
||||
* The roster group(s) allowed to subscribe and retrieve items.
|
||||
*
|
||||
* <p><b>Value: List of strings</b></p>
|
||||
*/
|
||||
roster_groups_allowed,
|
||||
/**
|
||||
* The roster group(s) allowed to subscribe and retrieve items.
|
||||
*
|
||||
* <p><b>Value: List of strings</b></p>
|
||||
*/
|
||||
roster_groups_allowed,
|
||||
|
||||
/**
|
||||
* Whether to allow subscriptions.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
subscribe,
|
||||
/**
|
||||
* Whether to allow subscriptions.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
subscribe,
|
||||
|
||||
/**
|
||||
* A friendly name for the node.
|
||||
*
|
||||
* <p><b>Value: String</b></p>
|
||||
*/
|
||||
title,
|
||||
/**
|
||||
* A friendly name for the node.
|
||||
*
|
||||
* <p><b>Value: String</b></p>
|
||||
*/
|
||||
title,
|
||||
|
||||
/**
|
||||
* The type of node data, ussually specified by the namespace
|
||||
* of the payload(if any);MAY be a list-single rather than a
|
||||
* text single.
|
||||
*
|
||||
* <p><b>Value: String</b></p>
|
||||
*/
|
||||
type;
|
||||
/**
|
||||
* The type of node data, ussually specified by the namespace
|
||||
* of the payload(if any);MAY be a list-single rather than a
|
||||
* text single.
|
||||
*
|
||||
* <p><b>Value: String</b></p>
|
||||
*/
|
||||
type;
|
||||
|
||||
public String getFieldName()
|
||||
{
|
||||
return "pubsub#" + toString();
|
||||
}
|
||||
public String getFieldName()
|
||||
{
|
||||
return "pubsub#" + toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,10 +39,10 @@ import org.jivesoftware.smack.util.PacketParserUtils;
|
|||
*/
|
||||
public interface EmbeddedPacketExtension extends ExtensionElement
|
||||
{
|
||||
/**
|
||||
* Get the list of embedded {@link ExtensionElement} objects.
|
||||
*
|
||||
* @return List of embedded {@link ExtensionElement}
|
||||
*/
|
||||
List<ExtensionElement> getExtensions();
|
||||
/**
|
||||
* Get the list of embedded {@link ExtensionElement} objects.
|
||||
*
|
||||
* @return List of embedded {@link ExtensionElement}
|
||||
*/
|
||||
List<ExtensionElement> getExtensions();
|
||||
}
|
||||
|
|
|
@ -44,39 +44,39 @@ public class EventElement implements EmbeddedPacketExtension
|
|||
*/
|
||||
public static final String NAMESPACE = PubSubNamespace.EVENT.getXmlns();
|
||||
|
||||
private EventElementType type;
|
||||
private NodeExtension ext;
|
||||
private EventElementType type;
|
||||
private NodeExtension ext;
|
||||
|
||||
public EventElement(EventElementType eventType, NodeExtension eventExt)
|
||||
{
|
||||
type = eventType;
|
||||
ext = eventExt;
|
||||
}
|
||||
public EventElement(EventElementType eventType, NodeExtension eventExt)
|
||||
{
|
||||
type = eventType;
|
||||
ext = eventExt;
|
||||
}
|
||||
|
||||
public EventElementType getEventType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
public EventElementType getEventType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public List<ExtensionElement> getExtensions()
|
||||
{
|
||||
return Arrays.asList(new ExtensionElement[]{getEvent()});
|
||||
}
|
||||
public List<ExtensionElement> getExtensions()
|
||||
{
|
||||
return Arrays.asList(new ExtensionElement[]{getEvent()});
|
||||
}
|
||||
|
||||
public NodeExtension getEvent()
|
||||
{
|
||||
return ext;
|
||||
}
|
||||
public NodeExtension getEvent()
|
||||
{
|
||||
return ext;
|
||||
}
|
||||
|
||||
public String getElementName()
|
||||
{
|
||||
return "event";
|
||||
}
|
||||
public String getElementName()
|
||||
{
|
||||
return "event";
|
||||
}
|
||||
|
||||
public String getNamespace()
|
||||
{
|
||||
return PubSubNamespace.EVENT.getXmlns();
|
||||
}
|
||||
public String getNamespace()
|
||||
{
|
||||
return PubSubNamespace.EVENT.getXmlns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlStringBuilder toXML() {
|
||||
|
|
|
@ -24,21 +24,21 @@ package org.jivesoftware.smackx.pubsub;
|
|||
*/
|
||||
public enum EventElementType
|
||||
{
|
||||
/** A node has been associated or dissassociated with a collection node. */
|
||||
collection,
|
||||
/** A node has been associated or dissassociated with a collection node. */
|
||||
collection,
|
||||
|
||||
/** A node has had its configuration changed. */
|
||||
configuration,
|
||||
/** A node has had its configuration changed. */
|
||||
configuration,
|
||||
|
||||
/** A node has been deleted. */
|
||||
delete,
|
||||
/** A node has been deleted. */
|
||||
delete,
|
||||
|
||||
/** Items have been published to a node. */
|
||||
items,
|
||||
/** Items have been published to a node. */
|
||||
items,
|
||||
|
||||
/** All items have been purged from a node. */
|
||||
purge,
|
||||
/** All items have been purged from a node. */
|
||||
purge,
|
||||
|
||||
/** A node has been subscribed to. */
|
||||
subscription
|
||||
/** A node has been subscribed to. */
|
||||
subscription
|
||||
}
|
||||
|
|
|
@ -28,75 +28,75 @@ import org.jivesoftware.smackx.xdata.Form;
|
|||
*/
|
||||
public class FormNode extends NodeExtension
|
||||
{
|
||||
private Form configForm;
|
||||
private Form configForm;
|
||||
|
||||
/**
|
||||
* Create a {@link FormNode} which contains the specified form.
|
||||
*
|
||||
* @param formType The type of form being sent
|
||||
* @param submitForm The form
|
||||
*/
|
||||
public FormNode(FormNodeType formType, Form submitForm)
|
||||
{
|
||||
super(formType.getNodeElement());
|
||||
/**
|
||||
* Create a {@link FormNode} which contains the specified form.
|
||||
*
|
||||
* @param formType The type of form being sent
|
||||
* @param submitForm The form
|
||||
*/
|
||||
public FormNode(FormNodeType formType, Form submitForm)
|
||||
{
|
||||
super(formType.getNodeElement());
|
||||
|
||||
if (submitForm == null)
|
||||
throw new IllegalArgumentException("Submit form cannot be null");
|
||||
configForm = submitForm;
|
||||
}
|
||||
if (submitForm == null)
|
||||
throw new IllegalArgumentException("Submit form cannot be null");
|
||||
configForm = submitForm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link FormNode} which contains the specified form, which is
|
||||
* associated with the specified node.
|
||||
*
|
||||
* @param formType The type of form being sent
|
||||
* @param nodeId The node the form is associated with
|
||||
* @param submitForm The form
|
||||
*/
|
||||
public FormNode(FormNodeType formType, String nodeId, Form submitForm)
|
||||
{
|
||||
super(formType.getNodeElement(), nodeId);
|
||||
/**
|
||||
* Create a {@link FormNode} which contains the specified form, which is
|
||||
* associated with the specified node.
|
||||
*
|
||||
* @param formType The type of form being sent
|
||||
* @param nodeId The node the form is associated with
|
||||
* @param submitForm The form
|
||||
*/
|
||||
public FormNode(FormNodeType formType, String nodeId, Form submitForm)
|
||||
{
|
||||
super(formType.getNodeElement(), nodeId);
|
||||
|
||||
if (submitForm == null)
|
||||
throw new IllegalArgumentException("Submit form cannot be null");
|
||||
configForm = submitForm;
|
||||
}
|
||||
if (submitForm == null)
|
||||
throw new IllegalArgumentException("Submit form cannot be null");
|
||||
configForm = submitForm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Form that is to be sent, or was retrieved from the server.
|
||||
*
|
||||
* @return The form
|
||||
*/
|
||||
public Form getForm()
|
||||
{
|
||||
return configForm;
|
||||
}
|
||||
/**
|
||||
* Get the Form that is to be sent, or was retrieved from the server.
|
||||
*
|
||||
* @return The form
|
||||
*/
|
||||
public Form getForm()
|
||||
{
|
||||
return configForm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence toXML()
|
||||
{
|
||||
if (configForm == null)
|
||||
{
|
||||
return super.toXML();
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder builder = new StringBuilder("<");
|
||||
builder.append(getElementName());
|
||||
@Override
|
||||
public CharSequence toXML()
|
||||
{
|
||||
if (configForm == null)
|
||||
{
|
||||
return super.toXML();
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder builder = new StringBuilder("<");
|
||||
builder.append(getElementName());
|
||||
|
||||
if (getNode() != null)
|
||||
{
|
||||
builder.append(" node='");
|
||||
builder.append(getNode());
|
||||
builder.append("'>");
|
||||
}
|
||||
else
|
||||
builder.append('>');
|
||||
builder.append(configForm.getDataFormToSend().toXML());
|
||||
builder.append("</");
|
||||
builder.append(getElementName() + '>');
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
if (getNode() != null)
|
||||
{
|
||||
builder.append(" node='");
|
||||
builder.append(getNode());
|
||||
builder.append("'>");
|
||||
}
|
||||
else
|
||||
builder.append('>');
|
||||
builder.append(configForm.getDataFormToSend().toXML());
|
||||
builder.append("</");
|
||||
builder.append(getElementName() + '>');
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,29 +27,29 @@ import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
|
|||
*/
|
||||
public enum FormNodeType
|
||||
{
|
||||
/** Form for configuring an existing node. */
|
||||
CONFIGURE_OWNER,
|
||||
/** Form for configuring an existing node. */
|
||||
CONFIGURE_OWNER,
|
||||
|
||||
/** Form for configuring a node during creation. */
|
||||
CONFIGURE,
|
||||
/** Form for configuring a node during creation. */
|
||||
CONFIGURE,
|
||||
|
||||
/** Form for configuring subscription options. */
|
||||
OPTIONS,
|
||||
/** Form for configuring subscription options. */
|
||||
OPTIONS,
|
||||
|
||||
/** Form which represents the default node configuration options. */
|
||||
DEFAULT;
|
||||
/** Form which represents the default node configuration options. */
|
||||
DEFAULT;
|
||||
|
||||
public PubSubElementType getNodeElement()
|
||||
{
|
||||
return PubSubElementType.valueOf(toString());
|
||||
}
|
||||
public PubSubElementType getNodeElement()
|
||||
{
|
||||
return PubSubElementType.valueOf(toString());
|
||||
}
|
||||
|
||||
public static FormNodeType valueOfFromElementName(String elem, String configNamespace)
|
||||
{
|
||||
if ("configure".equals(elem) && PubSubNamespace.OWNER.getXmlns().equals(configNamespace))
|
||||
{
|
||||
return CONFIGURE_OWNER;
|
||||
}
|
||||
return valueOf(elem.toUpperCase(Locale.US));
|
||||
}
|
||||
public static FormNodeType valueOfFromElementName(String elem, String configNamespace)
|
||||
{
|
||||
if ("configure".equals(elem) && PubSubNamespace.OWNER.getXmlns().equals(configNamespace))
|
||||
{
|
||||
return CONFIGURE_OWNER;
|
||||
}
|
||||
return valueOf(elem.toUpperCase(Locale.US));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,42 +25,42 @@ import org.jivesoftware.smack.util.XmlStringBuilder;
|
|||
*/
|
||||
public class GetItemsRequest extends NodeExtension
|
||||
{
|
||||
protected final String subId;
|
||||
protected final int maxItems;
|
||||
protected final String subId;
|
||||
protected final int maxItems;
|
||||
|
||||
public GetItemsRequest(String nodeId)
|
||||
{
|
||||
this(nodeId, null, -1);
|
||||
}
|
||||
public GetItemsRequest(String nodeId)
|
||||
{
|
||||
this(nodeId, null, -1);
|
||||
}
|
||||
|
||||
public GetItemsRequest(String nodeId, String subscriptionId)
|
||||
{
|
||||
public GetItemsRequest(String nodeId, String subscriptionId)
|
||||
{
|
||||
this(nodeId, subscriptionId, -1);
|
||||
}
|
||||
}
|
||||
|
||||
public GetItemsRequest(String nodeId, int maxItemsToReturn)
|
||||
{
|
||||
public GetItemsRequest(String nodeId, int maxItemsToReturn)
|
||||
{
|
||||
this(nodeId, null, maxItemsToReturn);
|
||||
}
|
||||
}
|
||||
|
||||
public GetItemsRequest(String nodeId, String subscriptionId, int maxItemsToReturn)
|
||||
{
|
||||
public GetItemsRequest(String nodeId, String subscriptionId, int maxItemsToReturn)
|
||||
{
|
||||
super(PubSubElementType.ITEMS, nodeId);
|
||||
maxItems = maxItemsToReturn;
|
||||
subId = subscriptionId;
|
||||
}
|
||||
subId = subscriptionId;
|
||||
}
|
||||
|
||||
public String getSubscriptionId()
|
||||
{
|
||||
return subId;
|
||||
}
|
||||
public String getSubscriptionId()
|
||||
{
|
||||
return subId;
|
||||
}
|
||||
|
||||
public int getMaxItems()
|
||||
{
|
||||
return maxItems;
|
||||
}
|
||||
public int getMaxItems()
|
||||
{
|
||||
return maxItems;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public XmlStringBuilder toXML() {
|
||||
XmlStringBuilder xml = new XmlStringBuilder();
|
||||
xml.halfOpenElement(getElementName());
|
||||
|
|
|
@ -50,94 +50,92 @@ import org.jivesoftware.smackx.pubsub.provider.ItemProvider;
|
|||
*/
|
||||
public class Item extends NodeExtension
|
||||
{
|
||||
private String id;
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Create an empty <tt>Item</tt> with no id. This is a valid item for nodes which are configured
|
||||
* so that {@link ConfigureForm#isDeliverPayloads()} is false. In most cases an id will be generated by the server.
|
||||
* For nodes configured with {@link ConfigureForm#isDeliverPayloads()} and {@link ConfigureForm#isPersistItems()}
|
||||
* set to false, no <tt>Item</tt> is sent to the node, you have to use {@link LeafNode#send()} or {@link LeafNode#publish()}
|
||||
* methods in this case.
|
||||
*/
|
||||
public Item()
|
||||
{
|
||||
super(PubSubElementType.ITEM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an <tt>Item</tt> with an id but no payload. This is a valid item for nodes which are configured
|
||||
* so that {@link ConfigureForm#isDeliverPayloads()} is false.
|
||||
*
|
||||
* @param itemId The id if the item. It must be unique within the node unless overwriting and existing item.
|
||||
* Passing null is the equivalent of calling {@link #Item()}.
|
||||
*/
|
||||
public Item(String itemId)
|
||||
{
|
||||
// The element type is actually irrelevant since we override getNamespace() to return null
|
||||
super(PubSubElementType.ITEM);
|
||||
id = itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an <tt>Item</tt> with an id and a node id.
|
||||
* <p>
|
||||
* <b>Note:</b> This is not valid for publishing an item to a node, only receiving from
|
||||
* one as part of {@link Message}. If used to create an Item to publish
|
||||
* (via {@link LeafNode#publish(Item)}, the server <i>may</i> return an
|
||||
* error for an invalid packet.
|
||||
*
|
||||
* @param itemId The id of the item.
|
||||
* @param nodeId The id of the node which the item was published to.
|
||||
*/
|
||||
public Item(String itemId, String nodeId)
|
||||
/**
|
||||
* Create an empty <tt>Item</tt> with no id. This is a valid item for nodes which are configured
|
||||
* so that {@link ConfigureForm#isDeliverPayloads()} is false. In most cases an id will be generated by the server.
|
||||
* For nodes configured with {@link ConfigureForm#isDeliverPayloads()} and {@link ConfigureForm#isPersistItems()}
|
||||
* set to false, no <tt>Item</tt> is sent to the node, you have to use {@link LeafNode#send()} or {@link LeafNode#publish()}
|
||||
* methods in this case.
|
||||
*/
|
||||
public Item()
|
||||
{
|
||||
// CHECKSTYLE:OFF
|
||||
super(PubSubElementType.ITEM_EVENT, nodeId);
|
||||
// CHECKSTYLE:ON
|
||||
super(PubSubElementType.ITEM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an <tt>Item</tt> with an id but no payload. This is a valid item for nodes which are configured
|
||||
* so that {@link ConfigureForm#isDeliverPayloads()} is false.
|
||||
*
|
||||
* @param itemId The id if the item. It must be unique within the node unless overwriting and existing item.
|
||||
* Passing null is the equivalent of calling {@link #Item()}.
|
||||
*/
|
||||
public Item(String itemId)
|
||||
{
|
||||
// The element type is actually irrelevant since we override getNamespace() to return null
|
||||
super(PubSubElementType.ITEM);
|
||||
id = itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item id. Unique to the node it is associated with.
|
||||
*
|
||||
* @return The id
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* Create an <tt>Item</tt> with an id and a node id.
|
||||
* <p>
|
||||
* <b>Note:</b> This is not valid for publishing an item to a node, only receiving from
|
||||
* one as part of {@link Message}. If used to create an Item to publish
|
||||
* (via {@link LeafNode#publish(Item)}, the server <i>may</i> return an
|
||||
* error for an invalid packet.
|
||||
*
|
||||
* @param itemId The id of the item.
|
||||
* @param nodeId The id of the node which the item was published to.
|
||||
*/
|
||||
public Item(String itemId, String nodeId)
|
||||
{
|
||||
super(PubSubElementType.ITEM_EVENT, nodeId);
|
||||
id = itemId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Get the item id. Unique to the node it is associated with.
|
||||
*
|
||||
* @return The id
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toXML()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder("<item");
|
||||
@Override
|
||||
public String getNamespace()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (id != null)
|
||||
{
|
||||
builder.append(" id='");
|
||||
builder.append(id);
|
||||
builder.append('\'');
|
||||
}
|
||||
@Override
|
||||
public String toXML()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder("<item");
|
||||
|
||||
if (id != null)
|
||||
{
|
||||
builder.append(" id='");
|
||||
builder.append(id);
|
||||
builder.append('\'');
|
||||
}
|
||||
|
||||
if (getNode() != null) {
|
||||
builder.append(" node='");
|
||||
builder.append(getNode());
|
||||
builder.append('\'');
|
||||
}
|
||||
builder.append("/>");
|
||||
builder.append("/>");
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + " | Content [" + toXML() + "]";
|
||||
}
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + " | Content [" + toXML() + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,40 +26,40 @@ import java.util.List;
|
|||
*/
|
||||
public class ItemDeleteEvent extends SubscriptionEvent
|
||||
{
|
||||
private List<String> itemIds = Collections.emptyList();
|
||||
private List<String> itemIds = Collections.emptyList();
|
||||
|
||||
/**
|
||||
* Constructs an <tt>ItemDeleteEvent</tt> that indicates the the supplied
|
||||
* items (by id) have been deleted, and that the event matches the listed
|
||||
* subscriptions. The subscriptions would have been created by calling
|
||||
* {@link LeafNode#subscribe(String)}.
|
||||
*
|
||||
* @param nodeId The id of the node the event came from
|
||||
* @param deletedItemIds The item ids of the items that were deleted.
|
||||
* @param subscriptionIds The subscriptions that match the event.
|
||||
*/
|
||||
public ItemDeleteEvent(String nodeId, List<String> deletedItemIds, List<String> subscriptionIds)
|
||||
{
|
||||
super(nodeId, subscriptionIds);
|
||||
/**
|
||||
* Constructs an <tt>ItemDeleteEvent</tt> that indicates the the supplied
|
||||
* items (by id) have been deleted, and that the event matches the listed
|
||||
* subscriptions. The subscriptions would have been created by calling
|
||||
* {@link LeafNode#subscribe(String)}.
|
||||
*
|
||||
* @param nodeId The id of the node the event came from
|
||||
* @param deletedItemIds The item ids of the items that were deleted.
|
||||
* @param subscriptionIds The subscriptions that match the event.
|
||||
*/
|
||||
public ItemDeleteEvent(String nodeId, List<String> deletedItemIds, List<String> subscriptionIds)
|
||||
{
|
||||
super(nodeId, subscriptionIds);
|
||||
|
||||
if (deletedItemIds == null)
|
||||
throw new IllegalArgumentException("deletedItemIds cannot be null");
|
||||
itemIds = deletedItemIds;
|
||||
}
|
||||
if (deletedItemIds == null)
|
||||
throw new IllegalArgumentException("deletedItemIds cannot be null");
|
||||
itemIds = deletedItemIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item id's of the items that have been deleted.
|
||||
*
|
||||
* @return List of item id's
|
||||
*/
|
||||
public List<String> getItemIds()
|
||||
{
|
||||
return Collections.unmodifiableList(itemIds);
|
||||
}
|
||||
/**
|
||||
* Get the item id's of the items that have been deleted.
|
||||
*
|
||||
* @return List of item id's
|
||||
*/
|
||||
public List<String> getItemIds()
|
||||
{
|
||||
return Collections.unmodifiableList(itemIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + " [subscriptions: " + getSubscriptions() + "], [Deleted Items: " + itemIds + ']';
|
||||
}
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + " [subscriptions: " + getSubscriptions() + "], [Deleted Items: " + itemIds + ']';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,98 +27,98 @@ import java.util.List;
|
|||
*/
|
||||
public class ItemPublishEvent<T extends Item> extends SubscriptionEvent
|
||||
{
|
||||
private List<T> items;
|
||||
private Date originalDate;
|
||||
private List<T> items;
|
||||
private Date originalDate;
|
||||
|
||||
/**
|
||||
* Constructs an <tt>ItemPublishEvent</tt> with the provided list
|
||||
* of {@link Item} that were published.
|
||||
*
|
||||
* @param nodeId The id of the node the event came from
|
||||
* @param eventItems The list of {@link Item} that were published
|
||||
*/
|
||||
public ItemPublishEvent(String nodeId, List<T> eventItems)
|
||||
{
|
||||
super(nodeId);
|
||||
items = eventItems;
|
||||
}
|
||||
/**
|
||||
* Constructs an <tt>ItemPublishEvent</tt> with the provided list
|
||||
* of {@link Item} that were published.
|
||||
*
|
||||
* @param nodeId The id of the node the event came from
|
||||
* @param eventItems The list of {@link Item} that were published
|
||||
*/
|
||||
public ItemPublishEvent(String nodeId, List<T> eventItems)
|
||||
{
|
||||
super(nodeId);
|
||||
items = eventItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <tt>ItemPublishEvent</tt> with the provided list
|
||||
* of {@link Item} that were published. The list of subscription ids
|
||||
* represents the subscriptions that matched the event, in the case
|
||||
* of the user having multiple subscriptions.
|
||||
*
|
||||
* @param nodeId The id of the node the event came from
|
||||
* @param eventItems The list of {@link Item} that were published
|
||||
* @param subscriptionIds The list of subscriptionIds
|
||||
*/
|
||||
public ItemPublishEvent(String nodeId, List<T> eventItems, List<String> subscriptionIds)
|
||||
{
|
||||
super(nodeId, subscriptionIds);
|
||||
items = eventItems;
|
||||
}
|
||||
/**
|
||||
* Constructs an <tt>ItemPublishEvent</tt> with the provided list
|
||||
* of {@link Item} that were published. The list of subscription ids
|
||||
* represents the subscriptions that matched the event, in the case
|
||||
* of the user having multiple subscriptions.
|
||||
*
|
||||
* @param nodeId The id of the node the event came from
|
||||
* @param eventItems The list of {@link Item} that were published
|
||||
* @param subscriptionIds The list of subscriptionIds
|
||||
*/
|
||||
public ItemPublishEvent(String nodeId, List<T> eventItems, List<String> subscriptionIds)
|
||||
{
|
||||
super(nodeId, subscriptionIds);
|
||||
items = eventItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <tt>ItemPublishEvent</tt> with the provided list
|
||||
* of {@link Item} that were published in the past. The published
|
||||
* date signifies that this is delayed event. The list of subscription ids
|
||||
* represents the subscriptions that matched the event, in the case
|
||||
* of the user having multiple subscriptions.
|
||||
*
|
||||
* @param nodeId The id of the node the event came from
|
||||
* @param eventItems The list of {@link Item} that were published
|
||||
* @param subscriptionIds The list of subscriptionIds
|
||||
*/
|
||||
public ItemPublishEvent(String nodeId, List<T> eventItems, List<String> subscriptionIds, Date publishedDate)
|
||||
{
|
||||
super(nodeId, subscriptionIds);
|
||||
items = eventItems;
|
||||
/**
|
||||
* Constructs an <tt>ItemPublishEvent</tt> with the provided list
|
||||
* of {@link Item} that were published in the past. The published
|
||||
* date signifies that this is delayed event. The list of subscription ids
|
||||
* represents the subscriptions that matched the event, in the case
|
||||
* of the user having multiple subscriptions.
|
||||
*
|
||||
* @param nodeId The id of the node the event came from
|
||||
* @param eventItems The list of {@link Item} that were published
|
||||
* @param subscriptionIds The list of subscriptionIds
|
||||
*/
|
||||
public ItemPublishEvent(String nodeId, List<T> eventItems, List<String> subscriptionIds, Date publishedDate)
|
||||
{
|
||||
super(nodeId, subscriptionIds);
|
||||
items = eventItems;
|
||||
|
||||
if (publishedDate != null)
|
||||
originalDate = publishedDate;
|
||||
}
|
||||
if (publishedDate != null)
|
||||
originalDate = publishedDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of {@link Item} that were published.
|
||||
*
|
||||
* @return The list of published {@link Item}
|
||||
*/
|
||||
public List<T> getItems()
|
||||
{
|
||||
return Collections.unmodifiableList(items);
|
||||
}
|
||||
/**
|
||||
* Get the list of {@link Item} that were published.
|
||||
*
|
||||
* @return The list of published {@link Item}
|
||||
*/
|
||||
public List<T> getItems()
|
||||
{
|
||||
return Collections.unmodifiableList(items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this event was delayed. That is, the items
|
||||
* were published to the node at some time in the past. This will
|
||||
* typically happen if there is an item already published to the node
|
||||
* before a user subscribes to it. In this case, when the user
|
||||
* subscribes, the server may send the last item published to the node
|
||||
* with a delay date showing its time of original publication.
|
||||
*
|
||||
* @return true if the items are delayed, false otherwise.
|
||||
*/
|
||||
public boolean isDelayed()
|
||||
{
|
||||
return (originalDate != null);
|
||||
}
|
||||
/**
|
||||
* Indicates whether this event was delayed. That is, the items
|
||||
* were published to the node at some time in the past. This will
|
||||
* typically happen if there is an item already published to the node
|
||||
* before a user subscribes to it. In this case, when the user
|
||||
* subscribes, the server may send the last item published to the node
|
||||
* with a delay date showing its time of original publication.
|
||||
*
|
||||
* @return true if the items are delayed, false otherwise.
|
||||
*/
|
||||
public boolean isDelayed()
|
||||
{
|
||||
return (originalDate != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the original date the items were published. This is only
|
||||
* valid if {@link #isDelayed()} is true.
|
||||
*
|
||||
*/
|
||||
public Date getPublishedDate()
|
||||
{
|
||||
return originalDate;
|
||||
}
|
||||
/**
|
||||
* Gets the original date the items were published. This is only
|
||||
* valid if {@link #isDelayed()} is true.
|
||||
*
|
||||
*/
|
||||
public Date getPublishedDate()
|
||||
{
|
||||
return originalDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + " [subscriptions: " + getSubscriptions() + "], [Delayed: " +
|
||||
(isDelayed() ? originalDate.toString() : "false") + ']';
|
||||
}
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + " [subscriptions: " + getSubscriptions() + "], [Delayed: " +
|
||||
(isDelayed() ? originalDate.toString() : "false") + ']';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@ package org.jivesoftware.smackx.pubsub;
|
|||
*/
|
||||
public enum ItemReply
|
||||
{
|
||||
/** The node owner. */
|
||||
owner,
|
||||
/** The node owner. */
|
||||
owner,
|
||||
|
||||
/** The item publisher. */
|
||||
publisher;
|
||||
/** The item publisher. */
|
||||
publisher;
|
||||
}
|
||||
|
|
|
@ -36,168 +36,168 @@ import org.jivesoftware.smack.packet.ExtensionElement;
|
|||
*/
|
||||
public class ItemsExtension extends NodeExtension implements EmbeddedPacketExtension
|
||||
{
|
||||
protected ItemsElementType type;
|
||||
protected Boolean notify;
|
||||
protected List<? extends ExtensionElement> items;
|
||||
protected ItemsElementType type;
|
||||
protected Boolean notify;
|
||||
protected List<? extends ExtensionElement> items;
|
||||
|
||||
public enum ItemsElementType
|
||||
{
|
||||
/** An items element, which has an optional <b>max_items</b> attribute when requesting items. */
|
||||
items(PubSubElementType.ITEMS, "max_items"),
|
||||
public enum ItemsElementType
|
||||
{
|
||||
/** An items element, which has an optional <b>max_items</b> attribute when requesting items. */
|
||||
items(PubSubElementType.ITEMS, "max_items"),
|
||||
|
||||
/** A retract element, which has an optional <b>notify</b> attribute when publishing deletions. */
|
||||
retract(PubSubElementType.RETRACT, "notify");
|
||||
/** A retract element, which has an optional <b>notify</b> attribute when publishing deletions. */
|
||||
retract(PubSubElementType.RETRACT, "notify");
|
||||
|
||||
private PubSubElementType elem;
|
||||
private String att;
|
||||
private PubSubElementType elem;
|
||||
private String att;
|
||||
|
||||
private ItemsElementType(PubSubElementType nodeElement, String attribute)
|
||||
{
|
||||
elem = nodeElement;
|
||||
att = attribute;
|
||||
}
|
||||
private ItemsElementType(PubSubElementType nodeElement, String attribute)
|
||||
{
|
||||
elem = nodeElement;
|
||||
att = attribute;
|
||||
}
|
||||
|
||||
public PubSubElementType getNodeElement()
|
||||
{
|
||||
return elem;
|
||||
}
|
||||
public PubSubElementType getNodeElement()
|
||||
{
|
||||
return elem;
|
||||
}
|
||||
|
||||
public String getElementAttribute()
|
||||
{
|
||||
return att;
|
||||
}
|
||||
}
|
||||
public String getElementAttribute()
|
||||
{
|
||||
return att;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance with a list representing items that have been published or deleted.
|
||||
*
|
||||
* <p>Valid scenarios are:</p>
|
||||
* <ul>
|
||||
* <li>Request items from node - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and an
|
||||
* optional value for the <b>max_items</b> attribute.
|
||||
* <li>Request to delete items - itemsType = {@link ItemsElementType#retract}, items = list of {@link Item} containing
|
||||
* only id's and an optional value for the <b>notify</b> attribute.
|
||||
* <li>Items published event - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and
|
||||
* attributeValue = <code>null</code>
|
||||
* <li>Items deleted event - itemsType = {@link ItemsElementType#items}, items = list of {@link RetractItem} and
|
||||
* attributeValue = <code>null</code>
|
||||
* </ul>
|
||||
*
|
||||
* @param itemsType Type of representation
|
||||
* @param nodeId The node to which the items are being sent or deleted
|
||||
* @param items The list of {@link Item} or {@link RetractItem}
|
||||
*/
|
||||
public ItemsExtension(ItemsElementType itemsType, String nodeId, List<? extends ExtensionElement> items)
|
||||
{
|
||||
super(itemsType.getNodeElement(), nodeId);
|
||||
type = itemsType;
|
||||
this.items = items;
|
||||
}
|
||||
/**
|
||||
* Construct an instance with a list representing items that have been published or deleted.
|
||||
*
|
||||
* <p>Valid scenarios are:</p>
|
||||
* <ul>
|
||||
* <li>Request items from node - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and an
|
||||
* optional value for the <b>max_items</b> attribute.
|
||||
* <li>Request to delete items - itemsType = {@link ItemsElementType#retract}, items = list of {@link Item} containing
|
||||
* only id's and an optional value for the <b>notify</b> attribute.
|
||||
* <li>Items published event - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and
|
||||
* attributeValue = <code>null</code>
|
||||
* <li>Items deleted event - itemsType = {@link ItemsElementType#items}, items = list of {@link RetractItem} and
|
||||
* attributeValue = <code>null</code>
|
||||
* </ul>
|
||||
*
|
||||
* @param itemsType Type of representation
|
||||
* @param nodeId The node to which the items are being sent or deleted
|
||||
* @param items The list of {@link Item} or {@link RetractItem}
|
||||
*/
|
||||
public ItemsExtension(ItemsElementType itemsType, String nodeId, List<? extends ExtensionElement> items)
|
||||
{
|
||||
super(itemsType.getNodeElement(), nodeId);
|
||||
type = itemsType;
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance with a list representing items that have been published or deleted.
|
||||
*
|
||||
* <p>Valid scenarios are:</p>
|
||||
* <ul>
|
||||
* <li>Request items from node - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and an
|
||||
* optional value for the <b>max_items</b> attribute.
|
||||
* <li>Request to delete items - itemsType = {@link ItemsElementType#retract}, items = list of {@link Item} containing
|
||||
* only id's and an optional value for the <b>notify</b> attribute.
|
||||
* <li>Items published event - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and
|
||||
* attributeValue = <code>null</code>
|
||||
* <li>Items deleted event - itemsType = {@link ItemsElementType#items}, items = list of {@link RetractItem} and
|
||||
* attributeValue = <code>null</code>
|
||||
* </ul>
|
||||
*
|
||||
* @param nodeId The node to which the items are being sent or deleted
|
||||
* @param items The list of {@link Item} or {@link RetractItem}
|
||||
*/
|
||||
public ItemsExtension(String nodeId, List<? extends ExtensionElement> items, boolean notify)
|
||||
{
|
||||
super(ItemsElementType.retract.getNodeElement(), nodeId);
|
||||
type = ItemsElementType.retract;
|
||||
this.items = items;
|
||||
this.notify = notify;
|
||||
}
|
||||
/**
|
||||
* Construct an instance with a list representing items that have been published or deleted.
|
||||
*
|
||||
* <p>Valid scenarios are:</p>
|
||||
* <ul>
|
||||
* <li>Request items from node - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and an
|
||||
* optional value for the <b>max_items</b> attribute.
|
||||
* <li>Request to delete items - itemsType = {@link ItemsElementType#retract}, items = list of {@link Item} containing
|
||||
* only id's and an optional value for the <b>notify</b> attribute.
|
||||
* <li>Items published event - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and
|
||||
* attributeValue = <code>null</code>
|
||||
* <li>Items deleted event - itemsType = {@link ItemsElementType#items}, items = list of {@link RetractItem} and
|
||||
* attributeValue = <code>null</code>
|
||||
* </ul>
|
||||
*
|
||||
* @param nodeId The node to which the items are being sent or deleted
|
||||
* @param items The list of {@link Item} or {@link RetractItem}
|
||||
*/
|
||||
public ItemsExtension(String nodeId, List<? extends ExtensionElement> items, boolean notify)
|
||||
{
|
||||
super(ItemsElementType.retract.getNodeElement(), nodeId);
|
||||
type = ItemsElementType.retract;
|
||||
this.items = items;
|
||||
this.notify = notify;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of element.
|
||||
*
|
||||
* @return The element type
|
||||
*/
|
||||
public ItemsElementType getItemsElementType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
/**
|
||||
* Get the type of element.
|
||||
*
|
||||
* @return The element type
|
||||
*/
|
||||
public ItemsElementType getItemsElementType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<ExtensionElement> getExtensions()
|
||||
{
|
||||
return (List<ExtensionElement>)getItems();
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<ExtensionElement> getExtensions()
|
||||
{
|
||||
return (List<ExtensionElement>)getItems();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the items related to the type of request or event.
|
||||
*
|
||||
* return List of {@link Item}, {@link RetractItem}, or null
|
||||
*/
|
||||
public List<? extends ExtensionElement> getItems()
|
||||
{
|
||||
return items;
|
||||
}
|
||||
/**
|
||||
* Gets the items related to the type of request or event.
|
||||
*
|
||||
* return List of {@link Item}, {@link RetractItem}, or null
|
||||
*/
|
||||
public List<? extends ExtensionElement> getItems()
|
||||
{
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the optional attribute related to the {@link ItemsElementType}.
|
||||
*
|
||||
* @return The attribute value
|
||||
*/
|
||||
public boolean getNotify()
|
||||
{
|
||||
return notify;
|
||||
}
|
||||
/**
|
||||
* Gets the value of the optional attribute related to the {@link ItemsElementType}.
|
||||
*
|
||||
* @return The attribute value
|
||||
*/
|
||||
public boolean getNotify()
|
||||
{
|
||||
return notify;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence toXML()
|
||||
{
|
||||
if ((items == null) || (items.size() == 0))
|
||||
{
|
||||
return super.toXML();
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder builder = new StringBuilder("<");
|
||||
builder.append(getElementName());
|
||||
builder.append(" node='");
|
||||
builder.append(getNode());
|
||||
@Override
|
||||
public CharSequence toXML()
|
||||
{
|
||||
if ((items == null) || (items.size() == 0))
|
||||
{
|
||||
return super.toXML();
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder builder = new StringBuilder("<");
|
||||
builder.append(getElementName());
|
||||
builder.append(" node='");
|
||||
builder.append(getNode());
|
||||
|
||||
if (notify != null)
|
||||
{
|
||||
builder.append("' ");
|
||||
builder.append(type.getElementAttribute());
|
||||
builder.append("='");
|
||||
builder.append(notify.equals(Boolean.TRUE) ? 1 : 0);
|
||||
builder.append("'>");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.append("'>");
|
||||
for (ExtensionElement item : items)
|
||||
{
|
||||
builder.append(item.toXML());
|
||||
}
|
||||
}
|
||||
if (notify != null)
|
||||
{
|
||||
builder.append("' ");
|
||||
builder.append(type.getElementAttribute());
|
||||
builder.append("='");
|
||||
builder.append(notify.equals(Boolean.TRUE) ? 1 : 0);
|
||||
builder.append("'>");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.append("'>");
|
||||
for (ExtensionElement item : items)
|
||||
{
|
||||
builder.append(item.toXML());
|
||||
}
|
||||
}
|
||||
|
||||
builder.append("</");
|
||||
builder.append(getElementName());
|
||||
builder.append('>');
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
builder.append("</");
|
||||
builder.append(getElementName());
|
||||
builder.append('>');
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + "Content [" + toXML() + "]";
|
||||
}
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + "Content [" + toXML() + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,125 +38,125 @@ import org.jivesoftware.smackx.pubsub.packet.PubSub;
|
|||
*/
|
||||
public class LeafNode extends Node
|
||||
{
|
||||
LeafNode(PubSubManager pubSubManager, String nodeId)
|
||||
{
|
||||
super(pubSubManager, nodeId);
|
||||
}
|
||||
LeafNode(PubSubManager pubSubManager, String nodeId)
|
||||
{
|
||||
super(pubSubManager, nodeId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information on the items in the node in standard
|
||||
* {@link DiscoverItems} format.
|
||||
*
|
||||
* @return The item details in {@link DiscoverItems} format
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public DiscoverItems discoverItems() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
DiscoverItems items = new DiscoverItems();
|
||||
items.setTo(pubSubManager.getServiceJid());
|
||||
items.setNode(getId());
|
||||
/**
|
||||
* Get information on the items in the node in standard
|
||||
* {@link DiscoverItems} format.
|
||||
*
|
||||
* @return The item details in {@link DiscoverItems} format
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public DiscoverItems discoverItems() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
DiscoverItems items = new DiscoverItems();
|
||||
items.setTo(pubSubManager.getServiceJid());
|
||||
items.setNode(getId());
|
||||
return pubSubManager.getConnection().createStanzaCollectorAndSend(items).nextResultOrThrow();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current items stored in the node.
|
||||
*
|
||||
* @return List of {@link Item} in the node
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
/**
|
||||
* Get the current items stored in the node.
|
||||
*
|
||||
* @return List of {@link Item} in the node
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
return getItems((List<ExtensionElement>) null, (List<ExtensionElement>) null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current items stored in the node based
|
||||
* on the subscription associated with the provided
|
||||
* subscription id.
|
||||
*
|
||||
* @param subscriptionId - The subscription id for the
|
||||
* associated subscription.
|
||||
* @return List of {@link Item} in the node
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems(String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.get, new GetItemsRequest(getId(), subscriptionId));
|
||||
/**
|
||||
* Get the current items stored in the node based
|
||||
* on the subscription associated with the provided
|
||||
* subscription id.
|
||||
*
|
||||
* @param subscriptionId - The subscription id for the
|
||||
* associated subscription.
|
||||
* @return List of {@link Item} in the node
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems(String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.get, new GetItemsRequest(getId(), subscriptionId));
|
||||
return getItems(request);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the items specified from the node. This would typically be
|
||||
* used when the server does not return the payload due to size
|
||||
* constraints. The user would be required to retrieve the payload
|
||||
* after the items have been retrieved via {@link #getItems()} or an
|
||||
* event, that did not include the payload.
|
||||
*
|
||||
* @param ids Item ids of the items to retrieve
|
||||
*
|
||||
* @return The list of {@link Item} with payload
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems(Collection<String> ids) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
List<Item> itemList = new ArrayList<Item>(ids.size());
|
||||
/**
|
||||
* Get the items specified from the node. This would typically be
|
||||
* used when the server does not return the payload due to size
|
||||
* constraints. The user would be required to retrieve the payload
|
||||
* after the items have been retrieved via {@link #getItems()} or an
|
||||
* event, that did not include the payload.
|
||||
*
|
||||
* @param ids Item ids of the items to retrieve
|
||||
*
|
||||
* @return The list of {@link Item} with payload
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems(Collection<String> ids) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
List<Item> itemList = new ArrayList<Item>(ids.size());
|
||||
|
||||
for (String id : ids)
|
||||
{
|
||||
itemList.add(new Item(id));
|
||||
}
|
||||
PubSub request = createPubsubPacket(Type.get, new ItemsExtension(ItemsExtension.ItemsElementType.items, getId(), itemList));
|
||||
for (String id : ids)
|
||||
{
|
||||
itemList.add(new Item(id));
|
||||
}
|
||||
PubSub request = createPubsubPacket(Type.get, new ItemsExtension(ItemsExtension.ItemsElementType.items, getId(), itemList));
|
||||
return getItems(request);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get items persisted on the node, limited to the specified number.
|
||||
*
|
||||
* @param maxItems Maximum number of items to return
|
||||
*
|
||||
* @return List of {@link Item}
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems(int maxItems) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.get, new GetItemsRequest(getId(), maxItems));
|
||||
/**
|
||||
* Get items persisted on the node, limited to the specified number.
|
||||
*
|
||||
* @param maxItems Maximum number of items to return
|
||||
*
|
||||
* @return List of {@link Item}
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems(int maxItems) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.get, new GetItemsRequest(getId(), maxItems));
|
||||
return getItems(request);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get items persisted on the node, limited to the specified number
|
||||
* based on the subscription associated with the provided subscriptionId.
|
||||
*
|
||||
* @param maxItems Maximum number of items to return
|
||||
* @param subscriptionId The subscription which the retrieval is based
|
||||
* on.
|
||||
*
|
||||
* @return List of {@link Item}
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems(int maxItems, String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.get, new GetItemsRequest(getId(), subscriptionId, maxItems));
|
||||
/**
|
||||
* Get items persisted on the node, limited to the specified number
|
||||
* based on the subscription associated with the provided subscriptionId.
|
||||
*
|
||||
* @param maxItems Maximum number of items to return
|
||||
* @param subscriptionId The subscription which the retrieval is based
|
||||
* on.
|
||||
*
|
||||
* @return List of {@link Item}
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems(int maxItems, String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.get, new GetItemsRequest(getId(), subscriptionId, maxItems));
|
||||
return getItems(request);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get items persisted on the node.
|
||||
|
@ -200,206 +200,206 @@ public class LeafNode extends Node
|
|||
return (List<T>) itemsElem.getItems();
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes an event to the node. This is an empty event
|
||||
* with no item.
|
||||
*
|
||||
* This is only acceptable for nodes with {@link ConfigureForm#isPersistItems()}=false
|
||||
* and {@link ConfigureForm#isDeliverPayloads()}=false.
|
||||
*
|
||||
* This is an asynchronous call which returns as soon as the
|
||||
* stanza(/packet) has been sent.
|
||||
*
|
||||
* For synchronous calls use {@link #send() send()}.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void publish() throws NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new NodeExtension(PubSubElementType.PUBLISH, getId()));
|
||||
/**
|
||||
* Publishes an event to the node. This is an empty event
|
||||
* with no item.
|
||||
*
|
||||
* This is only acceptable for nodes with {@link ConfigureForm#isPersistItems()}=false
|
||||
* and {@link ConfigureForm#isDeliverPayloads()}=false.
|
||||
*
|
||||
* This is an asynchronous call which returns as soon as the
|
||||
* stanza(/packet) has been sent.
|
||||
*
|
||||
* For synchronous calls use {@link #send() send()}.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void publish() throws NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new NodeExtension(PubSubElementType.PUBLISH, getId()));
|
||||
|
||||
pubSubManager.getConnection().sendStanza(packet);
|
||||
}
|
||||
pubSubManager.getConnection().sendStanza(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes an event to the node. This is a simple item
|
||||
* with no payload.
|
||||
*
|
||||
* If the id is null, an empty item (one without an id) will be sent.
|
||||
* Please note that this is not the same as {@link #send()}, which
|
||||
* publishes an event with NO item.
|
||||
*
|
||||
* This is an asynchronous call which returns as soon as the
|
||||
* stanza(/packet) has been sent.
|
||||
*
|
||||
* For synchronous calls use {@link #send(Item) send(Item))}.
|
||||
*
|
||||
* @param item - The item being sent
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Item> void publish(T item) throws NotConnectedException, InterruptedException
|
||||
{
|
||||
Collection<T> items = new ArrayList<T>(1);
|
||||
items.add((T)(item == null ? new Item() : item));
|
||||
publish(items);
|
||||
}
|
||||
/**
|
||||
* Publishes an event to the node. This is a simple item
|
||||
* with no payload.
|
||||
*
|
||||
* If the id is null, an empty item (one without an id) will be sent.
|
||||
* Please note that this is not the same as {@link #send()}, which
|
||||
* publishes an event with NO item.
|
||||
*
|
||||
* This is an asynchronous call which returns as soon as the
|
||||
* stanza(/packet) has been sent.
|
||||
*
|
||||
* For synchronous calls use {@link #send(Item) send(Item))}.
|
||||
*
|
||||
* @param item - The item being sent
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Item> void publish(T item) throws NotConnectedException, InterruptedException
|
||||
{
|
||||
Collection<T> items = new ArrayList<T>(1);
|
||||
items.add((T)(item == null ? new Item() : item));
|
||||
publish(items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes multiple events to the node. Same rules apply as in {@link #publish(Item)}.
|
||||
*
|
||||
* In addition, if {@link ConfigureForm#isPersistItems()}=false, only the last item in the input
|
||||
* list will get stored on the node, assuming it stores the last sent item.
|
||||
*
|
||||
* This is an asynchronous call which returns as soon as the
|
||||
* stanza(/packet) has been sent.
|
||||
*
|
||||
* For synchronous calls use {@link #send(Collection) send(Collection))}.
|
||||
*
|
||||
* @param items - The collection of items being sent
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> void publish(Collection<T> items) throws NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new PublishItem<T>(getId(), items));
|
||||
/**
|
||||
* Publishes multiple events to the node. Same rules apply as in {@link #publish(Item)}.
|
||||
*
|
||||
* In addition, if {@link ConfigureForm#isPersistItems()}=false, only the last item in the input
|
||||
* list will get stored on the node, assuming it stores the last sent item.
|
||||
*
|
||||
* This is an asynchronous call which returns as soon as the
|
||||
* stanza(/packet) has been sent.
|
||||
*
|
||||
* For synchronous calls use {@link #send(Collection) send(Collection))}.
|
||||
*
|
||||
* @param items - The collection of items being sent
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> void publish(Collection<T> items) throws NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new PublishItem<T>(getId(), items));
|
||||
|
||||
pubSubManager.getConnection().sendStanza(packet);
|
||||
}
|
||||
pubSubManager.getConnection().sendStanza(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes an event to the node. This is an empty event
|
||||
* with no item.
|
||||
*
|
||||
* This is only acceptable for nodes with {@link ConfigureForm#isPersistItems()}=false
|
||||
* and {@link ConfigureForm#isDeliverPayloads()}=false.
|
||||
*
|
||||
* This is a synchronous call which will throw an exception
|
||||
* on failure.
|
||||
*
|
||||
* For asynchronous calls, use {@link #publish() publish()}.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public void send() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new NodeExtension(PubSubElementType.PUBLISH, getId()));
|
||||
/**
|
||||
* Publishes an event to the node. This is an empty event
|
||||
* with no item.
|
||||
*
|
||||
* This is only acceptable for nodes with {@link ConfigureForm#isPersistItems()}=false
|
||||
* and {@link ConfigureForm#isDeliverPayloads()}=false.
|
||||
*
|
||||
* This is a synchronous call which will throw an exception
|
||||
* on failure.
|
||||
*
|
||||
* For asynchronous calls, use {@link #publish() publish()}.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public void send() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new NodeExtension(PubSubElementType.PUBLISH, getId()));
|
||||
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(packet).nextResultOrThrow();
|
||||
}
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(packet).nextResultOrThrow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes an event to the node. This can be either a simple item
|
||||
* with no payload, or one with it. This is determined by the Node
|
||||
* configuration.
|
||||
*
|
||||
* If the node has <b>deliver_payload=false</b>, the Item must not
|
||||
* have a payload.
|
||||
*
|
||||
* If the id is null, an empty item (one without an id) will be sent.
|
||||
* Please note that this is not the same as {@link #send()}, which
|
||||
* publishes an event with NO item.
|
||||
*
|
||||
* This is a synchronous call which will throw an exception
|
||||
* on failure.
|
||||
*
|
||||
* For asynchronous calls, use {@link #publish(Item) publish(Item)}.
|
||||
*
|
||||
* @param item - The item being sent
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Item> void send(T item) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
Collection<T> items = new ArrayList<T>(1);
|
||||
items.add((item == null ? (T)new Item() : item));
|
||||
send(items);
|
||||
}
|
||||
/**
|
||||
* Publishes an event to the node. This can be either a simple item
|
||||
* with no payload, or one with it. This is determined by the Node
|
||||
* configuration.
|
||||
*
|
||||
* If the node has <b>deliver_payload=false</b>, the Item must not
|
||||
* have a payload.
|
||||
*
|
||||
* If the id is null, an empty item (one without an id) will be sent.
|
||||
* Please note that this is not the same as {@link #send()}, which
|
||||
* publishes an event with NO item.
|
||||
*
|
||||
* This is a synchronous call which will throw an exception
|
||||
* on failure.
|
||||
*
|
||||
* For asynchronous calls, use {@link #publish(Item) publish(Item)}.
|
||||
*
|
||||
* @param item - The item being sent
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Item> void send(T item) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
Collection<T> items = new ArrayList<T>(1);
|
||||
items.add((item == null ? (T)new Item() : item));
|
||||
send(items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes multiple events to the node. Same rules apply as in {@link #send(Item)}.
|
||||
*
|
||||
* In addition, if {@link ConfigureForm#isPersistItems()}=false, only the last item in the input
|
||||
* list will get stored on the node, assuming it stores the last sent item.
|
||||
*
|
||||
* This is a synchronous call which will throw an exception
|
||||
* on failure.
|
||||
*
|
||||
* For asynchronous calls, use {@link #publish(Collection) publish(Collection))}.
|
||||
*
|
||||
* @param items - The collection of {@link Item} objects being sent
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public <T extends Item> void send(Collection<T> items) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new PublishItem<T>(getId(), items));
|
||||
/**
|
||||
* Publishes multiple events to the node. Same rules apply as in {@link #send(Item)}.
|
||||
*
|
||||
* In addition, if {@link ConfigureForm#isPersistItems()}=false, only the last item in the input
|
||||
* list will get stored on the node, assuming it stores the last sent item.
|
||||
*
|
||||
* This is a synchronous call which will throw an exception
|
||||
* on failure.
|
||||
*
|
||||
* For asynchronous calls, use {@link #publish(Collection) publish(Collection))}.
|
||||
*
|
||||
* @param items - The collection of {@link Item} objects being sent
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public <T extends Item> void send(Collection<T> items) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new PublishItem<T>(getId(), items));
|
||||
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(packet).nextResultOrThrow();
|
||||
}
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(packet).nextResultOrThrow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Purges the node of all items.
|
||||
*
|
||||
* <p>Note: Some implementations may keep the last item
|
||||
* sent.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void deleteAllItems() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.set, new NodeExtension(PubSubElementType.PURGE_OWNER, getId()), PubSubElementType.PURGE_OWNER.getNamespace());
|
||||
/**
|
||||
* Purges the node of all items.
|
||||
*
|
||||
* <p>Note: Some implementations may keep the last item
|
||||
* sent.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void deleteAllItems() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.set, new NodeExtension(PubSubElementType.PURGE_OWNER, getId()), PubSubElementType.PURGE_OWNER.getNamespace());
|
||||
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(request).nextResultOrThrow();
|
||||
}
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(request).nextResultOrThrow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the item with the specified id from the node.
|
||||
*
|
||||
* @param itemId The id of the item
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void deleteItem(String itemId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
Collection<String> items = new ArrayList<String>(1);
|
||||
items.add(itemId);
|
||||
deleteItem(items);
|
||||
}
|
||||
/**
|
||||
* Delete the item with the specified id from the node.
|
||||
*
|
||||
* @param itemId The id of the item
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void deleteItem(String itemId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
Collection<String> items = new ArrayList<String>(1);
|
||||
items.add(itemId);
|
||||
deleteItem(items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the items with the specified id's from the node.
|
||||
*
|
||||
* @param itemIds The list of id's of items to delete
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void deleteItem(Collection<String> itemIds) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
List<Item> items = new ArrayList<Item>(itemIds.size());
|
||||
/**
|
||||
* Delete the items with the specified id's from the node.
|
||||
*
|
||||
* @param itemIds The list of id's of items to delete
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void deleteItem(Collection<String> itemIds) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
List<Item> items = new ArrayList<Item>(itemIds.size());
|
||||
|
||||
for (String id : itemIds)
|
||||
{
|
||||
items.add(new Item(id));
|
||||
}
|
||||
PubSub request = createPubsubPacket(Type.set, new ItemsExtension(ItemsExtension.ItemsElementType.retract, getId(), items));
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(request).nextResultOrThrow();
|
||||
}
|
||||
for (String id : itemIds)
|
||||
{
|
||||
items.add(new Item(id));
|
||||
}
|
||||
PubSub request = createPubsubPacket(Type.set, new ItemsExtension(ItemsExtension.ItemsElementType.retract, getId(), items));
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(request).nextResultOrThrow();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,97 +48,97 @@ abstract public class Node
|
|||
protected final PubSubManager pubSubManager;
|
||||
protected final String id;
|
||||
|
||||
protected ConcurrentHashMap<ItemEventListener<Item>, StanzaListener> itemEventToListenerMap = new ConcurrentHashMap<ItemEventListener<Item>, StanzaListener>();
|
||||
protected ConcurrentHashMap<ItemDeleteListener, StanzaListener> itemDeleteToListenerMap = new ConcurrentHashMap<ItemDeleteListener, StanzaListener>();
|
||||
protected ConcurrentHashMap<NodeConfigListener, StanzaListener> configEventToListenerMap = new ConcurrentHashMap<NodeConfigListener, StanzaListener>();
|
||||
protected ConcurrentHashMap<ItemEventListener<Item>, StanzaListener> itemEventToListenerMap = new ConcurrentHashMap<ItemEventListener<Item>, StanzaListener>();
|
||||
protected ConcurrentHashMap<ItemDeleteListener, StanzaListener> itemDeleteToListenerMap = new ConcurrentHashMap<ItemDeleteListener, StanzaListener>();
|
||||
protected ConcurrentHashMap<NodeConfigListener, StanzaListener> configEventToListenerMap = new ConcurrentHashMap<NodeConfigListener, StanzaListener>();
|
||||
|
||||
/**
|
||||
* Construct a node associated to the supplied connection with the specified
|
||||
* node id.
|
||||
*
|
||||
* @param connection The connection the node is associated with
|
||||
* @param nodeName The node id
|
||||
*/
|
||||
Node(PubSubManager pubSubManager, String nodeId)
|
||||
{
|
||||
this.pubSubManager = pubSubManager;
|
||||
id = nodeId;
|
||||
}
|
||||
/**
|
||||
* Construct a node associated to the supplied connection with the specified
|
||||
* node id.
|
||||
*
|
||||
* @param connection The connection the node is associated with
|
||||
* @param nodeName The node id
|
||||
*/
|
||||
Node(PubSubManager pubSubManager, String nodeId)
|
||||
{
|
||||
this.pubSubManager = pubSubManager;
|
||||
id = nodeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NodeId.
|
||||
*
|
||||
* @return the node id
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* Returns a configuration form, from which you can create an answer form to be submitted
|
||||
* via the {@link #sendConfigurationForm(Form)}.
|
||||
*
|
||||
* @return the configuration form
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public ConfigureForm getNodeConfiguration() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
/**
|
||||
* Get the NodeId.
|
||||
*
|
||||
* @return the node id
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* Returns a configuration form, from which you can create an answer form to be submitted
|
||||
* via the {@link #sendConfigurationForm(Form)}.
|
||||
*
|
||||
* @return the configuration form
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public ConfigureForm getNodeConfiguration() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub pubSub = createPubsubPacket(Type.get, new NodeExtension(
|
||||
PubSubElementType.CONFIGURE_OWNER, getId()), PubSubNamespace.OWNER);
|
||||
Stanza reply = sendPubsubPacket(pubSub);
|
||||
return NodeUtils.getFormFromPacket(reply, PubSubElementType.CONFIGURE_OWNER);
|
||||
}
|
||||
Stanza reply = sendPubsubPacket(pubSub);
|
||||
return NodeUtils.getFormFromPacket(reply, PubSubElementType.CONFIGURE_OWNER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the configuration with the contents of the new {@link Form}.
|
||||
*
|
||||
* @param submitForm
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void sendConfigurationForm(Form submitForm) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
/**
|
||||
* Update the configuration with the contents of the new {@link Form}.
|
||||
*
|
||||
* @param submitForm
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void sendConfigurationForm(Form submitForm) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new FormNode(FormNodeType.CONFIGURE_OWNER,
|
||||
getId(), submitForm), PubSubNamespace.OWNER);
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(packet).nextResultOrThrow();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Discover node information in standard {@link DiscoverInfo} format.
|
||||
*
|
||||
* @return The discovery information about the node.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public DiscoverInfo discoverInfo() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
DiscoverInfo info = new DiscoverInfo();
|
||||
info.setTo(pubSubManager.getServiceJid());
|
||||
info.setNode(getId());
|
||||
return pubSubManager.getConnection().createStanzaCollectorAndSend(info).nextResultOrThrow();
|
||||
}
|
||||
/**
|
||||
* Discover node information in standard {@link DiscoverInfo} format.
|
||||
*
|
||||
* @return The discovery information about the node.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public DiscoverInfo discoverInfo() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
DiscoverInfo info = new DiscoverInfo();
|
||||
info.setTo(pubSubManager.getServiceJid());
|
||||
info.setNode(getId());
|
||||
return pubSubManager.getConnection().createStanzaCollectorAndSend(info).nextResultOrThrow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the subscriptions currently associated with this node.
|
||||
*
|
||||
* @return List of {@link Subscription}
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public List<Subscription> getSubscriptions() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
/**
|
||||
* Get the subscriptions currently associated with this node.
|
||||
*
|
||||
* @return List of {@link Subscription}
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public List<Subscription> getSubscriptions() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
return getSubscriptions(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the subscriptions currently associated with this node.
|
||||
|
@ -223,15 +223,15 @@ abstract public class Node
|
|||
return subElem.getSubscriptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the affiliations of this node.
|
||||
*
|
||||
* @return List of {@link Affiliation}
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
/**
|
||||
* Get the affiliations of this node.
|
||||
*
|
||||
* @return List of {@link Affiliation}
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public List<Affiliation> getAffiliations() throws NoResponseException, XMPPErrorException,
|
||||
NotConnectedException, InterruptedException {
|
||||
return getAffiliations(null, null);
|
||||
|
@ -346,398 +346,394 @@ abstract public class Node
|
|||
return sendPubsubPacket(pubSub);
|
||||
}
|
||||
|
||||
/**
|
||||
* The user subscribes to the node using the supplied jid. The
|
||||
* bare jid portion of this one must match the jid for the connection.
|
||||
*
|
||||
* Please note that the {@link Subscription.State} should be checked
|
||||
* on return since more actions may be required by the caller.
|
||||
* {@link Subscription.State#pending} - The owner must approve the subscription
|
||||
* request before messages will be received.
|
||||
* {@link Subscription.State#unconfigured} - If the {@link Subscription#isConfigRequired()} is true,
|
||||
* the caller must configure the subscription before messages will be received. If it is false
|
||||
* the caller can configure it but is not required to do so.
|
||||
* @param jid The jid to subscribe as.
|
||||
* @return The subscription
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public Subscription subscribe(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
// CHECKSTYLE:OFF
|
||||
PubSub pubSub = createPubsubPacket(Type.set, new SubscribeExtension(jid, getId()));
|
||||
// CHECKSTYLE:ON
|
||||
PubSub reply = sendPubsubPacket(pubSub);
|
||||
return reply.getExtension(PubSubElementType.SUBSCRIPTION);
|
||||
}
|
||||
/**
|
||||
* The user subscribes to the node using the supplied jid. The
|
||||
* bare jid portion of this one must match the jid for the connection.
|
||||
*
|
||||
* Please note that the {@link Subscription.State} should be checked
|
||||
* on return since more actions may be required by the caller.
|
||||
* {@link Subscription.State#pending} - The owner must approve the subscription
|
||||
* request before messages will be received.
|
||||
* {@link Subscription.State#unconfigured} - If the {@link Subscription#isConfigRequired()} is true,
|
||||
* the caller must configure the subscription before messages will be received. If it is false
|
||||
* the caller can configure it but is not required to do so.
|
||||
* @param jid The jid to subscribe as.
|
||||
* @return The subscription
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public Subscription subscribe(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub pubSub = createPubsubPacket(Type.set, new SubscribeExtension(jid, getId()));
|
||||
PubSub reply = sendPubsubPacket(pubSub);
|
||||
return reply.getExtension(PubSubElementType.SUBSCRIPTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* The user subscribes to the node using the supplied jid and subscription
|
||||
* options. The bare jid portion of this one must match the jid for the
|
||||
* connection.
|
||||
*
|
||||
* Please note that the {@link Subscription.State} should be checked
|
||||
* on return since more actions may be required by the caller.
|
||||
* {@link Subscription.State#pending} - The owner must approve the subscription
|
||||
* request before messages will be received.
|
||||
* {@link Subscription.State#unconfigured} - If the {@link Subscription#isConfigRequired()} is true,
|
||||
* the caller must configure the subscription before messages will be received. If it is false
|
||||
* the caller can configure it but is not required to do so.
|
||||
* @param jid The jid to subscribe as.
|
||||
* @return The subscription
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public Subscription subscribe(String jid, SubscribeForm subForm) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
// CHECKSTYLE:OFF
|
||||
PubSub request = createPubsubPacket(Type.set, new SubscribeExtension(jid, getId()));
|
||||
// CHECKSTYLE:ON
|
||||
request.addExtension(new FormNode(FormNodeType.OPTIONS, subForm));
|
||||
PubSub reply = sendPubsubPacket(request);
|
||||
return reply.getExtension(PubSubElementType.SUBSCRIPTION);
|
||||
}
|
||||
/**
|
||||
* The user subscribes to the node using the supplied jid and subscription
|
||||
* options. The bare jid portion of this one must match the jid for the
|
||||
* connection.
|
||||
*
|
||||
* Please note that the {@link Subscription.State} should be checked
|
||||
* on return since more actions may be required by the caller.
|
||||
* {@link Subscription.State#pending} - The owner must approve the subscription
|
||||
* request before messages will be received.
|
||||
* {@link Subscription.State#unconfigured} - If the {@link Subscription#isConfigRequired()} is true,
|
||||
* the caller must configure the subscription before messages will be received. If it is false
|
||||
* the caller can configure it but is not required to do so.
|
||||
* @param jid The jid to subscribe as.
|
||||
* @return The subscription
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public Subscription subscribe(String jid, SubscribeForm subForm) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.set, new SubscribeExtension(jid, getId()));
|
||||
request.addExtension(new FormNode(FormNodeType.OPTIONS, subForm));
|
||||
PubSub reply = sendPubsubPacket(request);
|
||||
return reply.getExtension(PubSubElementType.SUBSCRIPTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the subscription related to the specified JID. This will only
|
||||
* work if there is only 1 subscription. If there are multiple subscriptions,
|
||||
* use {@link #unsubscribe(String, String)}.
|
||||
*
|
||||
* @param jid The JID used to subscribe to the node
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public void unsubscribe(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
unsubscribe(jid, null);
|
||||
}
|
||||
/**
|
||||
* Remove the subscription related to the specified JID. This will only
|
||||
* work if there is only 1 subscription. If there are multiple subscriptions,
|
||||
* use {@link #unsubscribe(String, String)}.
|
||||
*
|
||||
* @param jid The JID used to subscribe to the node
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public void unsubscribe(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
unsubscribe(jid, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specific subscription related to the specified JID.
|
||||
*
|
||||
* @param jid The JID used to subscribe to the node
|
||||
* @param subscriptionId The id of the subscription being removed
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void unsubscribe(String jid, String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
sendPubsubPacket(createPubsubPacket(Type.set, new UnsubscribeExtension(jid, getId(), subscriptionId)));
|
||||
}
|
||||
/**
|
||||
* Remove the specific subscription related to the specified JID.
|
||||
*
|
||||
* @param jid The JID used to subscribe to the node
|
||||
* @param subscriptionId The id of the subscription being removed
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void unsubscribe(String jid, String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
sendPubsubPacket(createPubsubPacket(Type.set, new UnsubscribeExtension(jid, getId(), subscriptionId)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a SubscribeForm for subscriptions, from which you can create an answer form to be submitted
|
||||
* via the {@link #sendConfigurationForm(Form)}.
|
||||
*
|
||||
* @return A subscription options form
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public SubscribeForm getSubscriptionOptions(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
return getSubscriptionOptions(jid, null);
|
||||
}
|
||||
/**
|
||||
* Returns a SubscribeForm for subscriptions, from which you can create an answer form to be submitted
|
||||
* via the {@link #sendConfigurationForm(Form)}.
|
||||
*
|
||||
* @return A subscription options form
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public SubscribeForm getSubscriptionOptions(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
return getSubscriptionOptions(jid, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the options for configuring the specified subscription.
|
||||
*
|
||||
* @param jid JID the subscription is registered under
|
||||
* @param subscriptionId The subscription id
|
||||
*
|
||||
* @return The subscription option form
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public SubscribeForm getSubscriptionOptions(String jid, String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = sendPubsubPacket(createPubsubPacket(Type.get, new OptionsExtension(jid, getId(), subscriptionId)));
|
||||
FormNode ext = packet.getExtension(PubSubElementType.OPTIONS);
|
||||
return new SubscribeForm(ext.getForm());
|
||||
}
|
||||
/**
|
||||
* Get the options for configuring the specified subscription.
|
||||
*
|
||||
* @param jid JID the subscription is registered under
|
||||
* @param subscriptionId The subscription id
|
||||
*
|
||||
* @return The subscription option form
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public SubscribeForm getSubscriptionOptions(String jid, String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = sendPubsubPacket(createPubsubPacket(Type.get, new OptionsExtension(jid, getId(), subscriptionId)));
|
||||
FormNode ext = packet.getExtension(PubSubElementType.OPTIONS);
|
||||
return new SubscribeForm(ext.getForm());
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a listener for item publication events. This
|
||||
* listener will get called whenever an item is published to
|
||||
* this node.
|
||||
*
|
||||
* @param listener The handler for the event
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
/**
|
||||
* Register a listener for item publication events. This
|
||||
* listener will get called whenever an item is published to
|
||||
* this node.
|
||||
*
|
||||
* @param listener The handler for the event
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void addItemEventListener(@SuppressWarnings("rawtypes") ItemEventListener listener)
|
||||
{
|
||||
StanzaListener conListener = new ItemEventTranslator(listener);
|
||||
itemEventToListenerMap.put(listener, conListener);
|
||||
pubSubManager.getConnection().addSyncStanzaListener(conListener, new EventContentFilter(EventElementType.items.toString(), "item"));
|
||||
}
|
||||
{
|
||||
StanzaListener conListener = new ItemEventTranslator(listener);
|
||||
itemEventToListenerMap.put(listener, conListener);
|
||||
pubSubManager.getConnection().addSyncStanzaListener(conListener, new EventContentFilter(EventElementType.items.toString(), "item"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a listener for publication events.
|
||||
*
|
||||
* @param listener The handler to unregister
|
||||
*/
|
||||
public void removeItemEventListener(@SuppressWarnings("rawtypes") ItemEventListener listener)
|
||||
{
|
||||
StanzaListener conListener = itemEventToListenerMap.remove(listener);
|
||||
/**
|
||||
* Unregister a listener for publication events.
|
||||
*
|
||||
* @param listener The handler to unregister
|
||||
*/
|
||||
public void removeItemEventListener(@SuppressWarnings("rawtypes") ItemEventListener listener)
|
||||
{
|
||||
StanzaListener conListener = itemEventToListenerMap.remove(listener);
|
||||
|
||||
if (conListener != null)
|
||||
pubSubManager.getConnection().removeSyncStanzaListener(conListener);
|
||||
}
|
||||
if (conListener != null)
|
||||
pubSubManager.getConnection().removeSyncStanzaListener(conListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a listener for configuration events. This listener
|
||||
* will get called whenever the node's configuration changes.
|
||||
*
|
||||
* @param listener The handler for the event
|
||||
*/
|
||||
public void addConfigurationListener(NodeConfigListener listener)
|
||||
{
|
||||
StanzaListener conListener = new NodeConfigTranslator(listener);
|
||||
configEventToListenerMap.put(listener, conListener);
|
||||
pubSubManager.getConnection().addSyncStanzaListener(conListener, new EventContentFilter(EventElementType.configuration.toString()));
|
||||
}
|
||||
/**
|
||||
* Register a listener for configuration events. This listener
|
||||
* will get called whenever the node's configuration changes.
|
||||
*
|
||||
* @param listener The handler for the event
|
||||
*/
|
||||
public void addConfigurationListener(NodeConfigListener listener)
|
||||
{
|
||||
StanzaListener conListener = new NodeConfigTranslator(listener);
|
||||
configEventToListenerMap.put(listener, conListener);
|
||||
pubSubManager.getConnection().addSyncStanzaListener(conListener, new EventContentFilter(EventElementType.configuration.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a listener for configuration events.
|
||||
*
|
||||
* @param listener The handler to unregister
|
||||
*/
|
||||
public void removeConfigurationListener(NodeConfigListener listener)
|
||||
{
|
||||
StanzaListener conListener = configEventToListenerMap .remove(listener);
|
||||
/**
|
||||
* Unregister a listener for configuration events.
|
||||
*
|
||||
* @param listener The handler to unregister
|
||||
*/
|
||||
public void removeConfigurationListener(NodeConfigListener listener)
|
||||
{
|
||||
StanzaListener conListener = configEventToListenerMap .remove(listener);
|
||||
|
||||
if (conListener != null)
|
||||
pubSubManager.getConnection().removeSyncStanzaListener(conListener);
|
||||
}
|
||||
if (conListener != null)
|
||||
pubSubManager.getConnection().removeSyncStanzaListener(conListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an listener for item delete events. This listener
|
||||
* gets called whenever an item is deleted from the node.
|
||||
*
|
||||
* @param listener The handler for the event
|
||||
*/
|
||||
public void addItemDeleteListener(ItemDeleteListener listener)
|
||||
{
|
||||
StanzaListener delListener = new ItemDeleteTranslator(listener);
|
||||
itemDeleteToListenerMap.put(listener, delListener);
|
||||
EventContentFilter deleteItem = new EventContentFilter(EventElementType.items.toString(), "retract");
|
||||
EventContentFilter purge = new EventContentFilter(EventElementType.purge.toString());
|
||||
/**
|
||||
* Register an listener for item delete events. This listener
|
||||
* gets called whenever an item is deleted from the node.
|
||||
*
|
||||
* @param listener The handler for the event
|
||||
*/
|
||||
public void addItemDeleteListener(ItemDeleteListener listener)
|
||||
{
|
||||
StanzaListener delListener = new ItemDeleteTranslator(listener);
|
||||
itemDeleteToListenerMap.put(listener, delListener);
|
||||
EventContentFilter deleteItem = new EventContentFilter(EventElementType.items.toString(), "retract");
|
||||
EventContentFilter purge = new EventContentFilter(EventElementType.purge.toString());
|
||||
|
||||
pubSubManager.getConnection().addSyncStanzaListener(delListener, new OrFilter(deleteItem, purge));
|
||||
}
|
||||
pubSubManager.getConnection().addSyncStanzaListener(delListener, new OrFilter(deleteItem, purge));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a listener for item delete events.
|
||||
*
|
||||
* @param listener The handler to unregister
|
||||
*/
|
||||
public void removeItemDeleteListener(ItemDeleteListener listener)
|
||||
{
|
||||
StanzaListener conListener = itemDeleteToListenerMap .remove(listener);
|
||||
/**
|
||||
* Unregister a listener for item delete events.
|
||||
*
|
||||
* @param listener The handler to unregister
|
||||
*/
|
||||
public void removeItemDeleteListener(ItemDeleteListener listener)
|
||||
{
|
||||
StanzaListener conListener = itemDeleteToListenerMap .remove(listener);
|
||||
|
||||
if (conListener != null)
|
||||
pubSubManager.getConnection().removeSyncStanzaListener(conListener);
|
||||
}
|
||||
if (conListener != null)
|
||||
pubSubManager.getConnection().removeSyncStanzaListener(conListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return super.toString() + " " + getClass().getName() + " id: " + id;
|
||||
}
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return super.toString() + " " + getClass().getName() + " id: " + id;
|
||||
}
|
||||
|
||||
protected PubSub createPubsubPacket(Type type, ExtensionElement ext)
|
||||
{
|
||||
return createPubsubPacket(type, ext, null);
|
||||
}
|
||||
protected PubSub createPubsubPacket(Type type, ExtensionElement ext)
|
||||
{
|
||||
return createPubsubPacket(type, ext, null);
|
||||
}
|
||||
|
||||
protected PubSub createPubsubPacket(Type type, ExtensionElement ext, PubSubNamespace ns)
|
||||
{
|
||||
protected PubSub createPubsubPacket(Type type, ExtensionElement ext, PubSubNamespace ns)
|
||||
{
|
||||
return PubSub.createPubsubPacket(pubSubManager.getServiceJid(), type, ext, ns);
|
||||
}
|
||||
}
|
||||
|
||||
protected PubSub sendPubsubPacket(PubSub packet) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
return pubSubManager.sendPubsubPacket(packet);
|
||||
}
|
||||
protected PubSub sendPubsubPacket(PubSub packet) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
return pubSubManager.sendPubsubPacket(packet);
|
||||
}
|
||||
|
||||
|
||||
private static List<String> getSubscriptionIds(Stanza packet)
|
||||
{
|
||||
HeadersExtension headers = (HeadersExtension)packet.getExtension("headers", "http://jabber.org/protocol/shim");
|
||||
List<String> values = null;
|
||||
private static List<String> getSubscriptionIds(Stanza packet)
|
||||
{
|
||||
HeadersExtension headers = (HeadersExtension)packet.getExtension("headers", "http://jabber.org/protocol/shim");
|
||||
List<String> values = null;
|
||||
|
||||
if (headers != null)
|
||||
{
|
||||
values = new ArrayList<String>(headers.getHeaders().size());
|
||||
if (headers != null)
|
||||
{
|
||||
values = new ArrayList<String>(headers.getHeaders().size());
|
||||
|
||||
for (Header header : headers.getHeaders())
|
||||
{
|
||||
values.add(header.getValue());
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
for (Header header : headers.getHeaders())
|
||||
{
|
||||
values.add(header.getValue());
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class translates low level item publication events into api level objects for
|
||||
* user consumption.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
public class ItemEventTranslator implements StanzaListener
|
||||
{
|
||||
@SuppressWarnings("rawtypes")
|
||||
/**
|
||||
* This class translates low level item publication events into api level objects for
|
||||
* user consumption.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
public class ItemEventTranslator implements StanzaListener
|
||||
{
|
||||
@SuppressWarnings("rawtypes")
|
||||
private ItemEventListener listener;
|
||||
|
||||
public ItemEventTranslator(@SuppressWarnings("rawtypes") ItemEventListener eventListener)
|
||||
{
|
||||
listener = eventListener;
|
||||
}
|
||||
public ItemEventTranslator(@SuppressWarnings("rawtypes") ItemEventListener eventListener)
|
||||
{
|
||||
listener = eventListener;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public void processStanza(Stanza packet)
|
||||
{
|
||||
{
|
||||
// CHECKSTYLE:OFF
|
||||
EventElement event = (EventElement)packet.getExtension("event", PubSubNamespace.EVENT.getXmlns());
|
||||
EventElement event = (EventElement)packet.getExtension("event", PubSubNamespace.EVENT.getXmlns());
|
||||
// CHECKSTYLE:ON
|
||||
ItemsExtension itemsElem = (ItemsExtension)event.getEvent();
|
||||
ItemsExtension itemsElem = (ItemsExtension)event.getEvent();
|
||||
ItemPublishEvent eventItems = new ItemPublishEvent(itemsElem.getNode(), itemsElem.getItems(), getSubscriptionIds(packet), DelayInformationManager.getDelayTimestamp(packet));
|
||||
listener.handlePublishedItems(eventItems);
|
||||
}
|
||||
}
|
||||
listener.handlePublishedItems(eventItems);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class translates low level item deletion events into api level objects for
|
||||
* user consumption.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
public class ItemDeleteTranslator implements StanzaListener
|
||||
{
|
||||
private ItemDeleteListener listener;
|
||||
/**
|
||||
* This class translates low level item deletion events into api level objects for
|
||||
* user consumption.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
public class ItemDeleteTranslator implements StanzaListener
|
||||