All Downloads are FREE. Search and download functionalities are using the official Maven repository.

bitronix.tm.resource.jdbc.BaseProxyHandlerClass Maven / Gradle / Ivy

There is a newer version: 2.1.4
Show newest version
/*
 * Bitronix Transaction Manager
 *
 * Copyright (c) 2010, Bitronix Software.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA 02110-1301 USA
 */
package bitronix.tm.resource.jdbc;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Base class for Proxy InvocationHandlers.  Maintains a method cache
 * for swift delegation to either the overridden methods (implemented
 * in a sub-class of this class) or the underlying delegate class'
 * methods.  Makes proxying an interface almost completely painless.
 * 

* * @author brettw */ public abstract class BaseProxyHandlerClass implements InvocationHandler { private static final ConcurrentMap> classMethodCache = new ConcurrentHashMap>(); private final ConcurrentMap methodCache; public BaseProxyHandlerClass() { ConcurrentMap methodCache = classMethodCache.get(this.getClass()); if (methodCache == null) { methodCache = new ConcurrentHashMap(); ConcurrentMap previous = classMethodCache.putIfAbsent(this.getClass(), methodCache); if (previous != null) methodCache = previous; } this.methodCache = methodCache; } /** * Implementation of the InvocationHandler interface. * * @see java.lang.reflect.InvocationHandler */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { // If the method is directly overridden by "this" (i.e. sub-class) // class call "this" class' Method with "this" object, otherwise // call the non-overridden Method with the proxied object Method delegatedMethod = getDelegatedMethod(method); return delegatedMethod.invoke(isOurMethod(delegatedMethod) ? this : getProxiedDelegate(), args); } catch (InvocationTargetException ite) { // the InvocationTargetException's target actually is the exception thrown by the delegate // throw this one to avoid the caller to receive proxy-related exceptions throw ite.getTargetException(); } } /** * Get the overridden Method for the super-class of this base class, if it * exists. Otherwise, the method provided is not overridden by us and should * go to the underlying proxied class. *

* This method will return the original Method that was passed in, or if * the method is overridden by us it will return the Method from "this" * class. Where "this" is actually the sub-class of this class. * * @param method the Method object to map * @return the Method object that should be invoked, either ours * (overridden) or the underlying proxied object */ private Method getDelegatedMethod(Method method) { Method delegated = methodCache.get(method); if (delegated != null) { return delegated; } try { Class[] parameterTypes = method.getParameterTypes(); delegated = this.getClass().getMethod(method.getName(), parameterTypes); } catch (Exception ex) { delegated = method; } Method previous = methodCache.putIfAbsent(method, delegated); if (previous != null) { delegated = previous; } return delegated; } /** * Check whether the specified Method is overridden by us or not. * * @param method the Method object to check * @return true if the Method is ours, false if it belongs to the proxied * Class */ private boolean isOurMethod(Method method) { return this.getClass().equals(method.getDeclaringClass()); } /** * Must be implemented by the sub-class of this class. This method * should return the "true" object to be delegated to in the case * that the method is not overridden by the sub-class. * * @return the true delegate object * @throws Exception can throw any exception if desired */ public abstract Object getProxiedDelegate() throws Exception; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy