/*
* $Id$
*
* Copyright (C) 2003-2015 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.vm;
import java.nio.ByteBuffer;
import java.security.ProtectionDomain;
import org.jnode.vm.classmgr.SelectorMap;
import org.jnode.vm.classmgr.VmClassLoader;
import org.jnode.vm.classmgr.VmType;
/**
* @author Ewout Prangsma (epr@users.sourceforge.net)
*/
abstract class VmAbstractClassLoader extends VmClassLoader {
/**
* @see org.jnode.vm.classmgr.VmClassLoader#defineClass(java.lang.String, byte[], int, int,
* java.security.ProtectionDomain)
*/
public final VmType<?> defineClass(String name, byte[] data, int offset, int length, ProtectionDomain protDomain) {
ByteBuffer buf = ByteBuffer.wrap(data, offset, length);
return defineClass(name, buf, protDomain);
}
/**
* @see org.jnode.vm.classmgr.VmClassLoader#defineClass(java.lang.String, ByteBuffer,
* java.security.ProtectionDomain)
*/
public final VmType<?> defineClass(String name, ByteBuffer data, ProtectionDomain protDomain) {
VmType<?> vmClass;
synchronized (this) {
vmClass = findLoadedClass(name);
if (vmClass != null) {
return vmClass;
}
}
//vmClass = ClassDecoder.defineClass(name, data, true, this, protDomain);
vmClass = LoadCompileService.defineClass(name, data, protDomain, this);
name = vmClass.getName();
if (!isSystemClassLoader()) {
if (name.startsWith("org.jnode.vm") || name.startsWith("java.lang")) {
throw new SecurityException("Only the system classloader can load this class");
}
}
synchronized (this) {
VmType<?> foundClass = findLoadedClass(name);
if (foundClass != null) {
return foundClass;
} else {
addLoadedClass(name, vmClass);
}
}
return vmClass;
}
/**
* Define a class that is created in memory.
*
* @param createdType
* @return VmClass
*/
public final synchronized VmType<?> defineClass(VmType<?> createdType) {
if (createdType.getLoader() != this) {
throw new SecurityException("Created type not for this loader");
}
final String name = createdType.getName();
final VmType<?> vmClass = findLoadedClass(name);
if (vmClass != null) {
return vmClass;
}
addLoadedClass(name, createdType);
return createdType;
}
/**
* Load an array class with a given name
*
* @param name
* @param resolve
* @return VmClass
* @throws ClassNotFoundException
*/
protected final VmType loadArrayClass(String name, boolean resolve) throws ClassNotFoundException {
VmType<?> compType;
String compName = name.substring(1);
if ((compName.charAt(0) == 'L') && (compName.charAt(compName.length() - 1) == ';')) {
compName = compName.substring(1, compName.length() - 1);
compType = loadClass(compName, resolve);
return compType.getArrayClass();
} else if (compName.charAt(0) == '[') {
compType = loadClass(compName, resolve);
return compType.getArrayClass();
} else {
return VmType.getPrimitiveArrayClass(compName.charAt(0));
}
}
protected abstract SelectorMap getSelectorMap();
/**
* Add a class that has been loaded.
*
* @param name
* @param cls
*/
protected abstract void addLoadedClass(String name, VmType cls);
}