Search in sources :

Example 1 with CampaignFormElement

use of de.symeda.sormas.api.campaign.form.CampaignFormElement in project SORMAS-Project by hzi-braunschweig.

the class CampaignFormMetaFacadeEjb method validateAndClean.

@Override
public void validateAndClean(CampaignFormMetaDto campaignFormMetaDto) throws ValidationRuntimeException {
    if (CollectionUtils.isEmpty(campaignFormMetaDto.getCampaignFormElements())) {
        return;
    }
    // Throw an exception when the schema definition contains an element without an ID or type
    campaignFormMetaDto.getCampaignFormElements().stream().filter(e -> StringUtils.isBlank(e.getId()) || StringUtils.isBlank(e.getType())).findFirst().ifPresent(e -> {
        if (StringUtils.isBlank(e.getId())) {
            throw new ValidationRuntimeException(I18nProperties.getValidationError(Validations.campaignFormElementIdRequired));
        } else {
            throw new ValidationRuntimeException(I18nProperties.getValidationError(Validations.campaignFormElementTypeRequired, e.getId()));
        }
    });
    // Throw an exception when the schema definition contains the same ID more than once
    campaignFormMetaDto.getCampaignFormElements().forEach(e -> {
        if (Collections.frequency(campaignFormMetaDto.getCampaignFormElements(), e) > 1) {
            throw new ValidationRuntimeException(I18nProperties.getValidationError(Validations.campaignFormElementDuplicateId, e.getId()));
        }
    });
    // Throw an error if any translation does not have a language code or contains an element without an ID or caption
    if (CollectionUtils.isNotEmpty(campaignFormMetaDto.getCampaignFormTranslations())) {
        campaignFormMetaDto.getCampaignFormTranslations().forEach(cft -> {
            if (StringUtils.isBlank(cft.getLanguageCode())) {
                throw new ValidationRuntimeException(I18nProperties.getValidationError(Validations.campaignFormTranslationLanguageCodeRequired));
            }
            cft.getTranslations().stream().filter(t -> StringUtils.isBlank(t.getElementId()) || StringUtils.isBlank(t.getCaption())).findFirst().ifPresent(e -> {
                if (StringUtils.isBlank(e.getElementId())) {
                    throw new ValidationRuntimeException(I18nProperties.getValidationError(Validations.campaignFormTranslationIdRequired));
                } else {
                    throw new ValidationRuntimeException(I18nProperties.getValidationError(Validations.campaignFormTranslationCaptionRequired, e.getElementId(), cft.getLanguageCode()));
                }
            });
        });
    }
    Map<String, String> idsAndTypes = campaignFormMetaDto.getCampaignFormElements().stream().collect(Collectors.toMap(CampaignFormElement::getId, CampaignFormElement::getType));
    for (CampaignFormElement element : campaignFormMetaDto.getCampaignFormElements()) {
        // Clean the element caption from all HTML tags that are not explicitly allowed
        if (StringUtils.isNotBlank(element.getCaption())) {
            Whitelist whitelist = Whitelist.none();
            whitelist.addTags(CampaignFormElement.ALLOWED_HTML_TAGS);
            element.setCaption(HtmlHelper.cleanHtml(element.getCaption(), whitelist));
        }
        // Validate form elements
        validateCampaignFormElementType(element.getId(), element.getType());
        validateCampaignFormElementStyles(element.getId(), element.getStyles());
        if (StringUtils.isNotBlank(element.getDependingOn()) && ArrayUtils.isEmpty(element.getDependingOnValues())) {
            throw new ValidationRuntimeException(I18nProperties.getValidationError(Validations.campaignFormDependingOnValuesMissing, element.getId()));
        }
        validateCampaignFormMetaDependency(element.getId(), element.getDependingOn(), element.getDependingOnValues(), idsAndTypes);
    }
    // Validate element IDs used in translations and clean HTML used in translation captions
    if (CollectionUtils.isNotEmpty(campaignFormMetaDto.getCampaignFormTranslations())) {
        for (CampaignFormTranslations translations : campaignFormMetaDto.getCampaignFormTranslations()) {
            translations.getTranslations().forEach(e -> {
                if (idsAndTypes.get(e.getElementId()) == null) {
                    throw new ValidationRuntimeException(I18nProperties.getValidationError(Validations.campaignFormTranslationIdInvalid, e.getElementId(), translations.getLanguageCode()));
                }
                if (StringUtils.isNotBlank(e.getCaption())) {
                    Whitelist whitelist = Whitelist.none();
                    whitelist.addTags(CampaignFormElement.ALLOWED_HTML_TAGS);
                    e.setCaption(HtmlHelper.cleanHtml(e.getCaption(), whitelist));
                }
            });
        }
    }
}
Also used : CampaignFormTranslations(de.symeda.sormas.api.campaign.form.CampaignFormTranslations) CampaignFormElement(de.symeda.sormas.api.campaign.form.CampaignFormElement) Whitelist(org.jsoup.safety.Whitelist) ValidationRuntimeException(de.symeda.sormas.api.utils.ValidationRuntimeException)

Example 2 with CampaignFormElement

use of de.symeda.sormas.api.campaign.form.CampaignFormElement in project SORMAS-Project by hzi-braunschweig.

the class ExpressionProcessorTest method setup.

@Before
public void setup() throws IOException {
    GridLayout campaignFormLayout = new GridLayout(12, 1);
    ObjectMapper objectMapper = new ObjectMapper();
    List<CampaignFormElement> campaignFormElements = createData(objectMapper, this.getClass().getResourceAsStream("/campaign/expressions/formelements.json"), CampaignFormElement.class);
    List<CampaignFormDataEntry> campaignFormDataEntries = createData(objectMapper, this.getClass().getResourceAsStream("/campaign/expressions/formvalues.json"), CampaignFormDataEntry.class);
    campaignFormBuilder = new CampaignFormBuilder(campaignFormElements, campaignFormDataEntries, campaignFormLayout, Collections.emptyList());
    campaignFormBuilder.buildForm();
    expressionProcessor = new ExpressionProcessor(campaignFormBuilder);
}
Also used : GridLayout(com.vaadin.ui.GridLayout) CampaignFormBuilder(de.symeda.sormas.ui.campaign.campaigndata.CampaignFormBuilder) CampaignFormElement(de.symeda.sormas.api.campaign.form.CampaignFormElement) CampaignFormDataEntry(de.symeda.sormas.api.campaign.data.CampaignFormDataEntry) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) Before(org.junit.Before)

Example 3 with CampaignFormElement

use of de.symeda.sormas.api.campaign.form.CampaignFormElement in project SORMAS-Project by hzi-braunschweig.

the class CampaignFormDataEditFragment method onCreateView.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View view = super.onCreateView(inflater, container, savedInstanceState);
    final LinearLayout dynamicLayout = view.findViewById(R.id.dynamicLayout);
    final CampaignFormMeta campaignFormMeta = DatabaseHelper.getCampaignFormMetaDao().queryForId(record.getCampaignFormMeta().getId());
    final List<CampaignFormDataEntry> formValues = record.getFormValues();
    final Map<String, String> formValuesMap = new HashMap<>();
    formValues.forEach(campaignFormDataEntry -> formValuesMap.put(campaignFormDataEntry.getId(), DataHelper.toStringNullable(campaignFormDataEntry.getValue())));
    final Map<String, ControlPropertyField> fieldMap = new HashMap<>();
    final Map<CampaignFormElement, ControlPropertyField> expressionMap = new HashMap<>();
    for (CampaignFormElement campaignFormElement : campaignFormMeta.getCampaignFormElements()) {
        CampaignFormElementType type = CampaignFormElementType.fromString(campaignFormElement.getType());
        if (type != CampaignFormElementType.SECTION && type != CampaignFormElementType.LABEL) {
            String value = formValuesMap.get(campaignFormElement.getId());
            ControlPropertyField dynamicField;
            if (type == CampaignFormElementType.YES_NO) {
                dynamicField = createControlCheckBoxField(campaignFormElement, requireContext(), getUserTranslations(campaignFormMeta));
                ControlCheckBoxField.setValue((ControlCheckBoxField) dynamicField, Boolean.valueOf(value));
            } else {
                dynamicField = createControlTextEditField(campaignFormElement, requireContext(), getUserTranslations(campaignFormMeta));
                ControlTextEditField.setValue((ControlTextEditField) dynamicField, value);
            }
            fieldMap.put(campaignFormElement.getId(), dynamicField);
            dynamicField.setShowCaption(true);
            dynamicLayout.addView(dynamicField, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
            dynamicField.addValueChangedListener(field -> {
                final CampaignFormDataEntry campaignFormDataEntry = getOrCreateCampaignFormDataEntry(formValues, campaignFormElement);
                campaignFormDataEntry.setValue(field.getValue());
                if (campaignFormElement.getExpression() == null && fieldMap.get(campaignFormElement.getId()) != null) {
                    expressionMap.forEach((formElement, controlPropertyField) -> handleExpression(expressionParser, formValues, CampaignFormElementType.fromString(formElement.getType()), controlPropertyField, formElement.getExpression()));
                }
            });
            handleDependingOn(fieldMap, campaignFormElement, dynamicField);
            final String expressionString = campaignFormElement.getExpression();
            if (expressionString != null) {
                handleExpression(expressionParser, formValues, type, dynamicField, expressionString);
                expressionMap.put(campaignFormElement, dynamicField);
            }
        } else if (type == CampaignFormElementType.SECTION) {
            dynamicLayout.addView(new ImageView(requireContext(), null, R.style.FullHorizontalDividerStyle));
        } else if (type == CampaignFormElementType.LABEL) {
            TextView textView = new TextView(requireContext());
            TextViewBindingAdapters.setHtmlValue(textView, getUserLanguageCaption(getUserTranslations(campaignFormMeta), campaignFormElement));
            dynamicLayout.addView(textView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
        }
    }
    return view;
}
Also used : HashMap(java.util.HashMap) CampaignFormElement(de.symeda.sormas.api.campaign.form.CampaignFormElement) ControlPropertyField(de.symeda.sormas.app.component.controls.ControlPropertyField) ImageView(android.widget.ImageView) View(android.view.View) TextView(android.widget.TextView) CampaignFormMeta(de.symeda.sormas.app.backend.campaign.form.CampaignFormMeta) CampaignFormElementType(de.symeda.sormas.api.campaign.form.CampaignFormElementType) CampaignFormDataEntry(de.symeda.sormas.api.campaign.data.CampaignFormDataEntry) CampaignFormDataFragmentUtils.getOrCreateCampaignFormDataEntry(de.symeda.sormas.app.campaign.CampaignFormDataFragmentUtils.getOrCreateCampaignFormDataEntry) TextView(android.widget.TextView) ImageView(android.widget.ImageView) LinearLayout(android.widget.LinearLayout)

Example 4 with CampaignFormElement

use of de.symeda.sormas.api.campaign.form.CampaignFormElement in project SORMAS-Project by hzi-braunschweig.

the class CampaignFormDataNewFragment method onCreateView.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View view = super.onCreateView(inflater, container, savedInstanceState);
    final LinearLayout dynamicLayout = view.findViewById(R.id.dynamicLayout);
    final CampaignFormMeta campaignFormMeta = DatabaseHelper.getCampaignFormMetaDao().queryForId(record.getCampaignFormMeta().getId());
    record.setFormValues(new ArrayList<>());
    final List<CampaignFormDataEntry> formValues = record.getFormValues();
    final Map<String, ControlPropertyField> fieldMap = new HashMap<>();
    final Map<CampaignFormElement, ControlPropertyField> expressionMap = new HashMap<>();
    for (CampaignFormElement campaignFormElement : campaignFormMeta.getCampaignFormElements()) {
        CampaignFormElementType type = CampaignFormElementType.fromString(campaignFormElement.getType());
        if (type != CampaignFormElementType.SECTION && type != CampaignFormElementType.LABEL) {
            ControlPropertyField dynamicField;
            if (type == CampaignFormElementType.YES_NO) {
                dynamicField = createControlCheckBoxField(campaignFormElement, requireContext(), getUserTranslations(campaignFormMeta));
            } else {
                dynamicField = createControlTextEditField(campaignFormElement, requireContext(), getUserTranslations(campaignFormMeta));
            }
            fieldMap.put(campaignFormElement.getId(), dynamicField);
            dynamicField.setShowCaption(true);
            dynamicLayout.addView(dynamicField, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
            dynamicField.addValueChangedListener(field -> {
                final CampaignFormDataEntry campaignFormDataEntry = getOrCreateCampaignFormDataEntry(formValues, campaignFormElement);
                campaignFormDataEntry.setValue(field.getValue());
                if (campaignFormElement.getExpression() == null && fieldMap.get(campaignFormElement.getId()) != null) {
                    expressionMap.forEach((formElement, controlPropertyField) -> handleExpression(expressionParser, formValues, CampaignFormElementType.fromString(formElement.getType()), controlPropertyField, formElement.getExpression()));
                }
            });
            formValues.add(new CampaignFormDataEntry(campaignFormElement.getId(), null));
            handleDependingOn(fieldMap, campaignFormElement, dynamicField);
            final String expressionString = campaignFormElement.getExpression();
            if (expressionString != null) {
                handleExpression(expressionParser, formValues, type, dynamicField, expressionString);
                expressionMap.put(campaignFormElement, dynamicField);
            }
        } else if (type == CampaignFormElementType.SECTION) {
            dynamicLayout.addView(new ImageView(requireContext(), null, R.style.FullHorizontalDividerStyle));
        } else if (type == CampaignFormElementType.LABEL) {
            TextView textView = new TextView(requireContext());
            TextViewBindingAdapters.setHtmlValue(textView, getUserLanguageCaption(getUserTranslations(campaignFormMeta), campaignFormElement));
            dynamicLayout.addView(textView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
        }
    }
    return view;
}
Also used : HashMap(java.util.HashMap) CampaignFormElement(de.symeda.sormas.api.campaign.form.CampaignFormElement) ControlPropertyField(de.symeda.sormas.app.component.controls.ControlPropertyField) ImageView(android.widget.ImageView) View(android.view.View) TextView(android.widget.TextView) CampaignFormMeta(de.symeda.sormas.app.backend.campaign.form.CampaignFormMeta) CampaignFormElementType(de.symeda.sormas.api.campaign.form.CampaignFormElementType) CampaignFormDataEntry(de.symeda.sormas.api.campaign.data.CampaignFormDataEntry) CampaignFormDataFragmentUtils.getOrCreateCampaignFormDataEntry(de.symeda.sormas.app.campaign.CampaignFormDataFragmentUtils.getOrCreateCampaignFormDataEntry) TextView(android.widget.TextView) ImageView(android.widget.ImageView) LinearLayout(android.widget.LinearLayout)

Example 5 with CampaignFormElement

use of de.symeda.sormas.api.campaign.form.CampaignFormElement in project SORMAS-Project by hzi-braunschweig.

the class CampaignFormDataReadFragment method onCreateView.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View view = super.onCreateView(inflater, container, savedInstanceState);
    final LinearLayout dynamicLayout = view.findViewById(R.id.dynamicLayout);
    final CampaignFormMeta campaignFormMeta = DatabaseHelper.getCampaignFormMetaDao().queryForId(record.getCampaignFormMeta().getId());
    final List<CampaignFormDataEntry> formValues = record.getFormValues();
    final Map<String, String> formValuesMap = new HashMap<>();
    formValues.forEach(campaignFormDataEntry -> formValuesMap.put(campaignFormDataEntry.getId(), DataHelper.toStringNullable(campaignFormDataEntry.getValue())));
    final Map<String, ControlPropertyField> fieldMap = new HashMap<>();
    for (CampaignFormElement campaignFormElement : campaignFormMeta.getCampaignFormElements()) {
        CampaignFormElementType type = CampaignFormElementType.fromString(campaignFormElement.getType());
        if (type != CampaignFormElementType.SECTION && type != CampaignFormElementType.LABEL) {
            String value = formValuesMap.get(campaignFormElement.getId());
            ControlPropertyField dynamicField = createControlTextReadField(campaignFormElement, requireContext(), getUserTranslations(campaignFormMeta));
            dynamicField.setShowCaption(true);
            if (value != null) {
                if (type == CampaignFormElementType.YES_NO) {
                    ControlTextReadField.setValue((ControlTextReadField) dynamicField, Boolean.valueOf(value), null, null);
                } else {
                    ControlTextReadField.setValue((ControlTextReadField) dynamicField, value, null, null, null);
                }
            }
            dynamicLayout.addView(dynamicField, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
            fieldMap.put(campaignFormElement.getId(), dynamicField);
            final String dependingOn = campaignFormElement.getDependingOn();
            final String[] dependingOnValues = campaignFormElement.getDependingOnValues();
            if (dependingOn != null && dependingOnValues != null) {
                ControlPropertyField controlPropertyField = fieldMap.get(dependingOn);
                setVisibilityDependency(dynamicField, dependingOnValues, controlPropertyField.getValue());
            }
            final String expressionString = campaignFormElement.getExpression();
            if (expressionString != null) {
                try {
                    final Object expressionValue = getExpressionValue(expressionParser, formValues, expressionString);
                    if (type == CampaignFormElementType.YES_NO) {
                        ControlTextReadField.setValue((ControlTextReadField) dynamicField, (Boolean) expressionValue, null, null);
                    } else {
                        ControlTextReadField.setValue((ControlTextReadField) dynamicField, expressionValue.toString(), null, null, null);
                    }
                } catch (SpelEvaluationException e) {
                    Log.e("Error evaluating expression: " + expressionString, e.getMessage());
                }
            }
        } else if (type == CampaignFormElementType.SECTION) {
            dynamicLayout.addView(new ImageView(requireContext(), null, R.style.FullHorizontalDividerStyle));
        } else if (type == CampaignFormElementType.LABEL) {
            TextView textView = new TextView(requireContext());
            TextViewBindingAdapters.setHtmlValue(textView, campaignFormElement.getCaption());
            dynamicLayout.addView(textView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
        }
    }
    return view;
}
Also used : SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) HashMap(java.util.HashMap) CampaignFormElement(de.symeda.sormas.api.campaign.form.CampaignFormElement) ControlPropertyField(de.symeda.sormas.app.component.controls.ControlPropertyField) ImageView(android.widget.ImageView) View(android.view.View) TextView(android.widget.TextView) CampaignFormMeta(de.symeda.sormas.app.backend.campaign.form.CampaignFormMeta) CampaignFormElementType(de.symeda.sormas.api.campaign.form.CampaignFormElementType) CampaignFormDataEntry(de.symeda.sormas.api.campaign.data.CampaignFormDataEntry) TextView(android.widget.TextView) ImageView(android.widget.ImageView) LinearLayout(android.widget.LinearLayout)

Aggregations

CampaignFormElement (de.symeda.sormas.api.campaign.form.CampaignFormElement)10 CampaignFormDataEntry (de.symeda.sormas.api.campaign.data.CampaignFormDataEntry)6 CampaignFormElementType (de.symeda.sormas.api.campaign.form.CampaignFormElementType)6 HashMap (java.util.HashMap)4 View (android.view.View)3 ImageView (android.widget.ImageView)3 LinearLayout (android.widget.LinearLayout)3 TextView (android.widget.TextView)3 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)3 ValidationRuntimeException (de.symeda.sormas.api.utils.ValidationRuntimeException)3 CampaignFormMeta (de.symeda.sormas.app.backend.campaign.form.CampaignFormMeta)3 ControlPropertyField (de.symeda.sormas.app.component.controls.ControlPropertyField)3 AbstractComponent (com.vaadin.ui.AbstractComponent)2 GridLayout (com.vaadin.ui.GridLayout)2 Field (com.vaadin.v7.ui.Field)2 CampaignFormMetaDto (de.symeda.sormas.api.campaign.form.CampaignFormMetaDto)2 I18nProperties (de.symeda.sormas.api.i18n.I18nProperties)2 CampaignFormDataFragmentUtils.getOrCreateCampaignFormDataEntry (de.symeda.sormas.app.campaign.CampaignFormDataFragmentUtils.getOrCreateCampaignFormDataEntry)2 IOException (java.io.IOException)2 List (java.util.List)2