Package org.joget.apps.form.model

Source Code of org.joget.apps.form.model.AbstractSubForm

package org.joget.apps.form.model;

import java.util.ArrayList;
import java.util.Collection;
import org.joget.apps.app.dao.FormDefinitionDao;
import org.joget.apps.app.model.AppDefinition;
import org.joget.apps.app.model.FormDefinition;
import org.joget.apps.app.service.AppUtil;
import org.joget.apps.form.lib.HiddenField;
import org.joget.apps.form.service.FormService;
import org.joget.apps.form.service.FormUtil;
import org.joget.commons.util.LogUtil;
import org.joget.commons.util.StringUtil;
import org.joget.commons.util.UuidGenerator;
import org.joget.workflow.model.WorkflowAssignment;
import org.joget.workflow.model.service.WorkflowManager;
import org.springframework.beans.BeansException;

public abstract class AbstractSubForm extends Element implements FormContainer {
    public static final String PROPERTY_PARENT_SUBFORM_ID = "parentSubFormId";
    public static final String PROPERTY_SUBFORM_PARENT_ID = "subFormParentId";
   
    @Override
    public Collection<Element> getChildren(FormData formData) {
        Collection<Element> children = super.getChildren();
        if (children == null || children.isEmpty()) {
            // override getChildren to return the subform
            if (checkForRecursiveForm(this, getPropertyString("formDefId"))) {
                Form subForm = loadSubForm(formData);

                if (subForm != null) {
                    children = new ArrayList<Element>();
                    children.add(subForm);
                    setChildren(children);
                }
            }
        }
        return children;
    }
   
    /**
     * Loads the actual subform
     * @return
     * @throws BeansException
     */
    protected Form loadSubForm(FormData parentFormData) throws BeansException {
        FormData formData = new FormData();
        Form subForm = null;
        FormService formService = (FormService) FormUtil.getApplicationContext().getBean("formService");

        String json = getPropertyString("json");
        String formDefId = getPropertyString("formDefId");
        if (formDefId != null && !formDefId.isEmpty()) {
            // load subform
            AppDefinition appDef = AppUtil.getCurrentAppDefinition();
            FormDefinitionDao formDefinitionDao = (FormDefinitionDao) FormUtil.getApplicationContext().getBean("formDefinitionDao");
            FormDefinition formDef = formDefinitionDao.loadById(formDefId, appDef);
            if (formDef != null) {
                json = formDef.getJson();
            }
        }
        if (json != null && json.trim().length() > 0) {
            if (parentFormData != null && parentFormData.getProcessId() != null && !parentFormData.getProcessId().isEmpty()) {
                formData.setProcessId(parentFormData.getProcessId());
                WorkflowManager wm = (WorkflowManager) AppUtil.getApplicationContext().getBean("workflowManager");
                WorkflowAssignment wfAssignment = wm.getAssignmentByProcess(parentFormData.getProcessId());
                json = AppUtil.processHashVariable(json, wfAssignment, StringUtil.TYPE_JSON, null);
            }
           
            // use the json definition to create the subform
            try {
                subForm = (Form) formService.createElementFromJson(json);
               
                //if id field not exist, automatically add an id hidden field
                Element idElement = FormUtil.findElement(FormUtil.PROPERTY_ID, subForm, formData);
                if (idElement == null) {
                    Collection<Element> subFormElements = subForm.getChildren();
                    idElement = new HiddenField();
                    idElement.setProperty(FormUtil.PROPERTY_ID, FormUtil.PROPERTY_ID);
                    idElement.setParent(subForm);
                    subFormElements.add(idElement);
                }
               
            } catch (Exception e) {
                LogUtil.error(AbstractSubForm.class.getName(), e, null);
            }
        }

        if (subForm != null) {
            // set parent
            subForm.setParent(this);

            // replace binder(s) if necessary
            FormLoadBinder loadBinder = getLoadBinder();
            if (loadBinder != null) {
                subForm.setLoadBinder(loadBinder);
            } else {
                setLoadBinder(subForm.getLoadBinder());
            }
            FormStoreBinder storeBinder = getStoreBinder();
            if (storeBinder != null) {
                subForm.setStoreBinder(storeBinder);
            } else {
                setStoreBinder(subForm.getStoreBinder());
            }
            // recursively update parameter names for child elements
            String parentId = getCustomParameterName();
            if (parentId == null || parentId.isEmpty()) {
                parentId = getPropertyString(FormUtil.PROPERTY_ID);
            }
            updateElementParameterNames(subForm, parentId);
        }

        return subForm;
    }
   
    protected void updateElementParameterNames(Element element, String prefix) {
        if (prefix == null) {
            prefix = "";
        } else {
            String paramName = prefix + "_" + element.getPropertyString(FormUtil.PROPERTY_ID);
            element.setCustomParameterName(paramName);
        }
           
        if (element instanceof Form || element instanceof AbstractSubForm) {
            String formId = element.getPropertyString(FormUtil.PROPERTY_ID);
            if (formId == null) {
                formId = "";
            }
            prefix += "_" + formId;
        }

        // prefix parent ID set custom parameter name and readonly property for each child recursively
        boolean readonly = Boolean.valueOf(getPropertyString(FormUtil.PROPERTY_READONLY)).booleanValue();
        boolean readonlyLabel = Boolean.valueOf(getPropertyString(FormUtil.PROPERTY_READONLY_LABEL)).booleanValue();
        Collection<Element> children = element.getChildren();
        for (Element child : children) {
            if (readonly) {
                child.setProperty(FormUtil.PROPERTY_READONLY, "true");
            }
            if (readonlyLabel) {
                child.setProperty(FormUtil.PROPERTY_READONLY_LABEL, "true");
            }
            updateElementParameterNames(child, prefix);
        }
    }
   
    protected void populateParentWithSubFormKey(FormData formData) {
        String parentSubFormId = getPropertyString(PROPERTY_PARENT_SUBFORM_ID);
        if (parentSubFormId != null && !parentSubFormId.trim().isEmpty()) {
            Form subForm = getSubForm(formData);
           
            if (subForm != null) {

                // get subform's primary key value
                String subFormPrimaryKeyValue = null;
                Element subFormPrimaryElement = FormUtil.findElement(FormUtil.PROPERTY_ID, subForm, formData);
                if (subFormPrimaryElement != null) {
                    subFormPrimaryElement.formatData(formData);
                    subFormPrimaryKeyValue = FormUtil.getElementPropertyValue(subFormPrimaryElement, formData);
                }
               
                //try get value from parent field
                Form rootForm = FormUtil.findRootForm(this);
                String parentSubFormIdElementValue = "";
                Element parentSubFormIdElement = null;
                       
                if (FormUtil.PROPERTY_ID.equals(parentSubFormId) && rootForm.getParent() == null && formData.getPrimaryKeyValue() != null && !formData.getPrimaryKeyValue().isEmpty()) {
                    parentSubFormIdElementValue = formData.getPrimaryKeyValue();
                } else {
                    parentSubFormIdElement = FormUtil.findElement(parentSubFormId, rootForm, formData);
                   
                    if (parentSubFormIdElement != null) {
                        parentSubFormIdElementValue = FormUtil.getElementPropertyValue(parentSubFormIdElement, formData);
                    }
                }
               
                // generate new ID if empty
                if (subFormPrimaryKeyValue == null || subFormPrimaryKeyValue.trim().isEmpty()) {
                    // generate new ID
                    if (parentSubFormIdElementValue != null && !parentSubFormIdElementValue.isEmpty()) {
                        subFormPrimaryKeyValue = parentSubFormIdElementValue;
                    } else {
                        subFormPrimaryKeyValue = UuidGenerator.getInstance().getUuid();
                    }
                   
                    if (subFormPrimaryElement != null) {
                        // add into form data
                        String paramName = FormUtil.getElementParameterName(subFormPrimaryElement);
                        formData.addRequestParameterValues(paramName, new String[]{subFormPrimaryKeyValue});
                    } else {
                        // set value into subform's data
                        FormStoreBinder storeBinder = subForm.getStoreBinder();
                        if (storeBinder != null) {
                            FormRow row = null;
                            FormRowSet subFormRowSet = formData.getStoreBinderData(storeBinder);
                            if (subFormRowSet == null) {
                                subFormRowSet = new FormRowSet();
                            }
                            if (!subFormRowSet.isEmpty()) {
                                row = subFormRowSet.get(0);
                            } else {
                                row = new FormRow();
                                subFormRowSet.add(row);
                            }
                            row.setProperty(FormUtil.PROPERTY_ID, subFormPrimaryKeyValue);
                        }
                    }
                }

                // set value into root form's data
                if (subFormPrimaryKeyValue != null && !subFormPrimaryKeyValue.isEmpty() && !parentSubFormIdElementValue.equals(subFormPrimaryKeyValue)) {
                   
                    FormStoreBinder rootStoreBinder = rootForm.getStoreBinder();
                    if (rootStoreBinder != null) {
                        FormRowSet rootFormRowSet = formData.getStoreBinderData(rootStoreBinder);
                        if (!rootFormRowSet.isEmpty()) {
                            FormRow row = rootFormRowSet.get(0);
                            row.setProperty(parentSubFormId, subFormPrimaryKeyValue);
                        }
                    }
                    //add to request param to prevent overwrite
                    if (parentSubFormIdElement != null) {
                        String paramName = FormUtil.getElementParameterName(parentSubFormIdElement);
                        formData.addRequestParameterValues(paramName, new String[]{subFormPrimaryKeyValue});
                    }
                   
                    //set to form data primary key if the parent field is id field and the parent form is root form
                    if (FormUtil.PROPERTY_ID.equals(parentSubFormId) && rootForm.getParent() == null) {
                        formData.setPrimaryKeyValue(subFormPrimaryKeyValue);
                    }
                }
            }
        }
    }

    protected void populateSubFormWithParentKey(FormData formData) {
        String subFormParentId = getPropertyString(PROPERTY_SUBFORM_PARENT_ID);
        if (subFormParentId != null && !subFormParentId.trim().isEmpty()) {
            Form subForm = getSubForm(formData);
           
            if (subForm != null) {

                // get root form's primary key value
                String rootFormPrimaryKeyValue = null;
                Form rootForm = FormUtil.findRootForm(this);
                Element rootFormPrimaryElement = FormUtil.findElement(FormUtil.PROPERTY_ID, rootForm, formData);
                if (rootFormPrimaryElement != null) {
                    rootFormPrimaryKeyValue = FormUtil.getElementPropertyValue(rootFormPrimaryElement, formData);
                } else {
                    // look in the root form rowset
                    FormStoreBinder rootStoreBinder = rootForm.getStoreBinder();
                    if (rootStoreBinder != null) {
                        FormRowSet rootFormRowSet = formData.getStoreBinderData(rootStoreBinder);
                        if (!rootFormRowSet.isEmpty()) {
                            FormRow row = rootFormRowSet.get(0);
                            rootFormPrimaryKeyValue = row.getId();
                        }
                    }
                }
                if (rootFormPrimaryKeyValue == null || rootFormPrimaryKeyValue.isEmpty()) {
                    rootFormPrimaryKeyValue = formData.getPrimaryKeyValue();
                }
                // set value into subform's data
                if (rootFormPrimaryKeyValue != null && !rootFormPrimaryKeyValue.isEmpty()) {
                    Element subFormForeignKeyElement = FormUtil.findElement(subFormParentId, subForm, formData);
                    if (subFormForeignKeyElement != null) {
                        String paramName = FormUtil.getElementParameterName(subFormForeignKeyElement);
                        formData.addRequestParameterValues(paramName, new String[]{rootFormPrimaryKeyValue});
                    }
                }

            }
        }
    }
   
    @Override
    public String getPrimaryKeyValue(FormData formData) {
        String primaryKeyValue = null;
        if (formData != null && getLoadBinder() != null) {
            // custom load binder is used, custom primary key value
            Form rootForm = FormUtil.findRootForm(this);
            String parentSubFormId = getPropertyString(PROPERTY_PARENT_SUBFORM_ID);
            // get value from parent field
            Element foreignKeyElement = FormUtil.findElement(parentSubFormId, rootForm, formData);
            if (foreignKeyElement != null) {
                primaryKeyValue = FormUtil.getElementPropertyValue(foreignKeyElement, formData);
            }
            if (primaryKeyValue == null || primaryKeyValue.trim().isEmpty()) {
                primaryKeyValue = super.getPrimaryKeyValue(formData);
            }
        } else {
            primaryKeyValue = super.getPrimaryKeyValue(formData);
        }
        return primaryKeyValue;
    }
   
    @Override
    public FormRowSet formatData(FormData formData) {
        FormRowSet rowSet = null;

        // set parent field with subform's primary key value
        populateParentWithSubFormKey(formData);

        // set subform field with parent's primary key value
        populateSubFormWithParentKey(formData);

        return rowSet;
    }
   
    protected boolean checkForRecursiveForm(Element e, String id) {
        //Recursive find parent and compare
        Form form = FormUtil.findRootForm(e);
        if (form != null && form != e) {
            String formId = form.getPropertyString(FormUtil.PROPERTY_ID);
            if (id.equals(formId)) {
                return false;
            } else {
                return checkForRecursiveForm(form, id);
            }
        }
        return true;
    }
   
    protected Form getSubForm(FormData formData) {
        Collection<Element> children = getChildren(formData);
        if (children != null && !children.isEmpty()) {
            return (Form) getChildren().iterator().next();
        }
        return null;
    }
   
    @Override
    public boolean continueValidation(FormData formData) {
        if ("true".equalsIgnoreCase(getPropertyString(FormUtil.PROPERTY_READONLY))) {
            return false;
        }
       
        return true;
    }
}
TOP

Related Classes of org.joget.apps.form.model.AbstractSubForm

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.