AbstractClassLoader.java revision 674060f01e9090cd21b3c5656cc3204912ad17a6
1/*
2 * Copyright 2003,2004 The Apache Software Foundation
3 *
4 *  Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 *  Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.mockito.cglib.transform;
17
18import org.mockito.asm.Attribute;
19import org.mockito.asm.ClassReader;
20import org.mockito.asm.ClassWriter;
21import org.mockito.asm.util.*;
22import org.mockito.cglib.core.ClassGenerator;
23import org.mockito.cglib.core.CodeGenerationException;
24import org.mockito.cglib.core.DebuggingClassWriter;
25
26import java.io.IOException;
27
28abstract public class AbstractClassLoader extends ClassLoader {
29    private ClassFilter filter;
30    private ClassLoader classPath;
31    private static java.security.ProtectionDomain DOMAIN ;
32
33    static{
34
35        DOMAIN = (java.security.ProtectionDomain)
36        java.security.AccessController.doPrivileged(
37          new java.security.PrivilegedAction() {
38            public Object run() {
39               return AbstractClassLoader.class.getProtectionDomain();
40            }
41        });
42     }
43
44    protected AbstractClassLoader(ClassLoader parent, ClassLoader classPath, ClassFilter filter) {
45        super(parent);
46        this.filter = filter;
47        this.classPath = classPath;
48    }
49
50    public Class loadClass(String name) throws ClassNotFoundException {
51
52        Class loaded = findLoadedClass(name);
53
54        if( loaded != null ){
55            if( loaded.getClassLoader() == this ){
56               return loaded;
57            }//else reload with this class loader
58        }
59
60        if (!filter.accept(name)) {
61            return super.loadClass(name);
62        }
63        ClassReader r;
64        try {
65
66           java.io.InputStream is = classPath.getResourceAsStream(
67                       name.replace('.','/') + ".class"
68                  );
69
70           if (is == null) {
71
72              throw new ClassNotFoundException(name);
73
74           }
75           try {
76
77              r = new ClassReader(is);
78
79           } finally {
80
81              is.close();
82
83           }
84        } catch (IOException e) {
85            throw new ClassNotFoundException(name + ":" + e.getMessage());
86        }
87
88        try {
89            ClassWriter w =  new DebuggingClassWriter(ClassWriter.COMPUTE_MAXS);
90            getGenerator(r).generateClass(w);
91            byte[] b = w.toByteArray();
92            Class c = super.defineClass(name, b, 0, b.length, DOMAIN);
93            postProcess(c);
94            return c;
95        } catch (RuntimeException e) {
96            throw e;
97        } catch (Error e) {
98            throw e;
99        } catch (Exception e) {
100            throw new CodeGenerationException(e);
101        }
102    }
103
104    protected ClassGenerator getGenerator(ClassReader r) {
105        return new ClassReaderGenerator(r, attributes(), getFlags());
106    }
107
108    protected int getFlags() {
109        return 0;
110    }
111
112    protected Attribute[] attributes() {
113        return null;
114    }
115
116    protected void postProcess(Class c) {
117    }
118}
119