001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.proxy.compiler;
023:
024: import java.lang.reflect.Method;
025: import java.lang.reflect.Field;
026:
027: import java.io.InputStream;
028:
029: import java.net.URL;
030: import java.security.PrivilegedAction;
031: import java.security.AccessController;
032:
033: /**
034: * Manages bytecode assembly for dynamic proxy generation.
035: * <p/>
036: * <p>This is the only data needed at runtime.
037: *
038: * @author Unknown
039: * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
040: * @version <tt>$Revision: 57209 $</tt>
041: */
042: public class Runtime extends ClassLoader {
043: /**
044: * The field name of the runtime target proxies Runtime object.
045: */
046: public final static String RUNTIME_FN = "runtime";
047:
048: /**
049: * Construct a new <tt>Runtime</tt>
050: *
051: * @param parent The parent classloader to delegate to.
052: */
053: public Runtime(ClassLoader parent) {
054: super (parent);
055: }
056:
057: // These members are common utilities used by ProxyTarget classes.
058: // They are all public so they can be linked to from generated code.
059: // I.e., they are the runtime support for the code compiled below.
060:
061: Class targetTypes[];
062: Method methods[];
063: ProxyCompiler compiler;// temporary!
064:
065: public Class[] copyTargetTypes() {
066: return (Class[]) targetTypes.clone();
067: }
068:
069: public Object invoke(InvocationHandler invocationHandler,
070: int methodNum, Object values[]) throws Throwable {
071: return invocationHandler.invoke(null, methods[methodNum],
072: values);
073: }
074:
075: void makeProxyType(ProxyCompiler compiler) throws Exception {
076: this .compiler = compiler; // temporary, for use during loading
077: byte code[] = compiler.getCode();
078:
079: compiler.proxyType = super .defineClass(compiler
080: .getProxyClassName(), code, 0, code.length);
081: super .resolveClass(compiler.proxyType);
082:
083: // set the Foo$Impl.info pointer to myself
084: Field field = compiler.proxyType.getField(RUNTIME_FN);
085: field.set(null, this );
086:
087: compiler = null;
088: }
089:
090: ClassLoader getTargetClassLoader() {
091: PrivilegedAction action = new PrivilegedAction() {
092: public Object run() {
093: return getParent();
094: }
095: };
096: return (ClassLoader) AccessController.doPrivileged(action);
097: }
098:
099: public synchronized Class loadClass(String name, boolean resolve)
100: throws ClassNotFoundException {
101: // isn't this redundant?
102: if (name.endsWith("$Proxy")
103: && name.equals(compiler.getProxyClassName())) {
104: return compiler.proxyType;
105: }
106:
107: // delegate to the original class loader
108: ClassLoader cl = getTargetClassLoader();
109: if (cl == null) {
110: return super .findSystemClass(name);
111: }
112:
113: return cl.loadClass(name);
114: }
115:
116: /**
117: * Delegate to the original class loader.
118: */
119: public InputStream getResourceAsStream(String name) {
120: ClassLoader cl = getTargetClassLoader();
121:
122: if (cl == null) {
123: return super .getSystemResourceAsStream(name);
124: }
125:
126: return cl.getResourceAsStream(name);
127: }
128:
129: /**
130: * Delegate to the original class loader.
131: */
132: public URL getResource(String name) {
133: ClassLoader cl = getTargetClassLoader();
134:
135: if (cl == null) {
136: return super.getSystemResource(name);
137: }
138:
139: return cl.getResource(name);
140: }
141: }
|