1
0
Fork 0
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:
Florian Schmaus 2017-02-07 22:02:40 +01:00
parent ffe9397e66
commit ef0af66b21
125 changed files with 5336 additions and 5344 deletions

View file

@ -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"/>

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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) {

View file

@ -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();
}
}
}
}

View file

@ -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?

View file

@ -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&apos;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);

View file

@ -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");

View file

@ -18,6 +18,6 @@ package org.jivesoftware.smackx.blocking;
public interface AllJidsUnblockedListener {
void onAllJidsUnblocked();
void onAllJidsUnblocked();
}

View file

@ -22,6 +22,6 @@ import org.jxmpp.jid.Jid;
public interface JidsBlockedListener {
void onJidsBlocked(List<Jid> blockedJids);
void onJidsBlocked(List<Jid> blockedJids);
}

View file

@ -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;
}
}
}

View file

@ -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);
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}

View file

@ -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.

View file

@ -71,6 +71,6 @@ public class RegistrationProvider extends IQProvider<Registration> {
Registration registration = new Registration(instruction, fields);
registration.addExtensions(packetExtensions);
return registration;
}
}
}

View file

@ -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);
}
}
}

View file

@ -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

View file

@ -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;
}

View file

@ -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 {

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}
}
}
}
}

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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()));
}
}

View file

@ -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();
}
}

View file

@ -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();
}

View file

@ -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() {

View file

@ -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
}

View file

@ -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();
}
}
}

View file

@ -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));
}
}

View file

@ -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());

View file

@ -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() + "]";
}
}

View file

@ -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 + ']';
}
}

View file

@ -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") + ']';
}
}

View file

@ -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;
}

View file

@ -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() + "]";
}
}

View file

@ -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();
}
}

View file

@ -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