/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* 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 org.jbpm.shared.services.impl;
import org.kie.api.runtime.Context;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.Query;
import java.util.HashMap;
import java.util.Map;
public class JpaPersistenceContext implements Context {
public final static String FIRST_RESULT = "firstResult";
public final static String MAX_RESULTS = "maxResults";
private EntityManager em;
public JpaPersistenceContext(EntityManager em) {
this.em = em;
}
protected Query getQueryByName(String queryName, Map<String, Object> params) {
String queryStr = QueryManager.get().getQuery(queryName, params);
Query query = null;
if (queryStr != null) {
query = this.em.createQuery(queryStr);
} else {
query = this.em.createNamedQuery(queryName);
}
return query;
}
public <T> T queryWithParametersInTransaction(String queryName,
Map<String, Object> params, Class<T> clazz) {
check();
Query query = getQueryByName(queryName, params);
return queryStringWithParameters(params, false, LockModeType.NONE, clazz, query);
}
public <T> T queryAndLockWithParametersInTransaction(String queryName,
Map<String, Object> params, boolean singleResult, Class<T> clazz) {
check();
Query query = getQueryByName(queryName, params);
return queryStringWithParameters(params, singleResult, LockModeType.PESSIMISTIC_WRITE, clazz, query);
}
@SuppressWarnings("unchecked")
public <T> T queryInTransaction(String queryName, Class<T> clazz) {
check();
Query query = this.em.createNamedQuery(queryName);
return (T) query.getResultList();
}
@SuppressWarnings("unchecked")
public <T> T queryStringInTransaction(String queryString, Class<T> clazz) {
check();
Query query = this.em.createQuery(queryString);
return (T) query.getResultList();
}
public <T> T queryStringWithParametersInTransaction(String queryString,
Map<String, Object> params, Class<T> clazz) {
check();
Query query = this.em.createQuery(queryString);
return queryStringWithParameters(params, false, LockModeType.NONE, clazz, query);
}
public <T> T queryAndLockStringWithParametersInTransaction(
String queryName, Map<String, Object> params, boolean singleResult,
Class<T> clazz) {
check();
Query query = this.em.createNamedQuery(queryName);
return queryStringWithParameters(params, singleResult, LockModeType.PESSIMISTIC_WRITE, clazz, query);
}
public int executeUpdateString(String updateString) {
check();
Query query = this.em.createQuery(updateString);
return query.executeUpdate();
}
public int executeUpdateString(String updateString, Map<String, Object> parameters) {
check();
Query query = this.em.createQuery(updateString);
if (parameters != null && !parameters.isEmpty()) {
for (String name : parameters.keySet()) {
query.setParameter(name, parameters.get(name));
}
}
return query.executeUpdate();
}
public HashMap<String, Object> addParametersToMap(Object... parameterValues) {
HashMap<String, Object> parameters = new HashMap<String, Object>();
if( parameterValues.length % 2 != 0 ) {
throw new RuntimeException("Expected an even number of parameters, not " + parameterValues.length);
}
for( int i = 0; i < parameterValues.length; ++i ) {
String parameterName = null;
if( parameterValues[i] instanceof String ) {
parameterName = (String) parameterValues[i];
} else {
throw new RuntimeException("Expected a String as the parameter name, not a " + parameterValues[i].getClass().getSimpleName());
}
++i;
parameters.put(parameterName, parameterValues[i]);
}
return parameters;
}
public <T> T persist(T object) {
check();
this.em.persist( object );
return object;
}
public <T> T find(Class<T> entityClass, Object primaryKey) {
check();
return this.em.find( entityClass, primaryKey );
}
public <T> T remove(T entity) {
check();
em.remove( entity );
return entity;
}
public <T> T merge(T entity) {
check();
return this.em.merge(entity);
}
@SuppressWarnings("unchecked")
private <T> T queryStringWithParameters(Map<String, Object> params, boolean singleResult, LockModeType lockMode,
Class<T> clazz, Query query) {
;
if (lockMode != null) {
query.setLockMode(lockMode);
}
if (params != null && !params.isEmpty()) {
for (String name : params.keySet()) {
if (FIRST_RESULT.equals(name)) {
query.setFirstResult((Integer) params.get(name));
continue;
}
else if (MAX_RESULTS.equals(name)) {
if (((Integer) params.get(name)) > -1) {
query.setMaxResults((Integer) params.get(name));
}
continue;
}
// skip control parameters
else if (QueryManager.ASCENDING_KEY.equals(name)
|| QueryManager.DESCENDING_KEY.equals(name)
|| QueryManager.ORDER_BY_KEY.equals(name)
|| QueryManager.FILTER.equals(name)) {
continue;
}
query.setParameter(name, params.get(name));
}
}
if (singleResult) {
return (T) query.getSingleResult();
}
return (T) query.getResultList();
}
public boolean isOpen() {
if (this.em == null) {
return false;
}
return this.em.isOpen();
}
public void joinTransaction() {
if (this.em == null) {
return;
}
this.em.joinTransaction();
}
public void close(boolean txOwner, boolean emOwner) {
check();
if (txOwner) {
this.em.clear();
}
if (emOwner) {
this.em.close();
}
}
protected void check() {
if (em == null || !em.isOpen()) {
throw new IllegalStateException("Entity manager is null or is closed, exiting...");
}
}
@Override
public String getName() {
return this.getClass().getName();
}
@Override
public Object get(String identifier) {
return null;
}
@Override
public void set(String identifier, Object value) {
}
@Override
public void remove(String identifier) {
}
@Override
public boolean has( String identifier ) {
return false;
}
}