diff --git a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java index 8a076edfc..ba60df0a4 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -49,17 +49,17 @@ import org.jivesoftware.smack.filter.IQReplyFilter; import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.filter.PacketIDFilter; import org.jivesoftware.smack.packet.Bind; -import org.jivesoftware.smack.packet.CapsExtension; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Mechanisms; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.packet.Presence; -import org.jivesoftware.smack.packet.Registration; import org.jivesoftware.smack.packet.RosterVer; import org.jivesoftware.smack.packet.Session; import org.jivesoftware.smack.packet.StartTls; import org.jivesoftware.smack.packet.PlainStreamElement; +import org.jivesoftware.smack.provider.ProviderManager; +import org.jivesoftware.smack.provider.StreamFeatureProvider; import org.jivesoftware.smack.rosterstore.RosterStore; import org.jivesoftware.smack.util.PacketParserUtils; import org.jxmpp.util.XmppStringUtils; @@ -1015,42 +1015,32 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { } protected final void parseFeatures(XmlPullParser parser) throws XmlPullParserException, - IOException, SecurityRequiredException, NotConnectedException { + IOException, SmackException { streamFeatures.clear(); final int initialDepth = parser.getDepth(); while (true) { int eventType = parser.next(); if (eventType == XmlPullParser.START_TAG && parser.getDepth() == initialDepth + 1) { + PacketExtension streamFeature = null; String name = parser.getName(); String namespace = parser.getNamespace(); switch (name) { case StartTls.ELEMENT: - StartTls startTls = PacketParserUtils.parseStartTlsFeature(parser); - addStreamFeature(startTls); + streamFeature = PacketParserUtils.parseStartTlsFeature(parser); break; case Mechanisms.ELEMENT: - Mechanisms mechanisms = new Mechanisms(PacketParserUtils.parseMechanisms(parser)); - addStreamFeature(mechanisms); + streamFeature = new Mechanisms(PacketParserUtils.parseMechanisms(parser)); break; case Bind.ELEMENT: - addStreamFeature(Bind.Feature.INSTANCE); - break; - case CapsExtension.ELEMENT: - // Set the entity caps node for the server if one is send - // See http://xmpp.org/extensions/xep-0115.html#stream - String node = parser.getAttributeValue(null, "node"); - String ver = parser.getAttributeValue(null, "ver"); - String hash = parser.getAttributeValue(null, "hash"); - CapsExtension capsExtension = new CapsExtension(node, ver, hash); - addStreamFeature(capsExtension); + streamFeature = Bind.Feature.INSTANCE; break; case Session.ELEMENT: - addStreamFeature(Session.Feature.INSTANCE); + streamFeature = Session.Feature.INSTANCE; break; case RosterVer.ELEMENT: if(namespace.equals(RosterVer.NAMESPACE)) { - addStreamFeature(RosterVer.INSTANCE); + streamFeature = RosterVer.INSTANCE; } else { LOGGER.severe("Unkown Roster Versioning Namespace: " @@ -1059,16 +1049,18 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { } break; case Compress.Feature.ELEMENT: - Compress.Feature compression = PacketParserUtils.parseCompressionFeature(parser); - addStreamFeature(compression); - break; - case Registration.Feature.ELEMENT: - addStreamFeature(Registration.Feature.INSTANCE); + streamFeature = PacketParserUtils.parseCompressionFeature(parser); break; default: - parseFeaturesSubclass(name, namespace, parser); + StreamFeatureProvider provider = ProviderManager.getStreamFeatureProvider(name, namespace); + if (provider != null) { + streamFeature = provider.parseStreamFeature(parser); + } break; } + if (streamFeature != null) { + addStreamFeature(streamFeature); + } } else if (eventType == XmlPullParser.END_TAG && parser.getDepth() == initialDepth) { break; @@ -1096,10 +1088,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { afterFeaturesReceived(); } - protected void parseFeaturesSubclass (String name, String namespace, XmlPullParser parser) { - // Default implementation does nothing - } - protected void afterFeaturesReceived() throws SecurityRequiredException, NotConnectedException { // Default implementation does nothing } @@ -1115,7 +1103,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { return getFeature(element, namespace) != null; } - protected void addStreamFeature(PacketExtension feature) { + private void addStreamFeature(PacketExtension feature) { String key = XmppStringUtils.generateKey(feature.getElementName(), feature.getNamespace()); streamFeatures.put(key, feature); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java index 96f5a1640..8d7c3a1f9 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java @@ -17,7 +17,6 @@ package org.jivesoftware.smack.provider; import java.io.InputStream; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedList; @@ -40,8 +39,9 @@ import org.xmlpull.v1.XmlPullParser; public class ProviderFileLoader implements ProviderLoader { private static final Logger LOGGER = Logger.getLogger(ProviderFileLoader.class.getName()); - private Collection iqProviders; - private Collection extProviders; + private final Collection iqProviders = new LinkedList(); + private final Collection extProviders = new LinkedList(); + private final Collection sfProviders = new LinkedList(); private List exceptions = new LinkedList(); @@ -51,9 +51,6 @@ public class ProviderFileLoader implements ProviderLoader { @SuppressWarnings("unchecked") public ProviderFileLoader(InputStream providerStream, ClassLoader classLoader) { - iqProviders = new ArrayList(); - extProviders = new ArrayList(); - // Load processing providers. try { XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); @@ -62,8 +59,8 @@ public class ProviderFileLoader implements ProviderLoader { int eventType = parser.getEventType(); do { if (eventType == XmlPullParser.START_TAG) { - String typeName = parser.getName(); - + final String typeName = parser.getName(); + try { if (!"smackProviders".equals(typeName)) { parser.next(); @@ -78,21 +75,21 @@ public class ProviderFileLoader implements ProviderLoader { try { final Class provider = classLoader.loadClass(className); - // Attempt to load the provider class and then create - // a new instance if it's an IQProvider. Otherwise, if it's - // an IQ class, add the class object itself, then we'll use - // reflection later to create instances of the class. - if ("iqProvider".equals(typeName)) { + switch (typeName) { + case "iqProvider": + // Attempt to load the provider class and then create + // a new instance if it's an IQProvider. Otherwise, if it's + // an IQ class, add the class object itself, then we'll use + // reflection later to create instances of the class. // Add the provider to the map. - if (IQProvider.class.isAssignableFrom(provider)) { iqProviders.add(new IQProviderInfo(elementName, namespace, (IQProvider) provider.newInstance())); } else if (IQ.class.isAssignableFrom(provider)) { iqProviders.add(new IQProviderInfo(elementName, namespace, (Class)provider)); } - } - else { + break; + case "extensionProvider": // Attempt to load the provider class and then create // a new instance if it's an ExtensionProvider. Otherwise, if it's // a PacketExtension, add the class object itself and @@ -104,6 +101,14 @@ public class ProviderFileLoader implements ProviderLoader { else if (PacketExtension.class.isAssignableFrom(provider)) { extProviders.add(new ExtensionProviderInfo(elementName, namespace, provider)); } + break; + case "streamFeatureProvider": + sfProviders.add(new StreamFeatureProviderInfo(elementName, + namespace, + (StreamFeatureProvider) provider.newInstance())); + break; + default: + LOGGER.warning("Unkown provider type: " + typeName); } } catch (ClassNotFoundException cnfe) { @@ -145,6 +150,11 @@ public class ProviderFileLoader implements ProviderLoader { return extProviders; } + @Override + public Collection getStreamFeatureProviderInfo() { + return sfProviders; + } + public List getLoadingExceptions() { return Collections.unmodifiableList(exceptions); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderLoader.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderLoader.java index 6b66edfba..de4315ee9 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderLoader.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderLoader.java @@ -36,4 +36,12 @@ public interface ProviderLoader { * @return The extension provider info to load. */ Collection getExtensionProviderInfo(); + + /** + * Provides the stream feature providers information for the creation of stream feature + * providers to be added to the ProviderManager. + * + * @return The extension provider info to load. + */ + Collection getStreamFeatureProviderInfo(); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderManager.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderManager.java index 53c853b35..af6e396ec 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderManager.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderManager.java @@ -108,6 +108,7 @@ public final class ProviderManager { private static final Map extensionProviders = new ConcurrentHashMap(); private static final Map iqProviders = new ConcurrentHashMap(); + private static final Map streamFeatureProviders = new ConcurrentHashMap(); public static void addLoader(ProviderLoader loader) { if (loader.getIQProviderInfo() != null) { @@ -262,6 +263,21 @@ public final class ProviderManager { return Collections.unmodifiableCollection(extensionProviders.values()); } + public static StreamFeatureProvider getStreamFeatureProvider(String elementName, String namespace) { + String key = getKey(elementName, namespace); + return streamFeatureProviders.get(key); + } + + public static void addStreamFeatureProvider(String elementName, String namespace, StreamFeatureProvider provider) { + String key = getKey(elementName, namespace); + streamFeatureProviders.put(key, provider); + } + + public static void removeStreamFeatureProvider(String elementName, String namespace) { + String key = getKey(elementName, namespace); + streamFeatureProviders.remove(key); + } + private static String getKey(String elementName, String namespace) { return XmppStringUtils.generateKey(elementName, namespace); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/StreamFeatureProvider.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/StreamFeatureProvider.java new file mode 100644 index 000000000..7642ad3e3 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/StreamFeatureProvider.java @@ -0,0 +1,39 @@ +/** + * + * Copyright © 2014 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jivesoftware.smack.provider; + +import java.io.IOException; + +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.packet.PacketExtension; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +/** + * + */ +public interface StreamFeatureProvider { + + /** + * + * @param parser an XML parser. + * @return a new PacketExtension instance. + * @throws XmlPullParserException if an error occurs parsing the XML. + */ + public PacketExtension parseStreamFeature(XmlPullParser parser) throws XmlPullParserException, IOException, SmackException; +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/StreamFeatureProviderInfo.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/StreamFeatureProviderInfo.java new file mode 100644 index 000000000..5156c59b0 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/StreamFeatureProviderInfo.java @@ -0,0 +1,35 @@ +/** + * + * Copyright © 2014 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smack.provider; + +/** + * + */ +public final class StreamFeatureProviderInfo extends AbstractProviderInfo { + + /** + * Defines an extension provider which implements the StreamFeatureProvider interface. + * + * @param elementName Element that provider parses. + * @param namespace Namespace that provider parses. + * @param extProvider The provider implementation. + */ + public StreamFeatureProviderInfo(String elementName, String namespace, StreamFeatureProvider extProvider) { + super(elementName, namespace, extProvider); + } + +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java index a1643ec69..3b9976380 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java @@ -22,11 +22,10 @@ import java.io.StringReader; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; + import java.util.LinkedList; import java.util.List; import java.util.Locale; -import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; @@ -39,7 +38,6 @@ import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.packet.Presence; -import org.jivesoftware.smack.packet.Registration; import org.jivesoftware.smack.packet.RosterPacket; import org.jivesoftware.smack.packet.StartTls; import org.jivesoftware.smack.packet.StreamError; @@ -539,9 +537,6 @@ public class PacketParserUtils { else if (elementName.equals("query") && namespace.equals("jabber:iq:roster")) { iqPacket = parseRoster(parser); } - else if (elementName.equals("query") && namespace.equals("jabber:iq:register")) { - iqPacket = parseRegistration(parser); - } else if (elementName.equals(Bind.ELEMENT) && namespace.equals(Bind.NAMESPACE)) { iqPacket = parseResourceBinding(parser); } @@ -658,52 +653,6 @@ public class PacketParserUtils { return roster; } - private static Registration parseRegistration(XmlPullParser parser) throws Exception { - Registration registration = new Registration(); - Map fields = null; - boolean done = false; - while (!done) { - int eventType = parser.next(); - if (eventType == XmlPullParser.START_TAG) { - // Any element that's in the jabber:iq:register namespace, - // attempt to parse it if it's in the form value. - if (parser.getNamespace().equals("jabber:iq:register")) { - String name = parser.getName(); - String value = ""; - if (fields == null) { - fields = new HashMap(); - } - - if (parser.next() == XmlPullParser.TEXT) { - value = parser.getText(); - } - // Ignore instructions, but anything else should be added to the map. - if (!name.equals("instructions")) { - fields.put(name, value); - } - else { - registration.setInstructions(value); - } - } - // Otherwise, it must be a packet extension. - else { - registration.addExtension( - PacketParserUtils.parsePacketExtension( - parser.getName(), - parser.getNamespace(), - parser)); - } - } - else if (eventType == XmlPullParser.END_TAG) { - if (parser.getName().equals("query")) { - done = true; - } - } - } - registration.setAttributes(fields); - return registration; - } - public static Bind parseResourceBinding(XmlPullParser parser) throws IOException, XmlPullParserException { assert (parser.getEventType() == XmlPullParser.START_TAG); diff --git a/smack-core/src/main/resources/org.jivesoftware.smack/smack-config.xml b/smack-core/src/main/resources/org.jivesoftware.smack/smack-config.xml index a0e467987..df5ea47d8 100644 --- a/smack-core/src/main/resources/org.jivesoftware.smack/smack-config.xml +++ b/smack-core/src/main/resources/org.jivesoftware.smack/smack-config.xml @@ -14,6 +14,7 @@ org.jivesoftware.smack.initializer.extensions.ExtensionsInitializer org.jivesoftware.smack.initializer.experimental.ExperimentalInitializer org.jivesoftware.smack.initializer.legacy.LegacyInitializer + org.jivesoftware.smack.initializer.tcp.SmackTcpSmackInitializer org.jivesoftware.smack.sasl.javax.SASLJavaXSmackInitializer org.jivesoftware.smack.sasl.provided.SASLProvidedSmackInitializer org.jivesoftware.smack.android.AndroidSmackInitializer diff --git a/smack-core/src/test/java/org/jivesoftware/smack/provider/ProviderConfigTest.java b/smack-core/src/test/java/org/jivesoftware/smack/provider/ProviderConfigTest.java index e5ac95144..a7eabd6c2 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/provider/ProviderConfigTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/provider/ProviderConfigTest.java @@ -43,6 +43,11 @@ public class ProviderConfigTest { public Collection getExtensionProviderInfo() { return null; } + + @Override + public Collection getStreamFeatureProviderInfo() { + return null; + } }); Assert.assertNotNull(ProviderManager.getIQProvider("provider", "test:provider")); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java index cba5ed67c..2117ac671 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java @@ -26,7 +26,6 @@ import org.jivesoftware.smack.PacketInterceptor; import org.jivesoftware.smack.PacketListener; import org.jivesoftware.smack.XMPPConnectionRegistry; import org.jivesoftware.smack.XMPPException.XMPPErrorException; -import org.jivesoftware.smack.packet.CapsExtension; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.PacketExtension; @@ -39,6 +38,7 @@ import org.jivesoftware.smack.filter.PacketExtensionFilter; import org.jivesoftware.smack.util.Cache; import org.jivesoftware.smack.util.stringencoder.Base64; import org.jivesoftware.smackx.caps.cache.EntityCapsPersistentCache; +import org.jivesoftware.smackx.caps.packet.CapsExtension; import org.jivesoftware.smackx.disco.NodeInformationProvider; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/CapsExtension.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/packet/CapsExtension.java similarity index 94% rename from smack-core/src/main/java/org/jivesoftware/smack/packet/CapsExtension.java rename to smack-extensions/src/main/java/org/jivesoftware/smackx/caps/packet/CapsExtension.java index 8ec70c71f..9baa05022 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/CapsExtension.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/packet/CapsExtension.java @@ -14,8 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jivesoftware.smack.packet; +package org.jivesoftware.smackx.caps.packet; +import org.jivesoftware.smack.packet.Packet; +import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.util.XmlStringBuilder; /** diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/provider/CapsExtensionProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/provider/CapsExtensionProvider.java index 2862313f6..83bf78081 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/provider/CapsExtensionProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/provider/CapsExtensionProvider.java @@ -19,14 +19,15 @@ package org.jivesoftware.smackx.caps.provider; import java.io.IOException; import org.jivesoftware.smack.SmackException; -import org.jivesoftware.smack.packet.CapsExtension; import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.provider.PacketExtensionProvider; +import org.jivesoftware.smack.provider.StreamFeatureProvider; import org.jivesoftware.smackx.caps.EntityCapsManager; +import org.jivesoftware.smackx.caps.packet.CapsExtension; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -public class CapsExtensionProvider implements PacketExtensionProvider { +public class CapsExtensionProvider implements PacketExtensionProvider, StreamFeatureProvider { public PacketExtension parseExtension(XmlPullParser parser) throws XmlPullParserException, IOException, SmackException { @@ -55,4 +56,10 @@ public class CapsExtensionProvider implements PacketExtensionProvider { throw new SmackException("Caps elment with missing attributes"); } } + + @Override + public PacketExtension parseStreamFeature(XmlPullParser parser) throws XmlPullParserException, + IOException, SmackException { + return parseExtension(parser); + } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/AccountManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java similarity index 96% rename from smack-core/src/main/java/org/jivesoftware/smack/AccountManager.java rename to smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java index 3b84a5430..212a49065 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AccountManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.jivesoftware.smack; +package org.jivesoftware.smackx.iqregister; import java.util.Collection; import java.util.Collections; @@ -23,12 +23,17 @@ import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; +import org.jivesoftware.smack.Manager; +import org.jivesoftware.smack.PacketCollector; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.PacketIDFilter; import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smack.packet.Registration; +import org.jivesoftware.smackx.iqregister.packet.Registration; import org.jxmpp.util.XmppStringUtils; /** @@ -221,12 +226,11 @@ public class AccountManager extends Manager { */ public void createAccount(String username, String password, Map attributes) throws NoResponseException, XMPPErrorException, NotConnectedException { - Registration reg = new Registration(); - reg.setType(IQ.Type.set); - reg.setTo(connection().getServiceName()); attributes.put("username", username); attributes.put("password", password); - reg.setAttributes(attributes); + Registration reg = new Registration(attributes); + reg.setType(IQ.Type.set); + reg.setTo(connection().getServiceName()); createPacketCollectorAndSend(reg).nextResultOrThrow(); } @@ -241,13 +245,12 @@ public class AccountManager extends Manager { * @throws NotConnectedException */ public void changePassword(String newPassword) throws NoResponseException, XMPPErrorException, NotConnectedException { - Registration reg = new Registration(); - reg.setType(IQ.Type.set); - reg.setTo(connection().getServiceName()); Map map = new HashMap(); map.put("username",XmppStringUtils.parseLocalpart(connection().getUser())); map.put("password",newPassword); - reg.setAttributes(map); + Registration reg = new Registration(map); + reg.setType(IQ.Type.set); + reg.setTo(connection().getServiceName()); createPacketCollectorAndSend(reg).nextResultOrThrow(); } @@ -262,13 +265,12 @@ public class AccountManager extends Manager { * @throws NotConnectedException */ public void deleteAccount() throws NoResponseException, XMPPErrorException, NotConnectedException { - Registration reg = new Registration(); - reg.setType(IQ.Type.set); - reg.setTo(connection().getServiceName()); Map attributes = new HashMap(); // To delete an account, we add a single attribute, "remove", that is blank. attributes.put("remove", ""); - reg.setAttributes(attributes); + Registration reg = new Registration(attributes); + reg.setType(IQ.Type.set); + reg.setTo(connection().getServiceName()); createPacketCollectorAndSend(reg).nextResultOrThrow(); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Registration.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/packet/Registration.java similarity index 87% rename from smack-core/src/main/java/org/jivesoftware/smack/packet/Registration.java rename to smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/packet/Registration.java index a52b8b620..4cd4a8b9c 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Registration.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/packet/Registration.java @@ -15,10 +15,12 @@ * limitations under the License. */ -package org.jivesoftware.smack.packet; +package org.jivesoftware.smackx.iqregister.packet; import java.util.Map; +import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.util.XmlStringBuilder; /** @@ -48,8 +50,21 @@ public class Registration extends IQ { public static final String NAMESPACE = "jabber:iq:register"; - private String instructions = null; - private Map attributes = null; + private final String instructions; + private final Map attributes; + + public Registration() { + this(null); + } + + public Registration(Map attributes) { + this(null, attributes); + } + + public Registration(String instructions, Map attributes) { + this.instructions = instructions; + this.attributes = attributes; + } /** * Returns the registration instructions, or null if no instructions @@ -62,15 +77,6 @@ public class Registration extends IQ { return instructions; } - /** - * Sets the registration instructions. - * - * @param instructions the registration instructions. - */ - public void setInstructions(String instructions) { - this.instructions = instructions; - } - /** * Returns the map of String key/value pairs of account attributes. * @@ -80,15 +86,6 @@ public class Registration extends IQ { return attributes; } - /** - * Sets the account attributes. The map must only contain String key/value pairs. - * - * @param attributes the account attributes. - */ - public void setAttributes(Map attributes) { - this.attributes = attributes; - } - @Override public XmlStringBuilder getChildElementXML() { XmlStringBuilder xml = new XmlStringBuilder(); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/provider/RegistrationProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/provider/RegistrationProvider.java new file mode 100644 index 000000000..a6a1154ca --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/provider/RegistrationProvider.java @@ -0,0 +1,77 @@ +/** + * + * Copyright 2003-2007 Jive Software. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smackx.iqregister.provider; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.PacketExtension; +import org.jivesoftware.smack.provider.IQProvider; +import org.jivesoftware.smack.util.PacketParserUtils; +import org.jivesoftware.smackx.iqregister.packet.Registration; +import org.xmlpull.v1.XmlPullParser; + +public class RegistrationProvider implements IQProvider { + + @Override + public IQ parseIQ(XmlPullParser parser) throws Exception { + String instruction = null; + Map fields = new HashMap(); + List packetExtensions = new LinkedList(); + outerloop: + while (true) { + int eventType = parser.next(); + if (eventType == XmlPullParser.START_TAG) { + // Any element that's in the jabber:iq:register namespace, + // attempt to parse it if it's in the form value. + if (parser.getNamespace().equals(Registration.NAMESPACE)) { + String name = parser.getName(); + String value = ""; + + if (parser.next() == XmlPullParser.TEXT) { + value = parser.getText(); + } + // Ignore instructions, but anything else should be added to the map. + if (!name.equals("instructions")) { + fields.put(name, value); + } + else { + instruction = value; + } + } + // Otherwise, it must be a packet extension. + else { + packetExtensions.add(PacketParserUtils.parsePacketExtension( + parser.getName(), parser.getNamespace(), + parser)); + } + } + else if (eventType == XmlPullParser.END_TAG) { + if (parser.getName().equals(IQ.QUERY_ELEMENT)) { + break outerloop; + } + } + } + Registration registration = new Registration(instruction, fields); + registration.addExtensions(packetExtensions); + return registration; + } + +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/provider/RegistrationStreamFeatureProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/provider/RegistrationStreamFeatureProvider.java new file mode 100644 index 000000000..35726a14a --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/provider/RegistrationStreamFeatureProvider.java @@ -0,0 +1,31 @@ +/** + * + * Copyright © 2014 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smackx.iqregister.provider; + +import org.jivesoftware.smack.packet.PacketExtension; +import org.jivesoftware.smack.provider.StreamFeatureProvider; +import org.jivesoftware.smackx.iqregister.packet.Registration; +import org.xmlpull.v1.XmlPullParser; + +public class RegistrationStreamFeatureProvider implements StreamFeatureProvider { + + @Override + public PacketExtension parseStreamFeature(XmlPullParser parser) { + return Registration.Feature.INSTANCE; + } + +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index 417240d6b..c2406cd61 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -59,12 +59,12 @@ import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.packet.Presence; -import org.jivesoftware.smack.packet.Registration; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smackx.disco.NodeInformationProvider; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverItems; +import org.jivesoftware.smackx.iqregister.packet.Registration; import org.jivesoftware.smackx.muc.packet.Destroy; import org.jivesoftware.smackx.muc.packet.MUCAdmin; import org.jivesoftware.smackx.muc.packet.MUCInitialPresence; diff --git a/smack-extensions/src/main/resources/org.jivesoftware.smackx/extensions.providers b/smack-extensions/src/main/resources/org.jivesoftware.smackx/extensions.providers index e61e81eee..1eb277f5e 100644 --- a/smack-extensions/src/main/resources/org.jivesoftware.smackx/extensions.providers +++ b/smack-extensions/src/main/resources/org.jivesoftware.smackx/extensions.providers @@ -421,6 +421,12 @@ org.jivesoftware.smackx.caps.provider.CapsExtensionProvider + + c + http://jabber.org/protocol/caps + org.jivesoftware.smackx.caps.provider.CapsExtensionProvider + + forwarded @@ -455,4 +461,17 @@ http://www.jivesoftware.com/xmlns/xmpp/properties org.jivesoftware.smackx.jiveproperties.provider.JivePropertiesExtensionProvider + + + + query + jabber:iq:register + org.jivesoftware.smackx.iqregister.provider.RegistrationProvider + + + + register + http://jabber.org/features/iq-register + org.jivesoftware.smackx.iqregister.provider.RegistrationStreamFeatureProvider + diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/initializer/tcp/SmackTcpSmackInitalizer.java b/smack-tcp/src/main/java/org/jivesoftware/smack/initializer/tcp/SmackTcpSmackInitalizer.java new file mode 100644 index 000000000..cbc9599ee --- /dev/null +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/initializer/tcp/SmackTcpSmackInitalizer.java @@ -0,0 +1,28 @@ +/** + * + * Copyright © 2014 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smack.initializer.tcp; + +import org.jivesoftware.smack.initializer.UrlInitializer; + +public class SmackTcpSmackInitalizer extends UrlInitializer { + + @Override + protected String getProvidersUrl() { + return "classpath:org.jivesoftware.smack/smacktcp.providers"; + } + +} diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index 140e476ea..c1b1bbe57 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -917,19 +917,6 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { this.writer = writer; } - @Override - protected void parseFeaturesSubclass(String name, String namespace, XmlPullParser parser) { - switch(name) { - case StreamManagementFeature.ELEMENT: - if (namespace.equals(StreamManagement.NAMESPACE)) { - addStreamFeature(StreamManagementFeature.INSTANCE); - } else { - LOGGER.fine("Unsupported Stream Management version: " + namespace); - } - break; - } - } - @Override protected void afterFeaturesReceived() throws SecurityRequiredException, NotConnectedException { StartTls startTlsFeature = getFeature(StartTls.ELEMENT, StartTls.NAMESPACE); diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/sm/provider/StreamManagementStreamFeatureProvider.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/sm/provider/StreamManagementStreamFeatureProvider.java new file mode 100644 index 000000000..072c1e38f --- /dev/null +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/sm/provider/StreamManagementStreamFeatureProvider.java @@ -0,0 +1,33 @@ +/** + * + * Copyright © 2014 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smack.tcp.sm.provider; + +import org.jivesoftware.smack.packet.PacketExtension; +import org.jivesoftware.smack.provider.StreamFeatureProvider; +import org.jivesoftware.smack.tcp.sm.packet.StreamManagement.StreamManagementFeature; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +public class StreamManagementStreamFeatureProvider implements StreamFeatureProvider { + + @Override + public PacketExtension parseStreamFeature(XmlPullParser parser) + throws XmlPullParserException { + return StreamManagementFeature.INSTANCE; + } + +} diff --git a/smack-tcp/src/main/resources/org.jivesoftware.smack/smacktcp.providers b/smack-tcp/src/main/resources/org.jivesoftware.smack/smacktcp.providers new file mode 100644 index 000000000..2b9c8fd86 --- /dev/null +++ b/smack-tcp/src/main/resources/org.jivesoftware.smack/smacktcp.providers @@ -0,0 +1,11 @@ + + + + + + sm + urn:xmpp:sm:3 + org.jivesoftware.smack.tcp.sm.provider.StreamManagementStreamFeatureProvider + + +