Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    server-side custom validator implementation

    Hello,

    I'm trying to call a custom class which acts like a validator as explained in the Validator docs.

    But I get this error.
    Log:Server-side validation failed: java.lang.String cannot be cast to java.util.Map

    Is this Map for the argument "Map record" that I need in my condition's method according to the specs?


    Here's the field of my datasource:
    Code:
    <field zzzId="1216" name="amount" title="amount" type="zzzMCurrency" javaClass="zzz.parameter.zzzMCurrency" crud="15" required="true" >
    <validators>
    <validator type="serverCustom" serverOnly="true" serverObject="zzz.server.custom.zzzValidator" methodName="condition"/>
    </validators>
    </field>

    Not much in my Validator class, as I can't get it triggered yet:
    Code:
    public class zzzValidator {
    	
    
    public void condition(Object value, Validator validator, String fieldName, Map record,
    		DataSource datasource, HttpServletRequest request, HttpServletResponse response,
    		ServletContext context, HttpSession session, RequestContext requestContext,
    		RPCManager rpc) {
    	
    	
    	Log.debug("condition started");
    	
    	
    	
    }
    
    }


    The RPC data:
    Code:
    === 2010-09-07 12:18:39,625 [l0-0] DEBUG RPCManager - Request #1 (DSRequest) payload: {
        values:{
            __gwt_ObjectId:2057,
            amount:{
                refAmount:40
            },
            description:{
                text:null,
                id:null
            }
        },
        operationConfig:{
            dataSource:"238",
            operationType:"validate"
        },
        validationMode:"full",
        appID:"builtinApplication",
        operation:"238_validate",
        oldValues:{
            __gwt_ObjectId:2057,
            amount:{
                refAmount:40
            },
            description:{
                text:null,
                id:null
            }
        },
        criteria:{
        }
    }
    Response:
    Code:
    [
        {
            isDSResponse:true, 
            invalidateCache:false, 
            status:-1, 
            data:"java.lang.String cannot be cast to java.util.Map"
        }
    ]

    Stacktrace:
    Code:
    === 2010-09-07 12:18:39,843 [l0-0] DEBUG DataSource - Creating instance of DataSource '238'
    === 2010-09-07 12:18:39,843 [l0-0] DEBUG AppBase - [builtinApplication.238_validate] No userTypes defined, allowing anyone access to all operations for this application
    === 2010-09-07 12:18:39,843 [l0-0] DEBUG AppBase - [builtinApplication.238_validate] No public zero-argument method named '_238_validate' found, performing generic datasource operation
    === 2010-09-07 12:18:39,843 [l0-0] DEBUG BasicDataSource - [builtinApplication.238_validate] Validating 1 '238's at path ''
    === 2010-09-07 12:18:39,843 [l0-0] DEBUG BasicDataSource - [builtinApplication.238_validate] Validating a '238' at path ''
    === 2010-09-07 12:18:39,843 [l0-0] WARN  RequestContext - dsRequest.execute() failed: 
    java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map
    	at com.isomorphic.util.DefaultValidators$serverCustom.validate(DefaultValidators.java:1067)
    	at com.isomorphic.util.DefaultValidators.processValidator(DefaultValidators.java:263)
    	at com.isomorphic.util.DefaultValidators.validateField(DefaultValidators.java:229)
    	at com.isomorphic.datasource.SimpleType.validateValue(SimpleType.java:89)
    	at com.isomorphic.datasource.SimpleType.create(SimpleType.java:65)
    	at com.isomorphic.datasource.BasicDataSource.validateFieldValue(BasicDataSource.java:935)
    	at com.isomorphic.datasource.BasicDataSource.validateFieldValue(BasicDataSource.java:882)
    	at com.isomorphic.datasource.BasicDataSource.toRecord(BasicDataSource.java:560)
    	at com.isomorphic.datasource.BasicDataSource.toRecords(BasicDataSource.java:498)
    	at com.isomorphic.datasource.BasicDataSource.toRecords(BasicDataSource.java:461)
    	at com.isomorphic.datasource.DataSource.validateDSRequest(DataSource.java:1454)
    	at com.isomorphic.datasource.DataSource.validateDSRequest(DataSource.java:1404)
    	at com.isomorphic.datasource.DataSource.execute(DataSource.java:775)
    	at com.isomorphic.application.AppBase.executeDefaultDSOperation(AppBase.java:721)
    	at com.isomorphic.application.AppBase.executeAppOperation(AppBase.java:658)
    	at com.isomorphic.application.AppBase.execute(AppBase.java:491)
    	at com.isomorphic.datasource.DSRequest.execute(DSRequest.java:1382)
    	at com.isomorphic.servlet.IDACall.handleDSRequest(IDACall.java:155)
    	at zzz.server.custom.zzzIDACall.handleDSRequest(zzzIDACall.java:113)
    	at com.isomorphic.servlet.IDACall.processRequest(IDACall.java:106)
    	at zzz.server.custom.zzzIDACall.processRequest(zzzIDACall.java:97)
    	at com.isomorphic.servlet.IDACall.doPost(IDACall.java:54)
    	at zzz.server.custom.zzzIDACall.doPost(zzzIDACall.java:86)
    SmartGWT EE 2.3
    SmartClient Version: SC_SNAPSHOT-2010-08-03/EVAL Deployment (expires 2010.10.02_09.35.33)

    #2
    In your DS definition, "serverObject" should be an object, not a string

    Comment


      #3
      Thanks, I thought I tried this, but I tried again and now it works: my custom method gets called.


      Code:
      <field sraId="1216" name="amount" title="amount" type="zzzMCurrency" javaClass="zzz.parameter.zzzMCurrency" crud="15" required="true" >
        <validators>
          <validator type="serverCustom" serverOnly="true">
            <serverObject className="zzz.server.custom.zzzValidator" methodName="condition"/>
          </validator>
        </validators>
      </field>

      This now results in nullpointer:
      Code:
      === 2010-09-08 11:50:32,171 [0-11] DEBUG Reflection - [builtinApplication.238_validate] Successfully adapted optional arg type: com.isomorphic.rpc.RPCManager to type: com.isomorphic.rpc.RPCManager
      === 2010-09-08 11:50:32,171 [0-11] DEBUG Reflection - [builtinApplication.238_validate] method takes: 11 args.  I've assembled: 11 args
      === 2010-09-08 11:50:32,171 [0-11] DEBUG Reflection - [builtinApplication.238_validate] invoking method:
      void zzz.server.custom.zzzValidator.condition(java.lang.Object, com.isomorphic.datasource.Validator, java.lang.String, java.util.Map, com.isomorphic.datasource.DataSource, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, javax.servlet.ServletContext, javax.servlet.http.HttpSession, com.isomorphic.servlet.RequestContext, com.isomorphic.rpc.RPCManager)
      
      with arg types: org.apache.commons.collections.map.LinkedMap, com.isomorphic.datasource.Validator, java.lang.String, org.apache.commons.collections.map.LinkedMap, com.isomorphic.datasource.BasicDataSource, com.isomorphic.servlet.ISCHttpServletRequest, com.isomorphic.servlet.ProxyHttpServletResponse, org.mortbay.jetty.servlet.Context$SContext, org.mortbay.jetty.servlet.HashSessionManager$Session, com.isomorphic.servlet.RequestContext, com.isomorphic.rpc.RPCManager
      === 2010-09-08 11:50:32,171 [0-11] WARN  RequestContext - dsRequest.execute() failed: 
      java.lang.NullPointerException
      	at com.isomorphic.util.DefaultValidators$serverCustom.validate(DefaultValidators.java:1082)
      	at com.isomorphic.util.DefaultValidators.processValidator(DefaultValidators.java:263)
      	at com.isomorphic.util.DefaultValidators.validateField(DefaultValidators.java:229)
      	at com.isomorphic.datasource.SimpleType.validateValue(SimpleType.java:89)
      	at com.isomorphic.datasource.SimpleType.create(SimpleType.java:65)
      	at com.isomorphic.datasource.BasicDataSource.validateFieldValue(BasicDataSource.java:935)
      	at com.isomorphic.datasource.BasicDataSource.validateFieldValue(BasicDataSource.java:882)
      	at com.isomorphic.datasource.BasicDataSource.toRecord(BasicDataSource.java:560)
      	at com.isomorphic.datasource.BasicDataSource.toRecords(BasicDataSource.java:498)
      	at com.isomorphic.datasource.BasicDataSource.toRecords(BasicDataSource.java:461)
      	at com.isomorphic.datasource.DataSource.validateDSRequest(DataSource.java:1454)
      	at com.isomorphic.datasource.DataSource.validateDSRequest(DataSource.java:1404)
      	at com.isomorphic.datasource.DataSource.execute(DataSource.java:775)
      	at com.isomorphic.application.AppBase.executeDefaultDSOperation(AppBase.java:721)
      	at com.isomorphic.application.AppBase.executeAppOperation(AppBase.java:658)
      	at com.isomorphic.application.AppBase.execute(AppBase.java:491)
      	at com.isomorphic.datasource.DSRequest.execute(DSRequest.java:1382)
      	at com.isomorphic.servlet.IDACall.handleDSRequest(IDACall.java:155)
      I assume an empty void condition validator does not need to do anything for a valid value?

      I then tried failing always by doing
      Code:
      validator.addErrorMessageVariable(fieldName, "Not good.");
      but it results in the same nullpointer.

      Comment


        #4
        I assume an empty void condition validator does not need to do anything for a valid value?
        As far as the framework is concerned, what a custom validator method does or doesn't do is unimportant; the only thing it cares about is whether the validation passes or fails. A void method has no way of communicating this to the framework, and thus doesn't make sense. Return a boolean, or any other type of object whose toString() method resolves to "true" or "false"

        Comment


          #5
          Ok, I see. Good to know for future reference, thanks ;)
          So I'm also not supposed to work with the Validator objects to pass an applicable error message to the client? I've been searching for any APIs to do that, but am afraid I can't find any. Any hints? on that

          Comment


            #6
            The server validation method should return a boolean value based on validation success and failure.
            Then set the error message to a key which act as a place holder in ds xml.

            public class zzzValidator {


            public boolean condition(Object value, Validator validator, String fieldName, Map record,
            DataSource datasource, HttpServletRequest request, HttpServletResponse response,
            ServletContext context, HttpSession session, RequestContext requestContext,
            RPCManager rpc) {


            validator.addErrorMessageVariable("errorKey", "validation error occured");


            return false;
            }

            }


            add the place holder in errormessage tag in ds xml.


            <field sraId="1216" name="amount" title="amount" type="zzzMCurrency" javaClass="zzz.parameter.zzzMCurrency" crud="15" required="true" >
            <validators>
            <validator type="serverCustom" serverOnly="true">
            <serverObject className="zzz.server.custom.zzzValidator" methodName="condition"/>
            <errorMessage>$errorKey</errorMessage>
            </validator>
            </validators>
            </field>

            It will show the error message set from server.
            Last edited by Nipin; 13 Jan 2011, 02:23.

            Comment

            Working...
            X