001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.openejb.util.proxy;
017:
018: import java.lang.reflect.Constructor;
019: import java.lang.reflect.InvocationTargetException;
020: import java.lang.reflect.Proxy;
021: import java.util.Properties;
022:
023: import org.apache.openejb.OpenEJBException;
024:
025: /**
026: * @org.apache.xbean.XBean
027: */
028: public class Jdk13ProxyFactory implements ProxyFactory {
029:
030: public Jdk13ProxyFactory() {
031: }
032:
033: public void init(Properties props) throws OpenEJBException {
034: start();
035: }
036:
037: /**
038: * @org.apache.xbean.InitMethod
039: */
040: public void start() throws OpenEJBException {
041: String version = "";
042: String badVersion = "1.3.0-";
043: try {
044: version = System.getProperty("java.vm.version");
045: } catch (Exception e) {
046: }
047: if (version.indexOf(badVersion) != -1) {
048: String message = ""
049: + "INCOMPATIBLE VM: \n\n"
050: + "The Java Virtual Machine you are using contains a bug\n"
051: + "in the proxy generation logic. This bug has been \n"
052: + "documented by Sun and has been fixed in later VMs. \n"
053: + "Please download the latest 1.3 Virtual Machine. \n"
054: + "For more details see: \n"
055: + "http://developer.java.sun.com/developer/bugParade/bugs/4346224.html\n ";
056: throw new OpenEJBException(message);
057: }
058: }
059:
060: public org.apache.openejb.util.proxy.InvocationHandler getInvocationHandler(
061: Object proxy) throws IllegalArgumentException {
062: Jdk13InvocationHandler handler = (Jdk13InvocationHandler) Proxy
063: .getInvocationHandler(proxy);
064: if (handler == null)
065: return null;
066: return handler.getInvocationHandler();
067: }
068:
069: public Object setInvocationHandler(Object proxy,
070: org.apache.openejb.util.proxy.InvocationHandler handler)
071: throws IllegalArgumentException {
072: Jdk13InvocationHandler jdk13 = (Jdk13InvocationHandler) Proxy
073: .getInvocationHandler(proxy);
074: if (jdk13 == null)
075: throw new IllegalArgumentException("Proxy " + proxy
076: + " unknown!");
077: return jdk13.setInvocationHandler(handler);
078: }
079:
080: public Class getProxyClass(Class interfce)
081: throws IllegalArgumentException {
082: return Proxy.getProxyClass(interfce.getClassLoader(),
083: new Class[] { interfce });
084: }
085:
086: public Class getProxyClass(Class[] interfaces)
087: throws IllegalArgumentException {
088: if (interfaces.length < 1) {
089: throw new IllegalArgumentException(
090: "It's boring to implement 0 interfaces!");
091: }
092: return Proxy.getProxyClass(interfaces[0].getClassLoader(),
093: interfaces);
094: }
095:
096: /*
097: * Returns true if and only if the specified class was dynamically generated to be a proxy class using the getProxyClass method or the newProxyInstance method.
098: */
099: public boolean isProxyClass(Class cl) {
100: return Proxy.isProxyClass(cl);
101: }
102:
103: private final static Class[] constructorParams = { java.lang.reflect.InvocationHandler.class };
104:
105: public Object newProxyInstance(Class proxyClass)
106: throws IllegalArgumentException {
107: if (!Proxy.isProxyClass(proxyClass))
108: throw new IllegalArgumentException();
109: try {
110: Constructor cons = proxyClass
111: .getConstructor(constructorParams);
112: return (Object) cons
113: .newInstance(new Object[] { new Jdk13InvocationHandler() });
114: } catch (NoSuchMethodException e) {
115: throw (InternalError) new InternalError(e.toString())
116: .initCause(e);
117: } catch (IllegalAccessException e) {
118: throw (InternalError) new InternalError(e.toString())
119: .initCause(e);
120: } catch (InstantiationException e) {
121: throw (InternalError) new InternalError(e.toString())
122: .initCause(e);
123: } catch (InvocationTargetException e) {
124: throw (InternalError) new InternalError(e.toString())
125: .initCause(e);
126: }
127: }
128:
129: /*
130: * Returns an instance of a proxy class for the specified interface that dispatches method invocations to
131: * the specified invocation handler.
132: */
133: public Object newProxyInstance(Class interfce,
134: org.apache.openejb.util.proxy.InvocationHandler h)
135: throws IllegalArgumentException {
136: Jdk13InvocationHandler handler = new Jdk13InvocationHandler(h);
137: return Proxy.newProxyInstance(interfce.getClassLoader(),
138: new Class[] { interfce }, handler);
139: }
140:
141: /*
142: * Returns an instance of a proxy class for the specified interface that dispatches method invocations to
143: * the specified invocation handler.
144: */
145: public Object newProxyInstance(Class[] interfaces,
146: org.apache.openejb.util.proxy.InvocationHandler h)
147: throws IllegalArgumentException {
148: if (interfaces.length < 1) {
149: throw new IllegalArgumentException(
150: "It's boring to implement 0 interfaces!");
151: }
152: Jdk13InvocationHandler handler = new Jdk13InvocationHandler(h);
153: try {
154: return Proxy.newProxyInstance(interfaces[0]
155: .getClassLoader(), interfaces, handler);
156: } catch (IllegalArgumentException e) {
157: ClassLoader tccl = Thread.currentThread()
158: .getContextClassLoader();
159: try {
160: Class tcclHomeClass = tccl.loadClass(interfaces[0]
161: .getName());
162: if (tcclHomeClass == interfaces[0]) {
163: return Proxy.newProxyInstance(tccl, interfaces,
164: handler);
165: }
166: } catch (ClassNotFoundException e1) {
167: throw e;
168: }
169: throw e;
170: }
171: }
172: }
|