diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/XmppElementUtil.java b/smack-core/src/main/java/org/jivesoftware/smack/util/XmppElementUtil.java index 83d09cf21..1e4eabbc3 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/XmppElementUtil.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/XmppElementUtil.java @@ -23,7 +23,10 @@ import java.util.logging.Logger; import javax.xml.namespace.QName; +import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.FullyQualifiedElement; +import org.jivesoftware.smack.packet.StandardExtensionElement; +import org.jivesoftware.smack.provider.ProviderManager; import org.jxmpp.util.cache.LruCache; @@ -68,21 +71,47 @@ public class XmppElementUtil { return qname; } - public static List getElementsFrom( - MultiMap elementMap, Class extensionElementClass) { + public static List getElementsFrom( + MultiMap elementMap, Class extensionElementClass) { QName qname = XmppElementUtil.getQNameFor(extensionElementClass); - List extensionElements = elementMap.getAll(qname); + List extensionElements = elementMap.getAll(qname); if (extensionElements.isEmpty()) { return Collections.emptyList(); } - List res = new ArrayList<>(extensionElements.size()); - for (E extensionElement : extensionElements) { - R e = extensionElementClass.cast(extensionElement); + List res = new ArrayList<>(extensionElements.size()); + for (ExtensionElement extensionElement : extensionElements) { + E e = castOrThrow(extensionElement, extensionElementClass); res.add(e); } return res; } + + public static E castOrThrow(ExtensionElement extensionElement, Class extensionElementClass) { + if (!extensionElementClass.isInstance(extensionElement)) { + final QName qname = getQNameFor(extensionElementClass); + + final String detailMessage; + if (extensionElement instanceof StandardExtensionElement) { + detailMessage = "because there is no according extension element provider registered with ProviderManager for " + + qname + + ". WARNING: This indicates a serious problem with your Smack setup, probably causing Smack not being able to properly initialize itself."; + } else { + Object provider = ProviderManager.getExtensionProvider(qname); + detailMessage = "because there is an inconsistency with the provider registered with ProviderManager: the active provider for " + + qname + " '" + provider.getClass() + + "' does not return instances of type " + extensionElementClass + + ", but instead returns instances of type " + extensionElement.getClass() + "."; + } + + String message = "Extension element is not of expected class '" + extensionElementClass.getName() + "', " + + detailMessage; + throw new IllegalStateException(message); + } + + return extensionElementClass.cast(extensionElement); + } + }