All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.tsl2.nano.persistence.provider.NanoEntityManagerFactory Maven / Gradle / Ivy

/*
 * File: $HeadURL$
 * Id  : $Id$
 * 
 * created by: ts
 * created on: 08.09.2013
 * 
 * Copyright: (c) Thomas Schneider 2013, all rights reserved
 */
package de.tsl2.nano.persistence.provider;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.Cache;
import javax.persistence.EntityGraph;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.FlushModeType;
import javax.persistence.LockModeType;
import javax.persistence.Parameter;
import javax.persistence.Persistence;
import javax.persistence.PersistenceUnitUtil;
import javax.persistence.Query;
import javax.persistence.SynchronizationType;
import javax.persistence.TemporalType;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.metamodel.Metamodel;

import org.apache.commons.logging.Log;

import de.tsl2.nano.core.ENV;
import de.tsl2.nano.core.cls.BeanClass;
import de.tsl2.nano.core.log.LogFactory;
import de.tsl2.nano.core.util.StringUtil;
import de.tsl2.nano.core.util.Util;

/**
 * simplified base implementation of an {@link javax.persistence.EntityManagerFactory} and an abstract
 * {@link EntityManager}.
 * 

* Please extend the classes {@link NanoEntityManagerFactory.AbstractEntityManager}, * {@link NanoEntityManagerFactory.AbstractQuery} and implement the abstract methods to have a reduced jpa persistence * provider. This reduced provider wont support Criterias etc.
*

* Call {@link #setEntityManagerImpl(String)} to provide your implementation to this factory class
* Call {@link NanoEntityManagerFactory#createEntityManager(Map)} to get a new specialized {@link EntityManager}. The * property map has to contain the following specific entries:
* 1. {@link #EM_IMPLEMENTATION}: pointing to your special EntityManager implementation
* 2. jdbc.url: database connection url
* 3. jdbc.user: database connection user
* 4. jdbc.passwd: database connection password
* * @author ts * @version $Revision$ */ public class NanoEntityManagerFactory implements javax.persistence.EntityManagerFactory { private static final Log LOG = LogFactory.getLog(NanoEntityManagerFactory.class); Collection ems; Map props; EntityTransaction dummyTransaction; public static final String EM_IMPLEMENTATION = "entity.manager.implementation.class"; static NanoEntityManagerFactory self; /** * constructor */ NanoEntityManagerFactory() { LOG.debug("creating spimplified entitymanagerfactory: " + this); ems = new LinkedList(); props = new LinkedHashMap(); dummyTransaction = new NTransaction(); } public static final NanoEntityManagerFactory instance() { if (self == null) { self = new NanoEntityManagerFactory(); } return self; } @Override public void close() { LOG.debug("closing entitymanagerfactory: " + this); for (EntityManager em : ems) { em.close(); } ems = null; } public void setEntityManagerImpl(String clsEntityManagerImpl) { props.put(EM_IMPLEMENTATION, clsEntityManagerImpl); } @Override public EntityManager createEntityManager() { return createEntityManager(getProperties()); } /** * createEntityManager * * @param clsEntityManagerImpl class to be loaded and used to create an {@link EntityManager}. * @return special {@link EntityManager} */ @SuppressWarnings({ "unchecked", "rawtypes" }) public EntityManager createEntityManager(String clsEntityManagerImpl, Map props) { this.props.putAll(props); setEntityManagerImpl(clsEntityManagerImpl); return createEntityManager(this.props); } @Override @SuppressWarnings({ "rawtypes" }) public EntityManager createEntityManager(Map arg0) { String clsEM = (String) arg0.get(EM_IMPLEMENTATION); LOG.info("creating entity manager: " + clsEM); EntityManager em = (EntityManager) BeanClass.createInstance(clsEM, arg0); ems.add(em); return em; } @Override public Cache getCache() { throw new UnsupportedOperationException(); } @Override public CriteriaBuilder getCriteriaBuilder() { throw new UnsupportedOperationException(); } @Override public Metamodel getMetamodel() { throw new UnsupportedOperationException(); } @Override public PersistenceUnitUtil getPersistenceUnitUtil() { throw new UnsupportedOperationException(); } @Override public Map getProperties() { return props; } @Override public boolean isOpen() { return ems != null; } @SuppressWarnings("rawtypes") public abstract class AbstractEntityManager implements javax.persistence.EntityManager { Map props; FlushModeType flushModeType = FlushModeType.AUTO; LockModeType lockModeType = LockModeType.OPTIMISTIC; private final Log LOG = LogFactory.getLog(AbstractEntityManager.class); /** * constructor * * @param props */ public AbstractEntityManager(Map props) { super(); this.props = props; } @Override public Query createNamedQuery(String arg0) { return createNamedQuery(arg0, Object.class); } @Override public TypedQuery createNamedQuery(String arg0, Class arg1) { throw new UnsupportedOperationException(); } @Override public Query createNativeQuery(String arg0) { return createNativeQuery(arg0, Object.class); } @Override public Query createNativeQuery(String arg0, Class arg1) { throw new UnsupportedOperationException(); } @Override public Query createNativeQuery(String arg0, String arg1) { throw new UnsupportedOperationException(); } @Override public TypedQuery createQuery(CriteriaQuery arg0) { throw new UnsupportedOperationException(); } @Override public Query createQuery(String arg0) { return createQuery(arg0, Object.class); } @Override public T find(Class arg0, Object arg1, Map arg2) { LOG.warn("ignoring properties on find()"); return find(arg0, arg1); } @Override public T find(Class arg0, Object arg1, LockModeType arg2) { LOG.warn("ignoring lockmodetype on find()"); return find(arg0, arg1); } @Override public T find(Class arg0, Object arg1, LockModeType arg2, Map arg3) { LOG.warn("ignoring lockmodetype and properties on find()"); return find(arg0, arg1); } @Override public void flush() { LOG.warn("ignoring flush"); } @Override public CriteriaBuilder getCriteriaBuilder() { throw new UnsupportedOperationException(); } @Override public Object getDelegate() { return null; } @Override public NanoEntityManagerFactory getEntityManagerFactory() { return NanoEntityManagerFactory.self; } @Override public FlushModeType getFlushMode() { return flushModeType; } @Override public LockModeType getLockMode(Object arg0) { return lockModeType; } @Override public Metamodel getMetamodel() { return NanoEntityManagerFactory.self.getMetamodel(); } @SuppressWarnings("unchecked") @Override public Map getProperties() { return props; } @Override public T getReference(Class arg0, Object arg1) { return find(arg0, arg1); } @Override public EntityTransaction getTransaction() { return dummyTransaction; } @Override public void joinTransaction() { LOG.warn("ignoring joinTransaction"); } @Override public void lock(Object arg0, LockModeType arg1) { lock(arg0, arg1, null); } @Override public void lock(Object arg0, LockModeType arg1, Map arg2) { throw new UnsupportedOperationException(); } @Override public void persist(Object arg0) { merge(arg0); } @Override public void refresh(Object arg0) { refresh(arg0, null, null); } @Override public void refresh(Object arg0, Map arg1) { refresh(arg0, null, arg1); } @Override public void refresh(Object arg0, LockModeType arg1) { refresh(arg0, arg1); } @Override public void refresh(Object arg0, LockModeType arg1, Map arg2) { LOG.warn("ignoring refresh"); } @Override public void setFlushMode(FlushModeType arg0) { LOG.warn("ignoring flushmode"); } @SuppressWarnings("unchecked") @Override public void setProperty(String arg0, Object arg1) { props.put(arg0, arg1); } @Override public T unwrap(Class arg0) { return null; } } /** * * @author Tom * @version $Revision$ */ @SuppressWarnings({ "rawtypes", "unchecked" }) public abstract class AbstractQuery implements TypedQuery { protected EntityManager em; protected Map props = new HashMap(); protected Map parameter = new HashMap(); protected int first = 0; protected int max = -1; FlushModeType flushModeType = FlushModeType.AUTO; LockModeType lockModeType = LockModeType.OPTIMISTIC; @Override public X getSingleResult() { List resultList = getResultList(); if (resultList != null) { if (resultList.size() > 1) { throw new IllegalStateException(); } else { return resultList.size() == 1 ? resultList.iterator().next() : null; } } else { return null; } } @Override public int getFirstResult() { return first; } @Override public FlushModeType getFlushMode() { return em.getFlushMode(); } @Override public Map getHints() { return props; } @Override public LockModeType getLockMode() { return lockModeType; } @Override public int getMaxResults() { return max; } @Override public Parameter getParameter(String arg0) { return getParameter(arg0, Object.class); } @Override public Parameter getParameter(int arg0) { return getParameter(String.valueOf(arg0), Object.class); } @SuppressWarnings("unchecked") @Override public Parameter getParameter(String arg0, Class arg1) { return parameter.get(arg0); } @Override public Parameter getParameter(int arg0, Class arg1) { return getParameter(String.valueOf(arg0), arg1); } @Override public T getParameterValue(Parameter arg0) { return ((NanoEntityManagerFactory.NParameter) arg0).getValue(); } @Override public Object getParameterValue(String arg0) { return getParameterValue(getParameter(arg0)); } @Override public Object getParameterValue(int arg0) { return getParameterValue(getParameter(arg0)); } @Override public Set> getParameters() { return new HashSet>((Collection>) Util.untyped(parameter.values())); } @Override public boolean isBound(Parameter arg0) { return parameter.containsKey(arg0.getName()); } @Override public TypedQuery setFirstResult(int arg0) { first = arg0; return this; } @Override public TypedQuery setFlushMode(FlushModeType arg0) { flushModeType = arg0; return this; } @Override public TypedQuery setHint(String arg0, Object arg1) { props.put(arg0, arg1); return this; } @Override public TypedQuery setLockMode(LockModeType arg0) { lockModeType = arg0; return this; } @Override public TypedQuery setMaxResults(int arg0) { max = arg0; return this; } // @Override @Override public TypedQuery setParameter(Parameter arg0, T arg1) { parameter.put(arg0.getName(), arg0 instanceof NParameter ? arg0 : new NParameter(arg0.getName(), arg0.getParameterType(), arg1)); return this; } @Override public TypedQuery setParameter(String arg0, Object arg1) { return setParameter(new NParameter(arg0, null, arg1), arg1); } @Override public TypedQuery setParameter(int arg0, Object arg1) { return setParameter(String.valueOf(arg0), arg1); } @Override public TypedQuery setParameter(Parameter arg0, Calendar arg1, TemporalType arg2) { return setParameter(new NParameter(arg0.getName(), Calendar.class, arg1).setTemporalType(arg2), arg1); } @Override public TypedQuery setParameter(Parameter arg0, Date arg1, TemporalType arg2) { return setParameter(new NParameter(arg0.getName(), Date.class, arg1).setTemporalType(arg2), arg1); } @Override public TypedQuery setParameter(String arg0, Calendar arg1, TemporalType arg2) { return setParameter(arg0, new NParameter(arg0, Calendar.class, arg1).setTemporalType(arg2)); } @Override public TypedQuery setParameter(String arg0, Date arg1, TemporalType arg2) { return setParameter(arg0, new NParameter(arg0, Date.class, arg1).setTemporalType(arg2)); } @Override public TypedQuery setParameter(int arg0, Calendar arg1, TemporalType arg2) { return setParameter(String.valueOf(arg0), new NParameter(arg0, Calendar.class, arg1).setTemporalType(arg2)); } @Override public TypedQuery setParameter(int arg0, Date arg1, TemporalType arg2) { return setParameter(String.valueOf(arg0), new NParameter(arg0, Date.class, arg1).setTemporalType(arg2)); } @Override public T unwrap(Class arg0) { throw new UnsupportedOperationException(); } /** * utility to find the desired result type * * @param qstr sql-selection-statement * @return select result type */ protected Class evaluateResultType(String qstr) { //TODO: not-complete evaluation String clsName = StringUtil.substring(qstr, "from ", " t"); Collection beanTypes = ENV.get("service.loadedBeanTypes", null); if (beanTypes != null) { for (Class t : beanTypes) { if (t.getSimpleName().equals(clsName)) { return t; } } } throw new IllegalArgumentException("The result type is not evaluable through the given select: " +qstr); } protected String toNativeSQL(String jpqlStatement) { //not-complete: only transforming: t --> t.* return jpqlStatement.replaceAll("select t\\s", "select t.* "); } protected Object getNParameter(String key) { return ((NParameter)parameter.get(key)).getValue(); } /** * getParameterValues * @return all parameter values */ protected Collection getNParameterValues() { Set keys = parameter.keySet(); List pars = new ArrayList(parameter.size()); for (String k : keys) { pars.add(getNParameter(k)); } return pars; } } /** * implementation of {@link Persistence} * * @param * @author Tom * @version $Revision$ */ public class NParameter implements Parameter { protected String name; protected Class type; protected TemporalType temporalType; protected Integer position; protected T value; /** * constructor * * @param name * @param type * @param position */ public NParameter(String name, Class type, T value) { super(); this.name = name; this.type = type; this.value = value; } /** * constructor * * @param name * @param type * @param position */ public NParameter(Integer position, Class type, T value) { super(); this.name = String.valueOf(position); this.type = type; this.position = position; this.value = value; } @Override public String getName() { return name; } @Override public Class getParameterType() { return type; } @Override public Integer getPosition() { return position; } /** * @return Returns the value. */ protected T getValue() { return value; } /** * @param value The value to set. */ protected void setValue(T value) { this.value = value; } /** * @return Returns the temporalType. */ protected TemporalType getTemporalType() { return temporalType; } /** * @param temporalType The temporalType to set. */ protected NParameter setTemporalType(TemporalType temporalType) { this.temporalType = temporalType; return this; } } /** * * @author Tom, Thomas Schneider * @version $Revision$ */ public class NTransaction implements EntityTransaction { private final Log LOG = LogFactory.getLog(NTransaction.class); protected boolean rollbackOnly; @Override public void commit() { LOG.warn("ignoring transaction request!"); } @Override public void begin() { LOG.warn("ignoring transaction request!"); } @Override public boolean getRollbackOnly() { return rollbackOnly; } @Override public boolean isActive() { return true; } @Override public void rollback() { LOG.warn("ignoring transaction request!"); } @Override public void setRollbackOnly() { rollbackOnly = true; } } @Override public void addNamedEntityGraph(String arg0, EntityGraph arg1) { throw new UnsupportedOperationException(); } @Override public void addNamedQuery(String arg0, Query arg1) { throw new UnsupportedOperationException(); } @Override public EntityManager createEntityManager(SynchronizationType arg0) { // TODO Auto-generated method stub return null; } @Override public EntityManager createEntityManager(SynchronizationType arg0, Map arg1) { // TODO Auto-generated method stub return null; } @Override public T unwrap(Class arg0) { // TODO Auto-generated method stub return null; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy