Package org.beangle.model.persist.hibernate

Source Code of org.beangle.model.persist.hibernate.HibernateEntityContext

/* Copyright c 2005-2012.
* Licensed under GNU  LESSER General Public License, Version 3.
* http://www.gnu.org/licenses
*/
package org.beangle.model.persist.hibernate;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.time.StopWatch;
import org.beangle.commons.collection.CollectUtils;
import org.beangle.model.entity.Type;
import org.beangle.model.entity.context.AbstractEntityContext;
import org.beangle.model.entity.types.CollectionType;
import org.beangle.model.entity.types.ComponentType;
import org.beangle.model.entity.types.EntityType;
import org.hibernate.EntityMode;
import org.hibernate.SessionFactory;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata;
import org.hibernate.proxy.HibernateProxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HibernateEntityContext extends AbstractEntityContext {

  private final Logger logger = LoggerFactory.getLogger(HibernateEntityContext.class);

  private final Map<String, CollectionType> collectionTypes = CollectUtils.newHashMap();

  @Override
  public String getEntityName(Object target) {
    if (target instanceof HibernateProxy) {
      return ((HibernateProxy) target).getHibernateLazyInitializer().getEntityName();
    } else {
      return getEntityType(target.getClass()).getEntityName();
    }
  }

  public void initFrom(SessionFactory sessionFactory) {
    if (null != sessionFactory && entityTypes.isEmpty()) {
      StopWatch watch = new StopWatch();
      watch.start();
      Map<String, ClassMetadata> classMetadatas = sessionFactory.getAllClassMetadata();
      for (Iterator<ClassMetadata> iter = classMetadatas.values().iterator(); iter.hasNext();) {
        ClassMetadata cm = (ClassMetadata) iter.next();
        buildEntityType(sessionFactory, cm.getEntityName());
      }
      logger.info("Find {} entities,{} collections from hibernate in {} ms",
          new Object[] { entityTypes.size(), collectionTypes.size(), watch.getTime() });
      if (logger.isDebugEnabled()) {
        loggerTypeInfo();
      }
      collectionTypes.clear();
    }
  }

  private void loggerTypeInfo() {
    List<String> names = CollectUtils.newArrayList(entityTypes.keySet());
    Collections.sort(names);
    for (final String entityName : names) {
      EntityType entityType = (EntityType) entityTypes.get(entityName);
      logger.debug("entity:{}-->{}", entityType.getEntityName(), entityType.getEntityClass().getName());
      logger.debug("propertyType size:{}", Integer.valueOf(entityType.getPropertyTypes().size()));
    }
    names.clear();
    names.addAll(collectionTypes.keySet());
    Collections.sort(names);
    for (final String collectionName : names) {
      CollectionType collectionType = (CollectionType) collectionTypes.get(collectionName);
      logger.debug("collection:{}", collectionType.getName());
      logger.debug("class:{}", collectionType.getCollectionClass());
      logger.debug("elementType:{}", collectionType.getElementType().getReturnedClass());
    }
  }

  /**
   * 按照实体名,构建或者查找实体类型信息.<br>
   * 调用后,实体类型则存放与entityTypes中.
   *
   * @param entityName
   * @return
   */
  private EntityType buildEntityType(SessionFactory sessionFactory, String entityName) {
    EntityType entityType = (EntityType) entityTypes.get(entityName);
    if (null == entityType) {
      ClassMetadata cm = sessionFactory.getClassMetadata(entityName);
      if (null == cm) {
        logger.error("Cannot find ClassMetadata for {}", entityName);
        return null;
      }
      entityType = new EntityType();
      entityType.setEntityName(cm.getEntityName());
      entityType.setIdPropertyName(cm.getIdentifierPropertyName());
      entityType.setEntityClass(cm.getMappedClass(EntityMode.POJO));
      entityTypes.put(cm.getEntityName(), entityType);

      Map<String, Type> propertyTypes = entityType.getPropertyTypes();
      String[] ps = cm.getPropertyNames();
      for (int i = 0; i < ps.length; i++) {
        org.hibernate.type.Type type = cm.getPropertyType(ps[i]);
        if (type.isEntityType()) {
          propertyTypes.put(ps[i], buildEntityType(sessionFactory, type.getName()));
        } else if (type.isComponentType()) {
          propertyTypes.put(ps[i], buildComponentType(sessionFactory, entityName, ps[i]));
        } else if (type.isCollectionType()) {
          propertyTypes.put(
              ps[i],
              buildCollectionType(sessionFactory, defaultCollectionClass(type), entityName
                  + "." + ps[i]));
        }
      }
    }
    return entityType;
  }

  private CollectionType buildCollectionType(SessionFactory sessionFactory, Class<?> collectionClass,
      String role) {
    CollectionMetadata cm = sessionFactory.getCollectionMetadata(role);
    // FIXME buildCollectionType
    if (null == cm) { return null; }
    org.hibernate.type.Type type = cm.getElementType();
    EntityType elementType = null;
    if (type.isEntityType()) {
      elementType = (EntityType) entityTypes.get(type.getName());
      if (null == elementType) {
        elementType = buildEntityType(sessionFactory, type.getName());
      }
    } else {
      elementType = new EntityType(type.getReturnedClass());
    }

    CollectionType collectionType = new CollectionType();
    collectionType.setElementType(elementType);
    collectionType.setArray(cm.isArray());
    collectionType.setCollectionClass(collectionClass);
    if (!collectionTypes.containsKey(collectionType.getName())) {
      collectionTypes.put(collectionType.getName(), collectionType);
    }
    return collectionType;
  }

  private ComponentType buildComponentType(SessionFactory sessionFactory, String entityName,
      String propertyName) {
    EntityType entityType = (EntityType) entityTypes.get(entityName);
    if (null != entityType) {
      Type propertyType = (Type) entityType.getPropertyTypes().get(propertyName);
      if (null != propertyType) { return (ComponentType) propertyType; }
    }

    ClassMetadata cm = sessionFactory.getClassMetadata(entityName);
    org.hibernate.type.ComponentType hcType = (org.hibernate.type.ComponentType) cm
        .getPropertyType(propertyName);
    String[] propertyNames = hcType.getPropertyNames();

    ComponentType cType = new ComponentType(hcType.getReturnedClass());
    Map<String, Type> propertyTypes = cType.getPropertyTypes();
    for (int j = 0; j < propertyNames.length; j++) {
      org.hibernate.type.Type type = cm.getPropertyType(propertyName + "." + propertyNames[j]);
      if (type.isEntityType()) {
        propertyTypes.put(propertyNames[j], buildEntityType(sessionFactory, type.getName()));
      } else if (type.isComponentType()) {
        propertyTypes
            .put(propertyNames[j],
                buildComponentType(sessionFactory, entityName, propertyName + "."
                    + propertyNames[j]));
      } else if (type.isCollectionType()) {
        propertyTypes.put(
            propertyNames[j],
            buildCollectionType(sessionFactory, defaultCollectionClass(type), entityName + "."
                + propertyName + "." + propertyNames[j]));
      }
    }
    return cType;
  }

  private Class<?> defaultCollectionClass(org.hibernate.type.Type collectionType) {
    if (collectionType.isAnyType()) {
      return null;
    } else if (org.hibernate.type.SetType.class.isAssignableFrom(collectionType.getClass())) {
      return HashSet.class;
    } else if (org.hibernate.type.MapType.class.isAssignableFrom(collectionType.getClass())) {
      return HashMap.class;
    } else {
      return ArrayList.class;
    }
  }

}
TOP

Related Classes of org.beangle.model.persist.hibernate.HibernateEntityContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.