ProviderFileLoader.java
- /**
- *
- * Copyright the original author or authors
- *
- * 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.InputStream;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.LinkedList;
- import java.util.List;
- import java.util.logging.Level;
- import java.util.logging.Logger;
- import org.jivesoftware.smack.packet.ExtensionElement;
- import org.jivesoftware.smack.packet.IQ;
- import org.xmlpull.v1.XmlPullParser;
- import org.xmlpull.v1.XmlPullParserFactory;
- /**
- * Loads the {@link IQProvider} and {@link ExtensionElementProvider} information from a standard provider file in preparation
- * for loading into the {@link ProviderManager}.
- *
- * @author Robin Collier
- *
- */
- public class ProviderFileLoader implements ProviderLoader {
- private static final Logger LOGGER = Logger.getLogger(ProviderFileLoader.class.getName());
- private final Collection<IQProviderInfo> iqProviders = new LinkedList<IQProviderInfo>();
- private final Collection<ExtensionProviderInfo> extProviders = new LinkedList<ExtensionProviderInfo>();
- private final Collection<StreamFeatureProviderInfo> sfProviders = new LinkedList<StreamFeatureProviderInfo>();
- private List<Exception> exceptions = new LinkedList<Exception>();
- public ProviderFileLoader(InputStream providerStream) {
- this(providerStream, ProviderFileLoader.class.getClassLoader());
- }
- @SuppressWarnings("unchecked")
- public ProviderFileLoader(InputStream providerStream, ClassLoader classLoader) {
- // Load processing providers.
- try {
- XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
- parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(providerStream, "UTF-8");
- int eventType = parser.getEventType();
- do {
- if (eventType == XmlPullParser.START_TAG) {
- final String typeName = parser.getName();
- try {
- if (!"smackProviders".equals(typeName)) {
- parser.next();
- parser.next();
- String elementName = parser.nextText();
- parser.next();
- parser.next();
- String namespace = parser.nextText();
- parser.next();
- parser.next();
- String className = parser.nextText();
- try {
- final Class<?> provider = classLoader.loadClass(className);
- 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)) {
- IQProvider<IQ> iqProvider = (IQProvider<IQ>) provider.getConstructor().newInstance();
- iqProviders.add(new IQProviderInfo(elementName, namespace, iqProvider));
- }
- else {
- exceptions.add(new IllegalArgumentException(className + " is not a IQProvider"));
- }
- 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
- // then we'll use reflection later to create instances
- // of the class.
- if (ExtensionElementProvider.class.isAssignableFrom(provider)) {
- ExtensionElementProvider<ExtensionElement> extensionElementProvider = (ExtensionElementProvider<ExtensionElement>) provider.getConstructor().newInstance();
- extProviders.add(new ExtensionProviderInfo(elementName, namespace,
- extensionElementProvider));
- }
- else {
- exceptions.add(new IllegalArgumentException(className
- + " is not a PacketExtensionProvider"));
- }
- break;
- case "streamFeatureProvider":
- ExtensionElementProvider<ExtensionElement> streamFeatureProvider = (ExtensionElementProvider<ExtensionElement>) provider.getConstructor().newInstance();
- sfProviders.add(new StreamFeatureProviderInfo(elementName,
- namespace,
- streamFeatureProvider));
- break;
- default:
- LOGGER.warning("Unknown provider type: " + typeName);
- }
- }
- catch (ClassNotFoundException cnfe) {
- LOGGER.log(Level.SEVERE, "Could not find provider class", cnfe);
- exceptions.add(cnfe);
- }
- catch (InstantiationException ie) {
- LOGGER.log(Level.SEVERE, "Could not instanciate " + className, ie);
- exceptions.add(ie);
- }
- }
- }
- catch (IllegalArgumentException illExc) {
- LOGGER.log(Level.SEVERE, "Invalid provider type found [" + typeName + "] when expecting iqProvider or extensionProvider", illExc);
- exceptions.add(illExc);
- }
- }
- eventType = parser.next();
- }
- while (eventType != XmlPullParser.END_DOCUMENT);
- }
- catch (Exception e) {
- LOGGER.log(Level.SEVERE, "Unknown error occurred while parsing provider file", e);
- exceptions.add(e);
- }
- finally {
- try {
- providerStream.close();
- }
- catch (Exception e) {
- // Ignore.
- }
- }
- }
- @Override
- public Collection<IQProviderInfo> getIQProviderInfo() {
- return iqProviders;
- }
- @Override
- public Collection<ExtensionProviderInfo> getExtensionProviderInfo() {
- return extProviders;
- }
- @Override
- public Collection<StreamFeatureProviderInfo> getStreamFeatureProviderInfo() {
- return sfProviders;
- }
- public List<Exception> getLoadingExceptions() {
- return Collections.unmodifiableList(exceptions);
- }
- }