/**
* 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.mapping.form.renderer.internal;
import com.liferay.dynamic.data.mapping.model.DDMDataProviderInstance;
import com.liferay.dynamic.data.mapping.model.DDMForm;
import com.liferay.dynamic.data.mapping.model.DDMFormField;
import com.liferay.dynamic.data.mapping.model.DDMFormFieldValidation;
import com.liferay.dynamic.data.mapping.model.DDMFormRule;
import com.liferay.dynamic.data.mapping.service.DDMDataProviderInstanceService;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.CharPool;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.MapUtil;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
/**
* @author Leonardo Barros
* @author Rafael Praxedes
*/
public class DDMFormTemplateContextFactoryHelper {
public DDMFormTemplateContextFactoryHelper(
DDMDataProviderInstanceService ddmDataProviderInstanceService) {
_ddmDataProviderInstanceService = ddmDataProviderInstanceService;
}
public Map<String, Map<String, Object>> getDataProviderSettings(
DDMForm ddmForm) {
Map<String, Map<String, Object>> map = new HashMap<>();
extractDataProviderSettingsFromFieldSettings(ddmForm, map);
extractDataProviderSettingsFromAutoFillActions(ddmForm, map);
return map;
}
public Set<String> getEvaluableDDMFormFieldNames(DDMForm ddmForm) {
Set<String> evaluableDDMFormFieldNames = new HashSet<>();
Map<String, DDMFormField> ddmFormFieldsMap =
ddmForm.getDDMFormFieldsMap(true);
Set<String> ddmFormFieldNames = ddmFormFieldsMap.keySet();
evaluableDDMFormFieldNames.addAll(
getReferencedFieldNamesByDDMFormRules(
ddmForm.getDDMFormRules(), ddmFormFieldNames));
for (DDMFormField ddmFormField : ddmFormFieldsMap.values()) {
if (isDDMFormFieldEvaluable(ddmFormField)) {
evaluableDDMFormFieldNames.add(ddmFormField.getName());
}
String visibilityExpression =
ddmFormField.getVisibilityExpression();
evaluableDDMFormFieldNames.addAll(
getReferencedFieldNamesByExpression(
visibilityExpression, ddmFormFieldNames));
}
return evaluableDDMFormFieldNames;
}
protected Map<String, Object> createDataProviderSettingsMap(
String dataProviderInstanceUUID, String outputParameterName,
Map<String, String> inputParameters) {
Map<String, Object> ddmDataProviderSettingsMap = new HashMap<>();
ddmDataProviderSettingsMap.put(
"dataProviderInstanceUUID", dataProviderInstanceUUID);
ddmDataProviderSettingsMap.put("inputParameters", inputParameters);
ddmDataProviderSettingsMap.put(
"outputParameterName", outputParameterName);
return ddmDataProviderSettingsMap;
}
protected Map<String, String> extractAutoFillParameters(String expression) {
if (Validator.isNull(expression)) {
return Collections.emptyMap();
}
String[] innerExpressions = StringUtil.split(
expression, CharPool.SEMICOLON);
Map<String, String> map = new HashMap<>();
Stream.of(innerExpressions).forEach(
innerExpression -> {
String[] parts = StringUtil.split(
innerExpression, CharPool.EQUAL);
map.put(parts[0], parts[1]);
});
return map;
}
protected void extractDataProviderSettings(
DDMFormField ddmFormField,
Map<String, Map<String, Object>> dataProviderSettings) {
long ddmDataProviderInstanceId = MapUtil.getLong(
ddmFormField.getProperties(), "ddmDataProviderInstanceId");
if (ddmDataProviderInstanceId == 0) {
return;
}
try {
DDMDataProviderInstance ddmDataProviderInstance =
_ddmDataProviderInstanceService.getDataProviderInstance(
ddmDataProviderInstanceId);
String ddmDataProviderInstanceOutput = GetterUtil.getString(
ddmFormField.getProperty("ddmDataProviderInstanceOutput"));
dataProviderSettings.put(
ddmFormField.getName(),
createDataProviderSettingsMap(
ddmDataProviderInstance.getUuid(),
ddmDataProviderInstanceOutput, Collections.emptyMap()));
}
catch (PortalException pe) {
if (_log.isDebugEnabled()) {
_log.debug(pe, pe);
}
}
}
protected void extractDataProviderSettings(
String action, Map<String, DDMFormField> ddmFormFields,
Map<String, Map<String, Object>> dataProviderSettings) {
Matcher matcher = _callFunctionPattern.matcher(action);
if (matcher.find()) {
String dataProviderInstanceUUID = matcher.group(1);
Map<String, String> inputParameters = extractAutoFillParameters(
matcher.group(2));
Map<String, String> outputParameters = extractAutoFillParameters(
matcher.group(3));
Stream<Entry<String, String>> outputParametersStream =
outputParameters.entrySet().stream();
outputParametersStream = outputParametersStream.filter(
entry -> isSelectField(ddmFormFields.get(entry.getKey())));
outputParametersStream.forEach(
entry -> {
dataProviderSettings.put(
entry.getKey(),
createDataProviderSettingsMap(
dataProviderInstanceUUID, entry.getValue(),
inputParameters));
});
}
}
protected void extractDataProviderSettingsFromAutoFillActions(
DDMForm ddmForm,
Map<String, Map<String, Object>> dataProviderSettings) {
List<DDMFormRule> ddmFormRules = ddmForm.getDDMFormRules();
Map<String, DDMFormField> ddmFormFields = ddmForm.getDDMFormFieldsMap(
true);
Stream<DDMFormRule> stream = ddmFormRules.stream();
stream.flatMap(
ddmFormRule -> ddmFormRule.getActions().stream()
).filter(
this::isAutofillAction
).forEach(
action -> extractDataProviderSettings(
action, ddmFormFields, dataProviderSettings)
);
}
protected void extractDataProviderSettingsFromFieldSettings(
DDMForm ddmForm,
Map<String, Map<String, Object>> dataProviderSettings) {
Map<String, DDMFormField> ddmFormFields = ddmForm.getDDMFormFieldsMap(
true);
Stream<DDMFormField> ddmFormFieldStream =
ddmFormFields.values().stream();
ddmFormFieldStream.filter(
this::hasDataProviderSettings
).forEach(
ddmFormField -> extractDataProviderSettings(
ddmFormField, dataProviderSettings)
);
}
protected Set<String> getReferencedFieldNamesByDDMFormRules(
List<DDMFormRule> ddmFormRules, Set<String> ddmFormFieldNames) {
Set<String> referencedFieldNames = new HashSet<>();
for (DDMFormRule ddmFormRule : ddmFormRules) {
String condition = ddmFormRule.getCondition();
referencedFieldNames.addAll(
getReferencedFieldNamesByExpression(
condition, ddmFormFieldNames));
for (String action : ddmFormRule.getActions()) {
referencedFieldNames.addAll(
getReferencedFieldNamesByExpression(
action, ddmFormFieldNames));
}
}
return referencedFieldNames;
}
protected Set<String> getReferencedFieldNamesByExpression(
String expression, Set<String> ddmFormFieldNames) {
if (Validator.isNull(expression)) {
return Collections.emptySet();
}
Set<String> referencedFieldNames = new HashSet<>();
for (String ddmFormFieldName : ddmFormFieldNames) {
if (expression.contains(ddmFormFieldName)) {
referencedFieldNames.add(ddmFormFieldName);
}
}
return referencedFieldNames;
}
protected boolean hasDataProviderSettings(DDMFormField ddmFormField) {
if (MapUtil.getLong(
ddmFormField.getProperties(),
"ddmDataProviderInstanceId") > 0) {
return true;
}
return false;
}
protected boolean isAutofillAction(String action) {
Matcher matcher = _callFunctionPattern.matcher(action);
return matcher.matches();
}
protected boolean isDDMFormFieldEvaluable(DDMFormField ddmFormField) {
if (ddmFormField.isRequired()) {
return true;
}
DDMFormFieldValidation ddmFormFieldValidation =
ddmFormField.getDDMFormFieldValidation();
if ((ddmFormFieldValidation != null) &&
Validator.isNotNull(ddmFormFieldValidation.getExpression())) {
return true;
}
return false;
}
protected boolean isSelectField(DDMFormField ddmFormField) {
if (ddmFormField == null) {
return false;
}
String type = ddmFormField.getType();
return type.equals("select");
}
private static final Log _log = LogFactoryUtil.getLog(
DDMFormTemplateContextFactoryHelper.class);
private static final Pattern _callFunctionPattern = Pattern.compile(
"call\\(\\s*\'([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-" +
"[0-9a-f]{12})\'\\s*,\\s*\'(.*)\'\\s*,\\s*\'(.*)\'\\s*\\)");
private final DDMDataProviderInstanceService
_ddmDataProviderInstanceService;
}