diff --git a/source/org/jivesoftware/smack/PacketReader.java b/source/org/jivesoftware/smack/PacketReader.java
index 3bb912f9f..cf190755a 100644
--- a/source/org/jivesoftware/smack/PacketReader.java
+++ b/source/org/jivesoftware/smack/PacketReader.java
@@ -603,7 +603,7 @@ class PacketReader {
// Otherwise, see if there is a registered provider for
// this element name and namespace.
else {
- Object provider = ProviderManager.getIQProvider(elementName, namespace);
+ Object provider = ProviderManager.getInstance().getIQProvider(elementName, namespace);
if (provider != null) {
if (provider instanceof IQProvider) {
iqPacket = ((IQProvider)provider).parseIQ(parser);
diff --git a/source/org/jivesoftware/smack/provider/ProviderManager.java b/source/org/jivesoftware/smack/provider/ProviderManager.java
index 924d1766b..256b47ffa 100644
--- a/source/org/jivesoftware/smack/provider/ProviderManager.java
+++ b/source/org/jivesoftware/smack/provider/ProviderManager.java
@@ -105,16 +105,53 @@ import java.util.concurrent.ConcurrentHashMap;
* set the properties of the class using the values in the packet extension sub-element. When an
* extension provider is not registered for an element name and namespace combination, Smack will
* store all top-level elements of the sub-packet in DefaultPacketExtension object and then
- * attach it to the packet.
+ * attach it to the packet.
+ *
+ * It is possible to provide a custom provider manager instead of the default implementation
+ * provided by Smack. If you want to provide your own provider manager then you need to do it
+ * before creating any {@link org.jivesoftware.smack.XMPPConnection} by sending the static
+ * {@link #setInstance(ProviderManager)} message. Trying to change the provider manager after
+ * an XMPPConnection was created will result in an {@link IllegalStateException} error.
*
* @author Matt Tucker
*/
public class ProviderManager {
- private static Map extensionProviders = new ConcurrentHashMap();
- private static Map iqProviders = new ConcurrentHashMap();
+ private static ProviderManager instance;
- static {
+ private Map extensionProviders = new ConcurrentHashMap();
+ private Map iqProviders = new ConcurrentHashMap();
+
+ /**
+ * Returns the only ProviderManager valid instance. Use {@link #setInstance(ProviderManager)}
+ * to configure your own provider manager. If non was provided then an instance of this
+ * class will be used.
+ *
+ * @return the only ProviderManager valid instance.
+ */
+ public static synchronized ProviderManager getInstance() {
+ if (instance == null) {
+ instance = new ProviderManager();
+ }
+ return instance;
+ }
+
+ /**
+ * Sets the only ProviderManager valid instance to be used by all XMPPConnections. If you
+ * want to provide your own provider manager then you need to do it before creating
+ * any XMPPConnection. Otherwise an IllegalStateException will be thrown.
+ *
+ * @param providerManager the only ProviderManager valid instance to be used.
+ * @throws IllegalStateException if a provider manager was already configued.
+ */
+ public static synchronized void setInstance(ProviderManager providerManager) {
+ if (instance != null) {
+ throw new IllegalStateException("ProviderManager singleton already set");
+ }
+ instance = providerManager;
+ }
+
+ protected void initialize() {
// Load IQ processing providers.
try {
// Get an array of class loaders to try loading the providers files from.
@@ -155,7 +192,7 @@ public class ProviderManager {
// Add the provider to the map.
Class provider = Class.forName(className);
if (IQProvider.class.isAssignableFrom(provider)) {
- iqProviders.put(key, (IQProvider)provider.newInstance());
+ iqProviders.put(key, provider.newInstance());
}
else if (IQ.class.isAssignableFrom(provider)) {
iqProviders.put(key, provider);
@@ -243,7 +280,7 @@ public class ProviderManager {
* @param namespace the XML namespace.
* @return the IQ provider.
*/
- public static Object getIQProvider(String elementName, String namespace) {
+ public Object getIQProvider(String elementName, String namespace) {
String key = getProviderKey(elementName, namespace);
return iqProviders.get(key);
}
@@ -255,7 +292,7 @@ public class ProviderManager {
*
* @return all IQProvider instances.
*/
- public static Collection