Package com.adaptrex.core.persistence.jpa

Source Code of com.adaptrex.core.persistence.jpa.JPAPersistenceManager

package com.adaptrex.core.persistence.jpa;

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.Metamodel;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.adaptrex.core.ext.ExtConfig;
import com.adaptrex.core.persistence.api.ORMModelDefinition;
import com.adaptrex.core.persistence.api.ORMModelInstance;
import com.adaptrex.core.persistence.api.ORMPersistenceManager;
import com.adaptrex.core.persistence.api.ORMStoreData;
import com.adaptrex.core.utilities.Inflector;
import com.adaptrex.core.utilities.StringUtilities;

public class JPAPersistenceManager implements ORMPersistenceManager {

  private String factoryName;
  private EntityManagerFactory factory;

  private Map<String, Class<?>> entityClassCache = new HashMap<String, Class<?>>();

  public JPAPersistenceManager() throws IOException, SAXException,
      ParserConfigurationException {
    ClassLoader cl = Thread.currentThread().getContextClassLoader();
    List<InputStream> inputStreams = loadResources(
        "META-INF/persistence.xml", cl);

    if (inputStreams.size() > 1) {
      throw new RuntimeException(
          "Multiple persistence.xml descriptors found but no default has been configured");
    }

    SAXParserFactory.newInstance().newSAXParser()
        .parse(inputStreams.get(0), new DefaultHandler() {
          @Override
          public void startElement(String uri, String localName,
              String qName, Attributes attributes) {
            if (qName.equalsIgnoreCase("persistence-unit")) {
              factoryName = attributes.getValue("name");
            }
          }
        });

    this.factory = Persistence.createEntityManagerFactory(factoryName);
  }

  public JPAPersistenceManager(String factoryName) throws IOException {
    this.factory = Persistence.createEntityManagerFactory(factoryName);
  }

  @Override
  public Object getFactory() {
    return this.factory;
  }

  @Override
  public void shutdown() {
    this.factory.close();
  }

  @Override
  public Object getSession() {
    return this.factory.createEntityManager();
  }

  @Override
  public Class<?> getEntityClass(String className) {
    if (entityClassCache.containsKey(className)) {
      return entityClassCache.get(className);
    }

    EntityManager em = null;

    try {
      em = this.factory.createEntityManager();
      Metamodel meta = em.getMetamodel();
      for (EntityType<?> et : meta.getEntities()) {
        if (et.getJavaType().getName().endsWith("." + className)) {
          Class<?> clazz = et.getJavaType();
          entityClassCache.put(className, clazz);
          return clazz;
        }
      }

      return null;
    } catch (Exception e) {
      throw new RuntimeException("Could not load entity class ("
          + className + ")");
    } finally {
      if (em != null) {
        em.close();
      }
    }
  }

  @Override
  public Object getEntity(Class<?> clazz, Object id) {
    EntityManager em = null;
    try {
      em = this.factory.createEntityManager();
      return em.find(clazz, id);
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    } finally {
      em.close();
    }
  }

  @Override
  public Object getEntity(Class<?> clazz, String key, Object value) {
    return null;
  }

  @Override
  public ORMModelDefinition getModelDefinition(ExtConfig extConfig) {
    return new JPAModelDefinition(extConfig);
  }

  @Override
  public ORMModelInstance getModelInstance(ExtConfig extConfig, Object entity) {
    return new JPAModelInstance(extConfig, entity);
  }

  @Override
  public ORMStoreData getStoreData(ExtConfig extConfig) {
    return new JPAStoreData(extConfig);
  }
 
  @Override
  public boolean isIdField(Class<?> clazz, String fieldName) {
    return hasMemberAnnotation(clazz, fieldName, "Id");
  }
 
  @Override
  public Object getEntityId(Object entity) {
    Method idGetter;
    try {
      idGetter = entity.getClass().getDeclaredMethod("getId");
      return idGetter.invoke(entity);
    } catch (Exception e) {
      throw new RuntimeException ("Could not find id getter for " + entity.getClass().getName(), e);
    }
  } 
 

  @Override
  public boolean isOneToMany(Class<?> clazz, String fieldName) {
    return hasMemberAnnotation(clazz, fieldName, "OneToMany");
  }

  @Override
  public boolean isManyToOne(Class<?> clazz, String fieldName) {
    return hasMemberAnnotation(clazz, fieldName, "ManyToOne");
  }

  @Override
  public boolean isManyToMany(Class<?> clazz, String fieldName) {
    return hasMemberAnnotation(clazz, fieldName, "ManyToMany");
  }

  @Override
  public boolean isAssociated(Class<?> clazz, String associationName) {
    String fieldName = StringUtilities.uncapitalize(associationName);
    return isOneToMany(clazz, fieldName) || isManyToOne(clazz, fieldName)
        || isManyToMany(clazz, fieldName);
  }

  @Override
  public Class<?> getFieldEntityClass(Class<?> clazz, String fieldName) {
    Field field;
    try {
      field = clazz.getDeclaredField(fieldName);
    } catch (Exception e) {
      throw new RuntimeException("could not find field entity class");
    }

    if (field == null) {
      throw new RuntimeException("could not find field entity class");
    }

    if (Collection.class.isAssignableFrom(field.getType())) {
      Type type = field.getGenericType();
      if (type instanceof ParameterizedType) {
        ParameterizedType pt = (ParameterizedType) type;
        return (Class<?>) pt.getActualTypeArguments()[0];
      }
    } else {
      return field.getType();
    }

    return null;
  }

  @Override
  public Object getFieldValue(Object entity, String fieldName) {
    Method getter = null;
    Class<?> clazz = entity.getClass();
    try {
      getter = clazz.getMethod("get" + StringUtilities.capitalize(fieldName));
    } catch (Exception e) {
    }
    if (getter == null) {
      try {
        getter = clazz.getMethod("is" + StringUtilities.capitalize(fieldName));
      } catch (Exception e) {
      }
    }
    if (getter == null) {
      return null;
    }

    try {
      return getter.invoke(entity);
    } catch (Exception e) {
      //log.warn("Error", e);
      return null;
    }
  }

  private Map<String, String> fieldTypeCache = new HashMap<String, String>();

  /*
   * Get the type of field. Returns the Ext string for various data types Ext
   * supports.
   *
   * (non-Javadoc)
   *
   * @see
   * com.adaptrex.core.persistence.api.ORMPersistenceManager#getFieldType(
   * java.lang.Class, java.lang.String)
   */
  @Override
  public String getFieldType(Class<?> clazz, String fieldName) {
    String fieldKey = clazz.getName() + "." + fieldName;

    String fieldType = fieldTypeCache.get(fieldKey);
    if (fieldType != null)
      return fieldType;

    Field field = null;
    try {
      field = clazz.getDeclaredField(fieldName);
    } catch (Exception e) {
    }
    if (field == null)
      return null;
    String columnType = field.getType().getSimpleName().toLowerCase();

    if (columnType.equals("integer") || columnType.equals("long")) {
      columnType = "int";
    } else if (columnType.equals("double")) {
      columnType = "float";
    } else if (columnType.equals("time")) {
      columnType = "time";
    } else if (columnType.equals("calendar") || columnType.equals("date")) {
      columnType = "date";
    }

    if (columnType.equals("date")) {
      Temporal a = field.getAnnotation(Temporal.class);
      if (a == null) {
        try {
          Method getter = clazz.getMethod("get"
              + StringUtilities.capitalize(fieldName));
          if (getter != null) {
            a = getter.getAnnotation(Temporal.class);
          }
        } catch (Exception e) {
        }
      }
      if (a != null && a.value().equals(TemporalType.TIME)) {
        columnType = "time";
      }
    }

    fieldTypeCache.put(fieldKey, columnType);
    return columnType;
  }

  /* *******************************************************************
   *
   * private utilities
   */
  private Map<String, List<String>> memberAnnotationCache = new HashMap<String, List<String>>();

  private boolean hasMemberAnnotation(Class<?> clazz, String member,
      String annotationName) {
    List<String> memberAnnotations = memberAnnotationCache.get(clazz
        .getName() + "." + member);
    if (memberAnnotations == null) {
      memberAnnotations = getMemberAnnotations(clazz, member);
    }
    return memberAnnotations.contains(annotationName);
  }

  /*
   * This gets a list of all annotations on a class field (or it's getter)
   */
  private List<String> getMemberAnnotations(Class<?> clazz, String member) {
    List<String> list = memberAnnotationCache.get(clazz.getName() + "."
        + member);
    if (list != null) {
      return list;
    }

    list = new ArrayList<String>();
    try {
      Field field = clazz.getDeclaredField(member);
      if (field != null) {
        for (Annotation annotation : field.getDeclaredAnnotations()) {
          list.add(annotation.annotationType().getSimpleName());
        }
      }
    } catch (Exception e) {
    }

    try {
      Method getter = clazz.getMethod("get"
          + StringUtilities.capitalize(member));
      if (getter != null) {
        for (Annotation annotation : getter.getDeclaredAnnotations()) {
          list.add(annotation.annotationType().getSimpleName());
        }
      }
    } catch (Exception e) {
    }

    memberAnnotationCache.put(clazz.getName() + "." + member, list);
    return list;
  }

  /*
   * Ripped from: http://goo.gl/CYwbl
   */
  private static List<InputStream> loadResources(final String name,
      final ClassLoader classLoader) throws IOException {
    final List<InputStream> list = new ArrayList<InputStream>();
    final Enumeration<URL> systemResources = classLoader.getResources(name);
    while (systemResources.hasMoreElements()) {
      list.add(systemResources.nextElement().openStream());
    }
    return list;
  }

 
  @Override
  public ORMModelInstance createModelinstance(ExtConfig extConfig,
      Map<String, Object> data) {
    try {
      Object entity = extConfig.getEntityClass().newInstance();
      JPAModelInstance model = new JPAModelInstance(extConfig, entity);
      return model.update(data);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

 
  @Override
  public ORMModelInstance updateModelInstance(ExtConfig extConfig, Object id,
      Map<String, Object> data) {
    try {
      Object entity = this.getEntity(extConfig.getEntityClass(), id);
      JPAModelInstance model = new JPAModelInstance(extConfig, entity);
      return model.update(data);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

 
  @Override
  public ORMModelInstance deleteModelInstance(ExtConfig extConfig, Object id) {
    try {
      Object entity = this.getEntity(extConfig.getEntityClass(), id);
      JPAModelInstance model = new JPAModelInstance(extConfig, entity);
      model.delete();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
    return null;
  }
}
TOP

Related Classes of com.adaptrex.core.persistence.jpa.JPAPersistenceManager

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.