All Downloads are FREE. Search and download functionalities are using the official Maven repository.

base.plugin.PluginClassLoader Maven / Gradle / Ivy

/**
 * Creative commons Attribution-NonCommercial license.
 *
 * http://creativecommons.org/licenses/by-nc/2.5/au/deed.en_GB
 *
 * NO WARRANTY IS GIVEN OR IMPLIED, USE AT YOUR OWN RISK.
 */
package base.plugin;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.ResultSet;
import java.util.Hashtable;

import javax.sql.DataSource;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * Experimental support for installation of newer versions of classes at
 * runtime. Compiled classes are installed with a version number, allowing
 * runtime selection of which version of classes should be in use.
 */
public class PluginClassLoader extends ClassLoader {

	private Hashtable> classes = new Hashtable>();
	private int version;
	private File folder;
	private DataSource ds;

	public PluginClassLoader(File folder, int version) {
		super(PluginClassLoader.class.getClassLoader());
		this.version = version;
		this.folder = folder;
	}

	public PluginClassLoader(DataSource ds, int version) {
		super(PluginClassLoader.class.getClassLoader());
		this.version = version;
		this.ds = ds;
	}

	public Class findClass(String className) throws ClassNotFoundException {
		if(version == 0) {
			return findSystemClass(className);
		}

		byte[] classByte;
		Class result = (Class)classes.get(className);
		if(result != null) {
			return result;
		}

		try{
			classByte = loadClassData(className);
			if(classByte != null) {
				result = defineClass(className, classByte, 0, classByte.length, null);
				classes.put(className, result);
				return result;
			}
		} catch(IOException e) {
			return null;
		}

		return findSystemClass(className);
	}

	/**
	 * Load a class from the data store matching the current version
	 * of the plugin.
	 *
	 * @param className
	 * @return
	 * @throws IOException
	 */
	private byte[] loadClassData(String className) throws IOException {
		byte[] buff = null;

		if(folder != null) {
			File f = new File(folder, "v" + version + File.separatorChar + className);
			int size = (int)f.length();
			buff = new byte[size];
			FileInputStream fis = new FileInputStream(f);
			DataInputStream dis = new DataInputStream(fis);
			dis.readFully(buff);
			dis.close();
		} else {
			Connection c = null;
			PreparedStatement s = null;
			ResultSet r = null;
			try {
				c = ds.getConnection();
				s = c.prepareStatement("select data from plugin_class where name=? and version=?");
				s.setString(1, className);
				s.setInt(2, version);
				r = s.executeQuery();
				if(r.next()) {
					buff = r.getBytes(1);
				}
			} catch(SQLException e) {
				throw new IOException(e);
			} finally {
				if(r != null) { try { r.close(); } catch(Exception e) {} }
				if(s != null) { try { s.close(); } catch(Exception e) {} }
				if(c != null) { try { c.close(); } catch(Exception e) {} }
			}
		}

		return buff;
	}

	private static void installClassesFromZip(InputStream in, DataSource ds) {

	}

	private static void installClassesFromZip(InputStream in, File folder) {

	}

	private static void installClassesFromFolder(InputStream in, DataSource ds) {

	}

	private static void installClassesFromFolder(InputStream in, File folder) {

	}

	private static void writeClass(Connection c, String name, byte[] bytes) {
	}

	private static void writeClass(File folder, String name, byte[] bytes) {
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy