Uploaded image for project: 'Struts 1'
  1. Struts 1
  2. STR-2462

[validator] Expression Language Field Validator

    XMLWordPrintableJSON

    Details

    • Type: Improvement
    • Status: Open
    • Priority: Minor
    • Resolution: Unresolved
    • Affects Version/s: 1.2.6 Beta
    • Fix Version/s: Future
    • Component/s: Core
    • Labels:
      None
    • Environment:
      Operating System: other
      Platform: Other
    • Bugzilla Id:
      34849

      Description

      For all of those who are tired of requiredif and validWhen - here is the
      Expression Language Field Validator.

      What it does?
      It gives the developer the power of EL to do a validation. This implementation
      also provides access to most EL scopes including request, session, and
      application scope.
      No more "only two items may be joined with and or or "

      Implementation notes:

      • uses JEXL (http://jakarta.apache.org/commons/jexl/)
      • uses EnumeratedMap from standard taglibs (if someone does not like this
        dependency - Map can be copied over to struts package, or became the internal class)

      Things added:

      • ELValidator - class that provides validate method
      • PageContext implementation (reused MockPageContext)

      Two classes - simple and beautiful.

      1. Features:
      1.1 Operators
      (http://jakarta.apache.org/commons/jexl/reference/syntax.html#Functions):

      • Arithmetic: +, - (binary), /, div (int division), % and mod, -(unary)
      • Logical: and, &&, or, ||, not, !
      • Relational: ==, eq, !=, ne, <, lt, >, gt, <=, ge, >=, le.
      • Array access: arr1[0], arr1.0
      • Empty()
      • Size()

      Notes:

      • Avoid the '&', '<', '>' in validation.xml
      • escape them: & > &lt or use 'and' 'lt' 'gt'.
      • No ternary operator A?B:C, workaround:
      • if A return B else C -> can be translated as "(A and B) or (!A and C)"
      • if A return B -> can be translated as "(B or !A)"

      1.2 Implicit Objects

      • pageContext provides access to:
      • servletContext
      • session
      • request
      • response, servletConfig (no access to response and ServletConfig)
      • param - maps a request parameter name to a single value
      • paramValues - maps a request parameter name to an array of values
      • cookie - maps a cookie name to a single cookie
      • header - maps a request header name to a single value
      • headerValues - maps a request header name to an array of values
      • initParam - maps a context initialization parameter name to a single value

      1.3 Scoped variables:

      • pageScope - maps page-scoped variable names to their values
      • requestScope - maps request-scoped variable names to their values
      • sessionScope - maps session-scoped variable names to their values
      • applicationScope - maps application-scoped variable names to their values

      1.4 Additional Objects

      • form - form bean, added as a place holder for form variables
      • arrayUtils - "instance" of commons ArrayUtils
        allows expressions like:
        arrayUtils.contains(paramValues.topic, "spring')
      • stringUtils - "instance" of commons StringUtils
      • var - contains variables defined for this field in the validaton definitions
      • vars - contains variables defined for this field in validator definitions,
        each one is string array, elements should be coma separated

      2. Definition (this step is not needed since the
      jakarta-struts/conf/share/validator-rules.xml was updated)

      Validator definition in global section of validation.xml:

      <validator name="EL"
      classname=" org.apache.struts.validator.ELValidator"
      method="validateEL"
      methodParams="java.lang.Object,
      org.apache.commons.validator.ValidatorAction,
      org.apache.commons.validator.Field,
      org.apache.struts.action.ActionMessages,
      javax.servlet.http.HttpServletRequest,
      javax.servlet.ServletContext"
      msg=" errors.required"/>

      3. Examples
      3.1. Company field is required for everyone except CSR and Admin.

      <field property="company" depends="EL" page="1">
      <var><var-name>EL</var-name>
      <var-value>
      (sessionScope.currentUser != null
      and (
      sessionScope.currentUser.userCSR
      or sessionScope.currentUser.userAdmin
      )
      ) or !empty form.company
      </var-value></var>
      <arg0 key="company.displayname"/>
      </field>

      Note: Try to write it with the validWhen

      3.2. Only published status is allowed.
      <field property= "status" depends="EL" page="1">
      <var><var-name>allowedStatus</var-name>
      <var-value>published</var-value></var>
      <var><var-name>EL</var-name>
      <var-value>
      form.status == var.allowedStatus
      </var-value></var>
      <arg0 key="id.displayname"/>
      </field>

      3.3. "id" required only for edit, delete and store methods (RequestDispatcher).

      <field property= "id" depends="EL" page="1">
      <var><var-name>methods</var-name>
      <var-value>editForm,insert,update,delete</var-value></var>
      <var><var-name>EL</var-name>
      <var-value>
      !empty form.id
      or !arrayUtils.contains(vars.methods, param.email)
      </var-value></var>
      <arg0 key="id.displayname"/>
      </field>

      In my opinion it makes validation a way easier to write and to read
      Please fell free to post comments. I hope you will enjoy it.

      Lukasz Racon

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              lukasz_public@racon.pl Lukasz Racon
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated: