org.hibernate.tuple.entity.EntityTuplizerFactory.java Source code

Java tutorial

Introduction

Here is the source code for org.hibernate.tuple.entity.EntityTuplizerFactory.java

Source

/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
package org.hibernate.tuple.entity;

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

import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.internal.util.ReflectHelper;
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<EntityMode, Class<? extends EntityTuplizer>> 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<? extends EntityTuplizer> tuplizerClass) {
        assert isEntityTuplizerImplementor(tuplizerClass) : "Specified tuplizer class [" + tuplizerClass.getName()
                + "] does not implement " + EntityTuplizer.class.getName();
        // TODO: for now we need constructors for both PersistentClass and EntityBinding
        assert hasProperConstructor(tuplizerClass, ENTITY_TUP_CTOR_SIG) : "Specified tuplizer class ["
                + tuplizerClass.getName() + "] is not properly instantiatable";
        defaultImplClassByMode.put(entityMode, 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.
     */
    @SuppressWarnings({ "unchecked" })
    public EntityTuplizer constructTuplizer(String tuplizerClassName, EntityMetamodel metamodel,
            PersistentClass persistentClass) {
        try {
            Class<? extends EntityTuplizer> tuplizerClass = ReflectHelper.classForName(tuplizerClassName);
            return constructTuplizer(tuplizerClass, 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<? extends EntityTuplizer> tuplizerClass,
            EntityMetamodel metamodel, PersistentClass persistentClass) {
        Constructor<? extends EntityTuplizer> constructor = getProperConstructor(tuplizerClass,
                ENTITY_TUP_CTOR_SIG);
        assert constructor != null : "Unable to locate proper constructor for tuplizer [" + tuplizerClass.getName()
                + "]";
        try {
            return constructor.newInstance(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<? extends EntityTuplizer> tuplizerClass = defaultImplClassByMode.get(entityMode);
        if (tuplizerClass == null) {
            throw new HibernateException("could not determine default tuplizer class to use [" + entityMode + "]");
        }

        return constructTuplizer(tuplizerClass, metamodel, persistentClass);
    }

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

    private boolean hasProperConstructor(Class<? extends EntityTuplizer> tuplizerClass, Class[] constructorArgs) {
        return getProperConstructor(tuplizerClass, constructorArgs) != null
                && !ReflectHelper.isAbstractClass(tuplizerClass);
    }

    private Constructor<? extends EntityTuplizer> getProperConstructor(Class<? extends EntityTuplizer> clazz,
            Class[] constructorArgs) {
        Constructor<? extends EntityTuplizer> constructor = null;
        try {
            constructor = clazz.getDeclaredConstructor(constructorArgs);
            try {
                ReflectHelper.ensureAccessibility(constructor);
            } catch (SecurityException e) {
                constructor = null;
            }
        } catch (NoSuchMethodException ignore) {
        }

        return constructor;
    }

    private static Map<EntityMode, Class<? extends EntityTuplizer>> buildBaseMapping() {
        Map<EntityMode, Class<? extends EntityTuplizer>> map = new ConcurrentHashMap<EntityMode, Class<? extends EntityTuplizer>>();
        map.put(EntityMode.POJO, PojoEntityTuplizer.class);
        map.put(EntityMode.MAP, DynamicMapEntityTuplizer.class);
        return map;
    }
}