2014-02-17 23:58:40 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* 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;
|
|
|
|
|
2015-02-26 18:41:17 +01:00
|
|
|
import org.jivesoftware.smack.packet.ExtensionElement;
|
2017-06-14 17:12:43 +02:00
|
|
|
import org.jivesoftware.smack.packet.IQ;
|
2019-05-06 22:06:13 +02:00
|
|
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
|
|
|
import org.jivesoftware.smack.xml.XmlPullParser;
|
2014-02-17 23:58:40 +01:00
|
|
|
|
|
|
|
/**
|
2018-05-09 23:06:12 +02:00
|
|
|
* Loads the {@link IQProvider} and {@link ExtensionElementProvider} information from a standard provider file in preparation
|
2014-02-17 23:58:40 +01:00
|
|
|
* for loading into the {@link ProviderManager}.
|
2018-05-09 23:06:12 +02:00
|
|
|
*
|
2014-02-17 23:58:40 +01:00
|
|
|
* @author Robin Collier
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
public class ProviderFileLoader implements ProviderLoader {
|
2014-02-26 21:38:02 +01:00
|
|
|
private static final Logger LOGGER = Logger.getLogger(ProviderFileLoader.class.getName());
|
2014-05-11 09:27:41 +02:00
|
|
|
|
2014-09-11 23:58:07 +02:00
|
|
|
private final Collection<IQProviderInfo> iqProviders = new LinkedList<IQProviderInfo>();
|
|
|
|
private final Collection<ExtensionProviderInfo> extProviders = new LinkedList<ExtensionProviderInfo>();
|
|
|
|
private final Collection<StreamFeatureProviderInfo> sfProviders = new LinkedList<StreamFeatureProviderInfo>();
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2014-05-11 09:27:41 +02:00
|
|
|
private List<Exception> exceptions = new LinkedList<Exception>();
|
2014-02-17 23:58:40 +01:00
|
|
|
|
2014-05-11 09:27:41 +02:00
|
|
|
public ProviderFileLoader(InputStream providerStream) {
|
2014-05-15 15:04:46 +02:00
|
|
|
this(providerStream, ProviderFileLoader.class.getClassLoader());
|
|
|
|
}
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
public ProviderFileLoader(InputStream providerStream, ClassLoader classLoader) {
|
2014-02-17 23:58:40 +01:00
|
|
|
// Load processing providers.
|
2019-02-04 09:36:37 +01:00
|
|
|
try (InputStream is = providerStream) {
|
2019-05-06 22:06:13 +02:00
|
|
|
XmlPullParser parser = PacketParserUtils.getParserFor(is);
|
|
|
|
XmlPullParser.Event eventType = parser.getEventType();
|
2014-02-17 23:58:40 +01:00
|
|
|
do {
|
2019-05-06 22:06:13 +02:00
|
|
|
if (eventType == XmlPullParser.Event.START_ELEMENT) {
|
2014-09-11 23:58:07 +02:00
|
|
|
final String typeName = parser.getName();
|
|
|
|
|
2014-02-17 23:58:40 +01:00
|
|
|
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 {
|
2014-05-15 15:04:46 +02:00
|
|
|
final Class<?> provider = classLoader.loadClass(className);
|
2014-09-11 23:58:07 +02:00
|
|
|
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.
|
2014-02-17 23:58:40 +01:00
|
|
|
// Add the provider to the map.
|
|
|
|
if (IQProvider.class.isAssignableFrom(provider)) {
|
2017-02-11 16:16:41 +01:00
|
|
|
IQProvider<IQ> iqProvider = (IQProvider<IQ>) provider.getConstructor().newInstance();
|
|
|
|
iqProviders.add(new IQProviderInfo(elementName, namespace, iqProvider));
|
2014-02-17 23:58:40 +01:00
|
|
|
}
|
2014-10-07 21:15:20 +02:00
|
|
|
else {
|
2014-12-10 11:06:04 +01:00
|
|
|
exceptions.add(new IllegalArgumentException(className + " is not a IQProvider"));
|
2014-10-07 21:15:20 +02:00
|
|
|
}
|
2014-09-11 23:58:07 +02:00
|
|
|
break;
|
|
|
|
case "extensionProvider":
|
2014-02-17 23:58:40 +01:00
|
|
|
// 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.
|
2015-02-26 18:41:17 +01:00
|
|
|
if (ExtensionElementProvider.class.isAssignableFrom(provider)) {
|
2017-02-11 16:16:41 +01:00
|
|
|
ExtensionElementProvider<ExtensionElement> extensionElementProvider = (ExtensionElementProvider<ExtensionElement>) provider.getConstructor().newInstance();
|
|
|
|
extProviders.add(new ExtensionProviderInfo(elementName, namespace,
|
|
|
|
extensionElementProvider));
|
2014-02-17 23:58:40 +01:00
|
|
|
}
|
2014-10-07 21:15:20 +02:00
|
|
|
else {
|
2014-12-10 11:06:04 +01:00
|
|
|
exceptions.add(new IllegalArgumentException(className
|
|
|
|
+ " is not a PacketExtensionProvider"));
|
2014-10-07 21:15:20 +02:00
|
|
|
}
|
2014-09-11 23:58:07 +02:00
|
|
|
break;
|
|
|
|
case "streamFeatureProvider":
|
2017-02-11 16:16:41 +01:00
|
|
|
ExtensionElementProvider<ExtensionElement> streamFeatureProvider = (ExtensionElementProvider<ExtensionElement>) provider.getConstructor().newInstance();
|
2014-09-11 23:58:07 +02:00
|
|
|
sfProviders.add(new StreamFeatureProviderInfo(elementName,
|
|
|
|
namespace,
|
2017-02-11 16:16:41 +01:00
|
|
|
streamFeatureProvider));
|
2014-09-11 23:58:07 +02:00
|
|
|
break;
|
|
|
|
default:
|
2014-11-24 19:50:59 +01:00
|
|
|
LOGGER.warning("Unknown provider type: " + typeName);
|
2014-02-17 23:58:40 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (ClassNotFoundException cnfe) {
|
2014-02-26 21:38:02 +01:00
|
|
|
LOGGER.log(Level.SEVERE, "Could not find provider class", cnfe);
|
2014-02-17 23:58:40 +01:00
|
|
|
exceptions.add(cnfe);
|
|
|
|
}
|
2014-10-29 23:47:47 +01:00
|
|
|
catch (InstantiationException ie) {
|
|
|
|
LOGGER.log(Level.SEVERE, "Could not instanciate " + className, ie);
|
|
|
|
exceptions.add(ie);
|
|
|
|
}
|
2014-02-17 23:58:40 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (IllegalArgumentException illExc) {
|
2014-02-26 21:38:02 +01:00
|
|
|
LOGGER.log(Level.SEVERE, "Invalid provider type found [" + typeName + "] when expecting iqProvider or extensionProvider", illExc);
|
2014-02-17 23:58:40 +01:00
|
|
|
exceptions.add(illExc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
eventType = parser.next();
|
|
|
|
}
|
2019-05-06 22:06:13 +02:00
|
|
|
while (eventType != XmlPullParser.Event.END_DOCUMENT);
|
2014-02-17 23:58:40 +01:00
|
|
|
}
|
2017-05-23 16:45:04 +02:00
|
|
|
catch (Exception e) {
|
2014-02-26 21:38:02 +01:00
|
|
|
LOGGER.log(Level.SEVERE, "Unknown error occurred while parsing provider file", e);
|
2014-05-11 09:27:41 +02:00
|
|
|
exceptions.add(e);
|
2014-02-17 23:58:40 +01:00
|
|
|
}
|
|
|
|
}
|
2014-05-11 09:27:41 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public Collection<IQProviderInfo> getIQProviderInfo() {
|
|
|
|
return iqProviders;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Collection<ExtensionProviderInfo> getExtensionProviderInfo() {
|
|
|
|
return extProviders;
|
|
|
|
}
|
|
|
|
|
2014-09-11 23:58:07 +02:00
|
|
|
@Override
|
|
|
|
public Collection<StreamFeatureProviderInfo> getStreamFeatureProviderInfo() {
|
|
|
|
return sfProviders;
|
|
|
|
}
|
|
|
|
|
2014-05-11 09:27:41 +02:00
|
|
|
public List<Exception> getLoadingExceptions() {
|
|
|
|
return Collections.unmodifiableList(exceptions);
|
2014-02-17 23:58:40 +01:00
|
|
|
}
|
|
|
|
}
|