1
/*
2
 * $Id$
3
 *
4
 * Copyright (C) 2003-2009 JNode.org
5
 *
6
 * This library is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU Lesser General Public License as published
8
 * by the Free Software Foundation; either version 2.1 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful, but 
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
14
 * License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with this library; If not, write to the Free Software Foundation, Inc., 
18
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
 */
20
 
21
package org.jnode.vm;
22
23
import java.nio.ByteBuffer;
24
import java.security.ProtectionDomain;
25
26
import org.jnode.vm.classmgr.SelectorMap;
27
import org.jnode.vm.classmgr.VmClassLoader;
28
import org.jnode.vm.classmgr.VmType;
29
30
/**
31
 * @author Ewout Prangsma (epr@users.sourceforge.net)
32
 */
33
abstract class VmAbstractClassLoader extends VmClassLoader {
34
35
    /**
36
     * @see org.jnode.vm.classmgr.VmClassLoader#defineClass(java.lang.String, byte[], int, int,
37
     * java.security.ProtectionDomain)
38
     */
39
    public final VmType<?> defineClass(String name, byte[] data, int offset, int length, ProtectionDomain protDomain) {
40
        ByteBuffer buf = ByteBuffer.wrap(data, offset, length);
41
        return defineClass(name, buf, protDomain);
42
    }
43
44
    /**
45
     * @see org.jnode.vm.classmgr.VmClassLoader#defineClass(java.lang.String, ByteBuffer,
46
     * java.security.ProtectionDomain)
47
     */
48
    public final VmType<?> defineClass(String name, ByteBuffer data, ProtectionDomain protDomain) {
49
        VmType<?> vmClass;
50
        synchronized (this) {
51
            vmClass = findLoadedClass(name);
52
            if (vmClass != null) {
53
                return vmClass;
54
            }
55
        }
56
        //vmClass = ClassDecoder.defineClass(name, data, true, this, protDomain);
57
        vmClass = LoadCompileService.defineClass(name, data, protDomain, this);
58
        name = vmClass.getName();
59
        if (!isSystemClassLoader()) {
60
            if (name.startsWith("org.jnode.vm") || name.startsWith("java.lang")) {
61
                throw new SecurityException("Only the system classloader can load this class");
62
            }
63
        }
64
        synchronized (this) {
65
            VmType<?> foundClass = findLoadedClass(name);
66
            if (foundClass != null) {
67
                return foundClass;
68
            } else {
69
                addLoadedClass(name, vmClass);
70
            }
71
        }
72
        return vmClass;
73
    }
74
75
    /**
76
     * Define a class that is created in memory.
77
     *
78
     * @param createdType
79
     * @return VmClass
80
     */
81
    public final synchronized VmType<?> defineClass(VmType<?> createdType) {
82
        if (createdType.getLoader() != this) {
83
            throw new SecurityException("Created type not for this loader");
84
        }
85
        final String name = createdType.getName();
86
        final VmType<?> vmClass = findLoadedClass(name);
87
        if (vmClass != null) {
88
            return vmClass;
89
        }
90
        addLoadedClass(name, createdType);
91
        return createdType;
92
    }
93
94
    /**
95
     * Load an array class with a given name
96
     *
97
     * @param name
98
     * @param resolve
99
     * @return VmClass
100
     * @throws ClassNotFoundException
101
     */
102
    protected final VmType loadArrayClass(String name, boolean resolve) throws ClassNotFoundException {
103
        VmType<?> compType;
104
        String compName = name.substring(1);
105
        if ((compName.charAt(0) == 'L') && (compName.charAt(compName.length() - 1) == ';')) {
106
            compName = compName.substring(1, compName.length() - 1);
107
            compType = loadClass(compName, resolve);
108
            return compType.getArrayClass();
109
        } else if (compName.charAt(0) == '[') {
110
            compType = loadClass(compName, resolve);
111
            return compType.getArrayClass();
112
        } else {
113
            return VmType.getPrimitiveArrayClass(compName.charAt(0));
114
        }
115
    }
116
117
    protected abstract SelectorMap getSelectorMap();
118
119
    /**
120
     * Add a class that has been loaded.
121
     *
122
     * @param name
123
     * @param cls
124
     */
125
    protected abstract void addLoadedClass(String name, VmType cls);
126
}