Class MultistepFormsService

java.lang.Object
sk.iway.iwcm.components.multistep_form.rest.MultistepFormsService

@Service public class MultistepFormsService extends Object
Validates, stores, and submits multistep forms.

The service maintains intermediate values in the HTTP session, applies field, anti-spam, and file validation, invokes optional form processors, and persists the completed form through SaveFormService.

  • Field Details

  • Constructor Details

  • Method Details

    • getSessionKey

      public static final String getSessionKey(String formName, jakarta.servlet.http.HttpServletRequest request)
      Build the session key used to store per-form, per-request step data.
      Parameters:
      formName - logical form name
      request - HTTP request providing the CSRF token header
      Returns:
      stable session key in format MultistepForm_<formName>_<domainId>_<csrf>
    • getNewSessionKey

      public static final String getNewSessionKey(String formName, String csrf)
      Build a new session key for the given form and CSRF token.
      Parameters:
      formName - logical form name
      csrf - CSRF token value
      Returns:
      session key string
    • getFormName

      public static final String getFormName(Map<String,String> params)
      Reads the formName value from a parameter map.
      Parameters:
      params - map potentially containing key formName
      Returns:
      form name, or an empty string when the value is missing
    • getFormName

      public static final String getFormName(jakarta.servlet.http.HttpServletRequest request)
      Reads the formName parameter from the request.
      Parameters:
      request - HTTP request containing parameter formName
      Returns:
      form name, or an empty string when the parameter is missing
    • getRegExOptions

      public static final List<LabelValue> getRegExOptions(RegExpRepository regExpRepository, jakarta.servlet.http.HttpServletRequest request)
      Provide available regular expression validations as label/value pairs for UI.
      Parameters:
      regExpRepository - repository of regex definitions
      request - request used to resolve localized titles
      Returns:
      list of label/value options
    • getFieldTypes

      public static final Pair<List<LabelValue>,List<LabelValue>> getFieldTypes(jakarta.servlet.http.HttpServletRequest request)
      Provide supported form field types as label/value pairs.
      Parameters:
      request - request used to resolve localized labels
      Returns:
      pair containing localized visible options and technical iterable/text classifications
    • isFieldtypeIterable

      public static final boolean isFieldtypeIterable(String fieldType, jakarta.servlet.http.HttpServletRequest request)
    • isFileUploadField

      public static final boolean isFileUploadField(String fieldType)
      Determine whether a form field stores an asynchronously uploaded attachment.
      Parameters:
      fieldType - configured form field type
      Returns:
      true for multi-upload variants and the single-file input
    • getFiledTypeVisibility

      public static final List<LabelValue> getFiledTypeVisibility(jakarta.servlet.http.HttpServletRequest request)
      Provide visibility configuration per field type (which technical fields are hidden). Adds a special option allwaysHidden.
      Parameters:
      request - request used to resolve localized labels
      Returns:
      list of visibility label/value pairs
    • clearUnsupportedItemValues

      public static final void clearUnsupportedItemValues(FormItemEntity entity, jakarta.servlet.http.HttpServletRequest request)
      Clears values that are not available for the selected form item type.
      Parameters:
      entity - form item being saved
      request - request used to resolve the field visibility configuration
    • getFieldTabVisibility

      public static final List<LabelValue> getFieldTabVisibility(jakarta.servlet.http.HttpServletRequest request)
      Provide tab visibility configuration per field type.

      Depending on the field type, returns the visibility, requirement, and statistics tabs that should be shown in administration.

      Parameters:
      request - request used to resolve localized labels and field metadata
      Returns:
      list mapping field type to a comma-separated list of visible tabs
    • getNextStep

      public static final FormStepEntity getNextStep(String formName, FormStepEntity currentStep, FormStepsRepository repo)
      Get the next step following the provided step within a form sequence.
      Parameters:
      formName - logical form name
      currentStep - current step entity
      repo - repository used to fetch ordered steps
      Returns:
      next step entity or null if current step is the last
      Throws:
      IllegalStateException - when the expected next step does not exist in the current domain
    • getPreviousStep

      public static final FormStepEntity getPreviousStep(String formName, FormStepEntity currentStep, FormStepsRepository repo)
      Get the step preceding the provided step within a form sequence.
      Parameters:
      formName - logical form name
      currentStep - current step entity
      repo - repository used to fetch ordered steps
      Returns:
      previous step entity or null if current step is the first
      Throws:
      IllegalStateException - when the expected previous step does not exist in the current domain
    • getRowViewItemTypes

      public static final List<String> getRowViewItemTypes()
      Return technical field types used only for row/column layout in the form editor.
      Returns:
      list of non-input layout item field types
    • getFieldName

      public static final String getFieldName(FormItemEntity stepItem, Prop prop)
      Resolve human-readable field name for validation and UI messages.
      Parameters:
      stepItem - form item definition
      prop - localization provider
      Returns:
      localized field label or plain text extracted from custom HTML label
    • getChartStatInfo

      public static final Pair<String,String> getChartStatInfo(jakarta.servlet.http.HttpServletRequest request)
      Extract chart statistics parameters from request.
      Parameters:
      request - HTTP request containing optional formName and itemFormId
      Returns:
      pair of (formName, itemFormId) when both are present, otherwise null
    • getFormId

      public final int getFormId(String formName)
      Resolves the settings identifier of a form in the current domain.
      Parameters:
      formName - logical form name
      Returns:
      form settings identifier, or -1 when the form is not found
    • getFormIdStatic

      public static int getFormIdStatic(String formName)
      Resolves a form settings identifier through the registered service bean.
      Parameters:
      formName - logical form name
      Returns:
      form settings identifier, or -1 when the form is not found
    • validateFormInfo

      public final boolean validateFormInfo(String formName, Long currentStepId, jakarta.servlet.http.HttpServletRequest request)
      Validate whether provided form and step represent an allowed step for current session.
      Parameters:
      formName - logical form name
      currentStepId - step id to validate
      request - request with session context
      Returns:
      true when the step exists and is permitted in current session
    • getSavedStepData

      public final Pair<org.json.JSONObject,org.json.JSONObject> getSavedStepData(String formName, Long stepId, jakarta.servlet.http.HttpServletRequest request)
      Load values previously saved for a step and prepare metadata for temporary uploads.
      Parameters:
      formName - logical form name
      stepId - step identifier
      request - request containing the form session
      Returns:
      pair containing saved values and Dropzone-compatible upload metadata
    • getDraftStepData

      public final Pair<org.json.JSONObject,org.json.JSONObject> getDraftStepData(String formName, Long stepId, jakarta.servlet.http.HttpServletRequest request)
      Returns unconfirmed step values and metadata for completed temporary uploads.
      Parameters:
      formName - logical form name
      stepId - step identifier
      request - request identifying the form instance
      Returns:
      draft values and upload metadata, without changing confirmed answers
    • saveStepDraft

      public final void saveStepDraft(String formName, Long stepId, jakarta.servlet.http.HttpServletRequest request) throws SaveFormException, IOException
      Stores a complete draft of the current step without field validation or submission side effects. Only configured fields are accepted; CAPTCHA responses and widget metadata are not retained. Plain strings are restored through control values; rich text is sanitized before editor restoration.
      Parameters:
      formName - logical form name
      stepId - current step identifier
      request - request containing field values and the form session
      Throws:
      SaveFormException - when cookie or CSRF checks fail
      IOException - when reading the JSON body fails
      IllegalStateException - when the form or step is not permitted, the form counter is invalid, or the request body is empty
      IllegalArgumentException - when a configured field contains unsupported JSON values
    • clearStepDrafts

      public final void clearStepDrafts(String formName, jakarta.servlet.http.HttpServletRequest request)
      Removes all drafts for the completed or definitively terminated form instance.
      Parameters:
      formName - logical form name
      request - request identifying the form instance and its session
    • getSavedTempFilePreview

      public IwcmFile getSavedTempFilePreview(String formName, String fileKey, jakarta.servlet.http.HttpServletRequest request)
      Resolves a previewable temporary image owned by the current form session.

      The file key must belong to an upload field stored in the session. Missing files, unsupported image formats, and SVG files are rejected.

      Parameters:
      formName - logical form name
      fileKey - temporary upload key
      request - request containing the form session
      Returns:
      validated image file, or null when it cannot be previewed
    • getAutocompleteOptions

      public final List<LabelValue> getAutocompleteOptions(String formName, Long stepId, Long itemId, String term, jakarta.servlet.http.HttpServletRequest request)
      Return matching configured options for an autocomplete form item.
      Parameters:
      formName - form name used to validate the current session; the item's form name is used when empty
      stepId - current form step
      itemId - autocomplete form item
      term - text entered by the user; at least two characters are required
      request - current form request
      Returns:
      matching label/value options
    • getAutocompleteOptions

      public final List<LabelValue> getAutocompleteOptions(Long stepId, Long itemId, String term, jakarta.servlet.http.HttpServletRequest request)
      Backward-compatible variant for callers that do not provide the form instance name.
      Parameters:
      stepId - current form step
      itemId - autocomplete form item
      term - text entered by the user
      request - current form request
      Returns:
      matching label/value options
    • getAvailableConditionFields

      public final List<LabelValue> getAvailableConditionFields(String formName, Long stepId, Prop prop)
      Build available source fields for condition builder up to the current step.
      Parameters:
      formName - logical form name
      stepId - current step id
      prop - localization provider
      Returns:
      sorted condition field options grouped by step labels
    • prepareConditionFieldOptions

      public final List<LabelValue> prepareConditionFieldOptions(List<FormItemEntity> fields, String formName, Prop prop)
      Build condition field options from arbitrary field collection.
      Parameters:
      fields - fields to transform into options
      formName - logical form name used to resolve step labels/positions
      prop - localization provider
      Returns:
      sorted options in format (Step X) Field Name
    • getFormStepsOptions

      public final List<LabelValue> getFormStepsOptions(String formName, Prop prop)
      Build human-readable options for steps of a form suitable for selection inputs.
      Parameters:
      formName - logical form name
      prop - localization provider used for step labels
      Returns:
      list of label/value pairs for the form steps
    • getValidItemFormId

      public final String getValidItemFormId(FormItemEntity entity)
      Generates a valid itemFormId for a form item within a form.

      For radio fields, derives the identifier from the label or field type and required flag, allowing radio buttons to share the same logical identifier. For other fields, adds a numeric suffix to avoid collisions within the form and domain.

      Parameters:
      entity - form item to generate id for
      Returns:
      identifier safe for storage and queries, unique for non-radio fields
    • updateFormPattern

      public final void updateFormPattern(String formName)
      Updates or creates the pattern entity for a form by concatenating its validation item identifiers in order. Upload fields append the -fileNames postfix.
      Parameters:
      formName - logical form name
    • validateField

      public final Map<String,String> validateField(String formName, Long stepId, String fieldId, jakarta.servlet.http.HttpServletRequest request) throws SaveFormException, IOException
      Validates one field without saving values or invoking step processors and statistics. Conditional visibility and requirement rules are evaluated only during step submission.
      Parameters:
      formName - logical form name
      stepId - current step identifier
      fieldId - logical identifier of the field to validate
      request - request containing the field value and the form session
      Returns:
      localized errors for the requested field, or an empty map when valid
      Throws:
      SaveFormException - when CSRF, cookie, or XSS checks fail
      IOException - when reading the request body fails
      IllegalStateException - when the form or step is not permitted, the form counter is invalid, or the request body is empty
      IllegalArgumentException - when the field is not in the step or is an upload, CAPTCHA, or WYSIWYG field
    • saveFormStep

      public final void saveFormStep(String formName, Long stepId, jakarta.servlet.http.HttpServletRequest request, org.json.JSONObject response) throws SaveFormException, IOException
      Validate and persist a single step of a multistep form into session, and optionally finalize the form submission. Performs CSRF/CAPTCHA/file validations and invokes custom processors. When the last step is completed, triggers final save into DB. Omitted current-step values are cleared before condition evaluation, and hidden answers are excluded from confirmed data while their drafts are retained. Field validation errors are returned through response without saving the submitted step. On completion, adds the configured redirect or rendered thank-you page content to the response; unavailable inline content leaves the client to display its standard success message.
      Parameters:
      formName - logical form name
      stepId - current step identifier
      request - HTTP request containing JSON body of field values
      response - JSON response to be enriched with errors, next step, forward or thank-you content
      Throws:
      SaveFormException - when validation or processing fails in a controlled way
      IOException - when reading request body fails
    • getFormItemsForValidation

      public static List<FormItemEntity> getFormItemsForValidation(String formName)
      Returns independent validation-field copies for the form in the current domain. Consecutive radio options sharing a logical identifier are collapsed for form-wide processing.
      Parameters:
      formName - logical form name
      Returns:
      simplified items in step and item display order, or an empty list for an empty form name
    • clearValidationFieldsCache

      public static void clearValidationFieldsCache(String formName, Integer domainId)
      Evicts a form's validation definitions locally and requests domain-wide eviction on the cluster. Called explicitly after saving, deleting, duplicating, or reordering the form structure.
      Parameters:
      formName - logical form name
      domainId - domain owning the form
    • refresh

      public static void refresh(long domainId)
      Handles cluster refresh requests using the same monitor as validation-field loading.
      Parameters:
      domainId - domain whose validation definitions should be evicted locally
    • updateStepsPositions

      public void updateStepsPositions(RowReorderDto rowReorderDto)
      Refresh step positions after row reorder operation payload.
      Parameters:
      rowReorderDto - datatable row reorder payload
    • updateStepsPositions

      public void updateStepsPositions(String formName)
      Recompute current and max positions for all steps in a form.
      Parameters:
      formName - logical form name
    • getFormCounter

      public int getFormCounter(String formName, jakarta.servlet.http.HttpServletRequest request)
      Retrieve the form instance counter for the current request.

      When multiple instances of the same form appear on a single page, each gets a unique counter value stored in the session during MultistepFormApp.view(org.springframework.ui.Model, jakarta.servlet.http.HttpServletRequest).

      Parameters:
      formName - logical form name
      request - HTTP request with session containing the counter
      Returns:
      stored form instance counter clamped to at least -1, or -1 when absent
    • updateFormValues

      public static final StringBuilder updateFormValues(String formName, jakarta.servlet.http.HttpServletRequest request, StringBuilder formHtml)
      Replaces form value placeholders with values stored for the current session.
      Parameters:
      formName - logical form name
      request - request containing values saved by earlier steps
      formHtml - form markup containing !fieldId! placeholders
      Returns:
      updated markup, null when formHtml is null
    • updateFormValues

      public static final StringBuilder updateFormValues(Map<String,String> formData, StringBuilder formHtml)
      Replaces placeholders using prepared values without reading the submission session. HTML entities are normalized before escaping to avoid double-escaping filtered values.
      Parameters:
      formData - values keyed by logical field IDs, containing HTML-escaped text, sanitized WYSIWYG HTML, saved filenames and empty answers; markup in these values is escaped for placeholder replacement
      formHtml - markup containing !fieldId! placeholders
      Returns:
      updated markup, or null when formHtml is null