1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2025-09-10 01:29:38 +02:00

Rework Smack Provider design

this is the first stop towards fixing "SMACK-65: parsing should look for
depth", by providing the initial parsing depth to the provider. Some
methods (.e.g parseMessage) now use the depth as abort condition,
instead of a unclean String equals check.

parseIQ() and parseExtension() where both renamed to parse.

This also restricts the Exceptions thrown by the parse method, to just
XmlPullParserException, IOException and SmackException (not really a big
victory, but nevertheless a slight improvement).

StreamFeatureProvider is now gone, we simply use PacketExtensionProvider
for stream features.
This commit is contained in:
Florian Schmaus 2014-10-07 21:15:20 +02:00
parent d04517cd08
commit 6980c8e63d
137 changed files with 1101 additions and 841 deletions

View file

@ -125,7 +125,7 @@ public class PrivacyProviderTest extends SmackTestCase {
// Create the xml parser
XmlPullParser parser = getParserFromXML(xml);
// Create a packet from the xml
Privacy packet = (Privacy) (new PrivacyProvider()).parseIQ(parser);
Privacy packet = (Privacy) (new PrivacyProvider()).parse(parser);
// check if it exist
assertNotNull(packet);
@ -317,7 +317,7 @@ public class PrivacyProviderTest extends SmackTestCase {
// Create the xml parser
XmlPullParser parser = getParserFromXML(xml);
// Create a packet from the xml
Privacy packet = (Privacy) (new PrivacyProvider()).parseIQ(parser);
Privacy packet = (Privacy) (new PrivacyProvider()).parse(parser);
assertNotNull(packet);
assertNotNull(packet.getChildElementXML());
@ -356,7 +356,7 @@ public class PrivacyProviderTest extends SmackTestCase {
// Create the xml parser
XmlPullParser parser = getParserFromXML(xml);
// Create a packet from the xml
Privacy packet = (Privacy) (new PrivacyProvider()).parseIQ(parser);
Privacy packet = (Privacy) (new PrivacyProvider()).parse(parser);
assertNotNull(packet);

View file

@ -58,8 +58,8 @@ 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.PacketExtensionProvider;
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;
@ -1052,9 +1052,9 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
streamFeature = PacketParserUtils.parseCompressionFeature(parser);
break;
default:
StreamFeatureProvider provider = ProviderManager.getStreamFeatureProvider(name, namespace);
PacketExtensionProvider<PacketExtension> provider = ProviderManager.getStreamFeatureProvider(name, namespace);
if (provider != null) {
streamFeature = provider.parseStreamFeature(parser);
streamFeature = provider.parse(parser);
}
break;
}

View file

@ -16,14 +16,17 @@
*/
package org.jivesoftware.smack.provider;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.util.PacketParserUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
/**
*
@ -78,11 +81,12 @@ import org.xmlpull.v1.XmlPullParser;
*
* @author Robin Collier
*/
abstract public class EmbeddedExtensionProvider implements PacketExtensionProvider
abstract public class EmbeddedExtensionProvider<PE extends PacketExtension> extends PacketExtensionProvider<PE>
{
final public PacketExtension parseExtension(XmlPullParser parser) throws Exception
{
@Override
final public PE parse(XmlPullParser parser, int initialDepth)
throws XmlPullParserException, IOException, SmackException {
String namespace = parser.getNamespace();
String name = parser.getName();
Map<String, String> attMap = new HashMap<String, String>();
@ -92,17 +96,18 @@ abstract public class EmbeddedExtensionProvider implements PacketExtensionProvid
attMap.put(parser.getAttributeName(i), parser.getAttributeValue(i));
}
List<PacketExtension> extensions = new ArrayList<PacketExtension>();
int tag;
do
{
int tag = parser.next();
tag = parser.next();
if (tag == XmlPullParser.START_TAG)
extensions.add(PacketParserUtils.parsePacketExtension(parser.getName(), parser.getNamespace(), parser));
} while (!name.equals(parser.getName()));
} while (!(tag == XmlPullParser.END_TAG && parser.getDepth() == initialDepth));
return createReturnExtension(name, namespace, attMap, extensions);
}
abstract protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content);
abstract protected PE createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content);
}

View file

@ -16,6 +16,8 @@
*/
package org.jivesoftware.smack.provider;
import org.jivesoftware.smack.packet.PacketExtension;
/**
* Defines the information required to register a packet extension Provider with the {@link ProviderManager} when using the
* {@link ProviderLoader}.
@ -32,7 +34,7 @@ public final class ExtensionProviderInfo extends AbstractProviderInfo {
* @param namespace Namespace that provider parses.
* @param extProvider The provider implementation.
*/
public ExtensionProviderInfo(String elementName, String namespace, PacketExtensionProvider extProvider) {
public ExtensionProviderInfo(String elementName, String namespace, PacketExtensionProvider<PacketExtension> extProvider) {
super(elementName, namespace, extProvider);
}

View file

@ -18,27 +18,14 @@
package org.jivesoftware.smack.provider;
import org.jivesoftware.smack.packet.IQ;
import org.xmlpull.v1.XmlPullParser;
/**
* An interface for parsing custom IQ packets. Each IQProvider must be registered with
* An abstract class for parsing custom IQ packets. Each IQProvider must be registered with
* the ProviderManager class for it to be used. Every implementation of this
* interface <b>must</b> have a public, no-argument constructor.
* abstract class <b>must</b> have a public, no-argument constructor.
*
* @author Matt Tucker
*/
public interface IQProvider {
public abstract class IQProvider<I extends IQ> extends Provider<I> {
/**
* Parse the IQ sub-document and create an IQ instance. Each IQ must have a
* single child element. At the beginning of the method call, the xml parser
* will be positioned at the opening tag of the IQ child element. At the end
* of the method call, the parser <b>must</b> be positioned on the closing tag
* of the child element.
*
* @param parser an XML parser.
* @return a new IQ instance.
* @throws Exception if an error occurs parsing the XML.
*/
public IQ parseIQ(XmlPullParser parser) throws Exception;
}

View file

@ -34,7 +34,7 @@ public final class IQProviderInfo extends AbstractProviderInfo {
* @param namespace Namespace that provider parses.
* @param iqProvider The provider implementation.
*/
public IQProviderInfo(String elementName, String namespace, IQProvider iqProvider) {
public IQProviderInfo(String elementName, String namespace, IQProvider<IQ> iqProvider) {
super(elementName, namespace, iqProvider);
}

View file

@ -17,27 +17,16 @@
package org.jivesoftware.smack.provider;
import org.jivesoftware.smack.packet.PacketExtension;
import org.xmlpull.v1.XmlPullParser;
/**
* An interface for parsing custom packets extensions. Each PacketExtensionProvider must
* An abstract class for parsing custom packets extensions. Each PacketExtensionProvider must
* be registered with the ProviderManager class for it to be used. Every implementation
* of this interface <b>must</b> have a public, no-argument constructor.
* of this abstract class <b>must</b> have a public, no-argument constructor.
*
* @author Matt Tucker
*/
public interface PacketExtensionProvider {
public abstract class PacketExtensionProvider<PE extends PacketExtension> extends Provider<PE> {
/**
* Parse an extension sub-packet and create a PacketExtension instance. At
* the beginning of the method call, the xml parser will be positioned on the
* opening element of the packet extension. At the end of the method call, the
* parser <b>must</b> be positioned on the closing element of the packet extension.
*
* @param parser an XML parser.
* @return a new IQ instance.
* @throws java.lang.Exception if an error occurs parsing the XML.
*/
public PacketExtension parseExtension(XmlPullParser parser) throws Exception;
}

View file

@ -20,20 +20,24 @@ package org.jivesoftware.smack.provider;
import java.io.IOException;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.packet.Element;
import org.jivesoftware.smack.util.ParserUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
/**
*
*/
public interface StreamFeatureProvider {
public abstract class Provider<E extends Element> {
/**
*
* @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;
public final E parse(XmlPullParser parser) throws XmlPullParserException, IOException, SmackException {
// XPP3 calling convention assert: Parser should be at start tag
ParserUtils.assertAtStartTag(parser);
final int initialDepth = parser.getDepth();
E e = parse(parser, initialDepth);
// XPP3 calling convention assert: Parser should be at end tag of the consumed/parsed element
ParserUtils.forwardToEndTagOfDepth(parser, initialDepth);
return e;
}
public abstract E parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException, SmackException;;
}

View file

@ -83,11 +83,16 @@ public class ProviderFileLoader implements ProviderLoader {
// 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()));
iqProviders.add(new IQProviderInfo(elementName, namespace, (IQProvider<IQ>) provider.newInstance()));
}
else if (IQ.class.isAssignableFrom(provider)) {
iqProviders.add(new IQProviderInfo(elementName, namespace, (Class<? extends IQ>)provider));
}
else {
exceptions.add(new IllegalArgumentException(
className
+ " is neither IQProvider or IQ class"));
}
break;
case "extensionProvider":
// Attempt to load the provider class and then create
@ -96,16 +101,21 @@ public class ProviderFileLoader implements ProviderLoader {
// then we'll use reflection later to create instances
// of the class.
if (PacketExtensionProvider.class.isAssignableFrom(provider)) {
extProviders.add(new ExtensionProviderInfo(elementName, namespace, (PacketExtensionProvider) provider.newInstance()));
extProviders.add(new ExtensionProviderInfo(elementName, namespace, (PacketExtensionProvider<PacketExtension>) provider.newInstance()));
}
else if (PacketExtension.class.isAssignableFrom(provider)) {
extProviders.add(new ExtensionProviderInfo(elementName, namespace, provider));
}
else {
exceptions.add(new IllegalArgumentException(
className
+ " is neither PacketExtensionProvider or PacketExtension class"));
}
break;
case "streamFeatureProvider":
sfProviders.add(new StreamFeatureProviderInfo(elementName,
namespace,
(StreamFeatureProvider) provider.newInstance()));
(PacketExtensionProvider<PacketExtension>) provider.newInstance()));
break;
default:
LOGGER.warning("Unkown provider type: " + typeName);

View file

@ -109,11 +109,11 @@ import org.jxmpp.util.XmppStringUtils;
*/
public final class ProviderManager {
private static final Map<String, PacketExtensionProvider> extensionProviders = new ConcurrentHashMap<String, PacketExtensionProvider>();
private static final Map<String, IQProvider> iqProviders = new ConcurrentHashMap<String, IQProvider>();
private static final Map<String, PacketExtensionProvider<PacketExtension>> extensionProviders = new ConcurrentHashMap<String, PacketExtensionProvider<PacketExtension>>();
private static final Map<String, IQProvider<IQ>> iqProviders = new ConcurrentHashMap<String, IQProvider<IQ>>();
private static final Map<String, Class<?>> extensionIntrospectionProviders = new ConcurrentHashMap<String, Class<?>>();
private static final Map<String, Class<?>> iqIntrospectionProviders = new ConcurrentHashMap<String, Class<?>>();
private static final Map<String, StreamFeatureProvider> streamFeatureProviders = new ConcurrentHashMap<String, StreamFeatureProvider>();
private static final Map<String, PacketExtensionProvider<PacketExtension>> streamFeatureProviders = new ConcurrentHashMap<String, PacketExtensionProvider<PacketExtension>>();
static {
// Ensure that Smack is initialized by calling getVersion, so that user
@ -157,7 +157,7 @@ public final class ProviderManager {
* @param namespace the XML namespace.
* @return the IQ provider.
*/
public static IQProvider getIQProvider(String elementName, String namespace) {
public static IQProvider<IQ> getIQProvider(String elementName, String namespace) {
String key = getKey(elementName, namespace);
return iqProviders.get(key);
}
@ -190,13 +190,14 @@ public final class ProviderManager {
* @param namespace the XML namespace.
* @param provider the IQ provider.
*/
@SuppressWarnings("unchecked")
public static void addIQProvider(String elementName, String namespace,
Object provider)
{
// First remove existing providers
String key = removeIQProvider(elementName, namespace);
if (provider instanceof IQProvider) {
iqProviders.put(key, (IQProvider) provider);
iqProviders.put(key, (IQProvider<IQ>) provider);
} else if (provider instanceof Class && IQ.class.isAssignableFrom((Class<?>) provider)) {
iqIntrospectionProviders.put(key, (Class<?>) provider);
} else {
@ -240,7 +241,7 @@ public final class ProviderManager {
* @param namespace namespace associated with extension provider.
* @return the extenion provider.
*/
public static PacketExtensionProvider getExtensionProvider(String elementName, String namespace) {
public static PacketExtensionProvider<PacketExtension> getExtensionProvider(String elementName, String namespace) {
String key = getKey(elementName, namespace);
return extensionProviders.get(key);
}
@ -259,13 +260,14 @@ public final class ProviderManager {
* @param namespace the XML namespace.
* @param provider the extension provider.
*/
@SuppressWarnings("unchecked")
public static void addExtensionProvider(String elementName, String namespace,
Object provider)
{
// First remove existing providers
String key = removeExtensionProvider(elementName, namespace);
if (provider instanceof PacketExtensionProvider) {
extensionProviders.put(key, (PacketExtensionProvider) provider);
extensionProviders.put(key, (PacketExtensionProvider<PacketExtension>) provider);
} else if (provider instanceof Class && PacketExtension.class.isAssignableFrom((Class<?>) provider)) {
extensionIntrospectionProviders.put(key, (Class<?>) provider);
} else {
@ -304,12 +306,12 @@ public final class ProviderManager {
return Collections.unmodifiableList(providers);
}
public static StreamFeatureProvider getStreamFeatureProvider(String elementName, String namespace) {
public static PacketExtensionProvider<PacketExtension> getStreamFeatureProvider(String elementName, String namespace) {
String key = getKey(elementName, namespace);
return streamFeatureProviders.get(key);
}
public static void addStreamFeatureProvider(String elementName, String namespace, StreamFeatureProvider provider) {
public static void addStreamFeatureProvider(String elementName, String namespace, PacketExtensionProvider<PacketExtension> provider) {
String key = getKey(elementName, namespace);
streamFeatureProviders.put(key, provider);
}

View file

@ -16,6 +16,8 @@
*/
package org.jivesoftware.smack.provider;
import org.jivesoftware.smack.packet.PacketExtension;
/**
*
*/
@ -28,7 +30,8 @@ public final class StreamFeatureProviderInfo extends AbstractProviderInfo {
* @param namespace Namespace that provider parses.
* @param extProvider The provider implementation.
*/
public StreamFeatureProviderInfo(String elementName, String namespace, StreamFeatureProvider extProvider) {
public StreamFeatureProviderInfo(String elementName, String namespace,
PacketExtensionProvider<PacketExtension> extProvider) {
super(elementName, namespace, extProvider);
}

View file

@ -22,13 +22,13 @@ import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.compress.packet.Compress;
import org.jivesoftware.smack.packet.Bind;
@ -121,7 +121,7 @@ public class PacketParserUtils {
case Message.ELEMENT:
return parseMessage(parser);
case IQ.ELEMENT:
return parseIQ(parser, connection);
return parse(parser, connection);
case Presence.ELEMENT:
return parsePresence(parser);
default:
@ -171,9 +171,16 @@ public class PacketParserUtils {
*
* @param parser the XML parser, positioned at the start of a message packet.
* @return a Message packet.
* @throws Exception if an exception occurs while parsing the packet.
* @throws IOException
* @throws XmlPullParserException
* @throws SmackException
*/
public static Message parseMessage(XmlPullParser parser) throws Exception {
public static Message parseMessage(XmlPullParser parser)
throws XmlPullParserException, IOException, SmackException {
ParserUtils.assertAtStartTag(parser);
assert(parser.getName().equals(Message.ELEMENT));
final int initialDepth = parser.getDepth();
Message message = new Message();
message.setPacketID(parser.getAttributeValue("", "id"));
message.setTo(parser.getAttributeValue("", "to"));
@ -197,26 +204,27 @@ public class PacketParserUtils {
// Parse sub-elements. We include extra logic to make sure the values
// are only read once. This is because it's possible for the names to appear
// in arbitrary sub-elements.
boolean done = false;
String thread = null;
while (!done) {
outerloop: while (true) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
switch (eventType) {
case XmlPullParser.START_TAG:
String elementName = parser.getName();
String namespace = parser.getNamespace();
if (elementName.equals("subject")) {
String xmlLang = getLanguageAttribute(parser);
if (xmlLang == null) {
xmlLang = defaultLanguage;
switch(elementName) {
case "subject":
String xmlLangSubject = getLanguageAttribute(parser);
if (xmlLangSubject == null) {
xmlLangSubject = defaultLanguage;
}
String subject = parseElementText(parser);
if (message.getSubject(xmlLang) == null) {
message.addSubject(xmlLang, subject);
if (message.getSubject(xmlLangSubject) == null) {
message.addSubject(xmlLangSubject, subject);
}
}
else if (elementName.equals(Message.BODY)) {
break;
case Message.BODY:
String xmlLang = getLanguageAttribute(parser);
if (xmlLang == null) {
xmlLang = defaultLanguage;
@ -227,25 +235,26 @@ public class PacketParserUtils {
if (message.getBody(xmlLang) == null) {
message.addBody(xmlLang, body);
}
}
else if (elementName.equals("thread")) {
break;
case "thread":
if (thread == null) {
thread = parser.nextText();
}
}
else if (elementName.equals("error")) {
break;
case "error":
message.setError(parseError(parser));
}
// Otherwise, it must be a packet extension.
else {
break;
default:
message.addExtension(
PacketParserUtils.parsePacketExtension(elementName, namespace, parser));
break;
}
}
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("message")) {
done = true;
break;
case XmlPullParser.END_TAG:
if (parser.getDepth() == initialDepth) {
break outerloop;
}
break;
}
}
@ -434,9 +443,15 @@ public class PacketParserUtils {
*
* @param parser the XML parser, positioned at the start of a presence packet.
* @return a Presence packet.
* @throws Exception if an exception occurs while parsing the packet.
* @throws IOException
* @throws XmlPullParserException
* @throws SmackException
*/
public static Presence parsePresence(XmlPullParser parser) throws Exception {
public static Presence parsePresence(XmlPullParser parser)
throws XmlPullParserException, IOException, SmackException {
ParserUtils.assertAtStartTag(parser);
final int initialDepth = parser.getDepth();
Presence.Type type = Presence.Type.available;
String typeString = parser.getAttributeValue("", "type");
if (typeString != null && !typeString.equals("")) {
@ -453,20 +468,21 @@ public class PacketParserUtils {
}
// Parse sub-elements
boolean done = false;
while (!done) {
outerloop: while (true) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
switch (eventType) {
case XmlPullParser.START_TAG:
String elementName = parser.getName();
String namespace = parser.getNamespace();
if (elementName.equals("status")) {
switch(elementName) {
case "status":
presence.setStatus(parser.nextText());
}
else if (elementName.equals("priority")) {
break;
case "priority":
int priority = Integer.parseInt(parser.nextText());
presence.setPriority(priority);
}
else if (elementName.equals("show")) {
break;
case "show":
String modeText = parser.nextText();
if (StringUtils.isNotEmpty(modeText)) {
presence.setMode(Presence.Mode.fromString(modeText));
@ -480,12 +496,12 @@ public class PacketParserUtils {
+ presence.getPacketID()
+ "' which is invalid according to RFC6121 4.7.2.1");
}
}
else if (elementName.equals("error")) {
break;
case "error":
presence.setError(parseError(parser));
}
break;
default:
// Otherwise, it must be a packet extension.
else {
// Be extra robust: Skip PacketExtensions that cause Exceptions, instead of
// failing completely here. See SMACK-390 for more information.
try {
@ -496,12 +512,13 @@ public class PacketParserUtils {
"Failed to parse extension packet in Presence packet.",
e);
}
break;
}
}
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("presence")) {
done = true;
case XmlPullParser.END_TAG:
if (parser.getDepth() == initialDepth) {
break outerloop;
}
break;
}
}
return presence;
@ -515,7 +532,7 @@ public class PacketParserUtils {
* @return an IQ object.
* @throws Exception if an exception occurs while parsing the packet.
*/
public static IQ parseIQ(XmlPullParser parser, XMPPConnection connection) throws Exception {
public static IQ parse(XmlPullParser parser, XMPPConnection connection) throws Exception {
IQ iqPacket = null;
XMPPError error = null;
@ -543,9 +560,9 @@ public class PacketParserUtils {
// Otherwise, see if there is a registered provider for
// this element name and namespace.
else {
IQProvider provider = ProviderManager.getIQProvider(elementName, namespace);
IQProvider<IQ> provider = ProviderManager.getIQProvider(elementName, namespace);
if (provider != null) {
iqPacket =provider.parseIQ(parser);
iqPacket = provider.parse(parser);
} else {
Class<?> introspectionProvider = ProviderManager.getIQIntrospectionProvider(
elementName, namespace);
@ -611,7 +628,7 @@ public class PacketParserUtils {
return iqPacket;
}
public static RosterPacket parseRoster(XmlPullParser parser) throws Exception {
public static RosterPacket parseRoster(XmlPullParser parser) throws XmlPullParserException, IOException {
RosterPacket roster = new RosterPacket();
boolean done = false;
RosterPacket.Item item = null;
@ -826,9 +843,12 @@ public class PacketParserUtils {
*
* @param parser the XML parser.
* @return an error sub-packet.
* @throws Exception if an exception occurs while parsing the packet.
* @throws IOException
* @throws XmlPullParserException
* @throws SmackException
*/
public static XMPPError parseError(XmlPullParser parser) throws Exception {
public static XMPPError parseError(XmlPullParser parser)
throws XmlPullParserException, IOException, SmackException {
String type = null;
String message = null;
String condition = null;
@ -882,18 +902,26 @@ public class PacketParserUtils {
* @param namespace the XML namespace of the packet extension.
* @param parser the XML parser, positioned at the starting element of the extension.
* @return a PacketExtension.
* @throws Exception
*/
public static PacketExtension parsePacketExtension(String elementName, String namespace,
XmlPullParser parser) throws Exception {
XmlPullParser parser) throws XmlPullParserException,
IOException, SmackException {
// See if a provider is registered to handle the extension.
PacketExtensionProvider provider = ProviderManager.getExtensionProvider(elementName, namespace);
PacketExtensionProvider<PacketExtension> provider = ProviderManager.getExtensionProvider(elementName, namespace);
if (provider != null) {
return provider.parseExtension(parser);
return provider.parse(parser);
}
Class<?> introspectionProvider = ProviderManager.getExtensionIntrospectionProvider(elementName, namespace);
if (introspectionProvider != null) {
return (PacketExtension)parseWithIntrospection(elementName, introspectionProvider, parser);
try {
return (PacketExtension)parseWithIntrospection(elementName, introspectionProvider, parser);
} catch (NoSuchMethodException | SecurityException
| InstantiationException | IllegalAccessException
| IllegalArgumentException
| InvocationTargetException
| ClassNotFoundException e) {
throw new SmackException(e);
}
}
// No providers registered, so use a default extension.
DefaultPacketExtension extension = new DefaultPacketExtension(elementName, namespace);

View file

@ -31,6 +31,14 @@ public class ParserUtils {
assert(parser.getEventType() == XmlPullParser.END_TAG);
}
public static void forwardToEndTagOfDepth(XmlPullParser parser, int depth)
throws XmlPullParserException, IOException {
int event = parser.getEventType();
while (!(event == XmlPullParser.END_TAG && parser.getDepth() == depth)) {
event = parser.next();
}
}
/**
* Get the boolean value of an argument.
*

View file

@ -327,7 +327,7 @@ public class RosterTest {
.append("</query>")
.append("</iq>");
final XmlPullParser parser = TestUtils.getIQParser(sb.toString());
final IQ rosterPush = PacketParserUtils.parseIQ(parser, connection);
final IQ rosterPush = PacketParserUtils.parse(parser, connection);
initRoster(connection, roster);
rosterListener.reset();
@ -460,7 +460,7 @@ public class RosterTest {
.append("</query>")
.append("</iq>");
final XmlPullParser parser = TestUtils.getIQParser(sb.toString());
final IQ rosterPush = PacketParserUtils.parseIQ(parser, connection);
final IQ rosterPush = PacketParserUtils.parse(parser, connection);
initRoster(connection, roster);
rosterListener.reset();

View file

@ -72,12 +72,12 @@ public class ParsingExceptionTest {
assertThat(MESSAGE_EXCEPTION_ELEMENT + EXTENSION2 + "</message>", equalsCharSequence(content));
}
static class ThrowException implements PacketExtensionProvider {
static class ThrowException extends PacketExtensionProvider<PacketExtension> {
public static final String ELEMENT = "exception";
public static final String NAMESPACE = "http://smack.jivesoftware.org/exception";
@Override
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
public PacketExtension parse(XmlPullParser parser, int initialDepth) throws SmackException {
throw new SmackException("Test Exception");
}

View file

@ -59,10 +59,10 @@ public class ProviderConfigTest {
Assert.assertNotNull(ProviderManager.getIQProvider("provider", "test:file_provider"));
}
public static class TestIQProvider implements IQProvider {
public static class TestIQProvider extends IQProvider<IQ> {
@Override
public IQ parseIQ(XmlPullParser parser) throws Exception {
public IQ parse(XmlPullParser parser, int initialDepth) {
return null;
}

View file

@ -34,10 +34,10 @@ public class ProviderManagerTest {
assertTrue(SmackConfiguration.isSmackInitialized());
}
public static class TestIQProvider implements IQProvider {
public static class TestIQProvider extends IQProvider<IQ> {
@Override
public IQ parseIQ(XmlPullParser parser) throws Exception {
public IQ parse(XmlPullParser parser, int initialDepth) {
return null;
}