Home » Hibernate-3.3.2.GA » org.hibernate » bytecode » javassist » [javadoc | source]

    1   /*
    2    * Hibernate, Relational Persistence for Idiomatic Java
    3    *
    4    * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
    5    * indicated by the @author tags or express copyright attribution
    6    * statements applied by the authors.  All third-party contributions are
    7    * distributed under license by Red Hat Middleware LLC.
    8    *
    9    * This copyrighted material is made available to anyone wishing to use, modify,
   10    * copy, or redistribute it subject to the terms and conditions of the GNU
   11    * Lesser General Public License, as published by the Free Software Foundation.
   12    *
   13    * This program is distributed in the hope that it will be useful,
   14    * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   15    * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
   16    * for more details.
   17    *
   18    * You should have received a copy of the GNU Lesser General Public License
   19    * along with this distribution; if not, write to:
   20    * Free Software Foundation, Inc.
   21    * 51 Franklin Street, Fifth Floor
   22    * Boston, MA  02110-1301  USA
   23    *
   24    */
   25   package org.hibernate.bytecode.javassist;
   26   
   27   import org.hibernate.bytecode.ProxyFactoryFactory;
   28   import org.hibernate.bytecode.BasicProxyFactory;
   29   import org.hibernate.proxy.ProxyFactory;
   30   import org.hibernate.proxy.pojo.javassist.JavassistProxyFactory;
   31   import org.hibernate.AssertionFailure;
   32   import org.hibernate.HibernateException;
   33   import javassist.util.proxy.MethodFilter;
   34   import javassist.util.proxy.ProxyObject;
   35   import javassist.util.proxy.MethodHandler;
   36   
   37   import java.lang.reflect.Method;
   38   import java.util.HashMap;
   39   
   40   /**
   41    * A factory for Javassist-based {@link ProxyFactory} instances.
   42    *
   43    * @author Steve Ebersole
   44    */
   45   public class ProxyFactoryFactoryImpl implements ProxyFactoryFactory {
   46   
   47   	/**
   48   	 * Builds a Javassist-based proxy factory.
   49   	 *
   50   	 * @return a new Javassist-based proxy factory.
   51   	 */
   52   	public ProxyFactory buildProxyFactory() {
   53   		return new JavassistProxyFactory();
   54   	}
   55   
   56   	public BasicProxyFactory buildBasicProxyFactory(Class superClass, Class[] interfaces) {
   57   		return new BasicProxyFactoryImpl( superClass, interfaces );
   58   	}
   59   
   60   	private static class BasicProxyFactoryImpl implements BasicProxyFactory {
   61   		private final Class proxyClass;
   62   
   63   		public BasicProxyFactoryImpl(Class superClass, Class[] interfaces) {
   64   			if ( superClass == null && ( interfaces == null || interfaces.length < 1 ) ) {
   65   				throw new AssertionFailure( "attempting to build proxy without any superclass or interfaces" );
   66   			}
   67   			javassist.util.proxy.ProxyFactory factory = new javassist.util.proxy.ProxyFactory();
   68   			factory.setFilter( FINALIZE_FILTER );
   69   			if ( superClass != null ) {
   70   				factory.setSuperclass( superClass );
   71   			}
   72   			if ( interfaces != null && interfaces.length > 0 ) {
   73   				factory.setInterfaces( interfaces );
   74   			}
   75   			proxyClass = factory.createClass();
   76   		}
   77   
   78   		public Object getProxy() {
   79   			try {
   80   				ProxyObject proxy = ( ProxyObject ) proxyClass.newInstance();
   81   				proxy.setHandler( new PassThroughHandler( proxy, proxyClass.getName() ) );
   82   				return proxy;
   83   			}
   84   			catch ( Throwable t ) {
   85   				throw new HibernateException( "Unable to instantiated proxy instance" );
   86   			}
   87   		}
   88   
   89   		public boolean isInstance(Object object) {
   90   			return proxyClass.isInstance( object );
   91   		}
   92   	}
   93   
   94   	private static final MethodFilter FINALIZE_FILTER = new MethodFilter() {
   95   		public boolean isHandled(Method m) {
   96   			// skip finalize methods
   97   			return !( m.getParameterTypes().length == 0 && m.getName().equals( "finalize" ) );
   98   		}
   99   	};
  100   
  101   	private static class PassThroughHandler implements MethodHandler {
  102   		private HashMap data = new HashMap();
  103   		private final Object proxiedObject;
  104   		private final String proxiedClassName;
  105   
  106   		public PassThroughHandler(Object proxiedObject, String proxiedClassName) {
  107   			this.proxiedObject = proxiedObject;
  108   			this.proxiedClassName = proxiedClassName;
  109   		}
  110   
  111   		public Object invoke(
  112   				Object object,
  113   		        Method method,
  114   		        Method method1,
  115   		        Object[] args) throws Exception {
  116   			String name = method.getName();
  117   			if ( "toString".equals( name ) ) {
  118   				return proxiedClassName + "@" + System.identityHashCode( object );
  119   			}
  120   			else if ( "equals".equals( name ) ) {
  121   				return proxiedObject == object ? Boolean.TRUE : Boolean.FALSE;
  122   			}
  123   			else if ( "hashCode".equals( name ) ) {
  124   				return new Integer( System.identityHashCode( object ) );
  125   			}
  126   			boolean hasGetterSignature = method.getParameterTypes().length == 0 && method.getReturnType() != null;
  127   			boolean hasSetterSignature = method.getParameterTypes().length == 1 && ( method.getReturnType() == null || method.getReturnType() == void.class );
  128   			if ( name.startsWith( "get" ) && hasGetterSignature ) {
  129   				String propName = name.substring( 3 );
  130   				return data.get( propName );
  131   			}
  132   			else if ( name.startsWith( "is" ) && hasGetterSignature ) {
  133   				String propName = name.substring( 2 );
  134   				return data.get( propName );
  135   			}
  136   			else if ( name.startsWith( "set" ) && hasSetterSignature) {
  137   				String propName = name.substring( 3 );
  138   				data.put( propName, args[0] );
  139   				return null;
  140   			}
  141   			else {
  142   				// todo : what else to do here?
  143   				return null;
  144   			}
  145   		}
  146   	}
  147   }

Home » Hibernate-3.3.2.GA » org.hibernate » bytecode » javassist » [javadoc | source]