/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.dynamic.data.lists.form.web.internal.converter; import com.liferay.dynamic.data.lists.form.web.internal.converter.model.DDLFormRule; import com.liferay.dynamic.data.lists.form.web.internal.converter.model.DDLFormRuleAction; import com.liferay.dynamic.data.lists.form.web.internal.converter.model.DDLFormRuleCondition; import com.liferay.dynamic.data.mapping.model.DDMFormRule; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.StringUtil; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.UnaryOperator; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.commons.lang.math.NumberUtils; import org.osgi.service.component.annotations.Component; /** * @author Leonardo Barros * @author Marcellus Tavares */ @Component(immediate = true, service = DDLFormRuleToDDMFormRuleConverter.class) public class DDLFormRuleToDDMFormRuleConverter { public List<DDMFormRule> convert(List<DDLFormRule> ddlFormRules) { List<DDMFormRule> ddmFormRules = new ArrayList<>(); for (DDLFormRule ddlFormRule : ddlFormRules) { ddmFormRules.add(convertRule(ddlFormRule)); } return ddmFormRules; } protected String convertCondition( DDLFormRuleCondition ddlFormRuleCondition) { String operator = ddlFormRuleCondition.getOperator(); String functionName = _operatorFunctionNameMap.get(operator); List<DDLFormRuleCondition.Operand> operands = ddlFormRuleCondition.getOperands(); if (functionName == null) { return String.format( _comparisonExpressionFormat, convertOperand(operands.get(0)), _operatorMap.get(operator), convertOperand(operands.get(1))); } String condition = createCondition(functionName, operands); if (operator.startsWith("not")) { return String.format(_notExpressionFormat, condition); } return condition; } protected String convertConditions( String logicalOperator, List<DDLFormRuleCondition> ddlFormRuleConditions) { if (ddlFormRuleConditions.size() == 1) { return convertCondition(ddlFormRuleConditions.get(0)); } StringBundler sb = new StringBundler(ddlFormRuleConditions.size() * 4); for (DDLFormRuleCondition ddlFormRuleCondition : ddlFormRuleConditions) { sb.append(convertCondition(ddlFormRuleCondition)); sb.append(StringPool.SPACE); sb.append(logicalOperator); sb.append(StringPool.SPACE); } sb.setIndex(sb.index() - 3); return sb.toString(); } protected String convertOperand(DDLFormRuleCondition.Operand operand) { if (Objects.equals("field", operand.getType())) { return String.format( _functionCallUnaryExpressionFormat, "getValue", StringUtil.quote(operand.getValue())); } String value = operand.getValue(); if (NumberUtils.isNumber(value)) { return value; } String[] values = StringUtil.split(value); UnaryOperator<String> quoteOperation = StringUtil::quote; UnaryOperator<String> trimOperation = StringUtil::trim; Stream<String> valuesStream = Stream.of(values); Stream<String> valueStream = valuesStream.map( trimOperation.andThen(quoteOperation)); return valueStream.collect( Collectors.joining(StringPool.COMMA_AND_SPACE)); } protected String convertOperands( List<DDLFormRuleCondition.Operand> operands) { StringBundler sb = new StringBundler(operands.size()); for (DDLFormRuleCondition.Operand operand : operands) { sb.append(convertOperand(operand)); sb.append(StringPool.COMMA_AND_SPACE); } sb.setIndex(sb.index() - 1); return sb.toString(); } protected DDMFormRule convertRule(DDLFormRule ddlFormRule) { String condition = convertConditions( ddlFormRule.getLogicalOperator(), ddlFormRule.getDDLFormRuleConditions()); List<String> actions = new ArrayList<>(); for (DDLFormRuleAction ddlFormRuleAction : ddlFormRule.getDDLFormRuleActions()) { actions.add(ddlFormRuleAction.serialize()); } return new DDMFormRule(condition, actions); } protected String createCondition( String functionName, List<DDLFormRuleCondition.Operand> operands) { if (Objects.equals(functionName, "belongsTo")) { operands.remove(0); } return String.format( _functionCallUnaryExpressionFormat, functionName, convertOperands(operands)); } private static final String _comparisonExpressionFormat = "%s %s %s"; private static final String _functionCallUnaryExpressionFormat = "%s(%s)"; private static final String _notExpressionFormat = "not(%s)"; private static final Map<String, String> _operatorFunctionNameMap = new HashMap<>(); private static final Map<String, String> _operatorMap = new HashMap<>(); static { _operatorFunctionNameMap.put("belongs-to", "belongsTo"); _operatorFunctionNameMap.put("contains", "contains"); _operatorFunctionNameMap.put("equals-to", "equals"); _operatorFunctionNameMap.put("is-empty", "isEmpty"); _operatorFunctionNameMap.put("not-contains", "contains"); _operatorFunctionNameMap.put("not-equals-to", "equals"); _operatorFunctionNameMap.put("not-is-empty", "isEmpty"); _operatorMap.put("greater-than", ">"); _operatorMap.put("greater-than-equals", ">="); _operatorMap.put("less-than", "<"); _operatorMap.put("less-than-equals", "<="); } }