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:
parent
d04517cd08
commit
6980c8e63d
137 changed files with 1101 additions and 841 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;;
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue