org.broadleafcommerce.openadmin.server.service.AdminEntityServiceImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of broadleaf-open-admin-platform Show documentation
Show all versions of broadleaf-open-admin-platform Show documentation
BroadleafCommerce Open Admin Platform
/*
* Copyright 2008-2013 the original author or authors.
*
* 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.
*/
package org.broadleafcommerce.openadmin.server.service;
import org.apache.commons.lang3.StringUtils;
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.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.server.domain.PersistencePackageRequest;
import org.broadleafcommerce.openadmin.server.factory.PersistencePackageFactory;
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.springframework.stereotype.Service;
import org.springframework.util.Assert;
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.NoResultException;
import javax.persistence.PersistenceContext;
/**
* @author Andre Azzolini (apazzolini)
*/
@Service("blAdminEntityService")
public class AdminEntityServiceImpl implements AdminEntityService {
@Resource(name = "blDynamicEntityRemoteService")
protected DynamicEntityService service;
@Resource(name = "blPersistencePackageFactory")
protected PersistencePackageFactory persistencePackageFactory;
@PersistenceContext(unitName = "blPU")
protected EntityManager em;
@Resource(name = "blEntityConfiguration")
protected EntityConfiguration entityConfiguration;
protected DynamicDaoHelper dynamicDaoHelper = new DynamicDaoHelperImpl();
@Override
public ClassMetadata getClassMetadata(PersistencePackageRequest request)
throws ServiceException {
ClassMetadata cmd = inspect(request).getClassMetaData();
cmd.setCeilingType(request.getCeilingEntityClassname());
return cmd;
}
@Override
public DynamicResultSet getRecords(PersistencePackageRequest request) throws ServiceException {
return fetch(request);
}
@Override
public Entity 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);
Entity[] entities = fetch(request).getRecords();
Assert.isTrue(entities != null && entities.length == 1, "Entity not found");
Entity entity = entities[0];
return entity;
}
@Override
public Entity addEntity(EntityForm entityForm, String[] customCriteria)
throws ServiceException {
PersistencePackageRequest ppr = getRequestForEntityForm(entityForm, customCriteria);
// 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 entry : entityForm.getDynamicForms().entrySet()) {
DynamicEntityFormInfo info = entityForm.getDynamicFormInfo(entry.getKey());
customCriteria = new String[] {info.getCriteriaName()};
PersistencePackageRequest subRequest = getRequestForEntityForm(entry.getValue(), customCriteria);
ppr.addSubRequest(info.getPropertyName(), subRequest);
}
return add(ppr);
}
@Override
public Entity updateEntity(EntityForm entityForm, String[] customCriteria)
throws ServiceException {
PersistencePackageRequest ppr = getRequestForEntityForm(entityForm, customCriteria);
// 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 entry : entityForm.getDynamicForms().entrySet()) {
DynamicEntityFormInfo info = entityForm.getDynamicFormInfo(entry.getKey());
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);
ppr.addSubRequest(info.getPropertyName(), subRequest);
}
return update(ppr);
}
@Override
public void removeEntity(EntityForm entityForm, String[] customCriteria)
throws ServiceException {
PersistencePackageRequest ppr = getRequestForEntityForm(entityForm, customCriteria);
remove(ppr);
}
protected List getPropertiesFromEntityForm(EntityForm entityForm) {
List properties = new ArrayList(entityForm.getFields().size());
for (Entry entry : entityForm.getFields().entrySet()) {
Property p = new Property();
p.setName(entry.getKey());
p.setValue(entry.getValue().getValue());
properties.add(p);
}
return properties;
}
protected PersistencePackageRequest getRequestForEntityForm(EntityForm entityForm, String[] customCriteria) {
// 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 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());
return ppr;
}
@Override
public Entity getAdvancedCollectionRecord(ClassMetadata containingClassMetadata, Entity containingEntity,
Property collectionProperty, String collectionItemId)
throws ServiceException {
PersistencePackageRequest ppr = PersistencePackageRequest.fromMetadata(collectionProperty.getMetadata());
FieldMetadata md = collectionProperty.getMetadata();
String containingEntityId = getContextSpecificRelationshipId(containingClassMetadata, containingEntity,
collectionProperty.getName());
Entity entity = null;
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);
Entity[] entities = fetch(ppr).getRecords();
Assert.isTrue(entities != null && entities.length == 1, "Entity not found");
entity = entities[0];
} else if (md instanceof MapMetadata) {
MapMetadata mmd = (MapMetadata) md;
FilterAndSortCriteria fasc = new FilterAndSortCriteria(ppr.getForeignKey().getManyToField());
fasc.setFilterValue(containingEntityId);
ppr.addFilterAndSortCriteria(fasc);
Entity[] entities = fetch(ppr).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)) {
entity = 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()));
}
if (entity == null) {
throw new NoResultException(String.format("Could not find record for class [%s], field [%s], main entity id " +
"[%s], collection entity id [%s]", containingClassMetadata.getCeilingType(),
collectionProperty.getName(), containingEntityId, collectionItemId));
}
return entity;
}
@Override
public DynamicResultSet getRecordsForCollection(ClassMetadata containingClassMetadata, Entity containingEntity,
Property collectionProperty, FilterAndSortCriteria[] fascs, Integer startIndex, Integer maxIndex)
throws ServiceException {
return getRecordsForCollection(containingClassMetadata, containingEntity, collectionProperty, fascs, startIndex,
maxIndex, null);
}
@Override
public DynamicResultSet getRecordsForCollection(ClassMetadata containingClassMetadata, Entity containingEntity,
Property collectionProperty, FilterAndSortCriteria[] fascs, Integer startIndex, Integer maxIndex,
String idValueOverride) throws ServiceException {
PersistencePackageRequest ppr = PersistencePackageRequest.fromMetadata(collectionProperty.getMetadata())
.withFilterAndSortCriteria(fascs)
.withStartIndex(startIndex)
.withMaxIndex(maxIndex);
FilterAndSortCriteria fasc;
FieldMetadata md = collectionProperty.getMetadata();
if (md instanceof BasicCollectionMetadata) {
fasc = new FilterAndSortCriteria(ppr.getForeignKey().getManyToField());
} else if (md instanceof AdornedTargetCollectionMetadata) {
fasc = new FilterAndSortCriteria(ppr.getAdornedList().getCollectionFieldName());
} 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);
return fetch(ppr);
}
@Override
public Map getRecordsForAllSubCollections(PersistencePackageRequest ppr, Entity containingEntity)
throws ServiceException {
Map map = new HashMap();
ClassMetadata cmd = getClassMetadata(ppr);
for (Property p : cmd.getProperties()) {
if (p.getMetadata() instanceof CollectionMetadata) {
DynamicResultSet drs = getRecordsForCollection(cmd, containingEntity, p, null, null, null);
map.put(p.getName(), drs);
}
}
return map;
}
@Override
public Entity addSubCollectionEntity(EntityForm entityForm, ClassMetadata mainMetadata, Property field,
Entity parentEntity)
throws ServiceException, ClassNotFoundException {
// Assemble the properties from the entity form
List properties = new ArrayList();
for (Entry entry : entityForm.getFields().entrySet()) {
Property p = new Property();
p.setName(entry.getKey());
p.setValue(entry.getValue().getValue());
properties.add(p);
}
FieldMetadata md = field.getMetadata();
PersistencePackageRequest ppr = PersistencePackageRequest.fromMetadata(md)
.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)) {
List fieldsToRemove = new ArrayList();
String idProp = getIdProperty(mainMetadata);
for (String key : entityForm.getFields().keySet()) {
if (!idProp.equals(key)) {
fieldsToRemove.add(key);
}
}
for (String key : fieldsToRemove) {
ListIterator li = properties.listIterator();
while (li.hasNext()) {
if (li.next().getName().equals(key)) {
li.remove();
}
}
}
ppr.setValidateUnsubmittedProperties(false);
}
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]);
Property[] propArr = new Property[properties.size()];
properties.toArray(propArr);
ppr.getEntity().setProperties(propArr);
return add(ppr);
}
@Override
public Entity updateSubCollectionEntity(EntityForm entityForm, ClassMetadata mainMetadata, Property field,
Entity parentEntity, String collectionItemId)
throws ServiceException, ClassNotFoundException {
List properties = getPropertiesFromEntityForm(entityForm);
FieldMetadata md = field.getMetadata();
PersistencePackageRequest ppr = PersistencePackageRequest.fromMetadata(md)
.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()));
properties.add(fp);
} else if (md instanceof AdornedTargetCollectionMetadata) {
ppr.getEntity().setType(new String[] { ppr.getAdornedList().getAdornedTargetEntityClassname() });
} 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]);
Property p = new Property();
p.setName(entityForm.getIdProperty());
p.setValue(collectionItemId);
properties.add(p);
Property[] propArr = new Property[properties.size()];
properties.toArray(propArr);
ppr.getEntity().setProperties(propArr);
return update(ppr);
}
@Override
public void removeSubCollectionEntity(ClassMetadata mainMetadata, Property field, Entity parentEntity, String itemId,
String priorKey)
throws ServiceException {
List properties = new ArrayList();
Property p;
String parentId = getContextSpecificRelationshipId(mainMetadata, parentEntity, field.getName());
Entity entity = new Entity();
PersistencePackageRequest ppr = PersistencePackageRequest.fromMetadata(field.getMetadata())
.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);
entity.setType(new String[] { adornedList.getAdornedTargetEntityClassname() });
} else if (field.getMetadata() instanceof MapMetadata) {
MapMetadata fmd = (MapMetadata) field.getMetadata();
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() });
}
Property[] propArr = new Property[properties.size()];
properties.toArray(propArr);
ppr.getEntity().setProperties(propArr);
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)) {
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 Entity add(PersistencePackageRequest request)
throws ServiceException {
PersistencePackage pkg = persistencePackageFactory.create(request);
try {
return service.add(pkg);
} catch (ValidationException e) {
return e.getEntity();
}
}
@Override
public Entity update(PersistencePackageRequest request)
throws ServiceException {
PersistencePackage pkg = persistencePackageFactory.create(request);
try {
return service.update(pkg);
} catch (ValidationException e) {
return e.getEntity();
}
}
@Override
public DynamicResultSet inspect(PersistencePackageRequest request)
throws ServiceException {
PersistencePackage pkg = persistencePackageFactory.create(request);
return service.inspect(pkg);
}
@Override
public void remove(PersistencePackageRequest request)
throws ServiceException {
PersistencePackage pkg = persistencePackageFactory.create(request);
service.remove(pkg);
}
@Override
public DynamicResultSet 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(50);
return cto;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy