Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorslewis2007-01-22 07:07:19 +0000
committerslewis2007-01-22 07:07:19 +0000
commit4a6faff2164d30e13e915f0488619797fb195320 (patch)
treea4371f3ceafececde0ca61934399bce6a1531696 /protocols
parent6ea7a95e168251a564bb1859f086c13e42a9a386 (diff)
downloadorg.eclipse.ecf-4a6faff2164d30e13e915f0488619797fb195320.tar.gz
org.eclipse.ecf-4a6faff2164d30e13e915f0488619797fb195320.tar.xz
org.eclipse.ecf-4a6faff2164d30e13e915f0488619797fb195320.zip
Checked in v2.2.1 of smack api. Also changed IRosterItem.getParent() to return IRosterItem rather than Object. Changed refernences in constructors of IRosterEntry, IRosterGroup to refere to IRosterItem, also had Roster extend RosterItem.
Diffstat (limited to 'protocols')
-rw-r--r--protocols/bundles/org.jivesoftware.smack/.classpath4
-rw-r--r--protocols/bundles/org.jivesoftware.smack/META-INF/MANIFEST.MF10
-rw-r--r--protocols/bundles/org.jivesoftware.smack/META-INF/smack-config.xml (renamed from protocols/bundles/org.jivesoftware.smack/src/META-INF/smack-config.xml)0
-rw-r--r--protocols/bundles/org.jivesoftware.smack/META-INF/smack.providers (renamed from protocols/bundles/org.jivesoftware.smack/src/META-INF/smack.providers)0
-rw-r--r--protocols/bundles/org.jivesoftware.smack/build.properties6
-rw-r--r--protocols/bundles/org.jivesoftware.smack/jars/smack.jarbin178866 -> 0 bytes
-rw-r--r--protocols/bundles/org.jivesoftware.smack/jars/smackx-debug.jarbin52905 -> 0 bytes
-rw-r--r--protocols/bundles/org.jivesoftware.smack/jars/smackx.jarbin306783 -> 0 bytes
-rw-r--r--protocols/bundles/org.jivesoftware.smack/jars/xmlpull.v1.jarbin32679 -> 0 bytes
-rw-r--r--protocols/bundles/org.jivesoftware.smack/jars/xpp.jarbin0 -> 24676 bytes
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/ConnectionListener2.java10
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PacketReader.java44
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PacketWriter.java85
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/Roster.java14
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/RosterListener.java3
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/SmackConfiguration.java2
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/XMPPConnection.java9
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/Presence.java2
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/RosterPacket.java8
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/provider/ProviderManager.java71
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/Base64.java (renamed from protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/Base64.java)102
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/PacketParserUtils.java2
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/StringUtils.java119
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/PrivateDataManager.java14
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bookmark/BookmarkedConference.java91
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bookmark/BookmarkedURL.java57
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bookmark/Bookmarks.java277
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/debugger/EnhancedDebuggerWindow.java4
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java122
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java2
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/IBBTransferNegotiator.java28
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java71
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/Bytestream.java6
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/VCard.java101
-rw-r--r--protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/VCardProvider.java6
35 files changed, 869 insertions, 401 deletions
diff --git a/protocols/bundles/org.jivesoftware.smack/.classpath b/protocols/bundles/org.jivesoftware.smack/.classpath
index eb3e49cbe..2fca53c3f 100644
--- a/protocols/bundles/org.jivesoftware.smack/.classpath
+++ b/protocols/bundles/org.jivesoftware.smack/.classpath
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="src" path="src/"/>
- <classpathentry exported="true" kind="lib" path="jars/xmlpull.v1.jar"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry exported="true" kind="lib" path="jars/xpp.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
diff --git a/protocols/bundles/org.jivesoftware.smack/META-INF/MANIFEST.MF b/protocols/bundles/org.jivesoftware.smack/META-INF/MANIFEST.MF
index 1a6ba4da7..53dc291fe 100644
--- a/protocols/bundles/org.jivesoftware.smack/META-INF/MANIFEST.MF
+++ b/protocols/bundles/org.jivesoftware.smack/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Jive Software Smack API
Bundle-SymbolicName: org.jivesoftware.smack;singleton:=true
-Bundle-Version: 2.2.0
+Bundle-Version: 2.2.1
Bundle-Vendor: Jive Software
Bundle-Localization: plugin
Export-Package: org.jivesoftware.smack,
@@ -13,15 +13,15 @@ Export-Package: org.jivesoftware.smack,
org.jivesoftware.smack.sasl,
org.jivesoftware.smack.util,
org.jivesoftware.smackx,
+ org.jivesoftware.smackx.bookmark,
org.jivesoftware.smackx.debugger,
org.jivesoftware.smackx.filetransfer,
org.jivesoftware.smackx.muc,
org.jivesoftware.smackx.packet,
org.jivesoftware.smackx.provider,
- org.jivesoftware.smackx.search,
- org.xmlpull.mxp1,
- org.xmlpull.v1
-Bundle-ClassPath: ., jars/xmlpull.v1.jar
+ org.jivesoftware.smackx.search
+Bundle-ClassPath: .,
+ jars/xpp.jar
Bundle-RequiredExecutionEnvironment: J2SE-1.4,
CDC-1.1/Foundation-1.1
Eclipse-ExtensibleAPI: true
diff --git a/protocols/bundles/org.jivesoftware.smack/src/META-INF/smack-config.xml b/protocols/bundles/org.jivesoftware.smack/META-INF/smack-config.xml
index eb0ea25ce..eb0ea25ce 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/META-INF/smack-config.xml
+++ b/protocols/bundles/org.jivesoftware.smack/META-INF/smack-config.xml
diff --git a/protocols/bundles/org.jivesoftware.smack/src/META-INF/smack.providers b/protocols/bundles/org.jivesoftware.smack/META-INF/smack.providers
index 71312601f..71312601f 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/META-INF/smack.providers
+++ b/protocols/bundles/org.jivesoftware.smack/META-INF/smack.providers
diff --git a/protocols/bundles/org.jivesoftware.smack/build.properties b/protocols/bundles/org.jivesoftware.smack/build.properties
index 24dc502a3..7d900888d 100644
--- a/protocols/bundles/org.jivesoftware.smack/build.properties
+++ b/protocols/bundles/org.jivesoftware.smack/build.properties
@@ -1,9 +1,11 @@
-bin.includes = ., META-INF/,\
+bin.includes = META-INF/,\
plugin.xml,\
schema/,\
jars/,\
about.html,\
- asl-v20.txt
+ asl-v20.txt,\
+ jars/xpp.jar,\
+ .
src.includes = schema/,\
plugin.xml,\
META-INF/,\
diff --git a/protocols/bundles/org.jivesoftware.smack/jars/smack.jar b/protocols/bundles/org.jivesoftware.smack/jars/smack.jar
deleted file mode 100644
index dfe9d8426..000000000
--- a/protocols/bundles/org.jivesoftware.smack/jars/smack.jar
+++ /dev/null
Binary files differ
diff --git a/protocols/bundles/org.jivesoftware.smack/jars/smackx-debug.jar b/protocols/bundles/org.jivesoftware.smack/jars/smackx-debug.jar
deleted file mode 100644
index ff9c58781..000000000
--- a/protocols/bundles/org.jivesoftware.smack/jars/smackx-debug.jar
+++ /dev/null
Binary files differ
diff --git a/protocols/bundles/org.jivesoftware.smack/jars/smackx.jar b/protocols/bundles/org.jivesoftware.smack/jars/smackx.jar
deleted file mode 100644
index 00eeeaeb3..000000000
--- a/protocols/bundles/org.jivesoftware.smack/jars/smackx.jar
+++ /dev/null
Binary files differ
diff --git a/protocols/bundles/org.jivesoftware.smack/jars/xmlpull.v1.jar b/protocols/bundles/org.jivesoftware.smack/jars/xmlpull.v1.jar
deleted file mode 100644
index 937c885a3..000000000
--- a/protocols/bundles/org.jivesoftware.smack/jars/xmlpull.v1.jar
+++ /dev/null
Binary files differ
diff --git a/protocols/bundles/org.jivesoftware.smack/jars/xpp.jar b/protocols/bundles/org.jivesoftware.smack/jars/xpp.jar
new file mode 100644
index 000000000..80f659ca2
--- /dev/null
+++ b/protocols/bundles/org.jivesoftware.smack/jars/xpp.jar
Binary files differ
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/ConnectionListener2.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/ConnectionListener2.java
deleted file mode 100644
index 8a3a73174..000000000
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/ConnectionListener2.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.jivesoftware.smack;
-
-public interface ConnectionListener2 {
-
- /**
- * Notification that the connection has been authenticated.
- */
- public void connectionAuthenticated();
-
-}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PacketReader.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PacketReader.java
index 946468262..8ee3ba6c1 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PacketReader.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PacketReader.java
@@ -215,6 +215,11 @@ class PacketReader {
listener.connectionClosedOnError(e);
}
}
+
+ // Make sure that the listenerThread is awake to shutdown properly
+ synchronized (listenerThread) {
+ listenerThread.notify();
+ }
}
/**
@@ -499,37 +504,14 @@ class PacketReader {
releaseConnectionIDLock();
}
}
+
/**
- * Sends out a notification that there was an error with the connection and
- * closes the connection.
- *
- * @param e
- * the exception that causes the connection close event.
- */
- void notifyConnectionAuthenticated() {
- ArrayList listenersCopy;
- synchronized (connectionListeners) {
- // Make a copy since it's possible that a listener will be removed
- // from the list
- listenersCopy = new ArrayList(connectionListeners);
- for (Iterator i = listenersCopy.iterator(); i.hasNext();) {
- ConnectionListener listener = (ConnectionListener) i.next();
- if (listener instanceof ConnectionListener2)
- ((ConnectionListener2) listener).connectionAuthenticated();
- }
- }
- }
- /**
- * Returns a collection of Stings with the mechanisms included in the
- * mechanisms stanza.
- *
- * @param parser
- * the XML parser, positioned at the start of an IQ packet.
- * @return a collection of Stings with the mechanisms included in the
- * mechanisms stanza.
- * @throws Exception
- * if an exception occurs while parsing the stanza.
- */
+ * Returns a collection of Stings with the mechanisms included in the mechanisms stanza.
+ *
+ * @param parser the XML parser, positioned at the start of an IQ packet.
+ * @return a collection of Stings with the mechanisms included in the mechanisms stanza.
+ * @throws Exception if an exception occurs while parsing the stanza.
+ */
private Collection parseMechanisms(XmlPullParser parser) throws Exception {
List mechanisms = new ArrayList();
boolean done = false;
@@ -615,7 +597,7 @@ class PacketReader {
// Otherwise, see if there is a registered provider for
// this element name and namespace.
else {
- Object provider = ProviderManager.getDefault().getIQProvider(elementName, namespace);
+ Object provider = ProviderManager.getIQProvider(elementName, namespace);
if (provider != null) {
if (provider instanceof IQProvider) {
iqPacket = ((IQProvider)provider).parseIQ(parser);
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PacketWriter.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PacketWriter.java
index cbfc6be53..93cb37e68 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PacketWriter.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/PacketWriter.java
@@ -20,12 +20,15 @@
package org.jivesoftware.smack;
-import java.util.*;
-import java.io.*;
-
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Packet;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
/**
* Writes packets to a XMPP server. Packets are sent using a dedicated thread. Packet
* interceptors can be registered to dynamically modify packets before they're actually
@@ -38,18 +41,24 @@ class PacketWriter {
private Thread writerThread;
private Writer writer;
private XMPPConnection connection;
- private LinkedList queue;
+ final private LinkedList queue;
private boolean done = false;
- private List listeners = new ArrayList();
+ final private List listeners = new ArrayList();
private boolean listenersDeleted = false;
/**
+ * Timestamp when the last stanza was sent to the server. This information is used
+ * by the keep alive process to only send heartbeats when the connection has been idle.
+ */
+ private long lastActive = System.currentTimeMillis();
+
+ /**
* List of PacketInterceptor that will be notified when a new packet is about to be
* sent to the server. These interceptors may modify the packet before it is being
* actually sent to the server.
*/
- private List interceptors = new ArrayList();
+ final private List interceptors = new ArrayList();
/**
* Flag that indicates if an interceptor was deleted. This is an optimization flag.
*/
@@ -72,15 +81,6 @@ class PacketWriter {
};
writerThread.setName("Smack Packet Writer");
writerThread.setDaemon(true);
-
- // Schedule a keep-alive task to run if the feature is enabled. will write
- // out a space character each time it runs to keep the TCP/IP connection open.
- int keepAliveInterval = SmackConfiguration.getKeepAliveInterval();
- if (keepAliveInterval > 0) {
- Thread keepAliveThread = new Thread(new KeepAliveTask(keepAliveInterval));
- keepAliveThread.setDaemon(true);
- keepAliveThread.start();
- }
}
/**
@@ -195,6 +195,22 @@ class PacketWriter {
writerThread.start();
}
+ /**
+ * Starts the keep alive process. A white space (aka heartbeat) is going to be
+ * sent to the server every 30 seconds (by default) since the last stanza was sent
+ * to the server.
+ */
+ void startKeepAliveProcess() {
+ // Schedule a keep-alive task to run if the feature is enabled. will write
+ // out a space character each time it runs to keep the TCP/IP connection open.
+ int keepAliveInterval = SmackConfiguration.getKeepAliveInterval();
+ if (keepAliveInterval > 0) {
+ Thread keepAliveThread = new Thread(new KeepAliveTask(keepAliveInterval));
+ keepAliveThread.setDaemon(true);
+ keepAliveThread.start();
+ }
+ }
+
void setWriter(Writer writer) {
this.writer = writer;
}
@@ -218,7 +234,9 @@ class PacketWriter {
try {
queue.wait(2000);
}
- catch (InterruptedException ie) { }
+ catch (InterruptedException ie) {
+ // Do nothing
+ }
}
if (queue.size() > 0) {
return (Packet)queue.removeLast();
@@ -240,6 +258,8 @@ class PacketWriter {
synchronized (writer) {
writer.write(packet.toXML());
writer.flush();
+ // Keep track of the last time a stanza was sent to the server
+ lastActive = System.currentTimeMillis();
}
}
}
@@ -248,12 +268,16 @@ class PacketWriter {
writer.write("</stream:stream>");
writer.flush();
}
- catch (Exception e) { }
+ catch (Exception e) {
+ // Do nothing
+ }
finally {
try {
writer.close();
}
- catch (Exception e) { }
+ catch (Exception e) {
+ // Do nothing
+ }
}
}
catch (IOException ioe){
@@ -432,19 +456,34 @@ class PacketWriter {
}
public void run() {
+ try {
+ // Sleep 15 seconds before sending first heartbeat. This will give time to
+ // properly finish TLS negotiation and then start sending heartbeats.
+ Thread.sleep(15000);
+ }
+ catch (InterruptedException ie) {
+ // Do nothing
+ }
while (!done) {
synchronized (writer) {
- try {
- writer.write(" ");
- writer.flush();
+ // Send heartbeat if no packet has been sent to the server for a given time
+ if (System.currentTimeMillis() - lastActive >= delay) {
+ try {
+ writer.write(" ");
+ writer.flush();
+ }
+ catch (Exception e) {
+ // Do nothing
+ }
}
- catch (Exception e) { }
}
try {
// Sleep until we should write the next keep-alive.
Thread.sleep(delay);
}
- catch (InterruptedException ie) { }
+ catch (InterruptedException ie) {
+ // Do nothing
+ }
}
}
}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/Roster.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/Roster.java
index 196a4c3ea..9a46fb050 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/Roster.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/Roster.java
@@ -440,7 +440,15 @@ public class Roster {
* when you are not subscribed to the user's presence updates.<p>
*
* If the user has several presences (one for each resource) then answer the presence
- * with the highest priority.
+ * with the highest priority.<p>
+ *
+ * Note that presence information is received asynchronously. So, just after logging
+ * in to the server, presence values for users in the roster might be <tt>null</tt>
+ * even if they are actually online. In other words, the value returned by this
+ * method should only be treated as a snapshot in time, and may not accurately reflect
+ * other user's presence instant by instant. If you need to track presence over time,
+ * such as when showing a visual representation of the roster, consider using a
+ * {@link RosterListener}.
*
* @param user a fully qualified xmpp ID. The address could be in any valid format (e.g.
* "domain/resource", "user@domain" or "user@domain/resource").
@@ -552,7 +560,7 @@ public class Roster {
*/
private void fireRosterChangedEvent(Collection addedEntries, Collection updatedEntries,
Collection deletedEntries) {
- RosterListener [] listeners = null;
+ RosterListener [] listeners;
synchronized (rosterListeners) {
listeners = new RosterListener[rosterListeners.size()];
rosterListeners.toArray(listeners);
@@ -574,7 +582,7 @@ public class Roster {
* Fires roster presence changed event to roster listeners.
*/
private void fireRosterPresenceEvent(String user) {
- RosterListener [] listeners = null;
+ RosterListener [] listeners;
synchronized (rosterListeners) {
listeners = new RosterListener[rosterListeners.size()];
rosterListeners.toArray(listeners);
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/RosterListener.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/RosterListener.java
index fbc6ce8e7..11f6bcdd3 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/RosterListener.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/RosterListener.java
@@ -25,7 +25,8 @@ import java.util.Collection;
/**
* A listener that is fired any time a roster is changed or the presence of
* a user in the roster is changed.
- *
+ *
+ * @see Roster#addRosterListener(RosterListener)
* @author Matt Tucker
*/
public interface RosterListener {
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/SmackConfiguration.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/SmackConfiguration.java
index 250f372d6..b3ccd2d7d 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/SmackConfiguration.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/SmackConfiguration.java
@@ -44,7 +44,7 @@ import java.util.Enumeration;
*/
public final class SmackConfiguration {
- private static final String SMACK_VERSION = "2.2.0";
+ private static final String SMACK_VERSION = "2.2.1";
private static int packetReplyTimeout = 5000;
private static int keepAliveInterval = 30000;
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/XMPPConnection.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/XMPPConnection.java
index ce5be5c5f..af90568e8 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/XMPPConnection.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/XMPPConnection.java
@@ -459,9 +459,6 @@ public class XMPPConnection {
// Indicate that we're now authenticated.
authenticated = true;
-
- packetReader.notifyConnectionAuthenticated();
-
anonymous = false;
// If debugging is enabled, change the the debug window title to include the
@@ -519,9 +516,6 @@ public class XMPPConnection {
// Indicate that we're now authenticated.
authenticated = true;
-
- packetReader.notifyConnectionAuthenticated();
-
anonymous = true;
// If debugging is enabled, change the the debug window title to include the
@@ -882,6 +876,9 @@ public class XMPPConnection {
// Make note of the fact that we're now connected.
connected = true;
+ // Start keep alive process (after TLS was negotiated - if available)
+ packetWriter.startKeepAliveProcess();
+
// Notify that a new connection has been established
connectionEstablished(this);
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/Presence.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/Presence.java
index 52e17d0f0..ebc20565b 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/Presence.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/Presence.java
@@ -184,7 +184,7 @@ public class Presence extends Packet {
}
buf.append(">");
if (status != null) {
- buf.append("<status>").append(status).append("</status>");
+ buf.append("<status>").append(StringUtils.escapeForXML(status)).append("</status>");
}
if (priority != -1) {
buf.append("<priority>").append(priority).append("</priority>");
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/RosterPacket.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/RosterPacket.java
index 30048b7c3..88ac2966d 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/RosterPacket.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/packet/RosterPacket.java
@@ -20,6 +20,8 @@
package org.jivesoftware.smack.packet;
+import org.jivesoftware.smack.util.StringUtils;
+
import java.util.*;
/**
@@ -29,7 +31,7 @@ import java.util.*;
*/
public class RosterPacket extends IQ {
- private List rosterItems = new ArrayList();
+ private final List rosterItems = new ArrayList();
/**
* Adds a roster item to the packet.
@@ -88,7 +90,7 @@ public class RosterPacket extends IQ {
private String name;
private ItemType itemType;
private ItemStatus itemStatus;
- private List groupNames;
+ private final List groupNames;
/**
* Creates a new roster item.
@@ -219,7 +221,7 @@ public class RosterPacket extends IQ {
synchronized (groupNames) {
for (int i=0; i<groupNames.size(); i++) {
String groupName = (String)groupNames.get(i);
- buf.append("<group>").append(groupName).append("</group>");
+ buf.append("<group>").append(StringUtils.escapeForXML(groupName)).append("</group>");
}
}
buf.append("</item>");
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/provider/ProviderManager.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/provider/ProviderManager.java
index 34a6c356f..f7cd792da 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/provider/ProviderManager.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/provider/ProviderManager.java
@@ -23,6 +23,7 @@ package org.jivesoftware.smack.provider;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.PacketExtension;
import org.xmlpull.v1.*;
+import org.xmlpull.mxp1.MXParser;
import java.util.*;
import java.net.URL;
@@ -108,29 +109,10 @@ import java.net.URL;
*/
public class ProviderManager {
- private static ProviderManager defaultProvider = null;
+ private static Map extensionProviders = new Hashtable();
+ private static Map iqProviders = new Hashtable();
- private Map extensionProviders = new Hashtable();
- private Map iqProviders = new Hashtable();
-
- public static ProviderManager getDefault() {
- if (defaultProvider == null)
- defaultProvider = new ProviderManager();
- return defaultProvider;
- }
-
- public static void setDefault(ProviderManager value) {
- if (defaultProvider != null)
- throw new IllegalStateException("ProviderManager default already set");
- defaultProvider = value;
- }
-
- public ProviderManager() {
- super();
- initialize();
- }
-
- protected void initialize() {
+ static {
// Load IQ processing providers.
try {
// Get an array of class loaders to try loading the providers files from.
@@ -143,10 +125,8 @@ public class ProviderManager {
java.io.InputStream providerStream = null;
try {
providerStream = url.openStream();
- XmlPullParserFactory factory = XmlPullParserFactory.newInstance(
- "org.xmlpull.mxp1.MXParserFactory", null);
- factory.setNamespaceAware(true);
- XmlPullParser parser = factory.newPullParser();
+ XmlPullParser parser = new MXParser();
+ parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
parser.setInput(providerStream, "UTF-8");
int eventType = parser.getEventType();
do {
@@ -233,7 +213,9 @@ public class ProviderManager {
}
}
}
- catch (Exception e) { }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
}
/**
@@ -256,7 +238,7 @@ public class ProviderManager {
* @param namespace the XML namespace.
* @return the IQ provider.
*/
- public Object getIQProvider(String elementName, String namespace) {
+ public static Object getIQProvider(String elementName, String namespace) {
String key = getProviderKey(elementName, namespace);
return iqProviders.get(key);
}
@@ -266,7 +248,7 @@ public class ProviderManager {
*
* @return an Iterator for all IQProvider instances.
*/
- public Iterator getIQProviders() {
+ public static Iterator getIQProviders() {
return Collections.unmodifiableCollection(new HashMap(iqProviders).values()).iterator();
}
@@ -279,7 +261,7 @@ public class ProviderManager {
* @param namespace the XML namespace.
* @param provider the IQ provider.
*/
- public void addIQProvider(String elementName, String namespace,
+ public static void addIQProvider(String elementName, String namespace,
Object provider)
{
if (!(provider instanceof IQProvider || (provider instanceof Class &&
@@ -293,12 +275,14 @@ public class ProviderManager {
}
/**
- * Removes the IQ provider with the specified element name and name space.
+ * Removes an IQ provider with the specified element name and namespace. This
+ * method is typically called to cleanup providers that are programatically added
+ * using the {@link #addIQProvider(String, String, Object) addIQProvider} method.
*
* @param elementName the XML element name.
* @param namespace the XML namespace.
*/
- public void removeIQProvider(String elementName, String namespace) {
+ public static void removeIQProvider(String elementName, String namespace) {
String key = getProviderKey(elementName, namespace);
iqProviders.remove(key);
}
@@ -322,7 +306,7 @@ public class ProviderManager {
* @param namespace
* @return the extenion provider.
*/
- public Object getExtensionProvider(String elementName, String namespace) {
+ public static Object getExtensionProvider(String elementName, String namespace) {
String key = getProviderKey(elementName, namespace);
return extensionProviders.get(key);
}
@@ -336,7 +320,7 @@ public class ProviderManager {
* @param namespace the XML namespace.
* @param provider the extension provider.
*/
- public void addExtensionProvider(String elementName, String namespace,
+ public static void addExtensionProvider(String elementName, String namespace,
Object provider)
{
if (!(provider instanceof PacketExtensionProvider || provider instanceof Class)) {
@@ -348,12 +332,14 @@ public class ProviderManager {
}
/**
- * Removes the extension provider with the specified element name and name space.
+ * Removes an extension provider with the specified element name and namespace. This
+ * method is typically called to cleanup providers that are programatically added
+ * using the {@link #addExtensionProvider(String, String, Object) addExtensionProvider} method.
*
* @param elementName the XML element name.
* @param namespace the XML namespace.
*/
- public void removeExtensionProvider(String elementName, String namespace) {
+ public static void removeExtensionProvider(String elementName, String namespace) {
String key = getProviderKey(elementName, namespace);
extensionProviders.remove(key);
}
@@ -363,7 +349,7 @@ public class ProviderManager {
*
* @return an Iterator for all PacketExtensionProvider instances.
*/
- public Iterator getExtensionProviders() {
+ public static Iterator getExtensionProviders() {
return Collections.unmodifiableCollection(
new HashMap(extensionProviders).values()).iterator();
}
@@ -375,7 +361,7 @@ public class ProviderManager {
* @param namespace the namespace.
* @return a unique key for the element name and namespace pair.
*/
- protected static String getProviderKey(String elementName, String namespace) {
+ private static String getProviderKey(String elementName, String namespace) {
StringBuffer buf = new StringBuffer();
buf.append("<").append(elementName).append("/><").append(namespace).append("/>");
return buf.toString();
@@ -387,10 +373,13 @@ public class ProviderManager {
* @return an array of ClassLoader instances.
*/
private static ClassLoader[] getClassLoaders() {
- ClassLoader[] classLoaders = new ClassLoader[3];
- classLoaders[0] = ProviderManager.class.getClassLoader();
+ ClassLoader[] classLoaders = new ClassLoader[2];
+ classLoaders[0] = new ProviderManager().getClass().getClassLoader();
classLoaders[1] = Thread.currentThread().getContextClassLoader();
- classLoaders[2] = ClassLoader.getSystemClassLoader();
return classLoaders;
}
+
+ private ProviderManager() {
+
+ }
} \ No newline at end of file
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/Base64.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/Base64.java
index 8a7cf59a4..a3d384468 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/Base64.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/Base64.java
@@ -1,4 +1,4 @@
-package org.jivesoftware.smackx.filetransfer;
+package org.jivesoftware.smack.util;
/**
* Encodes and decodes to and from Base64 notation. <p/> <p/> Change Log:
@@ -359,19 +359,23 @@ class Base64 {
try {
oos.close();
} catch (Exception e) {
- }
+ /* Do Nothing */
+ }
try {
gzos.close();
} catch (Exception e) {
- }
+ /* Do Nothing */
+ }
try {
b64os.close();
} catch (Exception e) {
- }
+ /* Do Nothing */
+ }
try {
baos.close();
} catch (Exception e) {
- }
+ /* Do Nothing */
+ }
} // end finally
// Return value according to relevant encoding.
@@ -489,15 +493,18 @@ class Base64 {
try {
gzos.close();
} catch (Exception e) {
- }
+ /* Do Nothing */
+ }
try {
b64os.close();
} catch (Exception e) {
- }
+ /* Do Nothing */
+ }
try {
baos.close();
} catch (Exception e) {
- }
+ /* Do Nothing */
+ }
} // end finally
// Return value according to relevant encoding.
@@ -661,9 +668,9 @@ class Base64 {
byte[] b4 = new byte[4];
int b4Posn = 0;
- int i = 0;
- byte sbiCrop = 0;
- byte sbiDecode = 0;
+ int i;
+ byte sbiCrop;
+ byte sbiDecode;
for (i = off; i < off + len; i++) {
sbiCrop = (byte) (source[i] & 0x7f); // Only the low seven bits
sbiDecode = DECODABET[sbiCrop];
@@ -730,7 +737,7 @@ class Base64 {
java.util.zip.GZIPInputStream gzis = null;
java.io.ByteArrayOutputStream baos = null;
byte[] buffer = new byte[2048];
- int length = 0;
+ int length;
try {
baos = new java.io.ByteArrayOutputStream();
@@ -752,15 +759,18 @@ class Base64 {
try {
baos.close();
} catch (Exception e) {
- }
+ /* Do Nothing */
+ }
try {
gzis.close();
} catch (Exception e) {
- }
+ /* Do Nothing */
+ }
try {
bais.close();
} catch (Exception e) {
- }
+ /* Do Nothing */
+ }
} // end finally
} // end if: gzipped
@@ -802,13 +812,19 @@ class Base64 {
} // end catch
finally {
try {
- bais.close();
- } catch (Exception e) {
- }
+ if(bais != null) {
+ bais.close();
+ }
+ } catch (Exception e) {
+ /* Do Nothing */
+ }
try {
- ois.close();
- } catch (Exception e) {
- }
+ if(ois != null) {
+ ois.close();
+ }
+ } catch (Exception e) {
+ /* Do Nothing */
+ }
} // end finally
return obj;
@@ -839,9 +855,12 @@ class Base64 {
} // end catch: IOException
finally {
try {
- bos.close();
- } catch (Exception e) {
- }
+ if(bos != null) {
+ bos.close();
+ }
+ } catch (Exception e) {
+ /* Do Nothing */
+ }
} // end finally
return success;
@@ -871,9 +890,12 @@ class Base64 {
} // end catch: IOException
finally {
try {
- bos.close();
- } catch (Exception e) {
- }
+ if(bos != null) {
+ bos.close();
+ }
+ } catch (Exception e) {
+ /* Do Nothing */
+ }
} // end finally
return success;
@@ -893,9 +915,9 @@ class Base64 {
try {
// Set up some useful variables
java.io.File file = new java.io.File(filename);
- byte[] buffer = null;
+ byte[] buffer;
int length = 0;
- int numBytes = 0;
+ int numBytes;
// Check for size of file
if (file.length() > Integer.MAX_VALUE) {
@@ -925,8 +947,11 @@ class Base64 {
} // end catch: IOException
finally {
try {
- bis.close();
- } catch (Exception e) {
+ if(bis != null) {
+ bis.close();
+ }
+ } catch (Exception e) {
+ /* Do Nothing */
}
} // end finally
@@ -949,7 +974,7 @@ class Base64 {
java.io.File file = new java.io.File(filename);
byte[] buffer = new byte[(int) (file.length() * 1.4)];
int length = 0;
- int numBytes = 0;
+ int numBytes;
// Open a stream
bis = new Base64.InputStream(new java.io.BufferedInputStream(
@@ -970,9 +995,12 @@ class Base64 {
} // end catch: IOException
finally {
try {
- bis.close();
- } catch (Exception e) {
- }
+ if(bis != null) {
+ bis.close();
+ }
+ } catch (Exception e) {
+ /* Do Nothing */
+ }
} // end finally
return encodedData;
@@ -1095,10 +1123,10 @@ class Base64 {
// Else decoding
else {
byte[] b4 = new byte[4];
- int i = 0;
+ int i;
for (i = 0; i < 4; i++) {
// Read four "meaningful" bytes:
- int b = 0;
+ int b;
do {
b = in.read();
} while (b >= 0
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/PacketParserUtils.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/PacketParserUtils.java
index 842c0a34d..73c21ea3d 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/PacketParserUtils.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/PacketParserUtils.java
@@ -314,7 +314,7 @@ public class PacketParserUtils {
throws Exception
{
// See if a provider is registered to handle the extension.
- Object provider = ProviderManager.getDefault().getExtensionProvider(elementName, namespace);
+ Object provider = ProviderManager.getExtensionProvider(elementName, namespace);
if (provider != null) {
if (provider instanceof PacketExtensionProvider) {
return ((PacketExtensionProvider)provider).parseExtension(parser);
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/StringUtils.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/StringUtils.java
index b8a32959c..629be2931 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/StringUtils.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/util/StringUtils.java
@@ -147,7 +147,6 @@ public class StringUtils {
for (; i < len; i++) {
ch = input[i];
if (ch > '>') {
- continue;
}
else if (ch == '<') {
if (i > last) {
@@ -252,24 +251,10 @@ public class StringUtils {
}
hex.append(Integer.toString((int) bytes[i] & 0xff, 16));
}
-
+
return hex.toString();
}
- //*********************************************************************
- //* Base64 - a simple base64 encoder and decoder.
- //*
- //* Copyright (c) 1999, Bob Withers - bwit@pobox.com
- //*
- //* This code may be freely used for any purpose, either personal
- //* or commercial, provided the authors copyright notice remains
- //* intact.
- //*********************************************************************
-
- private static final int fillchar = '=';
- private static final String cvt = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
- + "0123456789+/";
-
/**
* Encodes a String as a base64 String.
*
@@ -294,95 +279,41 @@ public class StringUtils {
* @return a base64 encode String.
*/
public static String encodeBase64(byte[] data) {
- int c;
- int len = data.length;
- StringBuffer ret = new StringBuffer(((len / 3) + 1) * 4);
- for (int i = 0; i < len; ++i) {
- c = (data[i] >> 2) & 0x3f;
- ret.append(cvt.charAt(c));
- c = (data[i] << 4) & 0x3f;
- if (++i < len)
- c |= (data[i] >> 4) & 0x0f;
-
- ret.append(cvt.charAt(c));
- if (i < len) {
- c = (data[i] << 2) & 0x3f;
- if (++i < len)
- c |= (data[i] >> 6) & 0x03;
-
- ret.append(cvt.charAt(c));
- }
- else {
- ++i;
- ret.append((char) fillchar);
- }
+ return encodeBase64(data, false);
+ }
- if (i < len) {
- c = data[i] & 0x3f;
- ret.append(cvt.charAt(c));
- }
- else {
- ret.append((char) fillchar);
- }
- }
- return ret.toString();
+ /**
+ * Encodes a byte array into a bse64 String.
+ *
+ * @param data The byte arry to encode.
+ * @param lineBreaks True if the encoding should contain line breaks and false if it should not.
+ * @return A base64 encoded String.
+ */
+ public static String encodeBase64(byte[] data, boolean lineBreaks) {
+ return encodeBase64(data, 0, data.length, lineBreaks);
}
/**
- * Decodes a base64 String.
+ * Encodes a byte array into a bse64 String.
*
- * @param data a base64 encoded String to decode.
- * @return the decoded String.
+ * @param data The byte arry to encode.
+ * @param offset the offset of the bytearray to begin encoding at.
+ * @param len the length of bytes to encode.
+ * @param lineBreaks True if the encoding should contain line breaks and false if it should not.
+ * @return A base64 encoded String.
*/
- public static byte[] decodeBase64(String data) {
- byte [] bytes = null;
- try {
- bytes = data.getBytes("ISO-8859-1");
- return decodeBase64(bytes).getBytes("ISO-8859-1");
- }
- catch (UnsupportedEncodingException uee) {
- uee.printStackTrace();
- }
- return new byte[] { };
+ public static String encodeBase64(byte[] data, int offset, int len, boolean lineBreaks) {
+ return Base64.encodeBytes(data, offset, len, (lineBreaks ? Base64.NO_OPTIONS : Base64.DONT_BREAK_LINES));
}
/**
- * Decodes a base64 aray of bytes.
+ * Decodes a base64 String.
*
- * @param data a base64 encode byte array to decode.
+ * @param data a base64 encoded String to decode.
* @return the decoded String.
*/
- private static String decodeBase64(byte[] data) {
- int c, c1;
- int len = data.length;
- StringBuffer ret = new StringBuffer((len * 3) / 4);
- for (int i = 0; i < len; ++i) {
- c = cvt.indexOf(data[i]);
- ++i;
- c1 = cvt.indexOf(data[i]);
- c = ((c << 2) | ((c1 >> 4) & 0x3));
- ret.append((char) c);
- if (++i < len) {
- c = data[i];
- if (fillchar == c)
- break;
-
- c = cvt.indexOf(c);
- c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf);
- ret.append((char) c1);
- }
-
- if (++i < len) {
- c1 = data[i];
- if (fillchar == c1)
- break;
-
- c1 = cvt.indexOf(c1);
- c = ((c << 6) & 0xc0) | c1;
- ret.append((char) c);
- }
- }
- return ret.toString();
+ public static byte[] decodeBase64(String data) {
+ return Base64.decode(data);
}
/**
@@ -414,7 +345,7 @@ public class StringUtils {
* @param length the desired length of the random String to return.
* @return a random String of numbers and letters of the specified length.
*/
- public static final String randomString(int length) {
+ public static String randomString(int length) {
if (length < 1) {
return null;
}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/PrivateDataManager.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/PrivateDataManager.java
index 96bc6f781..040739912 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/PrivateDataManager.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/PrivateDataManager.java
@@ -102,6 +102,17 @@ public class PrivateDataManager {
privateDataProviders.put(key, provider);
}
+ /**
+ * Removes a private data provider with the specified element name and namespace.
+ *
+ * @param elementName The XML element name.
+ * @param namespace The XML namespace.
+ */
+ public static void removePrivateDataProvider(String elementName, String namespace) {
+ String key = getProviderKey(elementName, namespace);
+ privateDataProviders.remove(key);
+ }
+
private XMPPConnection connection;
@@ -312,8 +323,7 @@ public class PrivateDataManager {
}
}
}
- IQ result = new PrivateDataResult(privateData);
- return result;
+ return new PrivateDataResult(privateData);
}
}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bookmark/BookmarkedConference.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bookmark/BookmarkedConference.java
new file mode 100644
index 000000000..ed80cf156
--- /dev/null
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bookmark/BookmarkedConference.java
@@ -0,0 +1,91 @@
+/**
+ * $Revision: 1.1 $
+ * $Date: 2007/01/22 07:07:21 $
+ *
+ * Copyright (C) 1999-2005 Jive Software. All rights reserved.
+ * This software is the proprietary information of Jive Software. Use is subject to license terms.
+ */
+package org.jivesoftware.smackx.bookmark;
+
+/**
+ * Respresents a Conference Room bookmarked on the server using JEP-0048 Bookmark Storage JEP.
+ *
+ * @author Derek DeMoro
+ */
+public class BookmarkedConference {
+
+ private String name;
+ private boolean autoJoin;
+ private String jid;
+
+ private String nickname;
+ private String password;
+
+
+ /**
+ * Returns the display label representing the Conference room.
+ *
+ * @return the name of the conference room.
+ */
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns true if this conference room should be auto-joined on startup.
+ *
+ * @return true if room should be joined on startup, otherwise false.
+ */
+ public boolean isAutoJoin() {
+ return autoJoin;
+ }
+
+ public void setAutoJoin(boolean autoJoin) {
+ this.autoJoin = autoJoin;
+ }
+
+ /**
+ * Returns the full JID of this conference room. (ex.dev@conference.jivesoftware.com)
+ *
+ * @return the full JID of this conference room.
+ */
+ public String getJid() {
+ return jid;
+ }
+
+ public void setJid(String jid) {
+ this.jid = jid;
+ }
+
+ /**
+ * Returns the nickname to use when joining this conference room. This is an optional
+ * value and may return null.
+ *
+ * @return the nickname to use when joining, null may be returned.
+ */
+ public String getNickname() {
+ return nickname;
+ }
+
+ public void setNickname(String nickname) {
+ this.nickname = nickname;
+ }
+
+ /**
+ * Returns the password to use when joining this conference room. This is an optional
+ * value and may return null.
+ *
+ * @return the password to use when joining this conference room, null may be returned.
+ */
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bookmark/BookmarkedURL.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bookmark/BookmarkedURL.java
new file mode 100644
index 000000000..d5ffaf277
--- /dev/null
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bookmark/BookmarkedURL.java
@@ -0,0 +1,57 @@
+/**
+ * $Revision: 1.1 $
+ * $Date: 2007/01/22 07:07:21 $
+ *
+ * Copyright (C) 1999-2005 Jive Software. All rights reserved.
+ * This software is the proprietary information of Jive Software. Use is subject to license terms.
+ */
+package org.jivesoftware.smackx.bookmark;
+
+/**
+ * Respresents one instance of a URL defined using JEP-0048 Bookmark Storage JEP.
+ *
+ * @author Derek DeMoro
+ */
+public class BookmarkedURL {
+
+ private String name;
+ private String URL;
+
+ /**
+ * Returns the name representing the URL (eg. Jive Software). This can be used in as a label, or
+ * identifer in applications.
+ *
+ * @return the name reprenting the URL.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the name representing the URL.
+ *
+ * @param name the name.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns the URL.
+ *
+ * @return the url.
+ */
+ public String getURL() {
+ return URL;
+ }
+
+ /**
+ * Sets the URL.
+ *
+ * @param URL the url.
+ */
+ public void setURL(String URL) {
+ this.URL = URL;
+ }
+
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bookmark/Bookmarks.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bookmark/Bookmarks.java
new file mode 100644
index 000000000..0d081439d
--- /dev/null
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/bookmark/Bookmarks.java
@@ -0,0 +1,277 @@
+/**
+ * $Revision: 1.1 $
+ * $Date: 2007/01/22 07:07:21 $
+ *
+ * Copyright (C) 1999-2005 Jive Software. All rights reserved.
+ * This software is the proprietary information of Jive Software. Use is subject to license terms.
+ */
+package org.jivesoftware.smackx.bookmark;
+
+import org.jivesoftware.smackx.PrivateDataManager;
+import org.jivesoftware.smackx.packet.PrivateData;
+import org.jivesoftware.smackx.provider.PrivateDataProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Bookmarks is used for storing and retrieving URLS and Conference rooms.
+ * Bookmark Storage (JEP-0048) defined a protocol for the storage of bookmarks to conference rooms and other entities
+ * in a Jabber user's account.
+ * See the following code sample for saving Bookmarks:
+ * <p/>
+ * <pre>
+ * XMPPConnection con = new XMPPConnection("jabber.org");
+ * con.login("john", "doe");
+ * Bookmarks bookmarks = new Bookmarks();
+ * <p/>
+ * // Bookmark a URL
+ * BookmarkedURL url = new BookmarkedURL();
+ * url.setName("Google");
+ * url.setURL("http://www.jivesoftware.com");
+ * bookmarks.addURL(url);
+ * // Bookmark a Conference room.
+ * BookmarkedConference conference = new BookmarkedConference();
+ * conference.setName("My Favorite Room");
+ * conference.setAutoJoin("true");
+ * conference.setJID("dev@conference.jivesoftware.com");
+ * bookmarks.addConference(conference);
+ * // Save Bookmarks using PrivateDataManager.
+ * PrivateDataManager manager = new PrivateDataManager(con);
+ * manager.setPrivateData(bookmarks);
+ * <p/>
+ * <p/>
+ * LastActivity activity = LastActivity.getLastActivity(con, "xray@jabber.org");
+ * </pre>
+ *
+ * @author Derek DeMoro
+ */
+public class Bookmarks implements PrivateData {
+
+ private List bookmarkedURLS;
+ private List bookmarkedConferences;
+
+ /**
+ * Required Empty Constructor to use Bookmarks.
+ */
+ public Bookmarks() {
+ // Register own provider for simpler implementation.
+ PrivateDataManager.addPrivateDataProvider("storage", "storage:bookmarks", new Bookmarks.Provider());
+
+ bookmarkedURLS = new ArrayList();
+ bookmarkedConferences = new ArrayList();
+ }
+
+ /**
+ * Adds a BookmarkedURL.
+ *
+ * @param bookmarkedURL the bookmarked bookmarkedURL.
+ */
+ public void addBookmarkedURL(BookmarkedURL bookmarkedURL) {
+ bookmarkedURLS.add(bookmarkedURL);
+ }
+
+ /**
+ * Removes a bookmarked bookmarkedURL.
+ *
+ * @param bookmarkedURL the bookmarked bookmarkedURL to remove.
+ */
+ public void removeBookmarkedURL(BookmarkedURL bookmarkedURL) {
+ bookmarkedURLS.remove(bookmarkedURL);
+ }
+
+ /**
+ * Removes all BookmarkedURLs from user's bookmarks.
+ */
+ public void clearBookmarkedURLS() {
+ bookmarkedURLS.clear();
+ }
+
+ /**
+ * Add a BookmarkedConference to bookmarks.
+ *
+ * @param bookmarkedConference the conference to remove.
+ */
+ public void addBookmarkedConference(BookmarkedConference bookmarkedConference) {
+ bookmarkedConferences.add(bookmarkedConference);
+ }
+
+ /**
+ * Removes a BookmarkedConference.
+ *
+ * @param bookmarkedConference the BookmarkedConference to remove.
+ */
+ public void removeBookmarkedConference(BookmarkedConference bookmarkedConference) {
+ bookmarkedConferences.remove(bookmarkedConference);
+ }
+
+ /**
+ * Removes all BookmarkedConferences from Bookmarks.
+ */
+ public void clearBookmarkedConferences() {
+ bookmarkedConferences.clear();
+ }
+
+ /**
+ * Returns a Collection of all Bookmarked URLs for this user.
+ *
+ * @return a collection of all Bookmarked URLs.
+ */
+ public Collection getBookmarkedURLS() {
+ return bookmarkedURLS;
+ }
+
+ /**
+ * Returns a Collection of all Bookmarked Conference for this user.
+ *
+ * @return a collection of all Bookmarked Conferences.
+ */
+ public Collection getBookmarkedConferences() {
+ return bookmarkedConferences;
+ }
+
+
+ /**
+ * Returns the root element name.
+ *
+ * @return the element name.
+ */
+ public String getElementName() {
+ return "storage";
+ }
+
+ /**
+ * Returns the root element XML namespace.
+ *
+ * @return the namespace.
+ */
+ public String getNamespace() {
+ return "storage:bookmarks";
+ }
+
+ /**
+ * Returns the XML reppresentation of the PrivateData.
+ *
+ * @return the private data as XML.
+ */
+ public String toXML() {
+ StringBuffer buf = new StringBuffer();
+ buf.append("<storage xmlns=\"storage:bookmarks\">");
+
+ final Iterator urls = getBookmarkedURLS().iterator();
+ while (urls.hasNext()) {
+ BookmarkedURL urlStorage = (BookmarkedURL) urls.next();
+ buf.append("<url name=\"").append(urlStorage.getName()).append("\" url=\"").append(urlStorage.getURL()).append("\" />");
+ }
+
+ // Add Conference additions
+ final Iterator conferences = getBookmarkedConferences().iterator();
+ while (conferences.hasNext()) {
+ BookmarkedConference conference = (BookmarkedConference) conferences.next();
+ buf.append("<conference ");
+ buf.append("name=\"").append(conference.getName()).append("\" ");
+ buf.append("autojoin=\"").append(conference.isAutoJoin()).append("\" ");
+ buf.append("jid=\"").append(conference.getJid()).append("\" ");
+ buf.append(">");
+
+ if (conference.getNickname() != null) {
+ buf.append("<nick>").append(conference.getNickname()).append("</nick>");
+ }
+
+
+ if (conference.getPassword() != null) {
+ buf.append("<password>").append(conference.getPassword()).append("</password>");
+ }
+ buf.append("</conference>");
+ }
+
+
+ buf.append("</storage>");
+ return buf.toString();
+ }
+
+ /**
+ * The IQ Provider for BookmarkStorage.
+ *
+ * @author Derek DeMoro
+ */
+ public static class Provider implements PrivateDataProvider {
+
+ /**
+ * Empty Constructor for PrivateDataProvider.
+ */
+ public Provider() {
+ super();
+ }
+
+ public PrivateData parsePrivateData(XmlPullParser parser) throws Exception {
+ Bookmarks storage = new Bookmarks();
+
+ boolean done = false;
+ while (!done) {
+ int eventType = parser.next();
+ if (eventType == XmlPullParser.START_TAG && "url".equals(parser.getName())) {
+ final BookmarkedURL urlStorage = getURLStorage(parser);
+ if (urlStorage != null) {
+ storage.addBookmarkedURL(urlStorage);
+ }
+ }
+ else if (eventType == XmlPullParser.START_TAG && "conference".equals(parser.getName())) {
+ final BookmarkedConference conference = getConferenceStorage(parser);
+ storage.addBookmarkedConference(conference);
+ }
+ else if (eventType == XmlPullParser.END_TAG) {
+ if ("storage".equals(parser.getName())) {
+ done = true;
+ }
+ }
+ }
+
+
+ return storage;
+ }
+ }
+
+ private static BookmarkedURL getURLStorage(XmlPullParser parser) {
+ String name = parser.getAttributeValue("", "name");
+ String url = parser.getAttributeValue("", "url");
+ BookmarkedURL urlStore = new BookmarkedURL();
+ urlStore.setName(name);
+ urlStore.setURL(url);
+ return urlStore;
+ }
+
+ private static BookmarkedConference getConferenceStorage(XmlPullParser parser) throws Exception {
+ BookmarkedConference conf = new BookmarkedConference();
+ String name = parser.getAttributeValue("", "name");
+ String autojoin = parser.getAttributeValue("", "autojoin");
+ String jid = parser.getAttributeValue("", "jid");
+
+ conf.setName(name);
+ conf.setAutoJoin(Boolean.valueOf(autojoin).booleanValue());
+ conf.setJid(jid);
+
+ // Check for nickname
+ boolean done = false;
+ while (!done) {
+ int eventType = parser.next();
+ if (eventType == XmlPullParser.START_TAG && "nick".equals(parser.getName())) {
+ conf.setNickname(parser.nextText());
+ }
+ else if (eventType == XmlPullParser.START_TAG && "password".equals(parser.getName())) {
+ conf.setPassword(parser.nextText());
+ }
+ else if (eventType == XmlPullParser.END_TAG) {
+ if ("conference".equals(parser.getName())) {
+ done = true;
+ }
+ }
+ }
+
+
+ return conf;
+ }
+}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/debugger/EnhancedDebuggerWindow.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/debugger/EnhancedDebuggerWindow.java
index d47a062f0..ae516f740 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/debugger/EnhancedDebuggerWindow.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/debugger/EnhancedDebuggerWindow.java
@@ -219,7 +219,7 @@ public class EnhancedDebuggerWindow {
iqProvidersPanel.setLayout(new GridLayout(1, 1));
iqProvidersPanel.setBorder(BorderFactory.createTitledBorder("Installed IQ Providers"));
Vector providers = new Vector();
- for (Iterator it = ProviderManager.getDefault().getIQProviders(); it.hasNext();) {
+ for (Iterator it = ProviderManager.getIQProviders(); it.hasNext();) {
Object provider = it.next();
if (provider.getClass() == Class.class) {
providers.add(((Class) provider).getName());
@@ -239,7 +239,7 @@ public class EnhancedDebuggerWindow {
extensionProvidersPanel.setLayout(new GridLayout(1, 1));
extensionProvidersPanel.setBorder(BorderFactory.createTitledBorder("Installed Extension Providers"));
providers = new Vector();
- for (Iterator it = ProviderManager.getDefault().getExtensionProviders(); it.hasNext();) {
+ for (Iterator it = ProviderManager.getExtensionProviders(); it.hasNext();) {
Object provider = it.next();
if (provider.getClass() == Class.class) {
providers.add(((Class) provider).getName());
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java
index c58d44736..9065ac143 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransfer.java
@@ -28,9 +28,9 @@ import org.jivesoftware.smack.XMPPException;
/**
* Contains the generic file information and progress related to a particular
* file transfer.
- *
+ *
* @author Alexander Wenckus
- *
+ *
*/
public abstract class FileTransfer {
@@ -42,7 +42,9 @@ public abstract class FileTransfer {
private String peer;
- private org.jivesoftware.smackx.filetransfer.FileTransfer.Status status;
+ private org.jivesoftware.smackx.filetransfer.FileTransfer.Status status = Status.INITIAL;
+
+ private final Object statusMonitor = new Object();
protected FileTransferNegotiator negotiator;
@@ -54,7 +56,12 @@ public abstract class FileTransfer {
private Exception exception;
- protected FileTransfer(String peer, String streamID,
+ /**
+ * Buffer size between input and output
+ */
+ private static final int BUFFER_SIZE = 8192;
+
+ protected FileTransfer(String peer, String streamID,
FileTransferNegotiator negotiator) {
this.peer = peer;
this.streamID = streamID;
@@ -74,7 +81,7 @@ public abstract class FileTransfer {
/**
* Returns the size of the file being transfered.
- *
+ *
* @return Returns the size of the file being transfered.
*/
public long getFileSize() {
@@ -83,7 +90,7 @@ public abstract class FileTransfer {
/**
* Returns the name of the file being transfered.
- *
+ *
* @return Returns the name of the file being transfered.
*/
public String getFileName() {
@@ -92,7 +99,7 @@ public abstract class FileTransfer {
/**
* Returns the local path of the file.
- *
+ *
* @return Returns the local path of the file.
*/
public String getFilePath() {
@@ -101,7 +108,7 @@ public abstract class FileTransfer {
/**
* Returns the JID of the peer for this file transfer.
- *
+ *
* @return Returns the JID of the peer for this file transfer.
*/
public String getPeer() {
@@ -110,21 +117,21 @@ public abstract class FileTransfer {
/**
* 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) {
+ if (amountWritten <= 0 || fileSize <= 0) {
return 0;
}
- return amountWritten / fileSize;
+ return (double) amountWritten / (double) fileSize;
}
/**
* Returns true if the transfer has been cancled, if it has stopped because
* of a an error, or the transfer completed succesfully.
- *
+ *
* @return Returns true if the transfer has been cancled, if it has stopped
* because of a an error, or the transfer completed succesfully.
*/
@@ -135,7 +142,7 @@ public abstract class FileTransfer {
/**
* Retuns the current status of the file transfer.
- *
+ *
* @return Retuns the current status of the file transfer.
*/
public Status getStatus() {
@@ -150,7 +157,7 @@ public abstract class FileTransfer {
* 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 occured if one has occured.
*/
public Error getError() {
@@ -160,7 +167,7 @@ public abstract class FileTransfer {
/**
* If an exception occurs asynchronously it will be stored for later
* retrival. If there is an error there maybe an exception set.
- *
+ *
* @return The exception that occured or null if there was no exception.
* @see #getError()
*/
@@ -178,24 +185,29 @@ public abstract class FileTransfer {
}
protected final void setStatus(Status status) {
- this.status = status;
- }
+ synchronized (statusMonitor) {
+ this.status = status;
+ }
+ }
+
+ protected final boolean updateStatus(Status oldStatus, Status newStatus) {
+ synchronized (statusMonitor) {
+ if (oldStatus != status) {
+ return false;
+ }
+ status = newStatus;
+ return true;
+ }
+ }
protected void writeToStream(final InputStream in, final OutputStream out)
- throws XMPPException {
- final byte[] b = new byte[1000];
+ throws XMPPException
+ {
+ final byte[] b = new byte[BUFFER_SIZE];
int count = 0;
amountWritten = 0;
- try {
- count = in.read(b);
- } catch (IOException e) {
- throw new XMPPException("error reading from input stream", e);
- }
- while (count != -1 && !getStatus().equals(Status.CANCLED)) {
- if (getStatus().equals(Status.CANCLED)) {
- return;
- }
+ do {
// write to the output stream
try {
out.write(b, 0, count);
@@ -211,79 +223,95 @@ public abstract class FileTransfer {
} catch (IOException e) {
throw new XMPPException("error reading from input stream", e);
}
- }
+ } while (count != -1 && !getStatus().equals(Status.CANCLED));
- // the connection was likely terminated abrubtly if these are not
- // equal
+ // the connection was likely terminated abrubtly if these are not equal
if (!getStatus().equals(Status.CANCLED) && getError() == Error.NONE
&& amountWritten != fileSize) {
+ setStatus(Status.ERROR);
this.error = Error.CONNECTION;
}
}
/**
* A class to represent the current status of the file transfer.
- *
+ *
* @author Alexander Wenckus
- *
+ *
*/
public static class Status {
+
/**
* An error occured during the transfer.
- *
+ *
* @see FileTransfer#getError()
*/
- public static final Status ERROR = new Status();
+ public static final Status ERROR = new Status("Error");
/**
+ * The initial status of the file transfer.
+ */
+ public static final Status INITIAL = new Status("Initial");
+
+ /**
* The file transfer is being negotiated with the peer. The party
* recieving 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
*/
- public static final Status NEGOTIATING_TRANSFER = new Status();
+ public static final Status NEGOTIATING_TRANSFER = new Status("Negotiating Transfer");
/**
* The peer has refused the file transfer request halting the file
* transfer negotiation process.
*/
- public static final Status REFUSED = new Status();
+ public static final Status REFUSED = new Status("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
*/
- public static final Status NEGOTIATING_STREAM = new Status();
+ public static final Status NEGOTIATING_STREAM = new Status("Negotiating Stream");
/**
* After the stream negotitation has completed the intermediate state
* between the time when the negotiation is finished and the actual
* transfer begins.
*/
- public static final Status NEGOTIATED = new Status();
+ public static final Status NEGOTIATED = new Status("Negotiated");
/**
* The transfer is in progress.
- *
+ *
* @see FileTransfer#getProgress()
*/
- public static final Status IN_PROGRESS = new Status();
+ public static final Status IN_PROGRESS = new Status("In Progress");
/**
* The transfer has completed successfully.
*/
- public static final Status COMPLETE = new Status();
+ public static final Status COMPLETE = new Status("Complete");
/**
* The file transfer was canceled
*/
- public static final Status CANCLED = new Status();
- }
+ public static final Status CANCLED = new Status("Cancled");
+
+ private String status;
+
+ private Status(String status) {
+ this.status = status;
+ }
+
+ public String toString() {
+ return status;
+ }
+ }
/**
* Return the length of bytes written out to the stream.
@@ -338,7 +366,7 @@ public abstract class FileTransfer {
/**
* Returns a String representation of this error.
- *
+ *
* @return Returns a String representation of this error.
*/
public String getMessage() {
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java
index 1123b7fe7..c8c3a15e6 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java
@@ -149,7 +149,7 @@ public class FileTransferNegotiator {
* @param type The iq type of the packet.
* @return The created IQ packet.
*/
- protected static IQ createIQ(final String ID, final String to,
+ public static IQ createIQ(final String ID, final String to,
final String from, final IQ.Type type) {
IQ iqPacket = new IQ() {
public String getChildElementXML() {
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/IBBTransferNegotiator.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/IBBTransferNegotiator.java
index 53fed24ee..ace34a4be 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/IBBTransferNegotiator.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/IBBTransferNegotiator.java
@@ -23,6 +23,7 @@ import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.filter.*;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Message;
@@ -143,6 +144,9 @@ public class IBBTransferNegotiator extends StreamNegotiator {
public void cleanup() {
}
+ public void cancel() {
+ }
+
private class IBBOutputStream extends OutputStream {
protected byte[] buffer;
@@ -153,8 +157,6 @@ public class IBBTransferNegotiator extends StreamNegotiator {
final String userID;
- private final int options = Base64.DONT_BREAK_LINES;
-
final private IQ closePacket;
private String messageID;
@@ -191,9 +193,16 @@ public class IBBTransferNegotiator extends StreamNegotiator {
public synchronized void write(byte b[], int off, int len)
throws IOException {
if (len >= buffer.length) {
- throw new IllegalArgumentException(
- "byte size exceeds blocksize");
+ // "byte" off the first chunck to write out
+ writeOut(b, off, buffer.length);
+ // recursivly call this method again with the lesser amount subtracted.
+ write(b, off + buffer.length, len - buffer.length);
+ } else {
+ writeOut(b, off, len);
}
+ }
+
+ private void writeOut(byte b[], int off, int len) {
if (len > buffer.length - count) {
flushBuffer();
}
@@ -212,15 +221,16 @@ public class IBBTransferNegotiator extends StreamNegotiator {
IBBExtensions.Data ext = new IBBExtensions.Data(sid);
template.addExtension(ext);
- String enc = Base64.encodeBytes(buffer, offset, len, options);
+ String enc = StringUtils.encodeBase64(buffer, offset, len, false);
ext.setData(enc);
ext.setSeq(seq);
- synchronized(this) {
+ synchronized (this) {
try {
this.wait(100);
}
catch (InterruptedException e) {
+ /* Do Nothing */
}
}
@@ -333,9 +343,9 @@ public class IBBTransferNegotiator extends StreamNegotiator {
data = (IBBExtensions.Data) mess.getExtension(
IBBExtensions.Data.ELEMENT_NAME,
IBBExtensions.NAMESPACE);
-
+
checkSequence(mess, (int) data.getSeq());
- buffer = Base64.decode(data.getData());
+ buffer = StringUtils.decodeBase64(data.getData());
bufferPointer = 0;
return true;
}
@@ -394,7 +404,7 @@ public class IBBTransferNegotiator extends StreamNegotiator {
if (isEOF) {
sendCloseConfirmation();
}
- else if(lastMess != null) {
+ else if (lastMess != null) {
sendCancelMessage(lastMess);
}
isClosed = true;
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java
index db0f1c034..77c660cea 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java
@@ -19,23 +19,18 @@
*/
package org.jivesoftware.smackx.filetransfer;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.XMPPError;
+import java.io.*;
+
/**
* Handles the sending of a file to another user. File transfer's in jabber have
* several steps and there are several methods in this class that handle these
* steps differently.
- *
+ *
* @author Alexander Wenckus
- *
+ *
*/
public class OutgoingFileTransfer extends FileTransfer {
@@ -44,7 +39,7 @@ public class OutgoingFileTransfer extends FileTransfer {
/**
* Returns the time in milliseconds after which the file transfer
* negotiation process will timeout if the other user has not responded.
- *
+ *
* @return Returns the time in milliseconds after which the file transfer
* negotiation process will timeout if the remote user has not
* responded.
@@ -56,11 +51,11 @@ public class OutgoingFileTransfer extends FileTransfer {
/**
* 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 void setResponseTimeout(int responseTimeout) {
+ public static void setResponseTimeout(int responseTimeout) {
RESPONSE_TIMEOUT = responseTimeout;
}
@@ -86,7 +81,7 @@ public class OutgoingFileTransfer extends FileTransfer {
* Returns the output stream connected to the peer to transfer the file. It
* is only available after it has been succesfully negotiated by the
* {@link StreamNegotiator}.
- *
+ *
* @return Returns the output stream connected to the peer to transfer the
* file.
*/
@@ -101,7 +96,7 @@ public class OutgoingFileTransfer extends FileTransfer {
/**
* 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
@@ -138,7 +133,7 @@ public class OutgoingFileTransfer extends FileTransfer {
* {@link NegotiationProgress} callback. When the negotiation process is
* complete the OutputStream can be retrieved from the callback via the
* {@link NegotiationProgress#getOutputStream()} method.
- *
+ *
* @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
@@ -186,13 +181,13 @@ public class OutgoingFileTransfer extends FileTransfer {
* This method handles the stream negotiation process and transmits the file
* to the remote user. It returns immediatly 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>
- *
+ *
* @throws XMPPException
* If there is an error during the negotiation process or the
* sending of the file.
@@ -219,10 +214,9 @@ public class OutgoingFileTransfer extends FileTransfer {
return;
}
- if (!getStatus().equals(Status.NEGOTIATED)) {
+ if (!updateStatus(Status.NEGOTIATED, Status.IN_PROGRESS)) {
return;
}
- setStatus(Status.IN_PROGRESS);
InputStream inputStream = null;
try {
@@ -244,12 +238,11 @@ public class OutgoingFileTransfer extends FileTransfer {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
+ /* Do Nothing */
}
}
- if (getStatus().equals(Status.IN_PROGRESS)) {
- setStatus(FileTransfer.Status.COMPLETE);
+ updateStatus(Status.IN_PROGRESS, FileTransfer.Status.COMPLETE);
}
- }
}, "File Transfer " + streamID);
transferThread.start();
@@ -269,7 +262,6 @@ public class OutgoingFileTransfer extends FileTransfer {
}
}
setException(e);
- return;
}
/**
@@ -279,7 +271,7 @@ public class OutgoingFileTransfer extends FileTransfer {
* Note: This method is only useful when the {@link #sendFile(File, String)}
* method is called, as it is the only method that actualy 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.
*/
@@ -291,7 +283,9 @@ public class OutgoingFileTransfer extends FileTransfer {
String description) throws XMPPException {
// Negotiate the file transfer profile
- setStatus(Status.NEGOTIATING_TRANSFER);
+ if (!updateStatus(Status.INITIAL, Status.NEGOTIATING_TRANSFER)) {
+ throw new XMPPException("Illegal state change");
+ }
StreamNegotiator streamNegotiator = negotiator.negotiateOutgoingTransfer(
getPeer(), streamID, fileName, fileSize, description,
RESPONSE_TIMEOUT);
@@ -302,19 +296,16 @@ public class OutgoingFileTransfer extends FileTransfer {
return null;
}
- if (!getStatus().equals(Status.NEGOTIATING_TRANSFER)) {
- return null;
- }
-
- // Negotiate the stream
-
- setStatus(Status.NEGOTIATING_STREAM);
+ // Negotiate the stream
+ if (!updateStatus(Status.NEGOTIATING_TRANSFER, Status.NEGOTIATING_STREAM)) {
+ throw new XMPPException("Illegal state change");
+ }
outputStream = streamNegotiator.createOutgoingStream(streamID,
initiator, getPeer());
- if (!getStatus().equals(Status.NEGOTIATING_STREAM)) {
- return null;
+
+ if (!updateStatus(Status.NEGOTIATING_STREAM, Status.NEGOTIATED)) {
+ throw new XMPPException("Illegal state change");
}
- setStatus(Status.NEGOTIATED);
return outputStream;
}
@@ -325,9 +316,9 @@ public class OutgoingFileTransfer extends FileTransfer {
/**
* A callback class to retrive the status of an outgoing transfer
* negotiation process.
- *
+ *
* @author Alexander Wenckus
- *
+ *
*/
public static class NegotiationProgress {
@@ -335,7 +326,7 @@ public class OutgoingFileTransfer extends FileTransfer {
/**
* Returns the current status of the negotiation process.
- *
+ *
* @return Returns the current status of the negotiation process.
*/
public Status getStatus() {
@@ -348,10 +339,10 @@ public class OutgoingFileTransfer extends FileTransfer {
/**
* Once the negotiation process is completed the output stream can be
* retrieved.
- *
+ *
* @return Once the negotiation process is completed the output stream
* can be retrieved.
- *
+ *
*/
public OutputStream getOutputStream() {
if (delegate == null) {
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/Bytestream.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/Bytestream.java
index 57136218d..60eb9901f 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/Bytestream.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/Bytestream.java
@@ -244,6 +244,12 @@ public class Bytestream extends IQ {
buf.append(">");
if (getUsedHost() != null)
buf.append(getUsedHost().toXML());
+ // A result from the server can also contain stream hosts
+ else if (countStreamHosts() > 0) {
+ for (Iterator it = getStreamHosts().iterator(); it.hasNext();) {
+ buf.append(((StreamHost) it.next()).toXML());
+ }
+ }
}
else {
return null;
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/VCard.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/VCard.java
index 4f1248859..99e753e25 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/VCard.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/packet/VCard.java
@@ -118,6 +118,9 @@ public class VCard extends IQ {
*/
private Map otherSimpleFields = new HashMap();
+ // fields that, as they are should not be escaped before forwarding to the server
+ private Map otherUnescapableFields = new HashMap();
+
public VCard() {
}
@@ -139,7 +142,24 @@ public class VCard extends IQ {
* @see #getField(String)
*/
public void setField(String field, String value) {
- otherSimpleFields.put(field, value);
+ setField(field, value, false);
+ }
+
+ /**
+ * Set generic, unescapable VCard field. If unescabale is set to true, XML maybe a part of the
+ * value.
+ *
+ * @param value value of field
+ * @param field field to set. See {@link #getField(String)}
+ * @param isUnescapable True if the value should not be escaped, and false if it should.
+ */
+ public void setField(String field, String value, boolean isUnescapable) {
+ if(!isUnescapable) {
+ otherSimpleFields.put(field, value);
+ }
+ else {
+ otherUnescapableFields.put(field, value);
+ }
}
public String getFirstName() {
@@ -310,7 +330,7 @@ public class VCard extends IQ {
String encodedImage = StringUtils.encodeBase64(bytes);
avatar = encodedImage;
- setField("PHOTO", "<TYPE>image/jpeg</TYPE><BINVAL>" + encodedImage + "</BINVAL>");
+ setField("PHOTO", "<TYPE>image/jpeg</TYPE><BINVAL>" + encodedImage + "</BINVAL>", true);
}
/**
@@ -322,7 +342,7 @@ public class VCard extends IQ {
String encodedImage = StringUtils.encodeBase64(bytes);
avatar = encodedImage;
- setField("PHOTO", "<TYPE>image/jpeg</TYPE><BINVAL>" + encodedImage + "</BINVAL>");
+ setField("PHOTO", "<TYPE>image/jpeg</TYPE><BINVAL>" + encodedImage + "</BINVAL>", true);
}
/**
@@ -362,10 +382,7 @@ public class VCard extends IQ {
if (avatar == null) {
return null;
}
- if (avatar != null) {
- return StringUtils.decodeBase64(avatar);
- }
- return null;
+ return StringUtils.decodeBase64(avatar);
}
/**
@@ -384,12 +401,21 @@ public class VCard extends IQ {
}
private static byte[] getFileBytes(File file) throws IOException {
- BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
- int bytes = (int) file.length();
- byte[] buffer = new byte[bytes];
- int readBytes = bis.read(buffer);
- bis.close();
- return buffer;
+ BufferedInputStream bis = null;
+ try {
+ bis = new BufferedInputStream(new FileInputStream(file));
+ int bytes = (int) file.length();
+ byte[] buffer = new byte[bytes];
+ int readBytes = bis.read(buffer);
+ if(readBytes != buffer.length) {
+ throw new IOException("Entire file not read");
+ }
+ return buffer;
+ } finally {
+ if(bis != null) {
+ bis.close();
+ }
+ }
}
/**
@@ -403,12 +429,13 @@ public class VCard extends IQ {
return null;
}
- MessageDigest digest = null;
+ MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-1");
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
+ return null;
}
digest.update(bytes);
@@ -515,13 +542,13 @@ public class VCard extends IQ {
private void checkAuthenticated(XMPPConnection connection) {
if (connection == null) {
- new IllegalArgumentException("No connection was provided");
+ throw new IllegalArgumentException("No connection was provided");
}
if (!connection.isAuthenticated()) {
- new IllegalArgumentException("Connection is not authenticated");
+ throw new IllegalArgumentException("Connection is not authenticated");
}
if (connection.isAnonymous()) {
- new IllegalArgumentException("Connection cannot be anonymous");
+ throw new IllegalArgumentException("Connection cannot be anonymous");
}
}
@@ -532,6 +559,7 @@ public class VCard extends IQ {
|| emailHome != null
|| emailWork != null
|| otherSimpleFields.size() > 0
+ || otherUnescapableFields.size() > 0
|| homeAddr.size() > 0
|| homePhones.size() > 0
|| workAddr.size() > 0
@@ -590,11 +618,8 @@ public class VCard extends IQ {
if (!workAddr.equals(vCard.workAddr)) {
return false;
}
- if (!workPhones.equals(vCard.workPhones)) {
- return false;
- }
+ return workPhones.equals(vCard.workPhones);
- return true;
}
public int hashCode() {
@@ -662,7 +687,7 @@ public class VCard extends IQ {
appendEmptyTag(type);
appendEmptyTag("INTERNET");
appendEmptyTag("PREF");
- appendTag("USERID", email);
+ appendTag("USERID", StringUtils.escapeForXML(email));
}
});
}
@@ -676,7 +701,7 @@ public class VCard extends IQ {
public void addTagContent() {
appendEmptyTag(entry.getKey());
appendEmptyTag(code);
- appendTag("NUMBER", (String) entry.getValue());
+ appendTag("NUMBER", StringUtils.escapeForXML((String) entry.getValue()));
}
});
}
@@ -691,7 +716,7 @@ public class VCard extends IQ {
Iterator it = addr.entrySet().iterator();
while (it.hasNext()) {
final Map.Entry entry = (Map.Entry) it.next();
- appendTag((String) entry.getKey(), (String) entry.getValue());
+ appendTag((String) entry.getKey(), StringUtils.escapeForXML((String) entry.getValue()));
}
}
});
@@ -706,6 +731,13 @@ public class VCard extends IQ {
Iterator it = otherSimpleFields.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
+ appendTag(entry.getKey().toString(),
+ StringUtils.escapeForXML((String) entry.getValue()));
+ }
+
+ it = otherUnescapableFields.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry entry = (Map.Entry) it.next();
appendTag(entry.getKey().toString(), (String) entry.getValue());
}
}
@@ -714,29 +746,24 @@ public class VCard extends IQ {
if (hasOrganizationFields()) {
appendTag("ORG", true, new ContentBuilder() {
public void addTagContent() {
- appendTag("ORGNAME", organization);
- appendTag("ORGUNIT", organizationUnit);
+ appendTag("ORGNAME", StringUtils.escapeForXML(organization));
+ appendTag("ORGUNIT", StringUtils.escapeForXML(organizationUnit));
}
});
}
}
- private void appendField(String tag) {
- String value = (String) otherSimpleFields.get(tag);
- appendTag(tag, value);
- }
-
private void appendFN() {
final ContentBuilder contentBuilder = new ContentBuilder() {
public void addTagContent() {
if (firstName != null) {
- sb.append(firstName + ' ');
+ sb.append(StringUtils.escapeForXML(firstName)).append(' ');
}
if (middleName != null) {
- sb.append(middleName + ' ');
+ sb.append(StringUtils.escapeForXML(middleName)).append(' ');
}
if (lastName != null) {
- sb.append(lastName);
+ sb.append(StringUtils.escapeForXML(lastName));
}
}
};
@@ -746,9 +773,9 @@ public class VCard extends IQ {
private void appendN() {
appendTag("N", true, new ContentBuilder() {
public void addTagContent() {
- appendTag("FAMILY", lastName);
- appendTag("GIVEN", firstName);
- appendTag("MIDDLE", middleName);
+ appendTag("FAMILY", StringUtils.escapeForXML(lastName));
+ appendTag("GIVEN", StringUtils.escapeForXML(firstName));
+ appendTag("MIDDLE", StringUtils.escapeForXML(middleName));
}
});
}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/VCardProvider.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/VCardProvider.java
index af45448b3..681d951de 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/VCardProvider.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smackx/provider/VCardProvider.java
@@ -22,6 +22,7 @@ package org.jivesoftware.smackx.provider;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.provider.IQProvider;
+import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.packet.VCard;
import org.w3c.dom.*;
import org.xmlpull.v1.XmlPullParser;
@@ -35,7 +36,7 @@ import java.util.List;
import java.util.ArrayList;
/**
- * vCard provider.
+ * vCard provider.
*
* @author Gaston Dombiak
*/
@@ -49,7 +50,8 @@ public class VCardProvider implements IQProvider {
while (true) {
switch (event) {
case XmlPullParser.TEXT:
- sb.append(parser.getText());
+ // We must re-escape the xml so that the DOM won't throw an exception
+ sb.append(StringUtils.escapeForXML(parser.getText()));
break;
case XmlPullParser.START_TAG:
sb.append('<').append(parser.getName()).append('>');

Back to the top