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; //#else
021: /*
022: import net.sf.cglib.proxy.Proxy;
023: import net.sf.cglib.proxy.InvocationHandler;
024: */
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.10.2.3 2005/12/21 22:28:16 tomdz Exp $
040: */
041: public class InterceptorFactory implements Configurable {
042:
043: private static InterceptorFactory instance = null;
044:
045: private Class interceptorClassToBeUsed = null;
046:
047: /**
048: * Returns the instance.
049: * @return InterceptorFactory
050: */
051: public static InterceptorFactory getInstance() {
052: if (instance == null) {
053: instance = new InterceptorFactory();
054: OjbConfigurator.getInstance().configure(instance);
055: }
056: return instance;
057: }
058:
059: /**
060: * @see org.apache.ojb.broker.util.configuration.Configurable#configure(Configuration)
061: */
062: public void configure(Configuration pConfig)
063: throws ConfigurationException {
064: Class clazz = pConfig
065: .getClass("InterceptorClass", Object.class);
066: if (!clazz.equals(Object.class))
067: setInterceptorClassToBeUsed(clazz);
068: }
069:
070: public Object createInterceptorFor(Object instanceToIntercept) {
071: if (getInterceptorClassToBeUsed() != null) {
072: try {
073:
074: // Class[] parameterTypes = {Object.class};
075: // Object[] parameters = {instanceToIntercept};
076: // Constructor constructor = getInterceptorClassToBeUsed().getConstructor(parameterTypes);
077: // InvocationHandler handler = (InvocationHandler) constructor.newInstance(parameters);
078: // use helper class to instantiate
079: InvocationHandler handler = (InvocationHandler) ClassHelper
080: .newInstance(getInterceptorClassToBeUsed(),
081: Object.class, instanceToIntercept);
082: Class[] interfaces = computeInterfaceArrayFor(instanceToIntercept
083: .getClass());
084: Object result = Proxy.newProxyInstance(ClassHelper
085: .getClassLoader(), interfaces, handler);
086: return result;
087: } catch (Throwable t) {
088: LoggerFactory.getDefaultLogger().error(
089: "can't use Interceptor "
090: + getInterceptorClassToBeUsed()
091: .getName()
092: + "for "
093: + instanceToIntercept.getClass()
094: .getName(), t);
095: return instanceToIntercept;
096: }
097: } else {
098: return instanceToIntercept;
099: }
100: }
101:
102: public Class[] computeInterfaceArrayFor(Class clazz) {
103: Class super Class = clazz;
104: Class[] interfaces = clazz.getInterfaces();
105:
106: // clazz can be an interface itself and when getInterfaces()
107: // is called on an interface it returns only the extending
108: // interfaces, not the interface itself.
109: if (clazz.isInterface()) {
110: Class[] tempInterfaces = new Class[interfaces.length + 1];
111: tempInterfaces[0] = clazz;
112:
113: System.arraycopy(interfaces, 0, tempInterfaces, 1,
114: interfaces.length);
115: interfaces = tempInterfaces;
116: }
117:
118: // add all interfaces implemented by superclasses to the interfaces array
119: while ((super Class = super Class.getSuperclass()) != null) {
120: Class[] super Interfaces = super Class.getInterfaces();
121: Class[] combInterfaces = new Class[interfaces.length
122: + super Interfaces.length];
123: System.arraycopy(interfaces, 0, combInterfaces, 0,
124: interfaces.length);
125: System.arraycopy(super Interfaces, 0, combInterfaces,
126: interfaces.length, super Interfaces.length);
127: interfaces = combInterfaces;
128: }
129:
130: /**
131: * Must remove duplicate interfaces before calling Proxy.getProxyClass().
132: * Duplicates can occur if a subclass re-declares that it implements
133: * the same interface as one of its ancestor classes.
134: **/
135: HashMap unique = new HashMap();
136: for (int i = 0; i < interfaces.length; i++) {
137: unique.put(interfaces[i].getName(), interfaces[i]);
138: }
139: interfaces = (Class[]) unique.values().toArray(
140: new Class[unique.size()]);
141:
142: return interfaces;
143: }
144:
145: /**
146: * Returns the interceptorClassToBeUsed.
147: * @return Class
148: */
149: public Class getInterceptorClassToBeUsed() {
150: return interceptorClassToBeUsed;
151: }
152:
153: /**
154: * Sets the interceptorClassToBeUsed.
155: * @param interceptorClassToBeUsed The interceptorClassToBeUsed to set
156: */
157: public void setInterceptorClassToBeUsed(
158: Class interceptorClassToBeUsed) {
159: this.interceptorClassToBeUsed = interceptorClassToBeUsed;
160: }
161:
162: }
|