001 package org.apache.ojb.broker.util.interceptor;
002
003 /* Copyright 2002-2005 The Apache Software Foundation
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * 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 */
017
018 //#ifdef JDK13
019 import java.lang.reflect.Proxy;
020 import java.lang.reflect.InvocationHandler;
021 //#else
022 /*
023 import net.sf.cglib.proxy.Proxy;
024 import net.sf.cglib.proxy.InvocationHandler;
025 */
026 //#endif
027
028 import java.util.HashMap;
029
030 import org.apache.ojb.broker.util.configuration.Configurable;
031 import org.apache.ojb.broker.util.configuration.Configuration;
032 import org.apache.ojb.broker.util.configuration.ConfigurationException;
033 import org.apache.ojb.broker.util.configuration.impl.OjbConfigurator;
034 import org.apache.ojb.broker.util.logging.LoggerFactory;
035 import org.apache.ojb.broker.util.ClassHelper;
036
037 /**
038 * @author <a href="mailto:thma@apache.org">Thomas Mahler<a>
039 * @version $Id: InterceptorFactory.java,v 1.1 2007-08-24 22:17:39 ewestfal Exp $
040 */
041 public class InterceptorFactory implements Configurable
042 {
043
044 private static InterceptorFactory instance = null;
045
046 private Class interceptorClassToBeUsed = null;
047
048 /**
049 * Returns the instance.
050 * @return InterceptorFactory
051 */
052 public static InterceptorFactory getInstance()
053 {
054 if (instance == null)
055 {
056 instance = new InterceptorFactory();
057 OjbConfigurator.getInstance().configure(instance);
058 }
059 return instance;
060 }
061
062
063 /**
064 * @see org.apache.ojb.broker.util.configuration.Configurable#configure(Configuration)
065 */
066 public void configure(Configuration pConfig) throws ConfigurationException
067 {
068 Class clazz = pConfig.getClass("InterceptorClass", Object.class);
069 if(!clazz.equals(Object.class)) setInterceptorClassToBeUsed(clazz);
070 }
071
072 public Object createInterceptorFor(Object instanceToIntercept)
073 {
074 if (getInterceptorClassToBeUsed() != null)
075 {
076 try
077 {
078
079
080 // Class[] parameterTypes = {Object.class};
081 // Object[] parameters = {instanceToIntercept};
082 // Constructor constructor = getInterceptorClassToBeUsed().getConstructor(parameterTypes);
083 // InvocationHandler handler = (InvocationHandler) constructor.newInstance(parameters);
084 // use helper class to instantiate
085 InvocationHandler handler = (InvocationHandler) ClassHelper.newInstance(
086 getInterceptorClassToBeUsed(), Object.class, instanceToIntercept);
087 Class[] interfaces = computeInterfaceArrayFor(instanceToIntercept.getClass());
088 Object result =
089 Proxy.newProxyInstance(
090 ClassHelper.getClassLoader(),
091 interfaces,
092 handler);
093 return result;
094 }
095 catch (Throwable t)
096 {
097 LoggerFactory.getDefaultLogger().error("can't use Interceptor " + getInterceptorClassToBeUsed().getName() +
098 "for " + instanceToIntercept.getClass().getName(), t);
099 return instanceToIntercept;
100 }
101 }
102 else
103 {
104 return instanceToIntercept;
105 }
106 }
107
108
109
110 public Class[] computeInterfaceArrayFor(Class clazz)
111 {
112 Class superClass = clazz;
113 Class[] interfaces = clazz.getInterfaces();
114
115 // clazz can be an interface itself and when getInterfaces()
116 // is called on an interface it returns only the extending
117 // interfaces, not the interface itself.
118 if (clazz.isInterface())
119 {
120 Class[] tempInterfaces = new Class[interfaces.length + 1];
121 tempInterfaces[0] = clazz;
122
123 System.arraycopy(interfaces, 0, tempInterfaces, 1, interfaces.length);
124 interfaces = tempInterfaces;
125 }
126
127 // add all interfaces implemented by superclasses to the interfaces array
128 while ((superClass = superClass.getSuperclass()) != null)
129 {
130 Class[] superInterfaces = superClass.getInterfaces();
131 Class[] combInterfaces = new Class[interfaces.length + superInterfaces.length];
132 System.arraycopy(interfaces, 0, combInterfaces, 0, interfaces.length);
133 System.arraycopy(
134 superInterfaces,
135 0,
136 combInterfaces,
137 interfaces.length,
138 superInterfaces.length);
139 interfaces = combInterfaces;
140 }
141
142 /**
143 * Must remove duplicate interfaces before calling Proxy.getProxyClass().
144 * Duplicates can occur if a subclass re-declares that it implements
145 * the same interface as one of its ancestor classes.
146 **/
147 HashMap unique = new HashMap();
148 for (int i = 0; i < interfaces.length; i++)
149 {
150 unique.put(interfaces[i].getName(), interfaces[i]);
151 }
152 interfaces = (Class[]) unique.values().toArray(new Class[unique.size()]);
153
154 return interfaces;
155 }
156
157
158
159 /**
160 * Returns the interceptorClassToBeUsed.
161 * @return Class
162 */
163 public Class getInterceptorClassToBeUsed()
164 {
165 return interceptorClassToBeUsed;
166 }
167
168 /**
169 * Sets the interceptorClassToBeUsed.
170 * @param interceptorClassToBeUsed The interceptorClassToBeUsed to set
171 */
172 public void setInterceptorClassToBeUsed(Class interceptorClassToBeUsed)
173 {
174 this.interceptorClassToBeUsed = interceptorClassToBeUsed;
175 }
176
177 }