/* * #%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; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.broadleafcommerce.common.admin.domain.AdminMainEntity; import org.broadleafcommerce.common.dao.GenericEntityDao; import org.broadleafcommerce.common.exception.ServiceException; import org.broadleafcommerce.common.persistence.EntityConfiguration; import org.broadleafcommerce.common.presentation.client.AddMethodType; import org.broadleafcommerce.common.presentation.client.SupportedFieldType; import org.broadleafcommerce.common.util.BLCSystemProperty; import org.broadleafcommerce.common.util.dao.DynamicDaoHelper; import org.broadleafcommerce.common.util.dao.DynamicDaoHelperImpl; import org.broadleafcommerce.openadmin.dto.AdornedTargetCollectionMetadata; import org.broadleafcommerce.openadmin.dto.AdornedTargetList; import org.broadleafcommerce.openadmin.dto.BasicCollectionMetadata; import org.broadleafcommerce.openadmin.dto.BasicFieldMetadata; import org.broadleafcommerce.openadmin.dto.ClassMetadata; import org.broadleafcommerce.openadmin.dto.CollectionMetadata; 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.FilterAndSortCriteria; import org.broadleafcommerce.openadmin.dto.MapMetadata; import org.broadleafcommerce.openadmin.dto.MapStructure; import org.broadleafcommerce.openadmin.dto.PersistencePackage; import org.broadleafcommerce.openadmin.dto.Property; import org.broadleafcommerce.openadmin.dto.SectionCrumb; import org.broadleafcommerce.openadmin.exception.EntityNotFoundException; import org.broadleafcommerce.openadmin.server.domain.PersistencePackageRequest; import org.broadleafcommerce.openadmin.server.factory.PersistencePackageFactory; import org.broadleafcommerce.openadmin.server.service.persistence.PersistenceResponse; import org.broadleafcommerce.openadmin.server.service.persistence.module.BasicPersistenceModule; import org.broadleafcommerce.openadmin.web.form.entity.DynamicEntityFormInfo; import org.broadleafcommerce.openadmin.web.form.entity.EntityForm; import org.broadleafcommerce.openadmin.web.form.entity.Field; import org.hibernate.exception.ConstraintViolationException; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Map.Entry; import javax.annotation.Resource; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; /** * @author Andre Azzolini (apazzolini) */ @Service("blAdminEntityService") public class AdminEntityServiceImpl implements AdminEntityService { protected static final Log LOG = LogFactory.getLog(AdminEntityServiceImpl.class); @Resource(name = "blDynamicEntityRemoteService") protected DynamicEntityService service; @Resource(name = "blPersistencePackageFactory") protected PersistencePackageFactory persistencePackageFactory; @PersistenceContext(unitName = "blPU") protected EntityManager em; @Resource(name = "blEntityConfiguration") protected EntityConfiguration entityConfiguration; @Resource(name = "blGenericEntityDao") protected GenericEntityDao genericEntityDao; protected DynamicDaoHelper dynamicDaoHelper = new DynamicDaoHelperImpl(); @Override public PersistenceResponse getClassMetadata(PersistencePackageRequest request) throws ServiceException { PersistenceResponse response = inspect(request); ClassMetadata cmd = response.getDynamicResultSet().getClassMetaData(); cmd.setCeilingType(request.getCeilingEntityClassname()); cmd.setSecurityCeilingType(request.getSecurityCeilingEntityClassname()); return response; } @Override public PersistenceResponse getRecords(PersistencePackageRequest request) throws ServiceException { return fetch(request); } @Override public PersistenceResponse getRecord(PersistencePackageRequest request, String id, ClassMetadata cmd, boolean isCollectionRequest) throws ServiceException { String idProperty = getIdProperty(cmd); FilterAndSortCriteria fasc = new FilterAndSortCriteria(idProperty); fasc.setFilterValue(id); request.addFilterAndSortCriteria(fasc); PersistenceResponse response = fetch(request); Entity[] entities = response.getDynamicResultSet().getRecords(); if (ArrayUtils.isEmpty(entities)) { throw new EntityNotFoundException(); } return response; } @Override public PersistenceResponse addEntity(EntityForm entityForm, String[] customCriteria, List<SectionCrumb> sectionCrumb) throws ServiceException { PersistencePackageRequest ppr = getRequestForEntityForm(entityForm, customCriteria, sectionCrumb); // If the entity form has dynamic forms inside of it, we need to persist those as well. // They are typically done in their own custom persistence handlers, which will get triggered // based on the criteria specific in the PersistencePackage. for (Entry<String, EntityForm> entry : entityForm.getDynamicForms().entrySet()) { DynamicEntityFormInfo info = entityForm.getDynamicFormInfo(entry.getKey()); if (info.getCustomCriteriaOverride() != null) { customCriteria = info.getCustomCriteriaOverride(); } else { String propertyName = info.getPropertyName(); String propertyValue; if (entityForm.getFields().containsKey(propertyName)) { propertyValue = entityForm.getFields().get(propertyName).getValue(); } else { propertyValue = info.getPropertyValue(); } customCriteria = new String[] {info.getCriteriaName(), entityForm.getId(), propertyName, propertyValue}; } PersistencePackageRequest subRequest = getRequestForEntityForm(entry.getValue(), customCriteria, sectionCrumb); ppr.addSubRequest(info.getPropertyName(), subRequest); } return add(ppr); } @Override public PersistenceResponse updateEntity(EntityForm entityForm, String[] customCriteria, List<SectionCrumb> sectionCrumb) throws ServiceException { PersistencePackageRequest ppr = getRequestForEntityForm(entityForm, customCriteria, sectionCrumb); ppr.setRequestingEntityName(entityForm.getMainEntityName()); // If the entity form has dynamic forms inside of it, we need to persist those as well. // They are typically done in their own custom persistence handlers, which will get triggered // based on the criteria specific in the PersistencePackage. for (Entry<String, EntityForm> entry : entityForm.getDynamicForms().entrySet()) { DynamicEntityFormInfo info = entityForm.getDynamicFormInfo(entry.getKey()); if (info.getCustomCriteriaOverride() != null) { customCriteria = info.getCustomCriteriaOverride(); } else { String propertyName = info.getPropertyName(); String propertyValue = entityForm.getFields().get(propertyName).getValue(); customCriteria = new String[] { info.getCriteriaName(), entityForm.getId(), propertyName, propertyValue }; } PersistencePackageRequest subRequest = getRequestForEntityForm(entry.getValue(), customCriteria, sectionCrumb); subRequest.withSecurityCeilingEntityClassname(info.getSecurityCeilingClassName()); ppr.addSubRequest(info.getPropertyName(), subRequest); } return update(ppr); } @Override public PersistenceResponse removeEntity(EntityForm entityForm, String[] customCriteria, List<SectionCrumb> sectionCrumb) throws ServiceException { PersistencePackageRequest ppr = getRequestForEntityForm(entityForm, customCriteria, sectionCrumb); return remove(ppr); } protected List<Property> getPropertiesFromEntityForm(EntityForm entityForm) { List<Property> properties = new ArrayList<Property>(entityForm.getFields().size()); for (Entry<String, Field> entry : entityForm.getFields().entrySet()) { Property p = new Property(); p.setName(entry.getKey()); p.setValue(entry.getValue().getValue()); p.setDisplayValue(entry.getValue().getDisplayValue()); p.setIsDirty(entry.getValue().getIsDirty()); properties.add(p); } return properties; } protected PersistencePackageRequest getRequestForEntityForm(EntityForm entityForm, String[] customCriteria, List<SectionCrumb> sectionCrumbs) { // Ensure the ID property is on the form Field idField = entityForm.getFields().get(entityForm.getIdProperty()); if (idField == null) { idField = new Field(); idField.setName(entityForm.getIdProperty()); idField.setValue(entityForm.getId()); entityForm.getFields().put(entityForm.getIdProperty(), idField); } else { idField.setValue(entityForm.getId()); } List<Property> propList = getPropertiesFromEntityForm(entityForm); Property[] properties = new Property[propList.size()]; properties = propList.toArray(properties); Entity entity = new Entity(); entity.setProperties(properties); String entityType = entityForm.getEntityType(); if (StringUtils.isEmpty(entityType)) { entityType = entityForm.getCeilingEntityClassname(); } entity.setType(new String[] { entityType }); PersistencePackageRequest ppr = PersistencePackageRequest.standard() .withEntity(entity) .withCustomCriteria(customCriteria) .withCeilingEntityClassname(entityForm.getCeilingEntityClassname()) .withSectionCrumbs(sectionCrumbs) .withRequestingEntityName(entityForm.getMainEntityName()); return ppr; } @Override public PersistenceResponse getAdvancedCollectionRecord(ClassMetadata containingClassMetadata, Entity containingEntity, Property collectionProperty, String collectionItemId, List<SectionCrumb> sectionCrumbs, String alternateId) throws ServiceException { PersistencePackageRequest ppr = PersistencePackageRequest.fromMetadata(collectionProperty.getMetadata(), sectionCrumbs); FieldMetadata md = collectionProperty.getMetadata(); String containingEntityId = getContextSpecificRelationshipId(containingClassMetadata, containingEntity, collectionProperty.getName()); ppr.setSectionEntityField(collectionProperty.getName()); PersistenceResponse response; if (md instanceof AdornedTargetCollectionMetadata) { FilterAndSortCriteria fasc = new FilterAndSortCriteria(ppr.getAdornedList().getCollectionFieldName()); fasc.setFilterValue(containingEntityId); ppr.addFilterAndSortCriteria(fasc); fasc = new FilterAndSortCriteria(ppr.getAdornedList().getCollectionFieldName() + "Target"); fasc.setFilterValue(collectionItemId); ppr.addFilterAndSortCriteria(fasc); if (!StringUtils.isEmpty(alternateId)) { fasc = new FilterAndSortCriteria(ppr.getAdornedList().getIdProperty()); fasc.setFilterValue(alternateId); ppr.addFilterAndSortCriteria(fasc); } response = fetch(ppr); Entity[] entities = response.getDynamicResultSet().getRecords(); if (ArrayUtils.isEmpty(entities)) { throw new EntityNotFoundException(); } } else if (md instanceof MapMetadata) { MapMetadata mmd = (MapMetadata) md; FilterAndSortCriteria fasc = new FilterAndSortCriteria(ppr.getForeignKey().getManyToField()); fasc.setFilterValue(containingEntityId); ppr.addFilterAndSortCriteria(fasc); response = fetch(ppr); Entity[] entities = response.getDynamicResultSet().getRecords(); for (Entity e : entities) { String idProperty = getIdProperty(containingClassMetadata); if (mmd.isSimpleValue()) { idProperty = "key"; } Property p = e.getPMap().get(idProperty); if (p.getValue().equals(collectionItemId)) { response.setEntity(e); break; } } } else { throw new IllegalArgumentException(String.format("The specified field [%s] for class [%s] was not an " + "advanced collection field.", collectionProperty.getName(), containingClassMetadata.getCeilingType())); } return response; } @Override public PersistenceResponse getRecordsForCollection(ClassMetadata containingClassMetadata, Entity containingEntity, Property collectionProperty, FilterAndSortCriteria[] fascs, Integer startIndex, Integer maxIndex, List<SectionCrumb> sectionCrumb) throws ServiceException { return getRecordsForCollection(containingClassMetadata, containingEntity, collectionProperty, fascs, startIndex, maxIndex, null, sectionCrumb); } @Override public PersistenceResponse getRecordsForCollection(ClassMetadata containingClassMetadata, Entity containingEntity, Property collectionProperty, FilterAndSortCriteria[] fascs, Integer startIndex, Integer maxIndex, String idValueOverride, List<SectionCrumb> sectionCrumbs) throws ServiceException { PersistencePackageRequest ppr = PersistencePackageRequest.fromMetadata(collectionProperty.getMetadata(), sectionCrumbs) .withFilterAndSortCriteria(fascs) .withStartIndex(startIndex) .withMaxIndex(maxIndex); FilterAndSortCriteria fasc; FieldMetadata md = collectionProperty.getMetadata(); String collectionCeilingClass = null; if (md instanceof BasicCollectionMetadata) { fasc = new FilterAndSortCriteria(ppr.getForeignKey().getManyToField()); collectionCeilingClass = ((CollectionMetadata) md).getCollectionCeilingEntity(); } else if (md instanceof AdornedTargetCollectionMetadata) { fasc = new FilterAndSortCriteria(ppr.getAdornedList().getCollectionFieldName()); collectionCeilingClass = ((CollectionMetadata) md).getCollectionCeilingEntity(); } else if (md instanceof MapMetadata) { fasc = new FilterAndSortCriteria(ppr.getForeignKey().getManyToField()); } else { throw new IllegalArgumentException(String.format("The specified field [%s] for class [%s] was not a " + "collection field.", collectionProperty.getName(), containingClassMetadata.getCeilingType())); } String id; if (idValueOverride == null) { id = getContextSpecificRelationshipId(containingClassMetadata, containingEntity, collectionProperty.getName()); } else { id = idValueOverride; } fasc.setFilterValue(id); ppr.addFilterAndSortCriteria(fasc); if (collectionCeilingClass != null) { ppr.setCeilingEntityClassname(collectionCeilingClass); } ppr.setSectionEntityField(collectionProperty.getName()); return fetch(ppr); } @Override public Map<String, DynamicResultSet> getRecordsForAllSubCollections(PersistencePackageRequest ppr, Entity containingEntity, Integer startIndex, Integer maxIndex, List<SectionCrumb> sectionCrumb) throws ServiceException { Map<String, DynamicResultSet> map = new HashMap<String, DynamicResultSet>(); PersistenceResponse response = getClassMetadata(ppr); ClassMetadata cmd = response.getDynamicResultSet().getClassMetaData(); for (Property p : cmd.getProperties()) { if (ArrayUtils.contains(p.getMetadata().getAvailableToTypes(), containingEntity.getType()[0]) && p.getMetadata() instanceof CollectionMetadata) { PersistenceResponse response2 = getRecordsForCollection(cmd, containingEntity, p, null, startIndex, maxIndex, sectionCrumb); map.put(p.getName(), response2.getDynamicResultSet()); } } return map; } @Override public Map<String, DynamicResultSet> getRecordsForAllSubCollections(PersistencePackageRequest ppr, Entity containingEntity, List<SectionCrumb> sectionCrumb) throws ServiceException { return getRecordsForAllSubCollections(ppr, containingEntity, null, null, sectionCrumb); } @Override public PersistenceResponse addSubCollectionEntity(EntityForm entityForm, ClassMetadata mainMetadata, Property field, Entity parentEntity, List<SectionCrumb> sectionCrumbs) throws ServiceException, ClassNotFoundException { // Assemble the properties from the entity form List<Property> properties = getPropertiesFromEntityForm(entityForm); FieldMetadata md = field.getMetadata(); PersistencePackageRequest ppr = PersistencePackageRequest.fromMetadata(md, sectionCrumbs) .withEntity(new Entity()); if (md instanceof BasicCollectionMetadata) { BasicCollectionMetadata fmd = (BasicCollectionMetadata) md; ppr.getEntity().setType(new String[] { entityForm.getEntityType() }); // If we're looking up an entity instead of trying to create one on the fly, let's make sure // that we're not changing the target entity at all and only creating the association to the id if (fmd.getAddMethodType().equals(AddMethodType.LOOKUP) || fmd.getAddMethodType().equals(AddMethodType.LOOKUP_FOR_UPDATE)) { List<String> fieldsToRemove = new ArrayList<String>(); String idProp = getIdProperty(mainMetadata); for (String key : entityForm.getFields().keySet()) { if (!idProp.equals(key)) { fieldsToRemove.add(key); } } for (String key : fieldsToRemove) { ListIterator<Property> li = properties.listIterator(); while (li.hasNext()) { if (li.next().getName().equals(key)) { li.remove(); } } } ppr.setValidateUnsubmittedProperties(false); } if (fmd.getAddMethodType().equals(AddMethodType.LOOKUP_FOR_UPDATE)) { ppr.setUpdateLookupType(true); } Property fp = new Property(); fp.setName(ppr.getForeignKey().getManyToField()); fp.setValue(getContextSpecificRelationshipId(mainMetadata, parentEntity, field.getName())); properties.add(fp); } else if (md instanceof AdornedTargetCollectionMetadata) { ppr.getEntity().setType(new String[] { ppr.getAdornedList().getAdornedTargetEntityClassname() }); String[] maintainedFields = ((AdornedTargetCollectionMetadata) md).getMaintainedAdornedTargetFields(); if (maintainedFields == null || maintainedFields.length == 0) { ppr.setValidateUnsubmittedProperties(false); } } else if (md instanceof MapMetadata) { ppr.getEntity().setType(new String[] { entityForm.getEntityType() }); Property p = new Property(); p.setName("symbolicId"); p.setValue(getContextSpecificRelationshipId(mainMetadata, parentEntity, field.getName())); properties.add(p); } else { throw new IllegalArgumentException(String.format("The specified field [%s] for class [%s] was" + " not a collection field.", field.getName(), mainMetadata.getCeilingType())); } ppr.setCeilingEntityClassname(ppr.getEntity().getType()[0]); String sectionField = field.getName(); if (sectionField.contains(".")) { sectionField = sectionField.substring(0, sectionField.lastIndexOf(".")); } ppr.setSectionEntityField(sectionField); Property parentNameProp = parentEntity.getPMap().get(AdminMainEntity.MAIN_ENTITY_NAME_PROPERTY); if (parentNameProp != null) { ppr.setRequestingEntityName(parentNameProp.getValue()); } Property[] propArr = new Property[properties.size()]; properties.toArray(propArr); ppr.getEntity().setProperties(propArr); return add(ppr); } @Override public PersistenceResponse updateSubCollectionEntity(EntityForm entityForm, ClassMetadata mainMetadata, Property field, Entity parentEntity, String collectionItemId, List<SectionCrumb> sectionCrumb) throws ServiceException, ClassNotFoundException { return updateSubCollectionEntity(entityForm, mainMetadata, field, parentEntity, collectionItemId, null, sectionCrumb); } @Override public PersistenceResponse updateSubCollectionEntity(EntityForm entityForm, ClassMetadata mainMetadata, Property field, Entity parentEntity, String collectionItemId, String alternateId, List<SectionCrumb> sectionCrumbs) throws ServiceException, ClassNotFoundException { List<Property> properties = getPropertiesFromEntityForm(entityForm); FieldMetadata md = field.getMetadata(); PersistencePackageRequest ppr = PersistencePackageRequest.fromMetadata(md, sectionCrumbs) .withEntity(new Entity()); if (md instanceof BasicCollectionMetadata) { BasicCollectionMetadata fmd = (BasicCollectionMetadata) md; ppr.getEntity().setType(new String[] { fmd.getCollectionCeilingEntity() }); Property fp = new Property(); fp.setName(ppr.getForeignKey().getManyToField()); fp.setValue(getContextSpecificRelationshipId(mainMetadata, parentEntity, field.getName())); if (!properties.contains(fp)) { properties.add(fp); } } else if (md instanceof AdornedTargetCollectionMetadata) { ppr.getEntity().setType(new String[] { ppr.getAdornedList().getAdornedTargetEntityClassname() }); for (Property property : properties) { if (property.getName().equals(ppr.getAdornedList().getLinkedObjectPath() + "." + ppr.getAdornedList().getLinkedIdProperty())) { break; } } if (!StringUtils.isEmpty(alternateId)) { Property p = new Property(); p.setName(BasicPersistenceModule.ALTERNATE_ID_PROPERTY); p.setValue(alternateId); if (!properties.contains(p)) { properties.add(p); } } } else if (md instanceof MapMetadata) { ppr.getEntity().setType(new String[] { entityForm.getEntityType() }); Property p = new Property(); p.setName("symbolicId"); p.setValue(getContextSpecificRelationshipId(mainMetadata, parentEntity, field.getName())); properties.add(p); } else { throw new IllegalArgumentException(String.format("The specified field [%s] for class [%s] was" + " not a collection field.", field.getName(), mainMetadata.getCeilingType())); } ppr.setCeilingEntityClassname(ppr.getEntity().getType()[0]); String sectionField = field.getName(); if (sectionField.contains(".")) { sectionField = sectionField.substring(0, sectionField.lastIndexOf(".")); } ppr.setSectionEntityField(sectionField); Property parentNameProp = parentEntity.getPMap().get(AdminMainEntity.MAIN_ENTITY_NAME_PROPERTY); if (parentNameProp != null) { ppr.setRequestingEntityName(parentNameProp.getValue()); } Property p = new Property(); p.setName(entityForm.getIdProperty()); p.setValue(collectionItemId); if (!properties.contains(p)) { properties.add(p); } Property[] propArr = new Property[properties.size()]; properties.toArray(propArr); ppr.getEntity().setProperties(propArr); return update(ppr); } @Override public PersistenceResponse removeSubCollectionEntity(ClassMetadata mainMetadata, Property field, Entity parentEntity, String itemId, String priorKey, List<SectionCrumb> sectionCrumbs) throws ServiceException { return removeSubCollectionEntity(mainMetadata, field, parentEntity, itemId, null, priorKey, sectionCrumbs); } @Override public PersistenceResponse removeSubCollectionEntity(ClassMetadata mainMetadata, Property field, Entity parentEntity, String itemId, String alternateId, String priorKey, List<SectionCrumb> sectionCrumbs) throws ServiceException { List<Property> properties = new ArrayList<Property>(); Property p; String parentId = getContextSpecificRelationshipId(mainMetadata, parentEntity, field.getName()); Entity entity = new Entity(); PersistencePackageRequest ppr = PersistencePackageRequest.fromMetadata(field.getMetadata(), sectionCrumbs) .withEntity(entity); if (field.getMetadata() instanceof BasicCollectionMetadata) { BasicCollectionMetadata fmd = (BasicCollectionMetadata) field.getMetadata(); p = new Property(); p.setName("id"); p.setValue(itemId); properties.add(p); p = new Property(); p.setName(ppr.getForeignKey().getManyToField()); p.setValue(parentId); properties.add(p); entity.setType(new String[] { fmd.getCollectionCeilingEntity() }); } else if (field.getMetadata() instanceof AdornedTargetCollectionMetadata) { AdornedTargetList adornedList = ppr.getAdornedList(); p = new Property(); p.setName(adornedList.getLinkedObjectPath() + "." + adornedList.getLinkedIdProperty()); p.setValue(parentId); properties.add(p); p = new Property(); p.setName(adornedList.getTargetObjectPath() + "." + adornedList.getTargetIdProperty()); p.setValue(itemId); properties.add(p); if (!StringUtils.isEmpty(alternateId)) { p = new Property(); p.setName(BasicPersistenceModule.ALTERNATE_ID_PROPERTY); p.setValue(alternateId); properties.add(p); } entity.setType(new String[] { adornedList.getAdornedTargetEntityClassname() }); } else if (field.getMetadata() instanceof MapMetadata) { MapMetadata fmd = (MapMetadata) field.getMetadata(); p = new Property(); p.setName("id"); p.setValue(itemId); properties.add(p); p = new Property(); p.setName("symbolicId"); p.setValue(getContextSpecificRelationshipId(mainMetadata, parentEntity, field.getName())); properties.add(p); p = new Property(); p.setName("priorKey"); p.setValue(priorKey); properties.add(p); MapStructure mapStructure = ppr.getMapStructure(); p = new Property(); p.setName(mapStructure.getKeyPropertyName()); p.setValue(itemId); properties.add(p); entity.setType(new String[] { fmd.getTargetClass() }); } String sectionField = field.getName(); if (sectionField.contains(".")) { sectionField = sectionField.substring(0, sectionField.lastIndexOf(".")); } ppr.setSectionEntityField(sectionField); Property parentNameProp = parentEntity.getPMap().get(AdminMainEntity.MAIN_ENTITY_NAME_PROPERTY); if (parentNameProp != null) { ppr.setRequestingEntityName(parentNameProp.getValue()); } Property[] propArr = new Property[properties.size()]; properties.toArray(propArr); ppr.getEntity().setProperties(propArr); return remove(ppr); } @Override public String getContextSpecificRelationshipId(ClassMetadata cmd, Entity entity, String propertyName) { String prefix; if (propertyName.contains(".")) { prefix = propertyName.substring(0, propertyName.lastIndexOf(".")); } else { prefix = ""; } if (prefix.equals("")) { return entity.findProperty("id").getValue(); } else { //we need to check all the parts of the prefix. For example, the prefix could include an @Embedded class like //defaultSku.dimension. In this case, we want the id from the defaultSku property, since the @Embedded does //not have an id property - nor should it. String[] prefixParts = prefix.split("\\."); for (int j = 0; j < prefixParts.length; j++) { StringBuilder sb = new StringBuilder(); for (int x = 0; x < prefixParts.length - j; x++) { sb.append(prefixParts[x]); if (x < prefixParts.length - j - 1) { sb.append("."); } } String tempPrefix = sb.toString(); for (Property property : entity.getProperties()) { if (property.getName().startsWith(tempPrefix)) { if (cmd.getPMap().containsKey(property.getName())) { BasicFieldMetadata md = (BasicFieldMetadata) cmd.getPMap().get(property.getName()).getMetadata(); if (md.getFieldType().equals(SupportedFieldType.ID)) { return property.getValue(); } } } } } } if (!prefix.contains(".")) { //this may be an embedded class directly on the root entity (e.g. embeddablePriceList.restrictedPriceLists on OfferImpl) return entity.findProperty("id").getValue(); } throw new RuntimeException("Unable to establish a relationship id"); } @Override public String getIdProperty(ClassMetadata cmd) throws ServiceException { for (Property p : cmd.getProperties()) { if (p.getMetadata() instanceof BasicFieldMetadata) { BasicFieldMetadata fmd = (BasicFieldMetadata) p.getMetadata(); //check for ID type and also make sure the field we're looking at is not a "ToOne" association if (SupportedFieldType.ID.equals(fmd.getFieldType()) && !p.getName().contains(".")) { return p.getName(); } } } throw new ServiceException("Could not determine ID field for " + cmd.getCeilingType()); } @Override public PersistenceResponse add(PersistencePackageRequest request) throws ServiceException { return add(request, true); } @Override public PersistenceResponse add(PersistencePackageRequest request, boolean transactional) throws ServiceException { PersistencePackage pkg = persistencePackageFactory.create(request); try { if (request.isUpdateLookupType()) { if (pkg.getSectionCrumbs() != null && pkg.getSectionCrumbs().length > 0) { SectionCrumb sc = pkg.getSectionCrumbs()[0]; if (StringUtils.isNotBlank(sc.getSectionIdentifier())) { pkg.setSecurityCeilingEntityFullyQualifiedClassname(sc.getSectionIdentifier()); } } if (transactional) { return service.update(pkg); } else { return service.nonTransactionalUpdate(pkg); } } else { if (transactional) { return service.add(pkg); } else { return service.nonTransactionalAdd(pkg); } } } catch (ValidationException e) { ensureEntityMarkedAsValidationFailure(e, request); return new PersistenceResponse().withEntity(e.getEntity()); } } @Override public PersistenceResponse update(PersistencePackageRequest request) throws ServiceException { return update(request, true); } @Override public PersistenceResponse update(PersistencePackageRequest request, boolean transactional) throws ServiceException { PersistencePackage pkg = persistencePackageFactory.create(request); try { if (transactional) { return service.update(pkg); } else { return service.nonTransactionalUpdate(pkg); } } catch (ValidationException e) { ensureEntityMarkedAsValidationFailure(e, request); return new PersistenceResponse().withEntity(e.getEntity()); } } @Override public PersistenceResponse inspect(PersistencePackageRequest request) throws ServiceException { PersistencePackage pkg = persistencePackageFactory.create(request); return service.inspect(pkg); } @Override public PersistenceResponse remove(PersistencePackageRequest request) throws ServiceException { return remove(request, true); } @Override public PersistenceResponse remove(PersistencePackageRequest request, boolean transactional) throws ServiceException { PersistencePackage pkg = persistencePackageFactory.create(request); try { if (transactional) { return service.remove(pkg); } else { return service.nonTransactionalRemove(pkg); } } catch (ValidationException e) { ensureEntityMarkedAsValidationFailure(e, request); return new PersistenceResponse().withEntity(e.getEntity()); } } /** * <p> * Should be invoked when a {@link ValidationException} is thrown to verify that the {@link Entity} contained within the * given <b>originalRequest</b> has a validationFailure = true * * <p> * This will also check for a cause of {@link ConstraintViolationException} and add a gloal error to that. */ protected void ensureEntityMarkedAsValidationFailure(ValidationException e, PersistencePackageRequest originalRequest) { if (e.containsCause(ConstraintViolationException.class)) { e.getEntity().addGlobalValidationError("constraintViolationError"); } else if (!e.getEntity().isValidationFailure()) { e.getEntity().setValidationFailure(true); e.getEntity().addGlobalValidationError(e.getMessage()); } } @Override public PersistenceResponse fetch(PersistencePackageRequest request) throws ServiceException { PersistencePackage pkg = persistencePackageFactory.create(request); CriteriaTransferObject cto = getDefaultCto(); if (request.getFilterAndSortCriteria() != null) { cto.addAll(Arrays.asList(request.getFilterAndSortCriteria())); } if (request.getStartIndex() == null) { cto.setFirstResult(0); } else { cto.setFirstResult(request.getStartIndex()); } if (request.getMaxIndex() != null) { int requestedMaxResults = request.getMaxIndex() - request.getStartIndex() + 1; if (requestedMaxResults >= 0 && requestedMaxResults < cto.getMaxResults()) { cto.setMaxResults(requestedMaxResults); } } return service.fetch(pkg, cto); } protected CriteriaTransferObject getDefaultCto() { CriteriaTransferObject cto = new CriteriaTransferObject(); cto.setMaxResults(getDefaultMaxResults()); return cto; } @Override public String getForeignEntityName(String owningClass, String id) { if (owningClass == null || id == null) { return null; } Class<?> clazz = genericEntityDao.getImplClass(owningClass); Object foreignEntity = genericEntityDao.readGenericEntity(clazz, id); if (foreignEntity instanceof AdminMainEntity) { return ((AdminMainEntity) foreignEntity).getMainEntityName(); } return null; } protected int getDefaultMaxResults() { return BLCSystemProperty.resolveIntSystemProperty("admin.default.max.results", 50); } }