Search in sources :

Example 1 with MVELTranslationException

use of org.broadleafcommerce.openadmin.web.rulebuilder.MVELTranslationException in project BroadleafCommerce by BroadleafCommerce.

the class PhraseTranslator method createExpression.

public Expression createExpression(String phrase) throws MVELTranslationException {
    String[] components = extractComponents(phrase);
    String field = components[0];
    String operator = components[1];
    String value = components[2];
    boolean isNegation = false;
    if (field.startsWith("!") || phrase.startsWith("!")) {
        isNegation = true;
    }
    boolean isIgnoreCase = false;
    boolean isCollectionCase = false;
    if (phrase.contains(DataDTOToMVELTranslator.COLLECTION_OPERATOR)) {
        isCollectionCase = true;
    }
    // remove null check syntax
    field = field.replaceAll("\\.\\?", ".");
    // keep for backwards compatibility with legacy generated MVEL
    String legacyCaseInsensitivityKey = "MVEL.eval(\"toUpperCase()\",";
    String newCaseInsensitivityKey = "MvelHelper.toUpperCase(";
    String caseInsensitivityKey;
    if (field.contains(legacyCaseInsensitivityKey) || value.contains(legacyCaseInsensitivityKey)) {
        caseInsensitivityKey = legacyCaseInsensitivityKey;
    } else {
        caseInsensitivityKey = newCaseInsensitivityKey;
    }
    if (field.contains(caseInsensitivityKey)) {
        isIgnoreCase = true;
        field = field.substring(field.indexOf(caseInsensitivityKey) + caseInsensitivityKey.length(), field.length() - 1);
    }
    while (value.contains(caseInsensitivityKey)) {
        int caseIndex = value.indexOf(caseInsensitivityKey);
        value = value.substring(0, caseIndex) + value.substring(caseIndex + caseInsensitivityKey.length());
        if (value.contains("\")")) {
            value = value.substring(0, value.indexOf("\")") + 1) + value.substring(value.indexOf("\")") + 2);
        } else {
            value = value.substring(0, value.indexOf(")")) + value.substring(value.indexOf(")") + 1);
        }
    }
    if (value.startsWith("[") && value.endsWith("]") && !isCollectionCase) {
        value = value.substring(1, value.length() - 1);
        String[] temps = value.split(",");
        for (int j = 0; j < temps.length; j++) {
            if (temps[j].startsWith("\"") && temps[j].endsWith("\"")) {
                temps[j] = temps[j].substring(1, temps[j].length() - 1);
            }
        }
        StringBuffer sb = new StringBuffer();
        sb.append("[");
        for (int j = 0; j < temps.length; j++) {
            sb.append(temps[j]);
            if (j < temps.length - 1) {
                sb.append(",");
            }
        }
        sb.append("]");
        value = sb.toString();
    }
    // keep for backwards compatibility with legacy generated MVEL
    String legacyDateFormatKey = "java.text.DateFormat.getDateTimeInstance(3,3).parse(";
    String newDateFormatKey = "MvelHelper.convertField(\"DATE\",\"";
    String dateFormatKey;
    if (value.contains(legacyDateFormatKey)) {
        dateFormatKey = legacyDateFormatKey;
    } else {
        dateFormatKey = newDateFormatKey;
    }
    if (value.startsWith(dateFormatKey)) {
        value = value.substring(dateFormatKey.length(), value.length() - 1);
        // convert the date into admin display format
        try {
            if (value.startsWith("\"")) {
                value = value.substring(1, value.length());
            }
            if (value.endsWith("\"")) {
                value = value.substring(0, value.length() - 1);
            }
            value = RuleBuilderFormatUtil.formatDate(RuleBuilderFormatUtil.parseDate(value));
        } catch (ParseException e) {
            throw new MVELTranslationException(MVELTranslationException.INCOMPATIBLE_DATE_VALUE, "Unable to convert " + "the persisted date value(" + value + ") to the admin display format.");
        }
    }
    int entityKeyIndex = field.indexOf(".");
    if (entityKeyIndex < 0) {
        throw new MVELTranslationException(MVELTranslationException.NO_FIELD_FOUND_IN_RULE, "Could not identify a " + "valid property field value in the expression: (" + phrase + ")");
    }
    if (value.startsWith(caseInsensitivityKey)) {
        value = value.substring(caseInsensitivityKey.length(), value.length() - 1);
    }
    String entityKey = field.substring(0, entityKeyIndex);
    boolean isFieldComparison = false;
    if (value.startsWith("\"") && value.endsWith("\"")) {
        value = value.substring(1, value.length() - 1);
    } else if (value.startsWith(entityKey + ".")) {
        isFieldComparison = true;
        value = value.substring(entityKey.length() + 1, value.length());
    }
    field = field.substring(entityKeyIndex + 1, field.length());
    // If this is a Money field, then DataDTOToMVELTranslator.formatValue() will append .getAmount() onto the end
    // of the field name. We need to remove that as it should not be considered part of the field name, but we still
    // want to support other method invocations in MVEL expressions (like for getProductAttributes())
    String moneyAmountMethod = ".getAmount()";
    int amountMethodPos = field.lastIndexOf(moneyAmountMethod);
    if (amountMethodPos >= 0) {
        field = field.substring(0, amountMethodPos);
    }
    // Same as above, but for Enumeration types
    String typeMethod = ".getType()";
    int typeMethodPos = field.lastIndexOf(typeMethod);
    if (typeMethodPos >= 0) {
        field = field.substring(0, typeMethodPos);
    }
    Expression expression = new Expression();
    expression.setField(field);
    BLCOperator operatorId = getOperator(field, operator, value, isNegation, isFieldComparison, isIgnoreCase);
    expression.setOperator(operatorId);
    expression.setValue(value);
    return expression;
}
Also used : MVELTranslationException(org.broadleafcommerce.openadmin.web.rulebuilder.MVELTranslationException) ParseException(java.text.ParseException) BLCOperator(org.broadleafcommerce.openadmin.web.rulebuilder.BLCOperator)

Example 2 with MVELTranslationException

use of org.broadleafcommerce.openadmin.web.rulebuilder.MVELTranslationException in project BroadleafCommerce by BroadleafCommerce.

the class RuleFieldPersistenceProvider method updateQuantityRule.

protected boolean updateQuantityRule(EntityManager em, DataDTOToMVELTranslator translator, String entityKey, String fieldService, String jsonPropertyValue, Collection<QuantityBasedRule> criteriaList, Class<?> memberType, Object parent, String mappedBy, Property property) {
    boolean dirty = false;
    if (!StringUtils.isEmpty(jsonPropertyValue)) {
        // avoid lazy init exception on the criteria list for criteria created during an add
        criteriaList.size();
        DataWrapper dw = ruleFieldExtractionUtility.convertJsonToDataWrapper(jsonPropertyValue);
        if (dw != null && StringUtils.isEmpty(dw.getError())) {
            List<QuantityBasedRule> updatedRules = new ArrayList<QuantityBasedRule>();
            for (DataDTO dto : dw.getData()) {
                if (dto.getPk() != null && !CollectionUtils.isEmpty(criteriaList)) {
                    checkId: {
                        // Update Existing Criteria
                        for (QuantityBasedRule quantityBasedRule : criteriaList) {
                            // make compatible with enterprise module
                            boolean isParentRelated = sandBoxHelper.isRelatedToParentCatalogIds(quantityBasedRule, dto.getPk());
                            boolean isMatch = isParentRelated || dto.getPk().equals(quantityBasedRule.getId());
                            if (isMatch) {
                                String mvel;
                                // don't update if the data has not changed
                                if (!quantityBasedRule.getQuantity().equals(dto.getQuantity())) {
                                    dirty = true;
                                }
                                try {
                                    mvel = ruleFieldExtractionUtility.convertDTOToMvelString(translator, entityKey, dto, fieldService);
                                    if (!quantityBasedRule.getMatchRule().equals(mvel)) {
                                        dirty = true;
                                    }
                                } catch (MVELTranslationException e) {
                                    throw new RuntimeException(e);
                                }
                                if (!dirty && extensionManager != null) {
                                    ExtensionResultHolder<Boolean> resultHolder = new ExtensionResultHolder<Boolean>();
                                    ExtensionResultStatusType result = extensionManager.getProxy().establishDirtyState(quantityBasedRule, resultHolder);
                                    if (ExtensionResultStatusType.NOT_HANDLED != result && resultHolder.getResult() != null) {
                                        dirty = resultHolder.getResult();
                                    }
                                }
                                if (dirty) {
                                    // pre-merge (can result in a clone for enterprise)
                                    quantityBasedRule = em.merge(quantityBasedRule);
                                    // update the quantity based rule
                                    quantityBasedRule.setQuantity(dto.getQuantity());
                                    quantityBasedRule.setMatchRule(mvel);
                                    quantityBasedRule = em.merge(quantityBasedRule);
                                }
                                updatedRules.add(quantityBasedRule);
                                break checkId;
                            }
                        }
                        throw new IllegalArgumentException("Unable to update the rule of type (" + memberType.getName() + ") because an update was requested for id (" + dto.getPk() + "), which does not exist.");
                    }
                } else {
                    // Create a new Criteria
                    QuantityBasedRule quantityBasedRule;
                    try {
                        quantityBasedRule = (QuantityBasedRule) memberType.newInstance();
                        quantityBasedRule.setQuantity(dto.getQuantity());
                        quantityBasedRule.setMatchRule(ruleFieldExtractionUtility.convertDTOToMvelString(translator, entityKey, dto, fieldService));
                        if (StringUtils.isEmpty(quantityBasedRule.getMatchRule()) && !StringUtils.isEmpty(dw.getRawMvel())) {
                            quantityBasedRule.setMatchRule(dw.getRawMvel());
                        }
                        PropertyUtils.setNestedProperty(quantityBasedRule, mappedBy, parent);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                    em.persist(quantityBasedRule);
                    dto.setPk(quantityBasedRule.getId());
                    Object contained = findContainedRuleIfApplicable(quantityBasedRule);
                    if (contained != null) {
                        dto.setContainedPk((Long) em.unwrap(Session.class).getIdentifier(contained));
                    }
                    if (extensionManager != null) {
                        ExtensionResultHolder resultHolder = new ExtensionResultHolder();
                        extensionManager.getProxy().postAdd(quantityBasedRule, resultHolder);
                        if (resultHolder.getResult() != null) {
                            quantityBasedRule = (QuantityBasedRule) resultHolder.getResult();
                        }
                    }
                    if (cascadeExtensionManager != null) {
                        ExtensionResultHolder resultHolder = new ExtensionResultHolder();
                        cascadeExtensionManager.getProxy().postCascadeAdd(quantityBasedRule, dto, resultHolder);
                        if (resultHolder.getResult() != null) {
                            quantityBasedRule = (QuantityBasedRule) resultHolder.getResult();
                        }
                    }
                    updatedRules.add(quantityBasedRule);
                    dirty = true;
                }
            }
            // if an item was not included in the comprehensive submit from the client, we can assume that the
            // listing was deleted, so we remove it here.
            Iterator<QuantityBasedRule> itr = criteriaList.iterator();
            // Since this class explicitly removes the quantity based rule - we must also preserve the id of the element
            // as the CacheInvalidationProducer will need this in order to remove each collection member cache instance as well.
            BroadleafRequestContext context = BroadleafRequestContext.getBroadleafRequestContext();
            context.getAdditionalProperties().put("deletedQuantityBasedRules", new HashSet<QuantityBasedRule>());
            while (itr.hasNext()) {
                checkForRemove: {
                    QuantityBasedRule original = itr.next();
                    for (QuantityBasedRule quantityBasedRule : updatedRules) {
                        Long id = sandBoxHelper.getOriginalId(quantityBasedRule);
                        boolean isMatch = original.getId().equals(id) || original.getId().equals(quantityBasedRule.getId());
                        if (isMatch) {
                            break checkForRemove;
                        }
                    }
                    ((Set<QuantityBasedRule>) context.getAdditionalProperties().get("deletedQuantityBasedRules")).add(original);
                    em.remove(original);
                    itr.remove();
                    dirty = true;
                }
            }
            ObjectMapper mapper = new ObjectMapper();
            String json;
            try {
                json = mapper.writeValueAsString(dw);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            property.setValue(json);
        }
    }
    return dirty;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) MVELTranslationException(org.broadleafcommerce.openadmin.web.rulebuilder.MVELTranslationException) BroadleafRequestContext(org.broadleafcommerce.common.web.BroadleafRequestContext) ArrayList(java.util.ArrayList) DataDTO(org.broadleafcommerce.openadmin.web.rulebuilder.dto.DataDTO) ExtensionResultStatusType(org.broadleafcommerce.common.extension.ExtensionResultStatusType) FieldNotAvailableException(org.broadleafcommerce.openadmin.server.service.persistence.module.FieldNotAvailableException) MVELTranslationException(org.broadleafcommerce.openadmin.web.rulebuilder.MVELTranslationException) PersistenceException(org.broadleafcommerce.openadmin.server.service.persistence.PersistenceException) ParentEntityPersistenceException(org.broadleafcommerce.openadmin.server.service.persistence.ParentEntityPersistenceException) DataWrapper(org.broadleafcommerce.openadmin.web.rulebuilder.dto.DataWrapper) QuantityBasedRule(org.broadleafcommerce.common.rule.QuantityBasedRule) ExtensionResultHolder(org.broadleafcommerce.common.extension.ExtensionResultHolder) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) Session(org.hibernate.Session)

Example 3 with MVELTranslationException

use of org.broadleafcommerce.openadmin.web.rulebuilder.MVELTranslationException in project BroadleafCommerce by BroadleafCommerce.

the class RuleFieldValidator method validate.

@Override
public PropertyValidationResult validate(PopulateValueRequest populateValueRequest, Serializable instance) {
    if (canHandleValidation(populateValueRequest)) {
        DataDTOToMVELTranslator translator = new DataDTOToMVELTranslator();
        EntityManager em = populateValueRequest.getPersistenceManager().getDynamicEntityDao().getStandardEntityManager();
        if (SupportedFieldType.RULE_SIMPLE.equals(populateValueRequest.getMetadata().getFieldType()) || SupportedFieldType.RULE_SIMPLE_TIME.equals(populateValueRequest.getMetadata().getFieldType())) {
            // AntiSamy HTML encodes the rule JSON - pass the unHTMLEncoded version
            DataWrapper dw = ruleFieldExtractionUtility.convertJsonToDataWrapper(populateValueRequest.getProperty().getUnHtmlEncodedValue());
            if (dw != null && StringUtils.isNotEmpty(dw.getError())) {
                return new PropertyValidationResult(false, "Could not serialize JSON from rule builder: " + dw.getError());
            }
            if (dw == null || StringUtils.isEmpty(dw.getError())) {
                try {
                    String mvel = ruleFieldExtractionUtility.convertSimpleMatchRuleJsonToMvel(translator, RuleIdentifier.ENTITY_KEY_MAP.get(populateValueRequest.getMetadata().getRuleIdentifier()), populateValueRequest.getMetadata().getRuleIdentifier(), dw);
                } catch (MVELTranslationException e) {
                    return new PropertyValidationResult(false, getMvelParsingErrorMesage(dw, e));
                }
            }
        }
        if (SupportedFieldType.RULE_WITH_QUANTITY.equals(populateValueRequest.getMetadata().getFieldType())) {
            Collection<QuantityBasedRule> existingRules;
            try {
                existingRules = (Collection<QuantityBasedRule>) populateValueRequest.getFieldManager().getFieldValue(instance, populateValueRequest.getProperty().getName());
            } catch (FieldNotAvailableException e) {
                return new PropertyValidationResult(false, "Could not access rule field on Java object to set values");
            } catch (IllegalAccessException e) {
                return new PropertyValidationResult(false, "Could not access rule field on Java object to set values");
            }
            String entityKey = RuleIdentifier.ENTITY_KEY_MAP.get(populateValueRequest.getMetadata().getRuleIdentifier());
            String jsonPropertyValue = populateValueRequest.getProperty().getUnHtmlEncodedValue();
            String fieldService = populateValueRequest.getMetadata().getRuleIdentifier();
            if (!StringUtils.isEmpty(jsonPropertyValue)) {
                DataWrapper dw = ruleFieldExtractionUtility.convertJsonToDataWrapper(jsonPropertyValue);
                if (dw != null && StringUtils.isNotEmpty(dw.getError())) {
                    return new PropertyValidationResult(false, "Could not serialize JSON from rule builder: " + dw.getError());
                }
                if (dw != null && StringUtils.isEmpty(dw.getError())) {
                    for (DataDTO dto : dw.getData()) {
                        if (dto.getPk() != null) {
                            boolean foundIdToUpdate = false;
                            for (QuantityBasedRule quantityBasedRule : existingRules) {
                                Long sandBoxVersionId = sandBoxHelper.getSandBoxVersionId(quantityBasedRule.getClass(), dto.getPk());
                                if (sandBoxVersionId == null) {
                                    sandBoxVersionId = dto.getPk();
                                }
                                if (sandBoxVersionId.equals(quantityBasedRule.getId()) || sandBoxHelper.isRelatedToParentCatalogIds(quantityBasedRule, dto.getPk())) {
                                    foundIdToUpdate = true;
                                    try {
                                        String mvel = ruleFieldExtractionUtility.convertDTOToMvelString(translator, entityKey, dto, fieldService);
                                    } catch (MVELTranslationException e) {
                                        return new PropertyValidationResult(false, getMvelParsingErrorMesage(dw, e));
                                    }
                                }
                            }
                            if (!foundIdToUpdate) {
                                return new PropertyValidationResult(false, "Tried to update QuantityBasedRule with ID " + dto.getPk() + " but that rule does not exist");
                            }
                        } else {
                            // This is a new rule, just validate that it parses successfully
                            try {
                                ruleFieldExtractionUtility.convertDTOToMvelString(translator, entityKey, dto, fieldService);
                            } catch (MVELTranslationException e) {
                                return new PropertyValidationResult(false, getMvelParsingErrorMesage(dw, e));
                            }
                        }
                    }
                }
            }
        }
    }
    return new PropertyValidationResult(true);
}
Also used : MVELTranslationException(org.broadleafcommerce.openadmin.web.rulebuilder.MVELTranslationException) DataDTO(org.broadleafcommerce.openadmin.web.rulebuilder.dto.DataDTO) DataDTOToMVELTranslator(org.broadleafcommerce.openadmin.web.rulebuilder.DataDTOToMVELTranslator) DataWrapper(org.broadleafcommerce.openadmin.web.rulebuilder.dto.DataWrapper) EntityManager(javax.persistence.EntityManager) QuantityBasedRule(org.broadleafcommerce.common.rule.QuantityBasedRule) FieldNotAvailableException(org.broadleafcommerce.openadmin.server.service.persistence.module.FieldNotAvailableException)

Aggregations

MVELTranslationException (org.broadleafcommerce.openadmin.web.rulebuilder.MVELTranslationException)3 QuantityBasedRule (org.broadleafcommerce.common.rule.QuantityBasedRule)2 FieldNotAvailableException (org.broadleafcommerce.openadmin.server.service.persistence.module.FieldNotAvailableException)2 DataDTO (org.broadleafcommerce.openadmin.web.rulebuilder.dto.DataDTO)2 DataWrapper (org.broadleafcommerce.openadmin.web.rulebuilder.dto.DataWrapper)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 ParseException (java.text.ParseException)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1 EntityManager (javax.persistence.EntityManager)1 ExtensionResultHolder (org.broadleafcommerce.common.extension.ExtensionResultHolder)1 ExtensionResultStatusType (org.broadleafcommerce.common.extension.ExtensionResultStatusType)1 BroadleafRequestContext (org.broadleafcommerce.common.web.BroadleafRequestContext)1 ParentEntityPersistenceException (org.broadleafcommerce.openadmin.server.service.persistence.ParentEntityPersistenceException)1 PersistenceException (org.broadleafcommerce.openadmin.server.service.persistence.PersistenceException)1 BLCOperator (org.broadleafcommerce.openadmin.web.rulebuilder.BLCOperator)1 DataDTOToMVELTranslator (org.broadleafcommerce.openadmin.web.rulebuilder.DataDTOToMVELTranslator)1 Session (org.hibernate.Session)1