/*
* #%L
* BroadleafCommerce Open Admin Platform
* %%
* Copyright (C) 2009 - 2013 Broadleaf Commerce
* %%
* 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.
* #L%
*/
package org.broadleafcommerce.openadmin.server.service.persistence;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.CompareToBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.broadleafcommerce.common.admin.domain.AdminMainEntity;
import org.broadleafcommerce.common.exception.NoPossibleResultsException;
import org.broadleafcommerce.common.exception.ServiceException;
import org.broadleafcommerce.common.money.Money;
import org.broadleafcommerce.common.presentation.client.OperationType;
import org.broadleafcommerce.openadmin.dto.BasicFieldMetadata;
import org.broadleafcommerce.openadmin.dto.ClassMetadata;
import org.broadleafcommerce.openadmin.dto.CriteriaTransferObject;
import org.broadleafcommerce.openadmin.dto.DynamicResultSet;
import org.broadleafcommerce.openadmin.dto.Entity;
import org.broadleafcommerce.openadmin.dto.FieldMetadata;
import org.broadleafcommerce.openadmin.dto.MergedPropertyType;
import org.broadleafcommerce.openadmin.dto.PersistencePackage;
import org.broadleafcommerce.openadmin.dto.PersistencePerspective;
import org.broadleafcommerce.openadmin.dto.Property;
import org.broadleafcommerce.openadmin.server.dao.DynamicEntityDao;
import org.broadleafcommerce.openadmin.server.security.remote.AdminSecurityServiceRemote;
import org.broadleafcommerce.openadmin.server.security.remote.EntityOperationType;
import org.broadleafcommerce.openadmin.server.security.remote.SecurityVerifier;
import org.broadleafcommerce.openadmin.server.service.ValidationException;
import org.broadleafcommerce.openadmin.server.service.handler.CustomPersistenceHandler;
import org.broadleafcommerce.openadmin.server.service.handler.CustomPersistenceHandlerFilter;
import org.broadleafcommerce.openadmin.server.service.persistence.module.InspectHelper;
import org.broadleafcommerce.openadmin.server.service.persistence.module.PersistenceModule;
import org.broadleafcommerce.openadmin.server.service.persistence.module.RecordHelper;
import org.broadleafcommerce.openadmin.web.form.entity.DynamicEntityFormInfo;
import org.hibernate.mapping.PersistentClass;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
@Component("blPersistenceManager")
@Scope("prototype")
public class PersistenceManagerImpl implements InspectHelper, PersistenceManager, ApplicationContextAware {
private static final Log LOG = LogFactory.getLog(PersistenceManagerImpl.class);
@Resource(name="blDynamicEntityDao")
protected DynamicEntityDao dynamicEntityDao;
@Resource(name="blCustomPersistenceHandlers")
protected List<CustomPersistenceHandler> customPersistenceHandlers = new ArrayList<CustomPersistenceHandler>();
@Resource(name="blCustomPersistenceHandlerFilters")
protected List<CustomPersistenceHandlerFilter> customPersistenceHandlerFilters = new ArrayList<CustomPersistenceHandlerFilter>();
@Resource(name="blTargetEntityManagers")
protected Map<String, String> targetEntityManagers = new HashMap<String, String>();
@Resource(name="blAdminSecurityRemoteService")
protected SecurityVerifier adminRemoteSecurityService;
@Resource(name="blPersistenceModules")
protected PersistenceModule[] modules;
@Resource(name="blPersistenceManagerEventHandlers")
protected List<PersistenceManagerEventHandler> persistenceManagerEventHandlers;
protected TargetModeType targetMode;
protected ApplicationContext applicationContext;
@PostConstruct
public void postConstruct() {
for (PersistenceModule module : modules) {
module.setPersistenceManager(this);
}
Collections.sort(persistenceManagerEventHandlers, new Comparator<PersistenceManagerEventHandler>() {
@Override
public int compare(PersistenceManagerEventHandler o1, PersistenceManagerEventHandler o2) {
return Integer.valueOf(o1.getOrder()).compareTo(Integer.valueOf(o2.getOrder()));
}
});
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public Class<?>[] getAllPolymorphicEntitiesFromCeiling(Class<?> ceilingClass) {
return dynamicEntityDao.getAllPolymorphicEntitiesFromCeiling(ceilingClass);
}
@Override
public Class<?>[] getUpDownInheritance(String testClassname) throws ClassNotFoundException {
return getUpDownInheritance(Class.forName(testClassname));
}
@Override
public Class<?>[] getUpDownInheritance(Class<?> testClass) {
Class<?>[] pEntities = dynamicEntityDao.getAllPolymorphicEntitiesFromCeiling(testClass);
if (ArrayUtils.isEmpty(pEntities)) {
return pEntities;
}
Class<?> topConcreteClass = pEntities[pEntities.length - 1];
List<Class<?>> temp = new ArrayList<Class<?>>(pEntities.length);
temp.addAll(Arrays.asList(pEntities));
Collections.reverse(temp);
boolean eof = false;
while (!eof) {
Class<?> superClass = topConcreteClass.getSuperclass();
PersistentClass persistentClass = dynamicEntityDao.getPersistentClass(superClass.getName());
if (persistentClass == null) {
eof = true;
} else {
temp.add(0, superClass);
topConcreteClass = superClass;
}
}
return temp.toArray(new Class<?>[temp.size()]);
}
@Override
public Class<?>[] getPolymorphicEntities(String ceilingEntityFullyQualifiedClassname) throws ClassNotFoundException {
Class<?>[] entities = getAllPolymorphicEntitiesFromCeiling(Class.forName(ceilingEntityFullyQualifiedClassname));
return entities;
}
@Override
public Map<String, FieldMetadata> getSimpleMergedProperties(String entityName, PersistencePerspective persistencePerspective) {
return dynamicEntityDao.getSimpleMergedProperties(entityName, persistencePerspective);
}
@Override
public ClassMetadata getMergedClassMetadata(final Class<?>[] entities, Map<MergedPropertyType, Map<String, FieldMetadata>> mergedProperties) {
ClassMetadata classMetadata = new ClassMetadata();
classMetadata.setPolymorphicEntities(dynamicEntityDao.getClassTree(entities));
List<Property> propertiesList = new ArrayList<Property>();
for (PersistenceModule module : modules) {
module.extractProperties(entities, mergedProperties, propertiesList);
}
Property[] properties = new Property[propertiesList.size()];
properties = propertiesList.toArray(properties);
Arrays.sort(properties, new Comparator<Property>() {
@Override
public int compare(Property o1, Property o2) {
Integer tabOrder1 = o1.getMetadata().getTabOrder() == null ? 99999 : o1.getMetadata().getTabOrder();
Integer tabOrder2 = o2.getMetadata().getTabOrder() == null ? 99999 : o2.getMetadata().getTabOrder();
Integer groupOrder1 = null;
Integer groupOrder2 = null;
if (o1.getMetadata() instanceof BasicFieldMetadata) {
BasicFieldMetadata b1 = (BasicFieldMetadata) o1.getMetadata();
groupOrder1 = b1.getGroupOrder();
}
groupOrder1 = groupOrder1 == null ? 99999 : groupOrder1;
if (o2.getMetadata() instanceof BasicFieldMetadata) {
BasicFieldMetadata b2 = (BasicFieldMetadata) o2.getMetadata();
groupOrder2 = b2.getGroupOrder();
}
groupOrder2 = groupOrder2 == null ? 99999 : groupOrder2;
Integer fieldOrder1 = o1.getMetadata().getOrder() == null ? 99999 : o1.getMetadata().getOrder();
Integer fieldOrder2 = o2.getMetadata().getOrder() == null ? 99999 : o2.getMetadata().getOrder();
String friendlyName1 = o1.getMetadata().getFriendlyName() == null ? "zzzz" : o1.getMetadata().getFriendlyName();
String friendlyName2 = o2.getMetadata().getFriendlyName() == null ? "zzzz" : o2.getMetadata().getFriendlyName();
String name1 = o1.getName() == null ? "zzzzz" : o1.getName();
String name2 = o2.getName() == null ? "zzzzz" : o2.getName();
return new CompareToBuilder()
.append(tabOrder1, tabOrder2)
.append(groupOrder1, groupOrder2)
.append(fieldOrder1, fieldOrder2)
.append(friendlyName1, friendlyName2)
.append(name1, name2)
.toComparison();
}
});
classMetadata.setProperties(properties);
classMetadata.setCurrencyCode(Money.defaultCurrency().getCurrencyCode());
return classMetadata;
}
@Override
public PersistenceResponse inspect(PersistencePackage persistencePackage) throws ServiceException, ClassNotFoundException {
for (PersistenceManagerEventHandler handler : persistenceManagerEventHandlers) {
PersistenceManagerEventHandlerResponse response = handler.preInspect(this, persistencePackage);
if (PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.HANDLED_BREAK==response.getStatus()) {
break;
}
}
// check to see if there is a custom handler registered
for (CustomPersistenceHandler handler : getCustomPersistenceHandlers()) {
if (handler.canHandleInspect(persistencePackage)) {
if (!handler.willHandleSecurity(persistencePackage)) {
adminRemoteSecurityService.securityCheck(persistencePackage, EntityOperationType.INSPECT);
}
DynamicResultSet results = handler.inspect(persistencePackage, dynamicEntityDao, this);
return executePostInspectHandlers(persistencePackage, new PersistenceResponse().withDynamicResultSet
(results));
}
}
adminRemoteSecurityService.securityCheck(persistencePackage, EntityOperationType.INSPECT);
Class<?>[] entities = getPolymorphicEntities(persistencePackage.getCeilingEntityFullyQualifiedClassname());
Map<MergedPropertyType, Map<String, FieldMetadata>> allMergedProperties = new HashMap<MergedPropertyType, Map<String, FieldMetadata>>();
for (PersistenceModule module : modules) {
module.updateMergedProperties(persistencePackage, allMergedProperties);
}
ClassMetadata mergedMetadata = getMergedClassMetadata(entities, allMergedProperties);
DynamicResultSet results = new DynamicResultSet(mergedMetadata);
return executePostInspectHandlers(persistencePackage, new PersistenceResponse().withDynamicResultSet(results));
}
protected PersistenceResponse executePostInspectHandlers(PersistencePackage persistencePackage,
PersistenceResponse persistenceResponse) throws ServiceException {
for (PersistenceManagerEventHandler handler : persistenceManagerEventHandlers) {
PersistenceManagerEventHandlerResponse response = handler.postInspect(this, persistenceResponse.getDynamicResultSet(), persistencePackage);
if (PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.HANDLED_BREAK==response.getStatus()) {
persistenceResponse.setDynamicResultSet(response.getDynamicResultSet());
if (!MapUtils.isEmpty(response.getAdditionalData())) {
persistenceResponse.getAdditionalData().putAll(response.getAdditionalData());
}
break;
} else if (PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.HANDLED==response.getStatus()) {
persistenceResponse.setDynamicResultSet(response.getDynamicResultSet());
if (!MapUtils.isEmpty(response.getAdditionalData())) {
persistenceResponse.getAdditionalData().putAll(response.getAdditionalData());
}
}
}
return persistenceResponse;
}
@Override
public PersistenceResponse fetch(PersistencePackage persistencePackage, CriteriaTransferObject cto) throws ServiceException {
for (PersistenceManagerEventHandler handler : persistenceManagerEventHandlers) {
PersistenceManagerEventHandlerResponse response = handler.preFetch(this, persistencePackage, cto);
if (PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.HANDLED_BREAK==response.getStatus()) {
break;
}
}
//check to see if there is a custom handler registered
for (CustomPersistenceHandler handler : getCustomPersistenceHandlers()) {
if (handler.canHandleFetch(persistencePackage)) {
if (!handler.willHandleSecurity(persistencePackage)) {
adminRemoteSecurityService.securityCheck(persistencePackage, EntityOperationType.FETCH);
}
DynamicResultSet results = handler.fetch(persistencePackage, cto, dynamicEntityDao, (RecordHelper) getCompatibleModule(OperationType.BASIC));
return executePostFetchHandlers(persistencePackage, cto, new PersistenceResponse().withDynamicResultSet(results));
}
}
adminRemoteSecurityService.securityCheck(persistencePackage, EntityOperationType.FETCH);
PersistenceModule myModule = getCompatibleModule(persistencePackage.getPersistencePerspective().getOperationTypes().getFetchType());
try {
DynamicResultSet results = myModule.fetch(persistencePackage, cto);
return executePostFetchHandlers(persistencePackage, cto, new PersistenceResponse().withDynamicResultSet(results));
} catch (ServiceException e) {
if (e.getCause() instanceof NoPossibleResultsException) {
DynamicResultSet drs = new DynamicResultSet(null, new Entity[] {}, 0);
return executePostFetchHandlers(persistencePackage, cto, new PersistenceResponse().withDynamicResultSet(drs));
}
throw e;
}
}
protected PersistenceResponse executePostFetchHandlers(PersistencePackage persistencePackage, CriteriaTransferObject
cto, PersistenceResponse persistenceResponse) throws ServiceException {
for (PersistenceManagerEventHandler handler : persistenceManagerEventHandlers) {
PersistenceManagerEventHandlerResponse response = handler.postFetch(this, persistenceResponse.getDynamicResultSet(), persistencePackage, cto);
if (PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.HANDLED_BREAK==response.getStatus()) {
persistenceResponse.setDynamicResultSet(response.getDynamicResultSet());
if (!MapUtils.isEmpty(response.getAdditionalData())) {
persistenceResponse.getAdditionalData().putAll(response.getAdditionalData());
}
break;
} else if (PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.HANDLED==response.getStatus()) {
persistenceResponse.setDynamicResultSet(response.getDynamicResultSet());
if (!MapUtils.isEmpty(response.getAdditionalData())) {
persistenceResponse.getAdditionalData().putAll(response.getAdditionalData());
}
}
}
//support legacy api
persistenceResponse.setDynamicResultSet(postFetch(persistenceResponse.getDynamicResultSet(), persistencePackage, cto));
persistenceResponse.getDynamicResultSet().setStartIndex(cto.getFirstResult());
persistenceResponse.getDynamicResultSet().setPageSize(cto.getMaxResults());
return persistenceResponse;
}
/**
* Called after the fetch event
*
* @param resultSet
* @param persistencePackage
* @param cto
* @return the modified result set
* @throws ServiceException
* @deprecated use the PersistenceManagerEventHandler api instead
*/
@Deprecated
protected DynamicResultSet postFetch(DynamicResultSet resultSet, PersistencePackage persistencePackage,
CriteriaTransferObject cto)
throws ServiceException {
return resultSet;
}
@Override
public PersistenceResponse add(PersistencePackage persistencePackage) throws ServiceException {
for (PersistenceManagerEventHandler handler : persistenceManagerEventHandlers) {
PersistenceManagerEventHandlerResponse response = handler.preAdd(this, persistencePackage);
if (PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.HANDLED_BREAK==response.getStatus()) {
break;
}
}
//check to see if there is a custom handler registered
//execute the root PersistencePackage
Entity response;
try {
checkRoot: {
//if there is a validation exception in the root check, let it bubble, as we need a valid, persisted
//entity to execute the subPackage code later
for (CustomPersistenceHandler handler : getCustomPersistenceHandlers()) {
if (handler.canHandleAdd(persistencePackage)) {
if (!handler.willHandleSecurity(persistencePackage)) {
adminRemoteSecurityService.securityCheck(persistencePackage, EntityOperationType.ADD);
}
response = handler.add(persistencePackage, dynamicEntityDao, (RecordHelper) getCompatibleModule(OperationType.BASIC));
break checkRoot;
}
}
adminRemoteSecurityService.securityCheck(persistencePackage, EntityOperationType.ADD);
PersistenceModule myModule = getCompatibleModule(persistencePackage.getPersistencePerspective().getOperationTypes().getAddType());
response = myModule.add(persistencePackage);
}
} catch (ServiceException e) {
if (e.getCause() instanceof ValidationException) {
response = ((ValidationException) e.getCause()).getEntity();
} else {
throw e;
}
}
if (!MapUtils.isEmpty(persistencePackage.getSubPackages())) {
// Once the entity has been saved, we can utilize its id for the subsequent dynamic forms
Class<?> entityClass;
try {
entityClass = Class.forName(response.getType()[0]);
} catch (ClassNotFoundException e) {
throw new ServiceException(e);
}
Map<String, Object> idMetadata = getDynamicEntityDao().getIdMetadata(entityClass);
String idProperty = (String) idMetadata.get("name");
String idVal = response.findProperty(idProperty).getValue();
Map<String, List<String>> subPackageValidationErrors = new HashMap<String, List<String>>();
for (Map.Entry<String,PersistencePackage> subPackage : persistencePackage.getSubPackages().entrySet()) {
Entity subResponse;
try {
subPackage.getValue().getCustomCriteria()[1] = idVal;
//Run through any subPackages -- add up any validation errors
checkHandler: {
for (CustomPersistenceHandler handler : getCustomPersistenceHandlers()) {
if (handler.canHandleAdd(subPackage.getValue())) {
subResponse = handler.add(subPackage.getValue(), dynamicEntityDao, (RecordHelper) getCompatibleModule(OperationType.BASIC));
subPackage.getValue().setEntity(subResponse);
break checkHandler;
}
}
PersistenceModule subModule = getCompatibleModule(subPackage.getValue().getPersistencePerspective().getOperationTypes().getAddType());
subResponse = subModule.add(persistencePackage);
subPackage.getValue().setEntity(subResponse);
}
} catch (ValidationException e) {
subPackage.getValue().setEntity(e.getEntity());
} catch (ServiceException e) {
if (e.getCause() instanceof ValidationException) {
response = ((ValidationException) e.getCause()).getEntity();
} else {
throw e;
}
}
}
//Build up validation errors in all of the subpackages, even those that might not have thrown ValidationExceptions
for (Map.Entry<String, PersistencePackage> subPackage : persistencePackage.getSubPackages().entrySet()) {
for (Map.Entry<String, List<String>> error : subPackage.getValue().getEntity().getPropertyValidationErrors().entrySet()) {
subPackageValidationErrors.put(subPackage.getKey() + DynamicEntityFormInfo.FIELD_SEPARATOR + error.getKey(), error.getValue());
}
}
response.getPropertyValidationErrors().putAll(subPackageValidationErrors);
}
if (response.isValidationFailure()) {
PersistenceResponse validationResponse = executeValidationProcessors(persistencePackage, new PersistenceResponse().withEntity(response));
throw new ValidationException(validationResponse.getEntity(), "The entity has failed validation");
}
return executePostAddHandlers(persistencePackage, new PersistenceResponse().withEntity(response));
}
protected PersistenceResponse executeValidationProcessors(PersistencePackage persistencePackage, PersistenceResponse persistenceResponse) throws ServiceException {
for (PersistenceManagerEventHandler handler : persistenceManagerEventHandlers) {
PersistenceManagerEventHandlerResponse response = handler.processValidationError(this,
persistenceResponse.getEntity(), persistencePackage);
if (PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.HANDLED_BREAK==response.getStatus()) {
persistenceResponse.setEntity(response.getEntity());
if (!MapUtils.isEmpty(response.getAdditionalData())) {
persistenceResponse.getAdditionalData().putAll(response.getAdditionalData());
}
break;
} else if (PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.HANDLED==response.getStatus()) {
persistenceResponse.setEntity(response.getEntity());
if (!MapUtils.isEmpty(response.getAdditionalData())) {
persistenceResponse.getAdditionalData().putAll(response.getAdditionalData());
}
}
}
return persistenceResponse;
}
protected PersistenceResponse executePostAddHandlers(PersistencePackage persistencePackage, PersistenceResponse persistenceResponse) throws ServiceException {
setMainEntityName(persistencePackage, persistenceResponse.getEntity());
for (PersistenceManagerEventHandler handler : persistenceManagerEventHandlers) {
PersistenceManagerEventHandlerResponse response = handler.postAdd(this, persistenceResponse.getEntity(), persistencePackage);
if (PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.HANDLED_BREAK==response.getStatus()) {
persistenceResponse.setEntity(response.getEntity());
if (!MapUtils.isEmpty(response.getAdditionalData())) {
persistenceResponse.getAdditionalData().putAll(response.getAdditionalData());
}
break;
} else if (PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.HANDLED==response.getStatus()) {
persistenceResponse.setEntity(response.getEntity());
if (!MapUtils.isEmpty(response.getAdditionalData())) {
persistenceResponse.getAdditionalData().putAll(response.getAdditionalData());
}
}
}
//support legacy api
persistenceResponse.setEntity(postAdd(persistenceResponse.getEntity(), persistencePackage));
return persistenceResponse;
}
/**
* Called after the add event
*
* @param entity
* @param persistencePackage
* @return the modified Entity instance
* @throws ServiceException
* @deprecated use the PersistenceManagerEventHandler api instead
*/
@Deprecated
protected Entity postAdd(Entity entity, PersistencePackage persistencePackage) throws ServiceException {
//do nothing
return entity;
}
@Override
public PersistenceResponse update(PersistencePackage persistencePackage) throws ServiceException {
for (PersistenceManagerEventHandler handler : persistenceManagerEventHandlers) {
PersistenceManagerEventHandlerResponse response = handler.preUpdate(this, persistencePackage);
if (PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.HANDLED_BREAK==response.getStatus()) {
break;
}
}
//check to see if there is a custom handler registered
//execute the root PersistencePackage
Entity response;
try {
checkRoot: {
for (CustomPersistenceHandler handler : getCustomPersistenceHandlers()) {
if (handler.canHandleUpdate(persistencePackage)) {
if (!handler.willHandleSecurity(persistencePackage)) {
adminRemoteSecurityService.securityCheck(persistencePackage, EntityOperationType.UPDATE);
}
response = handler.update(persistencePackage, dynamicEntityDao, (RecordHelper) getCompatibleModule(OperationType.BASIC));
break checkRoot;
}
}
adminRemoteSecurityService.securityCheck(persistencePackage, EntityOperationType.UPDATE);
PersistenceModule myModule = getCompatibleModule(persistencePackage.getPersistencePerspective().getOperationTypes().getUpdateType());
response = myModule.update(persistencePackage);
}
} catch (ValidationException e) {
response = e.getEntity();
} catch (ServiceException e) {
if (e.getCause() instanceof ValidationException) {
response = ((ValidationException) e.getCause()).getEntity();
} else {
throw e;
}
}
Map<String, List<String>> subPackageValidationErrors = new HashMap<String, List<String>>();
for (Map.Entry<String,PersistencePackage> subPackage : persistencePackage.getSubPackages().entrySet()) {
try {
//Run through any subPackages -- add up any validation errors
checkHandler: {
for (CustomPersistenceHandler handler : getCustomPersistenceHandlers()) {
if (handler.canHandleUpdate(subPackage.getValue())) {
Entity subResponse = handler.update(subPackage.getValue(), dynamicEntityDao, (RecordHelper) getCompatibleModule(OperationType.BASIC));
subPackage.getValue().setEntity(subResponse);
break checkHandler;
}
}
PersistenceModule subModule = getCompatibleModule(subPackage.getValue().getPersistencePerspective().getOperationTypes().getUpdateType());
Entity subResponse = subModule.update(persistencePackage);
subPackage.getValue().setEntity(subResponse);
}
} catch (ValidationException e) {
subPackage.getValue().setEntity(e.getEntity());
} catch (ServiceException e) {
if (e.getCause() instanceof ValidationException) {
response = ((ValidationException) e.getCause()).getEntity();
} else {
throw e;
}
}
}
//Build up validation errors in all of the subpackages, even those that might not have thrown ValidationExceptions
for (Map.Entry<String, PersistencePackage> subPackage : persistencePackage.getSubPackages().entrySet()) {
for (Map.Entry<String, List<String>> error : subPackage.getValue().getEntity().getPropertyValidationErrors().entrySet()) {
subPackageValidationErrors.put(subPackage.getKey() + DynamicEntityFormInfo.FIELD_SEPARATOR + error.getKey(), error.getValue());
}
}
response.getPropertyValidationErrors().putAll(subPackageValidationErrors);
if (response.isValidationFailure()) {
PersistenceResponse validationResponse = executeValidationProcessors(persistencePackage, new PersistenceResponse().withEntity(response));
throw new ValidationException(validationResponse.getEntity(), "The entity has failed validation");
}
return executePostUpdateHandlers(persistencePackage, new PersistenceResponse().withEntity(response));
}
protected PersistenceResponse executePostUpdateHandlers(PersistencePackage persistencePackage, PersistenceResponse persistenceResponse) throws ServiceException {
setMainEntityName(persistencePackage, persistenceResponse.getEntity());
for (PersistenceManagerEventHandler handler : persistenceManagerEventHandlers) {
PersistenceManagerEventHandlerResponse response = handler.postUpdate(this, persistenceResponse.getEntity(), persistencePackage);
if (PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.HANDLED_BREAK==response.getStatus()) {
persistenceResponse.setEntity(response.getEntity());
if (!MapUtils.isEmpty(response.getAdditionalData())) {
persistenceResponse.getAdditionalData().putAll(response.getAdditionalData());
}
break;
} else if (PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.HANDLED==response.getStatus()) {
persistenceResponse.setEntity(response.getEntity());
if (!MapUtils.isEmpty(response.getAdditionalData())) {
persistenceResponse.getAdditionalData().putAll(response.getAdditionalData());
}
}
}
//support legacy api
persistenceResponse.setEntity(postUpdate(persistenceResponse.getEntity(), persistencePackage));
return persistenceResponse;
}
/**
* Called after the update event
*
* @param entity
* @param persistencePackage
* @return the modified Entity instance
* @throws ServiceException
* @deprecated use the PersistenceManagerEventHandler api instead
*/
@Deprecated
protected Entity postUpdate(Entity entity, PersistencePackage persistencePackage) throws ServiceException {
//do nothing
return entity;
}
@Override
public PersistenceResponse remove(PersistencePackage persistencePackage) throws ServiceException {
for (PersistenceManagerEventHandler handler : persistenceManagerEventHandlers) {
PersistenceManagerEventHandlerResponse response = handler.preRemove(this, persistencePackage);
if (PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.HANDLED_BREAK==response.getStatus()) {
break;
}
}
//check to see if there is a custom handler registered
for (CustomPersistenceHandler handler : getCustomPersistenceHandlers()) {
if (handler.canHandleRemove(persistencePackage)) {
if (!handler.willHandleSecurity(persistencePackage)) {
adminRemoteSecurityService.securityCheck(persistencePackage, EntityOperationType.REMOVE);
}
handler.remove(persistencePackage, dynamicEntityDao, (RecordHelper) getCompatibleModule(OperationType.BASIC));
return executePostRemoveHandlers(persistencePackage, new PersistenceResponse());
}
}
adminRemoteSecurityService.securityCheck(persistencePackage, EntityOperationType.REMOVE);
PersistenceModule myModule = getCompatibleModule(persistencePackage.getPersistencePerspective().getOperationTypes().getRemoveType());
myModule.remove(persistencePackage);
return executePostRemoveHandlers(persistencePackage, new PersistenceResponse());
}
protected PersistenceResponse executePostRemoveHandlers(PersistencePackage persistencePackage, PersistenceResponse persistenceResponse) throws ServiceException {
setMainEntityName(persistencePackage, persistenceResponse.getEntity());
for (PersistenceManagerEventHandler handler : persistenceManagerEventHandlers) {
PersistenceManagerEventHandlerResponse response = handler.postRemove(this, persistencePackage);
if (PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.HANDLED_BREAK==response.getStatus()) {
if (!MapUtils.isEmpty(response.getAdditionalData())) {
persistenceResponse.getAdditionalData().putAll(response.getAdditionalData());
}
break;
} else if (PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.HANDLED==response.getStatus()) {
if (!MapUtils.isEmpty(response.getAdditionalData())) {
persistenceResponse.getAdditionalData().putAll(response.getAdditionalData());
}
}
}
return persistenceResponse;
}
@Override
public PersistenceModule getCompatibleModule(OperationType operationType) {
PersistenceModule myModule = null;
for (PersistenceModule module : modules) {
if (module.isCompatible(operationType)) {
myModule = module;
break;
}
}
if (myModule == null) {
LOG.error("Unable to find a compatible remote service module for the operation type: " + operationType);
throw new RuntimeException("Unable to find a compatible remote service module for the operation type: " + operationType);
}
return myModule;
}
@Override
public DynamicEntityDao getDynamicEntityDao() {
return dynamicEntityDao;
}
@Override
public void setDynamicEntityDao(DynamicEntityDao dynamicEntityDao) {
this.dynamicEntityDao = dynamicEntityDao;
}
@Override
public Map<String, String> getTargetEntityManagers() {
return targetEntityManagers;
}
@Override
public void setTargetEntityManagers(Map<String, String> targetEntityManagers) {
this.targetEntityManagers = targetEntityManagers;
}
@Override
public TargetModeType getTargetMode() {
return targetMode;
}
@Override
public void setTargetMode(TargetModeType targetMode) {
String targetManagerRef = targetEntityManagers.get(targetMode.getType());
EntityManager targetManager = (EntityManager) applicationContext.getBean(targetManagerRef);
if (targetManager == null) {
throw new RuntimeException("Unable to find a target entity manager registered with the key: " + targetMode + ". Did you add an entity manager with this key to the targetEntityManagers property?");
}
dynamicEntityDao.setStandardEntityManager(targetManager);
this.targetMode = targetMode;
}
@Override
public List<CustomPersistenceHandler> getCustomPersistenceHandlers() {
List<CustomPersistenceHandler> cloned = new ArrayList<CustomPersistenceHandler>();
cloned.addAll(customPersistenceHandlers);
if (getCustomPersistenceHandlerFilters() != null) {
for (CustomPersistenceHandlerFilter filter : getCustomPersistenceHandlerFilters()) {
Iterator<CustomPersistenceHandler> itr = cloned.iterator();
while (itr.hasNext()) {
CustomPersistenceHandler handler = itr.next();
if (!filter.shouldUseHandler(handler.getClass().getName())) {
itr.remove();
}
}
}
}
Collections.sort(cloned, new Comparator<CustomPersistenceHandler>() {
@Override
public int compare(CustomPersistenceHandler o1, CustomPersistenceHandler o2) {
return new Integer(o1.getOrder()).compareTo(new Integer(o2.getOrder()));
}
});
return cloned;
}
protected void setMainEntityName(PersistencePackage pp, Entity entity) {
if (StringUtils.isBlank(pp.getRequestingEntityName()) && entity != null) {
Property nameProp = entity.getPMap().get(AdminMainEntity.MAIN_ENTITY_NAME_PROPERTY);
if (nameProp != null) {
pp.setRequestingEntityName(nameProp.getValue());
}
}
}
@Override
public void setCustomPersistenceHandlers(List<CustomPersistenceHandler> customPersistenceHandlers) {
this.customPersistenceHandlers = customPersistenceHandlers;
}
public SecurityVerifier getAdminRemoteSecurityService() {
return adminRemoteSecurityService;
}
public void setAdminRemoteSecurityService(AdminSecurityServiceRemote adminRemoteSecurityService) {
this.adminRemoteSecurityService = adminRemoteSecurityService;
}
public List<CustomPersistenceHandlerFilter> getCustomPersistenceHandlerFilters() {
return customPersistenceHandlerFilters;
}
public void setCustomPersistenceHandlerFilters(List<CustomPersistenceHandlerFilter> customPersistenceHandlerFilters) {
this.customPersistenceHandlerFilters = customPersistenceHandlerFilters;
}
public PersistenceModule[] getModules() {
return modules;
}
public void setModules(PersistenceModule[] modules) {
this.modules = modules;
}
}