/*
* XNap
*
* A pure java file sharing client.
*
* See AUTHORS for copyright information.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package xnap.util;
import xnap.XNap;
import xnap.plugin.PluginInfo;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.jar.*;
import org.apache.log4j.Logger;
public class JarClassLoader extends URLClassLoader
{
//--- Constant(s) ---
//--- Data field(s) ---
protected static Logger logger = Logger.getLogger(JarClassLoader.class);
protected static JarClassLoader singleton = new JarClassLoader();
protected LinkedList pluginInfos = new LinkedList();
//--- Constructor(s) ---
protected JarClassLoader()
{
super(new URL[] {});
}
//--- Method(s) ---
public static JarClassLoader getInstance()
{
return singleton;
}
public void addJar(File file) throws IOException
{
addJar(file.toURL());
}
public void addJar(URL url) throws IOException
{
//JarFile jar = new JarFile(url.getFile());
super.addURL(url);
}
public void init()
{
try {
readProperties(FileHelper.getResourceAsStream("plugins.properties"));
}
catch (IOException e) {
logger.error("plugin.properties not found", e);
}
// readDirectory(new File(FileHelper.getHomeDir() + "jars"));
// readDirectory(new File("libs/"));
}
public void readDirectory(File dir)
{
File[] files = dir.listFiles(new FiletypeFilter("properties"));
if (files != null) {
for (int i = 0; i < files.length; i++) {
if (!files[i].getName().equals("xnap.properties")) {
try {
readProperties(files[i]);
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
/**
* Reads plugin information from properties file.
*/
public void readProperties(File path, InputStream in) throws IOException
{
if (in == null) {
throw new IOException("Invalid input stream.");
}
Properties p = new Properties();
p.load(in);
String[] plugins
= StringHelper.toArray(p.getProperty("plugins", ""), ";");
for (int i = 0; i < plugins.length; i++) {
PluginInfo info = new PluginInfo(plugins[i], p);
// lafs are currently broken
if (info.getType() == PluginInfo.TYPE_LAF) {
continue;
}
// check requirements
// FIX: this has to be adopted to the release_nr compare mechanism
// String requires = info.getRequires();
// if (requires.length() > 0
// && VersionParser.compare(requires, XNap.VERSION) != 0) {
// logger.warn("plugin requires XNap " + requires);
// }
logger.debug("adding plugin: " + info.getClassName());
pluginInfos.add(info);
if (path != null) {
try {
loadPlugin(path, info);
}
catch (IOException e) {
logger.warn("could not load plugin", e);
}
}
else {
info.setLoaded(true);
}
}
}
public void readProperties(File f) throws IOException
{
FileInputStream in = new FileInputStream(f);
readProperties(f.getParentFile(), in);
}
public void readProperties(InputStream in) throws IOException
{
readProperties(null, in);
}
public void loadPlugin(File path, PluginInfo info) throws IOException
{
if (!info.isLoaded()) {
addJar(new File(path, info.getFilename()));
String[] depends = info.getDepends();
for (int i = 0; i < depends.length; i++) {
addJar(new File(path, depends[i]));
}
info.setLoaded(true);
}
}
public String[] getClassNames(int pluginType)
{
ArrayList classNames = new ArrayList();
for (Iterator i = pluginInfos.iterator(); i.hasNext();) {
PluginInfo info = (PluginInfo)i.next();
if (info.getType() == pluginType) {
String[] names = info.getClassNames();
for (int j = 0; j < names.length; j++) {
classNames.add(names[j]);
}
}
}
String[] array = new String[classNames.size()];
System.arraycopy(classNames.toArray(), 0, array, 0, array.length);
return array;
}
public PluginInfo[] getPluginInfos()
{
PluginInfo[] array = new PluginInfo[pluginInfos.size()];
System.arraycopy(pluginInfos.toArray(), 0, array, 0, array.length);
return array;
}
// protected Class loadClass(String name, boolean resolve)
// throws ClassNotFoundException
// {
// try {
// System.out.println("load: " + name);
// return super.loadClass(name, resolve);
// }
// catch (ClassNotFoundException e) {
// StringBuffer sb = new StringBuffer();
// sb.append("default");
// sb.append(File.separatorChar);
// sb.append(name.replace('.', File.separatorChar));
// sb.append(".class");
// String filename = sb.toString();
// System.out.println("lookup: " + filename);
// try {
// byte data[] = loadClassData(filename);
// Class c = defineClass(name, data, 0, data.length);
// if (c == null) {
// throw new ClassNotFoundException(name);
// }
// else if (resolve) {
// resolveClass(c);
// }
// return c;
// }
// catch (IOException ioe) {
// throw new ClassNotFoundException("Error reading file: "
// + filename);
// }
// }
// }
// private byte[] loadClassData(String filename) throws IOException
// {
// DataInputStream in
// = new DataInputStream(ClassLoader.getSystemResourceAsStream(filename));
// System.out.println("load size: " + in.available());
// byte[] data = new byte[in.available()];
// //byte[] data = new byte[(int)(new File(f)).length()];
// in.readFully(data);
// in.close();
// return data;
// }
// public Class findClass(String name) throws ClassNotFoundException
// {
// System.out.println("Find: " + name);
// return super.findClass(name);
// }
// public Class loadClass(String name) throws ClassNotFoundException
// {
// try {
// return findClass(name);
// }
// catch (ClassNotFoundException e) {
// return getParent().loadClass(name);
// }
// }
// public String getMainClassName(JarFile jar) throws IOException
// {
// Manifest m = jar.getManifest();
// Attributes attr = m.getMainAttributes();
// return attr != null ? attr.getValue(Attributes.Name.MAIN_CLASS) : null;
// }
public void addManifest(Manifest m)
{
Attributes attr = m.getAttributes("XNap");
if (attr != null) {
// String value = attr.getValue("Plugin");
// if (value != null) {
// StringTokenizer t = new StringTokenizer(value, " ");
// while (t.hasMoreTokens()) {
// String p = t.nextToken();
// System.out.println("Adding Plugin: " + p);
// pluginClassNames.add(p);
// }
// }
}
}
}