Open Source Repository

Home /hibernate/hibernate-3.2.7.ga | Repository Home



org/hibernate/tuple/entity/EntityTuplizerFactory.java
/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
 * indicated by the @author tags or express copyright attribution
 * statements applied by the authors.  All third-party contributions are
 * distributed under license by Red Hat Middleware LLC.
 *
 * 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 org.hibernate.tuple.entity;

import java.util.Map;
import java.lang.reflect.Constructor;
import java.io.Serializable;


import org.hibernate.util.FastHashMap;
import org.hibernate.util.ReflectHelper;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.mapping.PersistentClass;

/**
 * A registry allowing users to define the default {@link EntityTuplizer} class to use per {@link EntityMode}.
 *
 @author Steve Ebersole
 */
public class EntityTuplizerFactory implements Serializable {

  public static final Class[] ENTITY_TUP_CTOR_SIG = new Class[] { EntityMetamodel.class, PersistentClass.class };

  private Map defaultImplClassByMode = buildBaseMapping();

  /**
   * Method allowing registration of the tuplizer class to use as default for a particular entity-mode.
   *
   @param entityMode The entity-mode for which to register the tuplizer class
   @param tuplizerClass The class to use as the default tuplizer for the given entity-mode.
   */
  public void registerDefaultTuplizerClass(EntityMode entityMode, Class tuplizerClass) {
    assert isEntityTuplizerImplementortuplizerClass )
        "Specified tuplizer class [" + tuplizerClass.getName() "] does not implement " + EntityTuplizer.class.getName();
    assert hasProperConstructortuplizerClass )
        "Specified tuplizer class [" + tuplizerClass.getName() "] is not properly instantiatable";

    defaultImplClassByMode.putentityMode, tuplizerClass );
  }

  /**
   * Construct an instance of the given tuplizer class.
   *
   @param tuplizerClassName The name of the tuplizer class to instantiate
   @param metamodel The metadata for the entity.
   @param persistentClass The mapping info for the entity.
   *
   @return The instantiated tuplizer
   *
   @throws HibernateException If class name cannot be resolved to a class reference, or if the
   {@link Constructor#newInstance} call fails.
   */
  public EntityTuplizer constructTuplizer(
      String tuplizerClassName,
      EntityMetamodel metamodel,
      PersistentClass persistentClass) {
    try {
      Class tuplizerClass = ReflectHelper.classForNametuplizerClassName );
      return constructTuplizertuplizerClass, metamodel, persistentClass );
    }
    catch ClassNotFoundException e ) {
      throw new HibernateException"Could not locate specified tuplizer class [" + tuplizerClassName + "]" );
    }
  }

  /**
   * Construct an instance of the given tuplizer class.
   *
   @param tuplizerClass The tuplizer class to instantiate
   @param metamodel The metadata for the entity.
   @param persistentClass The mapping info for the entity.
   *
   @return The instantiated tuplizer
   *
   @throws HibernateException if the {@link Constructor#newInstance} call fails.
   */
  public EntityTuplizer constructTuplizer(
      Class tuplizerClass,
      EntityMetamodel metamodel,
      PersistentClass persistentClass) {
    Constructor ctor = getProperConstructortuplizerClass );
    assert ctor != null "Unable to locate proper constructor for tuplizer [" + tuplizerClass.getName() "]";
    try {
      return EntityTuplizer ctor.newInstancenew Object[] { metamodel, persistentClass } );
    }
    catch Throwable t ) {
      throw new HibernateException"Unable to instantiate default tuplizer [" + tuplizerClass.getName() "]", t );
    }
  }

  /**
   * Construct am instance of the default tuplizer for the given entity-mode.
   *
   @param entityMode The entity mode for which to build a default tuplizer.
   @param metamodel The entity metadata.
   @param persistentClass The entity mapping info.
   *
   @return The instantiated tuplizer
   *
   @throws HibernateException If no default tuplizer found for that entity-mode; may be re-thrown from
   {@link #constructTuplizer} too.
   */
  public EntityTuplizer constructDefaultTuplizer(
      EntityMode entityMode,
      EntityMetamodel metamodel,
      PersistentClass persistentClass) {
    Class tuplizerClass = Class defaultImplClassByMode.getentityMode );
    if tuplizerClass == null ) {
      throw new HibernateException"could not determine default tuplizer class to use [" + entityMode + "]" );
    }

    return constructTuplizertuplizerClass, metamodel, persistentClass );
  }

  private boolean isEntityTuplizerImplementor(Class tuplizerClass) {
    return ReflectHelper.implementsInterfacetuplizerClass, EntityTuplizer.class );
  }

  private boolean hasProperConstructor(Class tuplizerClass) {
    return getProperConstructortuplizerClass != null
        && ! ReflectHelper.isAbstractClasstuplizerClass );
  }

  private Constructor getProperConstructor(Class clazz) {
    Constructor ctor = null;
    try {
      ctor = clazz.getDeclaredConstructorENTITY_TUP_CTOR_SIG );
      if ! ReflectHelper.isPublicctor ) ) {
        try {
          // found a ctor, but it was not publicly accessible so try to request accessibility
          ctor.setAccessibletrue );
        }
        catch SecurityException e ) {
          ctor = null;
        }
      }
    }
    catch NoSuchMethodException ignore ) {
    }

    return ctor;
  }

  private static Map buildBaseMapping() {
    Map map = new FastHashMap();
    map.putEntityMode.POJO, PojoEntityTuplizer.class );
    map.putEntityMode.DOM4J, Dom4jEntityTuplizer.class );
    map.putEntityMode.MAP, DynamicMapEntityTuplizer.class );
    return map;
  }
}