Package com.adaptrex.core.persistence.jpa_old

Source Code of com.adaptrex.core.persistence.jpa_old.JpaPersistence

/*
* Copyright 2012 Adaptrex, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.adaptrex.core.persistence.jpa_old;

import com.adaptrex.core.ext.Filter;
import com.adaptrex.core.ext.Sorter;
import com.adaptrex.core.utilities.StringUtilities;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;

import javax.persistence.Cache;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.Metamodel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JpaPersistence  {

  private EntityManagerFactory factory;

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

  private Logger log = LoggerFactory.getLogger(JpaPersistence.class);

  private static SimpleDateFormat dateFormat = new SimpleDateFormat(
      "yyyy-MM-dd");

  public JpaPersistence(EntityManagerFactory factory) {
    this.factory = factory;
  }

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

      EntityManager em = 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;
        }
      }
    } catch (Exception e) {
      log.warn("Error", e);
    }
    return null;
  }

  /* *******************************************************************
   *
   * Get Single Entity
   */
//  public Object getEntity(AdaptrexSession session, String entityName,
//      Integer id) {
//    EntityManager em = (EntityManager) session.getPersistence()
//        .getNativeSession();
//    return em.find(getEntityClass(entityName), id);
//  }
//
//  public Object getEntity(AdaptrexSession session, Class<?> clazz, Integer id) {
//    EntityManager em = (EntityManager) session.getPersistence()
//        .getNativeSession();
//    return em.find(clazz, id);
//  }

  /* *******************************************************************
   *
   * Save Single Entity
   */
//  public Object saveEntity(AdaptrexSession session, Object entity) {
//    EntityManager em = (EntityManager) session.getPersistence()
//        .getNativeSession();
//    Integer id = null;
//    try {
//      Method idGetter = entity.getClass().getDeclaredMethod("getId");
//      id = (Integer) idGetter.invoke(entity);
//    } catch (Exception e) {
//      log.debug("Couldn't find id for entity");
//      return entity;
//    }
//
//    EntityTransaction tx = em.getTransaction();
//    tx.begin();
//
//    if (id != null && em.find(entity.getClass(), id) != null) {
//      log.debug("Merging entity: " + entity.getClass().getSimpleName());
//      entity = em.merge(entity);
//    } else {
//      em.persist(entity);
//      log.debug("Persisting entity: " + entity.getClass().getSimpleName());
//    }
//
//    /*
//     * Evict related objects from cache
//     */
//    try {
//      evictAssociated(em, entity);
//    } catch (Exception e) {
//      log.warn("Error: ", e);
//    }
//
//    tx.commit();
//    return entity;
//  }

  private void evictAssociated(EntityManager em, Object entity) {
    Class<?> clazz = entity.getClass();
    for (Field field : clazz.getDeclaredFields()) {

      /*
       * Evict ManyToOne
       */
      if (isManyToOne(clazz, field.getName())) {
        try {
          Method getter = clazz.getDeclaredMethod("get"
              + StringUtilities.capitalize(field.getName()));
          Object associated = getter.invoke(entity);
          if (associated == null) {
            continue;
          }
          Class<?> associatedClazz = associated.getClass();
          Method idGetter = associatedClazz
              .getDeclaredMethod("getId");
          EntityManagerFactory emf = em.getEntityManagerFactory();
          Cache emfCache = emf.getCache();
          emfCache.evict(associated.getClass(),
              idGetter.invoke(associated));
        } catch (Exception e) {
          log.warn("Error", e);
        }
      }

      /*
       * Evict OneToMany TODO: Test This
       */
      if (isOneToMany(clazz, field.getName())) {
        try {
          Method getter = clazz.getDeclaredMethod("get"
              + StringUtilities.capitalize(field.getName()));
          Set<?> associatedSet = (Set<?>) getter.invoke(entity);

          for (Object associated : associatedSet) {
            Class<?> associatedClazz = associated.getClass();
            Method idGetter = associatedClazz
                .getDeclaredMethod("getId");
            em.getEntityManagerFactory()
                .getCache()
                .evict(associated.getClass(),
                    idGetter.invoke(associated));
          }
        } catch (Exception e) {
          log.warn("Error", e);
        }
      }
    }
  }

  /* *******************************************************************
   *
   * Delete Single Entity
   */
//  public Object deleteEntity(AdaptrexSession session, Object entity) {
//    EntityManager em = (EntityManager) session.getPersistence()
//        .getNativeSession();
//    EntityTransaction tx = em.getTransaction();
//    tx.begin();
//    em.remove(em.merge(entity));
//
//    /*
//     * Evict related objects from cache
//     */
//    evictAssociated(em, entity);
//
//    tx.commit();
//    return entity;
//  }

  /* *******************************************************************
   *
   * Entity List
   */
  @SuppressWarnings("unchecked")
  public List<Object> getEntityList() {
//    List<Object> list = new ArrayList<Object>();

//    try {
////      EntityManager em = (EntityManager) session.getPersistence()
////          .getNativeSession();
//
//      Map<String, Object> parameters = new HashMap<String, Object>(
//          config.getParams());
//
//      Class<?> clazz = config.getClazz();
//      String className = clazz.getSimpleName();
//      String alias = className.toLowerCase().substring(0, 1);
//
//      /*
//       * Core JPQL
//       */
//      String jpql = "SELECT " + alias + " FROM " + className + " "
//          + alias;
//
//      /*
//       * Where
//       */
//      String where = "";
//      if (config.getWhere() != null) {
//        where += config.getWhere();
//      }
//
//      /*
//       * Filter
//       */
//      for (Filter filter : config.getFilters()) {
//        if (!where.isEmpty()) {
//          where += " AND ";
//        }
//
//        String val = String.valueOf(filter.getValue());
//        String prop = filter.getProperty();
//        String param = prop.replace(".", "_");
//
//        /*
//         * Handle between inclusive
//         */
//        if (val.contains(">=<")) {
//          String[] filterParts = val.split(">=<");
//
//          where += "(" + alias + "." + prop + " BETWEEN :" + param
//              + "_low AND :" + param + "_high)" + "";
//          parameters.put(param + "_low", filterParts[0]);
//          parameters.put(param + "_high", filterParts[1]);
//
//          /*
//           * Handle "OR"
//           */
//        } else if (val.contains("||")) {
//          String whereOr = "";
//          int i = 1;
//
//          for (String orPart : val.split("\\|\\|")) {
//            whereOr += whereOr.isEmpty() ? "(" : " OR ";
//            whereOr += alias + "." + prop + " = :" + param + i;
//            parameters.put(param + i, orPart);
//            i++;
//          }
//          whereOr += ")";
//          where += whereOr;
//
//        } else {
//          String eqType = val.contains("%") ? " like " : " = ";
//          if (eqType.contains("like")) {
//            where += "lower(" + alias + "." + prop + ")" + eqType
//                + ":" + param;
//
//          } else {
//            where += alias + "." + prop + eqType + ":" + param;
//          }
//
//          parameters.put(param, val);
//        }
//      }
//
//      /*
//       * Add where clause
//       */
//      if (!where.isEmpty()) {
//        jpql += " WHERE " + where;
//      }
//
//      if (config.getSorters().size() > 0) {
//        String sortClause = "";
//        for (Sorter sorter : config.getSorters()) {
//          if (!sortClause.isEmpty()) {
//            sortClause += ",";
//          }
//          sortClause += alias + "." + sorter.getProperty() + " "
//              + sorter.getDirection();
//        }
//        jpql += " ORDER BY " + sortClause;
//      }
//
//      log.debug("JPQL: " + jpql);
//      Query q = null;// = em.createQuery(jpql, clazz);
//
//      /*
//       * Add params TODO: This is tedius... we want to automatically
//       * determine the type for the field we're trying to set the
//       * parameter for
//       */
//      for (String key : parameters.keySet()) {
//        Object paramObj = parameters.get(key);
//
//        Class<?> paramType = q.getParameter(key).getParameterType();
//        String typeName = paramType.getSimpleName().toLowerCase();
//
//        try {
//          if (typeName.equals("boolean")) {
//            String stringVal = (String) paramObj;
//            paramObj = stringVal.equals("1")
//                || stringVal.equals("true")
//                || stringVal.equals("Y");
//
//          } else if (typeName.equals("date")) {
//            paramObj = dateFormat.parse((String) paramObj);
//
//          } else {
//            Method m = paramType.getDeclaredMethod("valueOf",
//                String.class);
//            paramObj = m.invoke(null, paramObj);
//          }
//        } catch (Exception e) {
//        }
//
//        log.debug("  Param: " + key + " = " + paramObj);
//        q.setParameter(key, paramObj);
//      }
//
//      //store.setTotalCount(q.getResultList().size());
//
//      if (config.getPageSize() != null) {
//        q.setMaxResults(config.getPageSize());
//      }
//      if (config.getStart() != null) {
//        q.setFirstResult(config.getStart());
//      }
//      //list = q.getResultList();
//    } catch (Exception e) {
//      log.warn("Error", e);
//    }

    return null;
  }

  /* ************************************************************************************
   *
   * Everything below this is experimental. Possibly moved under a separate
   * interface
   */
  public boolean isIdField(Class<?> clazz, String fieldName) {
    return hasMemberAnnotation(clazz, fieldName, "Id");
  }

  /*
   * TODO: Do we want to move ManyToMany to a separate method?
   */
  public boolean isOneToMany(Class<?> clazz, String fieldName) {
    return hasMemberAnnotation(clazz, fieldName, "OneToMany")
        || hasMemberAnnotation(clazz, fieldName, "ManyToMany");
  }

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

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

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

  public String getFieldType(Class<?> clazz, String fieldName) {
    String fieldType = fieldTypeCache
        .get(clazz.getName() + "." + fieldName);
    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(clazz.getName() + "." + fieldName, columnType);
    return columnType;
  }

  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;
  }

  private static String capitalize(String string) {
    return string.substring(0, 1).toUpperCase() + string.substring(1);
  }

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

  public Object getNativeSession() {
    return this.factory.createEntityManager();
  }

  public void closeNativeSession(Object entityManager) {
    ((EntityManager) entityManager).close();
  }
}
TOP

Related Classes of com.adaptrex.core.persistence.jpa_old.JpaPersistence

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.