/**
* 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.portlet.action;
import com.liferay.dynamic.data.lists.exception.RecordSetSettingsRedirectURLException;
import com.liferay.dynamic.data.lists.form.web.internal.converter.DDLFormRuleDeserializer;
import com.liferay.dynamic.data.lists.form.web.internal.converter.DDLFormRuleToDDMFormRuleConverter;
import com.liferay.dynamic.data.lists.form.web.internal.converter.model.DDLFormRule;
import com.liferay.dynamic.data.lists.model.DDLRecordSet;
import com.liferay.dynamic.data.lists.model.DDLRecordSetConstants;
import com.liferay.dynamic.data.lists.model.DDLRecordSetSettings;
import com.liferay.dynamic.data.lists.service.DDLRecordSetService;
import com.liferay.dynamic.data.mapping.exception.StructureDefinitionException;
import com.liferay.dynamic.data.mapping.exception.StructureLayoutException;
import com.liferay.dynamic.data.mapping.form.values.query.DDMFormValuesQuery;
import com.liferay.dynamic.data.mapping.form.values.query.DDMFormValuesQueryFactory;
import com.liferay.dynamic.data.mapping.io.DDMFormJSONDeserializer;
import com.liferay.dynamic.data.mapping.io.DDMFormLayoutJSONDeserializer;
import com.liferay.dynamic.data.mapping.io.DDMFormValuesJSONDeserializer;
import com.liferay.dynamic.data.mapping.model.DDMForm;
import com.liferay.dynamic.data.mapping.model.DDMFormLayout;
import com.liferay.dynamic.data.mapping.model.DDMFormRule;
import com.liferay.dynamic.data.mapping.model.DDMStructure;
import com.liferay.dynamic.data.mapping.model.DDMStructureConstants;
import com.liferay.dynamic.data.mapping.model.Value;
import com.liferay.dynamic.data.mapping.service.DDMStructureService;
import com.liferay.dynamic.data.mapping.storage.DDMFormFieldValue;
import com.liferay.dynamic.data.mapping.storage.DDMFormValues;
import com.liferay.dynamic.data.mapping.storage.StorageType;
import com.liferay.dynamic.data.mapping.util.DDMFormFactory;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.service.ServiceContext;
import com.liferay.portal.kernel.service.ServiceContextFactory;
import com.liferay.portal.kernel.service.ServiceContextThreadLocal;
import com.liferay.portal.kernel.service.WorkflowDefinitionLinkLocalService;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.Portal;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/**
* @author Marcellus Tavares
*/
@Component(immediate = true, service = SaveRecordSetMVCCommandHelper.class)
public class SaveRecordSetMVCCommandHelper {
public DDLRecordSet saveRecordSet(
PortletRequest portletRequest, PortletResponse portletResponse)
throws Exception {
long recordSetId = ParamUtil.getLong(portletRequest, "recordSetId");
if (recordSetId == 0) {
return addRecordSet(portletRequest, portletResponse);
}
else {
return updateRecordSet(portletRequest, portletResponse);
}
}
protected DDMStructure addDDMStructure(
PortletRequest portletRequest, DDMFormValues settingsDDMFormValues)
throws Exception {
ServiceContext serviceContext = ServiceContextFactory.getInstance(
DDMStructure.class.getName(), portletRequest);
ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
WebKeys.THEME_DISPLAY);
long groupId = ParamUtil.getLong(portletRequest, "groupId");
String structureKey = ParamUtil.getString(
portletRequest, "structureKey");
String storageType = getStorageType(settingsDDMFormValues);
String name = ParamUtil.getString(portletRequest, "name");
String description = ParamUtil.getString(portletRequest, "description");
DDMForm ddmForm = getDDMForm(portletRequest, serviceContext);
DDMFormLayout ddmFormLayout = getDDMFormLayout(portletRequest);
return ddmStructureService.addStructure(
groupId, DDMStructureConstants.DEFAULT_PARENT_STRUCTURE_ID,
_portal.getClassNameId(DDLRecordSet.class), structureKey,
getLocalizedMap(themeDisplay.getSiteDefaultLocale(), name),
getLocalizedMap(themeDisplay.getSiteDefaultLocale(), description),
ddmForm, ddmFormLayout, storageType,
DDMStructureConstants.TYPE_AUTO, serviceContext);
}
protected DDLRecordSet addRecordSet(
PortletRequest portletRequest, long ddmStructureId)
throws Exception {
ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
WebKeys.THEME_DISPLAY);
String name = ParamUtil.getString(portletRequest, "name");
String description = ParamUtil.getString(portletRequest, "description");
return addRecordSet(
portletRequest, ddmStructureId,
getLocalizedMap(themeDisplay.getSiteDefaultLocale(), name),
getLocalizedMap(themeDisplay.getSiteDefaultLocale(), description));
}
protected DDLRecordSet addRecordSet(
PortletRequest portletRequest, long ddmStructureId,
Map<Locale, String> nameMap, Map<Locale, String> descriptionMap)
throws Exception {
long groupId = ParamUtil.getLong(portletRequest, "groupId");
String recordSetKey = ParamUtil.getString(
portletRequest, "recordSetKey");
ServiceContext serviceContext = ServiceContextFactory.getInstance(
DDLRecordSet.class.getName(), portletRequest);
if (ParamUtil.getBoolean(portletRequest, "autoSave")) {
serviceContext.setAttribute(
"status", WorkflowConstants.STATUS_DRAFT);
}
return ddlRecordSetService.addRecordSet(
groupId, ddmStructureId, recordSetKey, nameMap, descriptionMap,
DDLRecordSetConstants.MIN_DISPLAY_ROWS_DEFAULT,
DDLRecordSetConstants.SCOPE_FORMS, serviceContext);
}
protected DDLRecordSet addRecordSet(
PortletRequest portletRequest, PortletResponse portletResponse)
throws Exception {
DDMFormValues settingsDDMFormValues = getSettingsDDMFormValues(
portletRequest);
DDMStructure ddmStructure = addDDMStructure(
portletRequest, settingsDDMFormValues);
DDLRecordSet recordSet = addRecordSet(
portletRequest, ddmStructure.getStructureId());
updateRecordSetSettings(
portletRequest, recordSet, settingsDDMFormValues);
return recordSet;
}
protected DDMForm getDDMForm(
PortletRequest portletRequest, ServiceContext serviceContext)
throws PortalException {
try {
String definition = ParamUtil.getString(
portletRequest, "definition");
DDMForm ddmForm = ddmFormJSONDeserializer.deserialize(definition);
serviceContext.setAttribute("form", ddmForm);
ServiceContextThreadLocal.pushServiceContext(serviceContext);
List<DDMFormRule> ddmFormRules = getDDMFormRules(portletRequest);
ddmForm.setDDMFormRules(ddmFormRules);
return ddmForm;
}
catch (PortalException pe) {
throw new StructureDefinitionException(pe);
}
finally {
ServiceContextThreadLocal.popServiceContext();
}
}
protected DDMFormLayout getDDMFormLayout(PortletRequest portletRequest)
throws PortalException {
try {
String layout = ParamUtil.getString(portletRequest, "layout");
return ddmFormLayoutJSONDeserializer.deserialize(layout);
}
catch (PortalException pe) {
throw new StructureLayoutException(pe);
}
}
protected List<DDMFormRule> getDDMFormRules(PortletRequest portletRequest)
throws PortalException {
String rules = ParamUtil.getString(portletRequest, "rules");
if (Validator.isNull(rules) || Objects.equals("[]", rules)) {
return Collections.emptyList();
}
List<DDLFormRule> ddlFormRules = ddlFormRuleDeserializer.deserialize(
rules);
return ddlFormRulesToDDMFormRulesConverter.convert(ddlFormRules);
}
protected Map<Locale, String> getLocalizedMap(Locale locale, String value) {
Map<Locale, String> localizedMap = new HashMap<>();
localizedMap.put(locale, value);
return localizedMap;
}
protected DDMFormValues getSettingsDDMFormValues(
PortletRequest portletRequest)
throws PortalException {
String serializedSettingsDDMFormValues = ParamUtil.getString(
portletRequest, "serializedSettingsDDMFormValues");
DDMForm ddmForm = DDMFormFactory.create(DDLRecordSetSettings.class);
DDMFormValues settingsDDMFormValues =
ddmFormValuesJSONDeserializer.deserialize(
ddmForm, serializedSettingsDDMFormValues);
return settingsDDMFormValues;
}
protected String getStorageType(DDMFormValues ddmFormValues)
throws PortalException {
DDMFormValuesQuery ddmFormValuesQuery =
ddmFormValuesQueryFactory.create(ddmFormValues, "/storageType");
DDMFormFieldValue ddmFormFieldValue =
ddmFormValuesQuery.selectSingleDDMFormFieldValue();
Value value = ddmFormFieldValue.getValue();
String storageType = value.getString(ddmFormValues.getDefaultLocale());
if (Validator.isNull(storageType)) {
storageType = StorageType.JSON.toString();
}
return storageType;
}
protected String getWorkflowDefinition(DDMFormValues ddmFormValues)
throws PortalException {
DDMFormValuesQuery ddmFormValuesQuery =
ddmFormValuesQueryFactory.create(
ddmFormValues, "/workflowDefinition");
DDMFormFieldValue ddmFormFieldValue =
ddmFormValuesQuery.selectSingleDDMFormFieldValue();
Value value = ddmFormFieldValue.getValue();
return value.getString(ddmFormValues.getDefaultLocale());
}
protected DDMStructure updateDDMStructure(PortletRequest portletRequest)
throws Exception {
ServiceContext serviceContext = ServiceContextFactory.getInstance(
DDMStructure.class.getName(), portletRequest);
long ddmStructureId = ParamUtil.getLong(
portletRequest, "ddmStructureId");
String name = ParamUtil.getString(portletRequest, "name");
String description = ParamUtil.getString(portletRequest, "description");
DDMForm ddmForm = getDDMForm(portletRequest, serviceContext);
DDMFormLayout ddmFormLayout = getDDMFormLayout(portletRequest);
return ddmStructureService.updateStructure(
ddmStructureId, DDMStructureConstants.DEFAULT_PARENT_STRUCTURE_ID,
getLocalizedMap(ddmForm.getDefaultLocale(), name),
getLocalizedMap(ddmForm.getDefaultLocale(), description), ddmForm,
ddmFormLayout, serviceContext);
}
protected DDLRecordSet updateRecordSet(
PortletRequest portletRequest, long ddmStructureId)
throws Exception {
ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
WebKeys.THEME_DISPLAY);
long recordSetId = ParamUtil.getLong(portletRequest, "recordSetId");
String name = ParamUtil.getString(portletRequest, "name");
String description = ParamUtil.getString(portletRequest, "description");
ServiceContext serviceContext = ServiceContextFactory.getInstance(
DDLRecordSet.class.getName(), portletRequest);
if (ParamUtil.getBoolean(portletRequest, "autoSave")) {
serviceContext.setAttribute(
"status", WorkflowConstants.ACTION_SAVE_DRAFT);
}
return ddlRecordSetService.updateRecordSet(
recordSetId, ddmStructureId,
getLocalizedMap(themeDisplay.getSiteDefaultLocale(), name),
getLocalizedMap(themeDisplay.getSiteDefaultLocale(), description),
DDLRecordSetConstants.MIN_DISPLAY_ROWS_DEFAULT, serviceContext);
}
protected DDLRecordSet updateRecordSet(
PortletRequest portletRequest, PortletResponse portletResponse)
throws Exception {
DDMStructure ddmStructure = updateDDMStructure(portletRequest);
DDLRecordSet recordSet = updateRecordSet(
portletRequest, ddmStructure.getStructureId());
DDMFormValues settingsDDMFormValues = getSettingsDDMFormValues(
portletRequest);
updateRecordSetSettings(
portletRequest, recordSet, settingsDDMFormValues);
return recordSet;
}
protected void updateRecordSetSettings(
PortletRequest portletRequest, DDLRecordSet recordSet,
DDMFormValues settingsDDMFormValues)
throws PortalException {
validateRedirectURL(settingsDDMFormValues);
ddlRecordSetService.updateRecordSet(
recordSet.getRecordSetId(), settingsDDMFormValues);
updateWorkflowDefinitionLink(
portletRequest, recordSet, settingsDDMFormValues);
}
protected void updateWorkflowDefinitionLink(
PortletRequest portletRequest, DDLRecordSet recordSet,
DDMFormValues ddmFormValues)
throws PortalException {
ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
WebKeys.THEME_DISPLAY);
long groupId = ParamUtil.getLong(portletRequest, "groupId");
String workflowDefinition = getWorkflowDefinition(ddmFormValues);
if (workflowDefinition.equals("no-workflow")) {
workflowDefinition = "";
}
workflowDefinitionLinkLocalService.updateWorkflowDefinitionLink(
themeDisplay.getUserId(), themeDisplay.getCompanyId(), groupId,
DDLRecordSet.class.getName(), recordSet.getRecordSetId(), 0,
workflowDefinition);
}
protected void validateRedirectURL(DDMFormValues settingsDDMFormValues)
throws PortalException {
Map<String, List<DDMFormFieldValue>> ddmFormFieldValuesMap =
settingsDDMFormValues.getDDMFormFieldValuesMap();
if (!ddmFormFieldValuesMap.containsKey("redirectURL")) {
return;
}
List<DDMFormFieldValue> ddmFormFieldValues = ddmFormFieldValuesMap.get(
"redirectURL");
DDMFormFieldValue ddmFormFieldValue = ddmFormFieldValues.get(0);
Value value = ddmFormFieldValue.getValue();
for (Locale availableLocale : value.getAvailableLocales()) {
String valueString = value.getString(availableLocale);
if (Validator.isNotNull(valueString)) {
String escapedRedirect = _portal.escapeRedirect(valueString);
if (Validator.isNull(escapedRedirect)) {
throw new RecordSetSettingsRedirectURLException();
}
}
}
}
@Reference
protected DDLFormRuleDeserializer ddlFormRuleDeserializer;
@Reference
protected DDLFormRuleToDDMFormRuleConverter
ddlFormRulesToDDMFormRulesConverter;
@Reference
protected DDLRecordSetService ddlRecordSetService;
@Reference
protected DDMFormJSONDeserializer ddmFormJSONDeserializer;
@Reference
protected DDMFormLayoutJSONDeserializer ddmFormLayoutJSONDeserializer;
@Reference
protected DDMFormValuesJSONDeserializer ddmFormValuesJSONDeserializer;
@Reference
protected DDMFormValuesQueryFactory ddmFormValuesQueryFactory;
@Reference
protected DDMStructureService ddmStructureService;
@Reference
protected volatile WorkflowDefinitionLinkLocalService
workflowDefinitionLinkLocalService;
@Reference
private Portal _portal;
}