blob: f12858edae4f0a218da3599c6be8ce9e9a704f34 [file] [log] [blame]
/**
* Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Florian Pirchner - Initial implementation
*/
package org.eclipse.osbp.dsl.dto.lib.services.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.LockModeType;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.validation.ConstraintViolationException;
import org.eclipse.osbp.dsl.dto.lib.IMapper;
import org.eclipse.osbp.dsl.dto.lib.IMapperAccess;
import org.eclipse.osbp.dsl.dto.lib.MappingContext;
import org.eclipse.osbp.jpa.services.JPQL;
import org.eclipse.osbp.jpa.services.Query;
import org.eclipse.osbp.jpa.services.history.HistorizedObjectWrapper;
import org.eclipse.osbp.jpa.services.metadata.EntityDelegate;
import org.eclipse.osbp.runtime.common.annotations.DtoUtils;
import org.eclipse.osbp.runtime.common.filter.DtoServiceException;
import org.eclipse.osbp.runtime.common.filter.IFilterEnhancer;
import org.eclipse.osbp.runtime.common.filter.IJPQL;
import org.eclipse.osbp.runtime.common.filter.IQuery;
import org.eclipse.osbp.runtime.common.session.ISessionManager;
import org.eclipse.osbp.runtime.common.session.ITransactionHandler;
import org.eclipse.osbp.runtime.common.state.ISharedStateContext;
import org.eclipse.osbp.runtime.common.util.BeanUtils;
import org.eclipse.osbp.runtime.common.validation.IStatus;
import org.eclipse.osbp.runtime.common.validation.IValidationParticipant;
import org.eclipse.osbp.runtime.common.validation.ValidationKind;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.sessions.Session;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Class AbstractDTOService.
*
* @param <DTO>
* the generic type
* @param <ENTITY>
* the generic type
*/
@SuppressWarnings("all")
public abstract class AbstractDTOService<DTO, ENTITY>
implements org.eclipse.osbp.runtime.common.filter.IDTOService<DTO>,
ServiceTrackerCustomizer<EntityManagerFactory, EntityManagerFactory> {
protected static Logger LOGGER = LoggerFactory.getLogger(AbstractDTOService.class);
private static final String FILTER__EMF = "(objectClass=javax.persistence.EntityManagerFactory)";
private static final String FILTER__EMF_WITH_PERSISTENCE = "(&(objectClass=javax.persistence.EntityManagerFactory)(osgi.unit.name=%s))";
/** The emf. */
protected EntityManagerFactory emf;
/** The mapper access. */
protected IMapperAccess mapperAccess;
protected ISessionManager sessionManager;
/** The validators. */
protected HashSet<IValidationParticipant> validators = new HashSet<IValidationParticipant>();
/** The filter enhancers. */
protected HashSet<IFilterEnhancer> filterEnhancers = new HashSet<IFilterEnhancer>();
private ServiceTracker<EntityManagerFactory, EntityManagerFactory> emfTracker;
private ComponentContext context;
private String persistenceId;
public String getPersistenceId() {
return persistenceId;
}
public void setPersistenceId(String persistenceId) {
this.persistenceId = persistenceId;
if (context != null) {
internalReset();
}
}
//
// OSGI Infrastructure
//
/**
* Called by OSGi-DS to activate the service.
*
* @param context
*/
protected void activate(ComponentContext context) throws Exception {
this.context = context;
internalActivate();
}
protected void internalActivate() throws InvalidSyntaxException {
if (emfTracker == null) {
emfTracker = new ServiceTracker<EntityManagerFactory, EntityManagerFactory>(
context.getBundleContext(), createEMFFilter(), this);
emfTracker.open();
}
}
/**
* Create the filter to find the proper service.
*
* @return
* @throws InvalidSyntaxException
*/
protected Filter createEMFFilter() throws InvalidSyntaxException {
if (getPersistenceId() == null || getPersistenceId().equals("")) {
return context.getBundleContext().createFilter(FILTER__EMF);
} else {
return context.getBundleContext().createFilter(
String.format(FILTER__EMF_WITH_PERSISTENCE,
getPersistenceId()));
}
}
/**
* Called by OSGi-DS to deactivate the service.
*
* @param context
*/
protected void deactivate(ComponentContext context) {
internalDeactivate();
this.context = null;
}
/**
* Resets the internal state.
*/
protected void internalReset() {
internalDeactivate();
if (context != null) {
try {
internalActivate();
} catch (InvalidSyntaxException e) {
LOGGER.error("{}", e);
}
}
}
protected void internalDeactivate() {
if (emfTracker != null) {
emfTracker.close();
emfTracker = null;
}
}
@Override
public EntityManagerFactory addingService(
ServiceReference<EntityManagerFactory> reference) {
EntityManagerFactory emf = context.getBundleContext().getService(
reference);
if (getEmf() == null) {
bindEmf(emf);
}
return emf;
}
@Override
public void modifiedService(
ServiceReference<EntityManagerFactory> reference,
EntityManagerFactory service) {
// nothing to do
}
@Override
public void removedService(
ServiceReference<EntityManagerFactory> reference,
EntityManagerFactory service) {
if (getEmf() == service) {
unbindEmf(getEmf());
}
}
/**
* Returns a new instance of JPQL.
*
* @param lgpl
* @param params
* @return
*/
public static JPQL createJPQL(String lgpl, Map<String, Object> params) {
return JPQL.create(lgpl, params);
}
/**
* Gets the dto class.
*
* @return the dto class
*/
protected abstract Class<DTO> getDtoClass();
/**
* Gets the entity class.
*
* @return the entity class
*/
protected abstract Class<ENTITY> getEntityClass();
/**
* Gets the id.
*
* @param dto
* the dto
* @return the id
*/
public abstract Object getId(DTO dto);
public boolean isIgnoreHistorizedFilter() {
return true;
}
public void setIgnoreHistorizedFilter(boolean ignoreHistorizedFilter) {
}
public DTO get(final Object id) {
return get(id, null, LockModeType.NONE);
}
/**
* Gets the DTO.
*
* @param id
* the id
* @return the dto
*/
public DTO get(final Object id, Object ui, LockModeType lockModeType) {
// if id is filtered - return null
if(!checkGet(getEntityClass(), id)) {
return null;
}
javax.persistence.EntityManager em = getEntityManager(ui);
EntityDelegate<ENTITY> delegate = new EntityDelegate<ENTITY>(getEntityClass(), em, 1);
// find the entity
DTO result = null;
try {
ENTITY entity = delegate.getEntity(id, lockModeType);
if (entity != null) {
IMapper<DTO, ENTITY> mapper = findToDtoMapper(getDtoClass(), (Class<ENTITY>) entity.getClass());
MappingContext mappingContext = createMappingContext();
try {
mappingContext.increaseLevel();
result = mapSingle(entity, mapper, mappingContext);
mappingContext.decreaseLevel();
mappingContext.flush();
} finally {
mappingContext.unmakeCurrent();
}
}
} finally {
closeEntityManager(em, ui);
}
return result;
}
/**
* Map single.
*
* @param entity
* the entity
* @param mapper
* the mapper
* @param context
* the context
* @return the dto
*/
protected DTO mapSingle(ENTITY entity, IMapper<DTO, ENTITY> mapper, MappingContext context) {
DTO result;
try {
context.increaseLevel();
DTO cached = context.get(mapper.createDtoHash(entity));
if (cached != null) {
result = cached;
} else {
DTO dto = mapper.createDto();
mapper.mapToDTO(dto, entity, context);
result = dto;
}
} finally {
context.decreaseLevel();
}
return result;
}
/**
* See {@link IMapperAccess#getToDtoMapper(Class, Class)}.
*
* @param dtoClass
* the dto class
* @param entityClass
* the entity class
* @return the i mapper
*/
protected IMapper<DTO, ENTITY> findToDtoMapper(Class<DTO> dtoClass, Class<ENTITY> entityClass) {
return (IMapper<DTO, ENTITY>) mapperAccess.getToDtoMapper(dtoClass, entityClass);
}
/**
* See {@link IMapperAccess#getToEntityMapper(Class, Class)}.
*
* @param dtoClass
* the dto class
* @param entityClass
* the entity class
* @return the i mapper
*/
protected IMapper<DTO, ENTITY> findToEntityMapper(Class<DTO> dtoClass, Class<ENTITY> entityClass) {
return (IMapper<DTO, ENTITY>) mapperAccess.getToEntityMapper(dtoClass, entityClass);
}
/**
* {@inheritDoc}.
*
* @param query
* the query
* @return the collection
*/
public Collection<DTO> find(final IQuery query) {
return find(query, null, LockModeType.NONE);
}
public Collection<DTO> find(final IQuery query, Object ui, LockModeType lockModeType) {
enhanceFilter(query);
javax.persistence.EntityManager em = getEntityManager(ui);
EntityDelegate<ENTITY> delegate = new EntityDelegate<ENTITY>(getEntityClass(), em, PROP_MAX_COLLECTION_CONTENT);
List<DTO> result = new ArrayList<DTO>();
try {
MappingContext mappingContext = createMappingContext();
try {
mappingContext.increaseLevel();
for (ENTITY entity : delegate.getAllEntities(query, lockModeType)) {
IMapper<DTO, ENTITY> mapper = findToDtoMapper(getDtoClass(), (Class<ENTITY>) entity.getClass());
result.add(mapSingle(entity, mapper, mappingContext));
}
mappingContext.decreaseLevel();
mappingContext.flush();
} finally {
mappingContext.unmakeCurrent();
}
} finally {
closeEntityManager(em, ui);
}
return result;
}
/**
* {@inheritDoc}.
*
* @param query
* the query
* @param startindex
* the startindex
* @return the collection
*/
public Collection<DTO> find(final IQuery query, final int startindex) {
return find(query, null, LockModeType.NONE);
}
public Collection<DTO> find(final IQuery query, final int startindex, Object ui, LockModeType lockModeType) {
enhanceFilter(query);
javax.persistence.EntityManager em = getEntityManager(ui);
EntityDelegate<ENTITY> delegate = new EntityDelegate<ENTITY>(getEntityClass(), em, PROP_MAX_COLLECTION_CONTENT);
List<DTO> result = new ArrayList<DTO>();
try {
MappingContext mappingContext = createMappingContext();
try {
mappingContext.increaseLevel();
for (ENTITY entity : delegate.getAllEntities(query, startindex, lockModeType)) {
IMapper<DTO, ENTITY> mapper = findToDtoMapper(getDtoClass(), (Class<ENTITY>) entity.getClass());
result.add(mapSingle(entity, mapper, mappingContext));
}
mappingContext.decreaseLevel();
mappingContext.flush();
} finally {
mappingContext.unmakeCurrent();
}
} finally {
closeEntityManager(em, ui);
}
return result;
}
@Override
public Collection<DTO> findDtos(IJPQL jpql) {
javax.persistence.EntityManager em = getEntityManager(null);
EntityDelegate<ENTITY> delegate = new EntityDelegate<ENTITY>(getEntityClass(), em, PROP_MAX_COLLECTION_CONTENT);
List<DTO> result = new ArrayList<DTO>();
try {
MappingContext mappingContext = createMappingContext();
try {
mappingContext.increaseLevel();
for (ENTITY entity : delegate.getAllEntities(jpql)) {
IMapper<DTO, ENTITY> mapper = findToDtoMapper(getDtoClass(), (Class<ENTITY>) entity.getClass());
result.add(mapSingle(entity, mapper, mappingContext));
}
mappingContext.decreaseLevel();
mappingContext.flush();
} finally {
mappingContext.unmakeCurrent();
}
} finally {
closeEntityManager(em, null);
}
return result;
}
@Override
public List<?> findValues(IJPQL jpql) {
javax.persistence.EntityManager em = getEntityManager(null);
EntityDelegate<ENTITY> delegate = new EntityDelegate<ENTITY>(getEntityClass(), em, PROP_MAX_COLLECTION_CONTENT);
try {
return delegate.getAllValues(jpql);
} finally {
closeEntityManager(em, null);
}
}
@Override
public void persist(final Object dto) {
update((DTO)dto);
}
/**
* {@inheritDoc}.
*
* @param dto
* the dto
*/
@Override
public void update(final DTO dto) {
TransactionHandler txn = null;
try {
if (emf != null) {
txn = new TransactionHandler(emf, sessionManager);
} else {
throw new NullPointerException("The emf for dto " + dto.getClass().getName() + " is null!");
}
ENTITY entity = null;
MappingContext entityMappingContext = new MappingContext();
entityMappingContext.makeCurrent();
entityMappingContext.setEntityManager(txn.getEntityManager());
// do not resolve any dto-lazyloading-list during mapping
entityMappingContext.setNoCollectionResolving(true);
try {
txn.begin();
/*
* Map the entity to the dto and merge the entity
*/
IMapper<DTO, ENTITY> toEntityMapper = findToEntityMapper((Class<DTO>) dto.getClass(),
(Class<ENTITY>) getEntityClass());
Object id = getId(dto);
if (!(id instanceof Integer) || ((Integer) id).intValue() != 0) {
entity = txn.getEntityManager().find(getEntityClass(), id);
if (entity == null) {
entity = toEntityMapper.createEntity();
}
} else {
entity = toEntityMapper.createEntity();
}
// map dto to entity and persist
toEntityMapper.mapToEntity(dto, entity, entityMappingContext);
entity = doHistorized(txn, entity);
txn.getEntityManager().persist(entity);
if (entity != null && id instanceof Integer && ((Integer) id).intValue() == 0) {
Object newId = new EntityDelegate<ENTITY>(getEntityClass(), txn.getEntityManager(), PROP_MAX_COLLECTION_CONTENT)
.getIdentifier(entity);
DtoUtils.setIdValue(dto, newId);
}
} finally {
entityMappingContext.unmakeCurrent();
}
txn.commit();
} catch (NamingException e) {
throw new ExceptionConverter().convertException(e);
} catch (NotSupportedException e) {
throw new ExceptionConverter().convertException(e);
} catch (SystemException e) {
throw new ExceptionConverter().convertException(e);
} catch (IllegalStateException e) {
throw new ExceptionConverter().convertException(e);
} catch (SecurityException e) {
throw new ExceptionConverter().convertException(e);
} catch (HeuristicMixedException e) {
throw new ExceptionConverter().convertException(e);
} catch (HeuristicRollbackException e) {
throw new ExceptionConverter().convertException(e);
} catch (RollbackException e) {
throw new ExceptionConverter().convertException(e);
} catch (NullPointerException e) {
throw new ExceptionConverter().convertException(e);
} catch (ConstraintViolationException e) {
throw new ExceptionConverter().convertException(e);
} finally {
if (txn != null) {
txn.dispose();
}
}
}
private ENTITY doHistorized(ITransactionHandler txn, ENTITY entity) {
// if historized, then update the id_validFrom
//
if(BeanUtils.isHistorized(entity.getClass())) {
txn.getEntityManager().detach(entity);
Session session = txn.getEntityManager().unwrap(Session.class);
ClassDescriptor descriptor = session.getClassDescriptor(entity.getClass());
Object oldEntity = entity;
try {
entity = (ENTITY) oldEntity.getClass().newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
descriptor.getObjectBuilder().copyInto(oldEntity, entity);
HistorizedObjectWrapper entityWrapper = new HistorizedObjectWrapper(
descriptor, entity);
entityWrapper.setCurrentHist(true);
entityWrapper.setId_ValidFrom(new Date().getTime());
}
return entity;
}
/**
* {@inheritDoc}.
*
* @param dto
* the dto
* @return the dto
*/
public DTO reload(final DTO dto) {
Object id = getId(dto);
return get(id);
}
/**
* Removes the dto with the given key from the dirty state cache.
*
* @param dtoKey
* the dto key
* @param affectedDto
* the affected dto
* @param sharedState
* the shared state
*/
private void removeFromDirtyState(Object dtoKey, Object affectedDto, ISharedStateContext sharedState) {
sharedState.makeUndirty(dtoKey, affectedDto);
}
/**
* Removes the dto with the given key from the dirty state cache.
*
* @param dtoKey
* the dto key
* @param affectedDto
* the affected dto
* @param sharedState
* the shared state
*/
private void removeFromSharedState(Object dtoKey, Object affectedDto, ISharedStateContext sharedState) {
// try to dispose the dto. Will remove it from caches automatically.
if (!DtoUtils.invokeDisposeMethod(affectedDto)) {
sharedState.getDirtyState().invalidate(dtoKey);
sharedState.getGlobalDataState().invalidate(dtoKey);
}
}
/**
* {@inheritDoc}.
*
* @param dto
* the dto
* @throws DtoServiceException
* the dto service exception
*/
public void delete(final DTO dto) throws DtoServiceException {
TransactionHandler txn = new TransactionHandler(emf, sessionManager);
try {
try {
txn.begin();
ENTITY entity = txn.getEntityManager().find(getEntityClass(), getId(dto));
if (entity != null) {
txn.getEntityManager().remove(entity);
}
try {
txn.commit();
} catch (Exception e) {
throw new ExceptionConverter().convertException(e);
}
} catch (NamingException e) {
throw new ExceptionConverter().convertException(e);
} catch (NotSupportedException e) {
throw new ExceptionConverter().convertException(e);
} catch (SystemException e) {
throw new ExceptionConverter().convertException(e);
} finally {
txn.dispose();
}
} finally {
}
}
/**
* Binds the service {@link IMapperAccess} to this component. <br>
* The cardinality is ONE_TO_ONE
*
* @param mapperAccess
* the mapper access
*/
protected void bindMapperAccess(final IMapperAccess mapperAccess) {
this.mapperAccess = mapperAccess;
}
/**
* Unbinds the service from this component. <br>
* The cardinality is ONE_TO_ONE
*
* @param mapperAccess
* the mapper access
*/
protected void unbindMapperAccess(final IMapperAccess mapperAccess) {
this.mapperAccess = null;
}
/**
* Binds the service {@link javax.persistence.EntityManagerFactory} to this
* component. <br>
* The cardinality is ONE_TO_ONE
*
* @param emf
* the service
*/
protected void bindEmf(final EntityManagerFactory emf) {
this.emf = emf;
}
/**
* Unbinds the service from this component. <br>
* The cardinality is ONE_TO_ONE
*
* @param emf
* the service
*/
protected void unbindEmf(final EntityManagerFactory emf) {
this.emf = null;
}
protected void bindSessionManager(final ISessionManager sessionManager) {
this.sessionManager = sessionManager;
}
protected void unbindSessionManager(final ISessionManager sessionManager) {
this.sessionManager = null;
}
/**
* Adds a new validation participant to the service.
*
* @param validator
* the validator
*/
protected void addValidationParticipant(IValidationParticipant validator) {
validators.add(validator);
}
/**
* Removes a validation participant from the service.
*
* @param validator
* the validator
*/
protected void removeValidationParticipant(IValidationParticipant validator) {
validators.remove(validator);
}
/**
* Gets the emf.
*
* @return the emf
*/
protected EntityManagerFactory getEmf() {
return emf;
}
@Override
public int size(IQuery query) {
return size(query, null, LockModeType.NONE);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.osbp.dsl.dto.lib.services.IDTOService#size(org.eclipse.osbp
* .dsl.dto.lib.services.IQuery)
*/
@Override
public int size(IQuery query, Object ui, LockModeType lockModeType) {
enhanceFilter(query);
EntityManager em = getEntityManager(ui);
EntityDelegate<ENTITY> delegate = new EntityDelegate<ENTITY>(getEntityClass(), em, 1);
int result = -1;
try {
result = delegate.getEntityCount(query, lockModeType);
} finally {
closeEntityManager(em, ui);
}
return result;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.osbp.dsl.dto.lib.services.IDTOService#contains(java.lang.
* Object, org.eclipse.osbp.dsl.dto.lib.services.IQuery)
*/
@Override
public boolean contains(Object dto, IQuery query, Object ui, LockModeType lockModeType) {
enhanceFilter(query);
EntityManager em = getEntityManager(ui);
EntityDelegate<ENTITY> delegate = new EntityDelegate<ENTITY>(getEntityClass(), em, 1);
boolean result = false;
try {
result = delegate.containsEntityIdentifier(dto, query, lockModeType);
} finally {
closeEntityManager(em, ui);
}
return result;
}
@Override
public boolean contains(IQuery query, Object ui, LockModeType lockModeType) {
enhanceFilter(query);
EntityManager em = getEntityManager(ui);
EntityDelegate<ENTITY> delegate = new EntityDelegate<ENTITY>(getEntityClass(), em, 1);
boolean result = false;
try {
result = delegate.getEntityCount(query, lockModeType) > 0;
} finally {
closeEntityManager(em, ui);
}
return result;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.dsl.dto.lib.services.IDTOService#getNext(java.lang.
* Object , org.eclipse.osbp.dsl.dto.lib.services.IQuery)
*/
@Override
public DTO getNext(DTO dto, IQuery query, Object ui, LockModeType lockModeType) {
enhanceFilter(query);
javax.persistence.EntityManager em = getEntityManager(ui);
EntityDelegate<ENTITY> delegate = new EntityDelegate<ENTITY>(getEntityClass(), em, 1);
DTO result = null;
try {
ENTITY entity = delegate.getNextEntity(getId(dto), query, lockModeType);
if (entity != null) {
IMapper<DTO, ENTITY> mapper = findToDtoMapper(getDtoClass(), (Class<ENTITY>) entity.getClass());
MappingContext mappingContext = createMappingContext();
try {
mappingContext.increaseLevel();
result = mapSingle(entity, mapper, mappingContext);
mappingContext.decreaseLevel();
mappingContext.flush();
} finally {
mappingContext.unmakeCurrent();
}
}
} finally {
closeEntityManager(em, ui);
}
return result;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.osbp.dsl.dto.lib.services.IDTOService#getPrevious(java.lang
* .Object, org.eclipse.osbp.dsl.dto.lib.services.IQuery)
*/
@Override
public DTO getPrevious(DTO dto, IQuery query, Object ui, LockModeType lockModeType) {
enhanceFilter(query);
javax.persistence.EntityManager em = getEntityManager(ui);
EntityDelegate<ENTITY> delegate = new EntityDelegate<ENTITY>(getEntityClass(), em, 1);
DTO result = null;
try {
ENTITY entity = delegate.getPreviousEntity(getId(dto), query, lockModeType);
if (entity != null) {
IMapper<DTO, ENTITY> mapper = findToDtoMapper(getDtoClass(), (Class<ENTITY>) entity.getClass());
MappingContext mappingContext = createMappingContext();
try {
mappingContext.increaseLevel();
result = mapSingle(entity, mapper, mappingContext);
mappingContext.decreaseLevel();
mappingContext.flush();
} finally {
mappingContext.unmakeCurrent();
}
}
} finally {
closeEntityManager(em, ui);
}
return result;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.runtime.common.filter.IDTOService#getFirst(org.eclipse.osbp.runtime.common.filter.IQuery)
*/
@Override
public DTO getFirst(IQuery query) {
return getFirst(query, null, LockModeType.NONE);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.osbp.dsl.dto.lib.services.IDTOService#getFirst(org.eclipse
* .osbp.dsl.dto.lib.services.IQuery)
*/
@Override
public DTO getFirst(IQuery query, Object ui, LockModeType lockModeType) {
enhanceFilter(query);
javax.persistence.EntityManager em = getEntityManager(ui);
EntityDelegate<ENTITY> delegate = new EntityDelegate<ENTITY>(getEntityClass(), em, 1);
DTO result = null;
try {
ENTITY entity = delegate.getFirstEntity(query, lockModeType);
if (entity != null) {
IMapper<DTO, ENTITY> mapper = findToDtoMapper(getDtoClass(), (Class<ENTITY>) entity.getClass());
MappingContext mappingContext = createMappingContext();
try {
mappingContext.increaseLevel();
result = mapSingle(entity, mapper, mappingContext);
mappingContext.decreaseLevel();
mappingContext.flush();
} finally {
mappingContext.unmakeCurrent();
}
}
} finally {
closeEntityManager(em, ui);
}
return result;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.runtime.common.filter.IDTOService#getLast(org.eclipse.osbp.runtime.common.filter.IQuery)
*/
@Override
public DTO getLast(IQuery query) {
return getLast(query, null, LockModeType.NONE);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.osbp.dsl.dto.lib.services.IDTOService#getLast(org.eclipse
* .osbp.dsl.dto.lib.services.IQuery)
*/
@Override
public DTO getLast(IQuery query, Object ui, LockModeType lockModeType) {
enhanceFilter(query);
javax.persistence.EntityManager em = getEntityManager(ui);
EntityDelegate<ENTITY> delegate = new EntityDelegate<ENTITY>(getEntityClass(), em, 1);
DTO result = null;
try {
ENTITY entity = delegate.getLastEntity(query, lockModeType);
if (entity != null) {
IMapper<DTO, ENTITY> mapper = findToDtoMapper(getDtoClass(), (Class<ENTITY>) entity.getClass());
MappingContext mappingContext = createMappingContext();
try {
mappingContext.increaseLevel();
result = mapSingle(entity, mapper, mappingContext);
mappingContext.decreaseLevel();
mappingContext.flush();
} finally {
mappingContext.unmakeCurrent();
}
}
} finally {
closeEntityManager(em, ui);
}
return result;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.dsl.dto.lib.services.IDTOService#isFirst(java.lang.
* Object , org.eclipse.osbp.dsl.dto.lib.services.IQuery)
*/
@Override
public boolean isFirst(DTO dto, IQuery query) {
return isFirst(dto, query, null, LockModeType.NONE);
}
@Override
public boolean isFirst(DTO dto, IQuery query, Object ui, LockModeType lockModeType) {
enhanceFilter(query);
javax.persistence.EntityManager em = getEntityManager(ui);
EntityDelegate<ENTITY> delegate = new EntityDelegate<ENTITY>(getEntityClass(), em, 1);
List<DTO> result = new ArrayList<DTO>();
try {
String firstId = (String) delegate.getFirstEntityIdentifier(query, lockModeType);
if (firstId != null && firstId.equals(getId(dto))) {
return true;
}
} finally {
closeEntityManager(em, ui);
}
return false;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.osbp.dsl.dto.lib.services.IDTOService#isLast(java.lang.Object
* , org.eclipse.osbp.dsl.dto.lib.services.IQuery)
*/
@Override
public boolean isLast(DTO dto, IQuery query) {
return isLast(dto, query, null, LockModeType.NONE);
}
@Override
public boolean isLast(DTO dto, IQuery query, Object ui, LockModeType lockModeType) {
enhanceFilter(query);
javax.persistence.EntityManager em = getEntityManager(ui);
EntityDelegate<ENTITY> delegate = new EntityDelegate<ENTITY>(getEntityClass(), em, 1);
List<DTO> result = new ArrayList<DTO>();
try {
String lastId = (String) delegate.getLastEntityIdentifier(query, lockModeType);
if (lastId != null && lastId.equals(getId(dto))) {
return true;
}
} finally {
closeEntityManager(em, ui);
}
return false;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.dsl.dto.lib.services.IDTOService#indexOf(java.lang.
* Object , org.eclipse.osbp.dsl.dto.lib.services.IQuery)
*/
@Override
public int indexOf(DTO dto, IQuery query) {
return 1;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.runtime.common.filter.IDTOService#getByIndex(int, org.eclipse.osbp.runtime.common.filter.IQuery)
*/
@Override
public DTO getByIndex(int index, IQuery query) {
return getByIndex(index, query, null, LockModeType.NONE);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.dsl.dto.lib.services.IDTOService#getByIndex(int,
* org.eclipse.osbp.dsl.dto.lib.services.IQuery)
*/
@Override
public DTO getByIndex(int index, IQuery query, Object ui, LockModeType lockModeType) {
enhanceFilter(query);
javax.persistence.EntityManager em = getEntityManager(ui);
EntityDelegate<ENTITY> delegate = new EntityDelegate<ENTITY>(getEntityClass(), em, 1);
DTO result = null;
try {
MappingContext mappingContext = createMappingContext();
try {
mappingContext.increaseLevel();
for (ENTITY entity : delegate.getAllEntities(query, index, lockModeType)) {
IMapper<DTO, ENTITY> mapper = findToDtoMapper(getDtoClass(), (Class<ENTITY>) entity.getClass());
result = mapSingle(entity, mapper, mappingContext);
break;
}
mappingContext.decreaseLevel();
mappingContext.flush();
} finally {
mappingContext.unmakeCurrent();
}
} finally {
closeEntityManager(em, ui);
}
return result;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.runtime.common.filter.IDTOService#getByIndex(int, int, org.eclipse.osbp.runtime.common.filter.IQuery)
*/
@Override
public List<DTO> getByIndex(int startIndex, int numberOfItems, IQuery query) {
return getByIndex(startIndex, numberOfItems, query, null, LockModeType.NONE);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.dsl.dto.lib.services.IDTOService#getByIndex(int,
* int, org.eclipse.osbp.dsl.dto.lib.services.IQuery)
*/
@Override
public List<DTO> getByIndex(int startIndex, int numberOfItems, IQuery query, Object ui, LockModeType lockModeType) {
enhanceFilter(query);
javax.persistence.EntityManager em = getEntityManager(ui);
EntityDelegate<ENTITY> delegate = new EntityDelegate<ENTITY>(getEntityClass(), em, numberOfItems);
List<DTO> result = new ArrayList<DTO>();
try {
MappingContext mappingContext = createMappingContext();
try {
mappingContext.increaseLevel();
for (ENTITY entity : delegate.getAllEntities(query, startIndex, lockModeType)) {
IMapper<DTO, ENTITY> mapper = findToDtoMapper(getDtoClass(), (Class<ENTITY>) entity.getClass());
result.add(mapSingle(entity, mapper, mappingContext));
}
mappingContext.decreaseLevel();
mappingContext.flush();
} finally {
mappingContext.unmakeCurrent();
}
} finally {
closeEntityManager(em, ui);
}
return result;
}
/**
* Creates the mapping context.
*
* @return the mapping context
*/
protected MappingContext createMappingContext() {
if (MappingContext.getCurrent() != null) {
MappingContext current = MappingContext.getCurrent();
// do resolve dto-lazyloading-list during mapping again
current.setNoCollectionResolving(false);
// call make current to ensure mapping levels
current.makeCurrent();
return current;
}
// call make current is internally done
MappingContext current = new MappingContext();
current.makeCurrent();
return current;
}
/**
* Enhance filter.
*
* @param query
* the query
*/
protected void enhanceFilter(IQuery query) {
Map<String, Object> queryMap = query.getMap();
List<Class> entityClasses = (List<Class>) queryMap.get(Query.ENTITY_CLASSES_KEY);
entityClasses = ((entityClasses != null) ? entityClasses : new ArrayList<Class>());
entityClasses.add(getEntityClass());
queryMap.put(Query.ENTITY_CLASSES_KEY, entityClasses);
if (filterEnhancers != null) {
for (IFilterEnhancer filterEnhancer : filterEnhancers) {
filterEnhancer.enhanceQuery(query);
}
}
}
/**
* Check if get is possible regarding the filters
*
* @param entityClass the entity class
* @param id the id
* @return true, if successful
*/
protected boolean checkGet(Class<ENTITY> entityClass, Object id) {
if (filterEnhancers != null) {
for (IFilterEnhancer filterEnhancer : filterEnhancers) {
if(!filterEnhancer.checkGet(entityClass, id)) {
return false;
}
}
}
return true;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.osbp.dsl.dto.lib.services.IDTOService#validate(java.lang.
* Object, org.eclipse.osbp.runtime.common.validation.ValidationKind,
* java.util.Map)
*/
@Override
public Set<IStatus> validate(DTO object, ValidationKind kind, Map<String, Object> properties) {
if (validators == null) {
return Collections.emptySet();
}
Set<IStatus> result = new HashSet<IStatus>();
for (IValidationParticipant val : validators) {
Set<IStatus> tempResult = val.validate(object, kind, properties);
if (tempResult != null) {
result.addAll(tempResult);
}
}
return result;
}
/**
* Adds the filter enhancer
* {@link org.eclipse.osbp.runtime.common.filter.IFilterEnhancer} to this
* service. <br>
*
* @param filterEnhancer
* the filter enhancer
*/
protected synchronized void addFilterEnhancer(final IFilterEnhancer filterEnhancer) {
filterEnhancers.add(filterEnhancer);
}
/**
* Removes the filter enhancer
* {@link org.eclipse.osbp.runtime.common.filter.IFilterEnhancer} from this
* service. <br>
*
* @param filterEnhancer
* the filter enhancer
*/
protected synchronized void removeFilterEnhancer(final IFilterEnhancer filterEnhancer) {
filterEnhancers.remove(filterEnhancer);
}
@Override
public boolean transactionBegin(Object ui) {
TransactionHandler txn = new TransactionHandler(emf, sessionManager);
sessionManager.setTransactionHandler(ui, txn);
// txn.setEntityMappingContext(entityMappingContext);
try {
txn.begin();
} catch (NamingException e) {
return false;
// throw new ExceptionConverter().convertException(e);
} catch (NotSupportedException e) {
return false;
// throw new ExceptionConverter().convertException(e);
} catch (SystemException e) {
return false;
// throw new ExceptionConverter().convertException(e);
}
return true;
}
@Override
public boolean transactionCommit(Object ui) {
ITransactionHandler txn = sessionManager.getTransactionHandler(ui);
if(txn != null) {
try {
txn.commit();
} catch (SystemException e) {
return false;
// throw new ExceptionConverter().convertException(e);
} catch (IllegalStateException e) {
return false;
// throw new ExceptionConverter().convertException(e);
} catch (SecurityException e) {
return false;
// throw new ExceptionConverter().convertException(e);
} catch (HeuristicMixedException e) {
return false;
// throw new ExceptionConverter().convertException(e);
} catch (HeuristicRollbackException e) {
return false;
// throw new ExceptionConverter().convertException(e);
} catch (RollbackException e) {
return false;
// throw new ExceptionConverter().convertException(e);
}
sessionManager.disposeTransactionHandler(ui);
}
return true;
}
@Override
public boolean transactionRollback(Object ui) {
ITransactionHandler txn = sessionManager.getTransactionHandler(ui);
if(txn != null) {
try {
txn.rollback();
} catch (SystemException e) {
return false;
// throw new ExceptionConverter().convertException(e);
} catch (IllegalStateException e) {
return false;
// throw new ExceptionConverter().convertException(e);
} catch (SecurityException e) {
return false;
// throw new ExceptionConverter().convertException(e);
}
sessionManager.disposeTransactionHandler(ui);
}
return true;
}
@Override
public boolean update(DTO dto, Object ui, LockModeType lockModeType) {
ITransactionHandler txn = sessionManager.getTransactionHandler(ui);
if(txn != null) {
MappingContext entityMappingContext = new MappingContext();
entityMappingContext.makeCurrent();
entityMappingContext.setEntityManager(txn.getEntityManager());
// do not resolve any dto-lazyloading-list during mapping
entityMappingContext.setNoCollectionResolving(true);
try {
ENTITY entity = null;
/*
* Map the entity to the dto and merge the entity
*/
IMapper<DTO, ENTITY> toEntityMapper = findToEntityMapper((Class<DTO>) dto.getClass(),
(Class<ENTITY>) getEntityClass());
Object id = getId(dto);
if (!(id instanceof Integer) || ((Integer) id).intValue() != 0) {
entity = txn.getEntityManager().find(getEntityClass(), id, lockModeType);
if (entity == null) {
entity = toEntityMapper.createEntity();
}
} else {
entity = toEntityMapper.createEntity();
}
// map dto to entity and persist
toEntityMapper.mapToEntity(dto, entity, (MappingContext) entityMappingContext);
entity = doHistorized(txn, entity);
txn.getEntityManager().persist(entity);
if (entity != null && id instanceof Integer && ((Integer) id).intValue() == 0) {
Object newId = new EntityDelegate<ENTITY>(getEntityClass(), txn.getEntityManager(), PROP_MAX_COLLECTION_CONTENT)
.getIdentifier(entity);
DtoUtils.setIdValue(dto, newId);
}
} catch (IllegalStateException e) {
return false;
// throw new ExceptionConverter().convertException(e);
} catch (SecurityException e) {
return false;
// throw new ExceptionConverter().convertException(e);
} finally {
entityMappingContext.unmakeCurrent();
}
}
return true;
}
@Override
public boolean insert(DTO dto, Object ui, LockModeType lockModeType) {
ITransactionHandler txn = sessionManager.getTransactionHandler(ui);
if(txn != null) {
MappingContext entityMappingContext = new MappingContext();
entityMappingContext.makeCurrent();
entityMappingContext.setEntityManager(txn.getEntityManager());
// do not resolve any dto-lazyloading-list during mapping
entityMappingContext.setNoCollectionResolving(true);
try {
ENTITY entity = null;
/*
* Map the entity to the dto and persist the entity
*/
IMapper<DTO, ENTITY> toEntityMapper = findToEntityMapper((Class<DTO>) dto.getClass(),
(Class<ENTITY>) getEntityClass());
entity = toEntityMapper.createEntity();
toEntityMapper.mapToEntity(dto, entity, (MappingContext) entityMappingContext);
entity = doHistorized(txn, entity);
txn.getEntityManager().persist(entity);
} catch (IllegalStateException e) {
return false;
// throw new ExceptionConverter().convertException(e);
} catch (SecurityException e) {
return false;
// throw new ExceptionConverter().convertException(e);
}
}
return true;
}
@Override
public boolean delete(final DTO dto, Object ui, LockModeType lockModeType) throws DtoServiceException {
ITransactionHandler txn = sessionManager.getTransactionHandler(ui);
if (txn != null) {
try {
txn.begin();
ENTITY entity = txn.getEntityManager().find(getEntityClass(), getId(dto), lockModeType);
if (entity != null) {
txn.getEntityManager().remove(entity);
}
try {
txn.commit();
} catch (Exception e) {
throw new ExceptionConverter().convertException(e);
}
} catch (NamingException e) {
return false;
// throw new ExceptionConverter().convertException(e);
} catch (NotSupportedException e) {
return false;
// throw new ExceptionConverter().convertException(e);
} catch (SystemException e) {
return false;
// throw new ExceptionConverter().convertException(e);
}
}
return true;
}
protected EntityManager getEntityManager(Object ui) {
if(ui != null) {
ITransactionHandler txn = sessionManager.getTransactionHandler(ui);
if(txn != null) {
return txn.getEntityManager();
} else {
return emf.createEntityManager();
}
} else {
return emf.createEntityManager();
}
}
protected void closeEntityManager(EntityManager em, Object ui) {
if(ui == null) {
em.close();
em = null;
}
}
@Override
public boolean contains(Object dto, IQuery query) {
return contains(dto, query, null, LockModeType.NONE);
}
@Override
public boolean contains(IQuery query) {
return contains(query, null, LockModeType.NONE);
}
@Override
public DTO getNext(DTO dto, IQuery query) {
return getNext(dto, query, null, LockModeType.NONE);
}
@Override
public DTO getPrevious(DTO dto, IQuery query) {
return getPrevious(dto, query, null, LockModeType.NONE);
}
}