/*
* $Id: ZoneClassLoader.java,v 1.9 2002/09/16 08:05:06 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.server;
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.jar.JarFile;
import java.util.jar.JarEntry;
import java.net.URL;
import java.net.MalformedURLException;
import anvil.codec.School;
/**
* class ZoneClassLoader
*
* @author: Jani Lehtim�ki
*/
public class ZoneClassLoader extends ClassLoader
{
protected Zone _zone;
protected ZoneClassLoader _parent = null;
protected HashMap _scripts = new HashMap();
protected Loader _loaders[] = null;
protected ThreadLocal _memoryloader = new ThreadLocal();
public ZoneClassLoader(Zone zone, CompilerPreferences prefs)
{
super();
initialize(zone, prefs);
}
public String toString()
{
return "ZoneClassLoader("+_zone.getPathinfo()+")";
}
public boolean onSameDomain(Domain domain)
{
return _zone.getDomain().equals(domain);
}
public void stop()
{
_parent = null;
_loaders = null;
_scripts.clear();
_zone.log().info(this + " stopped");
_zone = null;
}
public void initialize(Zone zone, CompilerPreferences prefs)
{
_zone = zone;
_parent = zone.getClassLoader();
Loader baseloader = null;
if (prefs != null) {
String classpath = prefs.getClassPath();
if (classpath != null && classpath.length()>0) {
baseloader = createLoader(classpath);
}
}
String repositories = zone.getRepositories();
if (repositories != null) {
StringTokenizer tokenizer = new StringTokenizer(repositories, " \n");
int tokens = tokenizer.countTokens();
int i = (baseloader != null) ? 1 : 0;
_loaders = new Loader[tokens + i];
while(tokenizer.hasMoreTokens()) {
Loader loader = createLoader(tokenizer.nextToken());
if (loader != null) {
_loaders[i++] = loader;
}
}
if (i<_loaders.length) {
Loader[] newloaders = new Loader[i];
System.arraycopy(_loaders, 0, newloaders, 0, i);
_loaders = newloaders;
}
} else {
_loaders = new Loader[(baseloader != null) ? 1 : 0];
}
if (baseloader != null) {
_loaders[0] = baseloader;
}
zone.log().info(this + " started");
}
protected Loader createLoader(String source)
{
try {
URL url = new URL(source);
return new URLLoader(url);
} catch (MalformedURLException muex) {
File file = new File(source);
try {
if (file.exists()) {
if (file.isDirectory()) {
return new PathLoader(file);
} else {
return new JarLoader(file);
}
}
} catch (IOException ioex) {
}
}
return null;
}
public Class loadClass(String name) throws ClassNotFoundException
{
if (name.startsWith(anvil.Version.getBuild())) {
synchronized(this) {
Class cls = (Class)_scripts.get(name);
if (cls != null) {
return cls;
}
cls = findScriptClass(name);
if (cls != null) {
return cls;
}
}
}
if (_parent != null) {
return _parent.loadClass(name);
} else {
return getClass().getClassLoader().loadClass(name);
}
}
public Class define(String name, byte[] bytes)
{
return defineClass(name, bytes, 0, bytes.length);
}
protected Class findScriptClass(String name) throws ClassNotFoundException
{
ClassData data = loadScriptClassData(name);
if (data != null) {
String name2 = data.getName();
byte[] bytes = data.getBytes();
Class cls = defineClass(name2, bytes, 0, bytes.length);
/* /.+[.]v_[^$]+^/ */
int i = name2.lastIndexOf(".v_");
if (i>0 && name2.indexOf('$', i)==-1) {
String sname = name2.substring(0, i);
_scripts.put(sname, cls);
}
_scripts.put(name2, cls);
return cls;
} else {
return null;
}
}
protected ClassData loadScriptClassData(String name)
{
String mangled = name.replace('.', '/');
ClassData data;
MemoryLoader loader = getMemoryLoader();
if (loader != null) {
data = loader.load(mangled);
if (data != null) {
return data;
}
}
Loader[] loaders = _loaders;
int n = loaders.length;
for(int i=0; i<n; i++) {
data = loaders[i].load(mangled);
if (data != null) {
return data;
}
}
return null;
}
public void setMemoryLoader(Loader loader)
{
_memoryloader.set(loader);
}
public MemoryLoader getMemoryLoader()
{
return (MemoryLoader)_memoryloader.get();
}
}