Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » tuple » component » [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.tuple.component;
   26   
   27   import java.io.Serializable;
   28   import java.lang.reflect.Method;
   29   
   30   import org.hibernate.AssertionFailure;
   31   import org.hibernate.HibernateException;
   32   import org.hibernate.bytecode.BasicProxyFactory;
   33   import org.hibernate.bytecode.ReflectionOptimizer;
   34   import org.hibernate.cfg.Environment;
   35   import org.hibernate.engine.SessionFactoryImplementor;
   36   import org.hibernate.mapping.Component;
   37   import org.hibernate.mapping.Property;
   38   import org.hibernate.property.BackrefPropertyAccessor;
   39   import org.hibernate.property.Getter;
   40   import org.hibernate.property.PropertyAccessor;
   41   import org.hibernate.property.PropertyAccessorFactory;
   42   import org.hibernate.property.Setter;
   43   import org.hibernate.tuple.Instantiator;
   44   import org.hibernate.tuple.PojoInstantiator;
   45   import org.hibernate.util.ReflectHelper;
   46   
   47   /**
   48    * A {@link ComponentTuplizer} specific to the pojo entity mode.
   49    *
   50    * @author Gavin King
   51    * @author Steve Ebersole
   52    */
   53   public class PojoComponentTuplizer extends AbstractComponentTuplizer {
   54   
   55   	private final Class componentClass;
   56   	private ReflectionOptimizer optimizer;
   57   	private final Getter parentGetter;
   58   	private final Setter parentSetter;
   59   
   60   	public PojoComponentTuplizer(Component component) {
   61   		super( component );
   62   
   63   		this.componentClass = component.getComponentClass();
   64   
   65   		String[] getterNames = new String[propertySpan];
   66   		String[] setterNames = new String[propertySpan];
   67   		Class[] propTypes = new Class[propertySpan];
   68   		for ( int i = 0; i < propertySpan; i++ ) {
   69   			getterNames[i] = getters[i].getMethodName();
   70   			setterNames[i] = setters[i].getMethodName();
   71   			propTypes[i] = getters[i].getReturnType();
   72   		}
   73   
   74   		final String parentPropertyName = component.getParentProperty();
   75   		if ( parentPropertyName == null ) {
   76   			parentSetter = null;
   77   			parentGetter = null;
   78   		}
   79   		else {
   80   			PropertyAccessor pa = PropertyAccessorFactory.getPropertyAccessor( null );
   81   			parentSetter = pa.getSetter( componentClass, parentPropertyName );
   82   			parentGetter = pa.getGetter( componentClass, parentPropertyName );
   83   		}
   84   
   85   		if ( hasCustomAccessors || !Environment.useReflectionOptimizer() ) {
   86   			optimizer = null;
   87   		}
   88   		else {
   89   			// TODO: here is why we need to make bytecode provider global :(
   90   			// TODO : again, fix this after HHH-1907 is complete
   91   			optimizer = Environment.getBytecodeProvider().getReflectionOptimizer(
   92   					componentClass, getterNames, setterNames, propTypes
   93   			);
   94   		}
   95   	}
   96   
   97   	public Class getMappedClass() {
   98   		return componentClass;
   99   	}
  100   
  101   	public Object[] getPropertyValues(Object component) throws HibernateException {
  102   		if ( component == BackrefPropertyAccessor.UNKNOWN ) {
  103   			return new Object[ propertySpan ];
  104   		}
  105   		if ( optimizer != null && optimizer.getAccessOptimizer() != null ) {
  106   			return optimizer.getAccessOptimizer().getPropertyValues( component );
  107   		}
  108   		else {
  109   			return super.getPropertyValues(component);
  110   		}
  111   	}
  112   
  113   	public void setPropertyValues(Object component, Object[] values) throws HibernateException {
  114   		if ( optimizer != null && optimizer.getAccessOptimizer() != null ) {
  115   				optimizer.getAccessOptimizer().setPropertyValues( component, values );
  116   		}
  117   		else {
  118   			super.setPropertyValues(component, values);
  119   		}
  120   
  121   	}
  122   
  123   	public Object getParent(Object component) {
  124   		return parentGetter.get( component );
  125   	}
  126   
  127   	public boolean hasParentProperty() {
  128   		return parentGetter!=null;
  129   	}
  130   
  131   	public boolean isMethodOf(Method method) {
  132   		for ( int i=0; i<propertySpan; i++ ) {
  133   			final Method getterMethod = getters[i].getMethod();
  134   			if ( getterMethod!=null && getterMethod.equals(method) ) return true;
  135   		}
  136   		return false;
  137   	}
  138   
  139   	public void setParent(Object component, Object parent, SessionFactoryImplementor factory) {
  140   		parentSetter.set(component, parent, factory);
  141   	}
  142   
  143   	protected Instantiator buildInstantiator(Component component) {
  144   		if ( component.isEmbedded() && ReflectHelper.isAbstractClass( component.getComponentClass() ) ) {
  145   			return new ProxiedInstantiator( component );
  146   		}
  147   		if ( optimizer == null ) {
  148   			return new PojoInstantiator( component, null );
  149   		}
  150   		else {
  151   			return new PojoInstantiator( component, optimizer.getInstantiationOptimizer() );
  152   		}
  153   	}
  154   
  155   	protected Getter buildGetter(Component component, Property prop) {
  156   		return prop.getGetter( component.getComponentClass() );
  157   	}
  158   
  159   	protected Setter buildSetter(Component component, Property prop) {
  160   		return prop.getSetter( component.getComponentClass() );
  161   	}
  162   
  163   	private static class ProxiedInstantiator implements Instantiator {
  164   		private final Class proxiedClass;
  165   		private final BasicProxyFactory factory;
  166   
  167   		public ProxiedInstantiator(Component component) {
  168   			proxiedClass = component.getComponentClass();
  169   			if ( proxiedClass.isInterface() ) {
  170   				factory = Environment.getBytecodeProvider()
  171   						.getProxyFactoryFactory()
  172   						.buildBasicProxyFactory( null, new Class[] { proxiedClass } );
  173   			}
  174   			else {
  175   				factory = Environment.getBytecodeProvider()
  176   						.getProxyFactoryFactory()
  177   						.buildBasicProxyFactory( proxiedClass, null );
  178   			}
  179   		}
  180   
  181   		public Object instantiate(Serializable id) {
  182   			throw new AssertionFailure( "ProxiedInstantiator can only be used to instantiate component" );
  183   		}
  184   
  185   		public Object instantiate() {
  186   			return factory.getProxy();
  187   		}
  188   
  189   		public boolean isInstance(Object object) {
  190   			return proxiedClass.isInstance( object );
  191   		}
  192   	}
  193   }

Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » tuple » component » [javadoc | source]