mirror of
https://github.com/igniterealtime/Spark.git
synced 2025-12-01 12:27:58 +00:00
git-svn-id: http://svn.igniterealtime.org/svn/repos/spark/trunk@12269 b35dd754-fafc-0310-a699-88a17e54d16e
208 lines
8.2 KiB
Java
208 lines
8.2 KiB
Java
/**
|
|
* $RCSfile: ,v $
|
|
* $Revision: $
|
|
* $Date: $
|
|
*
|
|
* Copyright (C) 2004-2010 Jive Software. All rights reserved.
|
|
*
|
|
* 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.spark.plugin;
|
|
|
|
import org.jivesoftware.smack.packet.IQ;
|
|
import org.jivesoftware.smack.packet.PacketExtension;
|
|
import org.jivesoftware.smack.provider.IQProvider;
|
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
|
import org.jivesoftware.smack.provider.ProviderManager;
|
|
import org.jivesoftware.spark.util.URLFileSystem;
|
|
import org.jivesoftware.spark.util.log.Log;
|
|
import org.xmlpull.mxp1.MXParser;
|
|
import org.xmlpull.v1.XmlPullParser;
|
|
|
|
import java.io.File;
|
|
import java.io.FilenameFilter;
|
|
import java.io.InputStream;
|
|
import java.net.MalformedURLException;
|
|
import java.net.URL;
|
|
import java.net.URLClassLoader;
|
|
import java.util.jar.JarFile;
|
|
import java.util.zip.ZipEntry;
|
|
import java.util.zip.ZipFile;
|
|
|
|
/**
|
|
* A simple classloader to extend the classpath to
|
|
* include all jars in a lib directory.<p>
|
|
* <p/>
|
|
* The new classpath includes all <tt>*.jar files.
|
|
*
|
|
* @author Derek DeMoro
|
|
*/
|
|
public class PluginClassLoader extends URLClassLoader {
|
|
|
|
/**
|
|
* Constructs the classloader.
|
|
*
|
|
* @param parent the parent class loader (or null for none).
|
|
* @param libDir the directory to load jar files from.
|
|
* @throws java.net.MalformedURLException if the libDir path is not valid.
|
|
*/
|
|
public PluginClassLoader(ClassLoader parent, File libDir) throws MalformedURLException {
|
|
super(new URL[]{libDir.toURI().toURL()}, parent);
|
|
}
|
|
|
|
/**
|
|
* Adds all archives in a plugin to the classpath.
|
|
*
|
|
* @param pluginDir the directory of the plugin.
|
|
* @throws MalformedURLException the exception thrown if URL is not valid.
|
|
*/
|
|
public void addPlugin(File pluginDir) throws MalformedURLException {
|
|
File libDir = new File(pluginDir, "lib");
|
|
|
|
File[] jars = libDir.listFiles(new FilenameFilter() {
|
|
public boolean accept(File dir, String name) {
|
|
boolean accept = false;
|
|
String smallName = name.toLowerCase();
|
|
if (smallName.endsWith(".jar")) {
|
|
accept = true;
|
|
}
|
|
else if (smallName.endsWith(".zip")) {
|
|
accept = true;
|
|
}
|
|
return accept;
|
|
}
|
|
});
|
|
|
|
// Do nothing if no jar or zip files were found
|
|
if (jars == null) {
|
|
return;
|
|
}
|
|
|
|
for (File jar : jars) {
|
|
if (jar.isFile()) {
|
|
final URL url = jar.toURI().toURL();
|
|
addURL(url);
|
|
try {
|
|
checkForSmackProviders(url);
|
|
}
|
|
catch (Throwable e) {
|
|
Log.error(e);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void checkForSmackProviders(URL jarURL) throws Throwable {
|
|
ZipFile zipFile = new JarFile(URLFileSystem.url2File(jarURL));
|
|
|
|
ZipEntry entry = zipFile.getEntry("META-INF/smack.providers");
|
|
if (entry != null) {
|
|
InputStream zin = zipFile.getInputStream(entry);
|
|
loadSmackProvider(zin);
|
|
}
|
|
|
|
}
|
|
|
|
private void loadSmackProvider(InputStream providerStream) throws Exception {
|
|
|
|
// Get an array of class loaders to try loading the providers files from.
|
|
|
|
try {
|
|
XmlPullParser parser = new MXParser();
|
|
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
|
parser.setInput(providerStream, "UTF-8");
|
|
int eventType = parser.getEventType();
|
|
do {
|
|
if (eventType == XmlPullParser.START_TAG) {
|
|
if (parser.getName().equals("iqProvider")) {
|
|
parser.next();
|
|
parser.next();
|
|
String elementName = parser.nextText();
|
|
parser.next();
|
|
parser.next();
|
|
String namespace = parser.nextText();
|
|
parser.next();
|
|
parser.next();
|
|
String className = parser.nextText();
|
|
// Only add the provider for the namespace if one isn't
|
|
// already registered.
|
|
|
|
// 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.
|
|
try {
|
|
// Add the provider to the map.
|
|
Class<?> provider = this.loadClass(className);
|
|
if (IQProvider.class.isAssignableFrom(provider)) {
|
|
ProviderManager.getInstance().addIQProvider(elementName, namespace, provider.newInstance());
|
|
}
|
|
else if (IQ.class.isAssignableFrom(provider)) {
|
|
ProviderManager.getInstance().addIQProvider(elementName, namespace, provider.newInstance());
|
|
}
|
|
}
|
|
catch (ClassNotFoundException cnfe) {
|
|
cnfe.printStackTrace();
|
|
}
|
|
|
|
}
|
|
else if (parser.getName().equals("extensionProvider")) {
|
|
parser.next();
|
|
parser.next();
|
|
String elementName = parser.nextText();
|
|
parser.next();
|
|
parser.next();
|
|
String namespace = parser.nextText();
|
|
parser.next();
|
|
parser.next();
|
|
String className = parser.nextText();
|
|
// Only add the provider for the namespace if one isn't
|
|
// already registered.
|
|
// Attempt to load the provider class and then create
|
|
// a new instance if it's a Provider. Otherwise, if it's
|
|
// a PacketExtension, add the class object itself and
|
|
// then we'll use reflection later to create instances
|
|
// of the class.
|
|
try {
|
|
// Add the provider to the map.
|
|
Class<?> provider = this.loadClass(className);
|
|
if (PacketExtensionProvider.class.isAssignableFrom(
|
|
provider)) {
|
|
ProviderManager.getInstance().addExtensionProvider(elementName, namespace, provider.newInstance());
|
|
}
|
|
else if (PacketExtension.class.isAssignableFrom(
|
|
provider)) {
|
|
ProviderManager.getInstance().addExtensionProvider(elementName, namespace, provider.newInstance());
|
|
}
|
|
}
|
|
catch (ClassNotFoundException cnfe) {
|
|
cnfe.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
eventType = parser.next();
|
|
}
|
|
while (eventType != XmlPullParser.END_DOCUMENT);
|
|
}
|
|
finally {
|
|
try {
|
|
providerStream.close();
|
|
}
|
|
catch (Exception e) {
|
|
// Nothing to do
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|