Announcement

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

    Velocity access to oldValues?

    Is there any way to access DSRequest.oldValues with Velocity in the ds.xml? $oldValues doesn't seem to do it.

    What I'm looking for is some way to pass an additional parameter with all of the fetches, updates, etc. that are generated by a particular ListGrid. I can pass it on the fetch and then return it as data in the fetch results. But it doesn't come back on the update or remove since it is hidden and isn't changed by the user. So I thought to use oldValues which do get passed, but it doesn't appear there is access to oldValues in Velocity.

    Is there another approach I can take to accomplish this?

    #2
    What's this value for, a sessionId or something?

    Consider rpcRequest.httpParams as one way to pass extra values that are logically unrelated to DataSource fields.

    Comment


      #3
      The server in this case is an IBM iSeries which has a feature called multi-membered files. Sort of like a partitioned data set on a mainframe. So one "table" can actually have multiple sets of data associated with it, a "primary" member and then n additional members. SQL statements access the primary member by default but can be directed to use a different member via an SQL ALIAS.

      The app we're working with makes use of this feature so we need some way to use one ds.xml to represent the file on the server, but then essentially change the "table" name that the generated SQL refers to so that one ListGrid, for example, can show data from the main member and another can show/edit data from an ALIAS.

      We have a custom tableClause in the ds.xml to redirect each of the CRUD operations to the correct table name. The problem is getting that table name passed on every request so it can be picked up in the Velocity code. I've tried using http parameters, but as far as I can tell those can be associated with a DataSource (assuming this bug has been fixed), but they can't be associated with a particular ListGrid.

      Is there a way to hang extra params on all DSRequests generated by a ListGrid? I'd prefer to do it that way, but failing that I was trying to include the ALIAS name in the actual grid data. But of course it needs to be hidden from the user and so does not get passed back to the server on the update, etc. since it's value isn't being changed, which is why I was looking for it in oldValues.

      Comment


        #4
        Have you considered using listGrid.fetchOperation?

        Comment


          #5
          The fetch is not the issue. It's the update, add and remove operations. But I now see that those can be overridden as well. I'll try that.

          Comment


            #6
            Its still not clear how setXXXoperation will help me here. Is the operation ID accessible to Velocity? I don't see that in the Velocity Support docs.

            The file member name I need to pass to the server needs to be a variable. I can't code a distinct operationBinding for every possible member name. It sounds like this will work if I can have one operationBinding per operationType and then refer to the operationId as a Velocity variable.

            Comment


              #7
              Right. And the Velocity expression is just $dsRequest.operationId.

              Comment


                #8
                In the ds.xml I have <operationBinding operationType="fetch"> and no operationId specified since it will be a variable. I'm using $dsRequest.operationId for the table name in that operation binding's tableClause. I've used setFetchOperation("test") and can see the operationId is being sent on the fetch, but the tableClause for that operation binding is not being used. It is just defaulting to the standard fetch.

                Comment


                  #9
                  That intended behavior - if you add an operationBinding with a specific operationId it's not supposed to override the default behavior for the operationType.

                  Since it's inconvenient here, try adding a DMI to the DataSource as a whole (top-level <serverObject> tag) and set the operationId to null on the DSRequest before proceeding to execute() it.

                  Comment


                    #10
                    That's basically what I've ended up doing but it feels like sort of a hack. It would be much nicer IMHO to have some way to specify a "template" for the DSRequests generated by a ListGrid so that you could customize them with other properties while still having the nice automatic behavior. Much like DataSource.setDefaultParams but at the UI component level; ListGrid, ValuesManager, DynamicForm, etc. Anything that generates DSRequests automatically. One for the wish list.

                    Comment


                      #11
                      I'm running into a problem with this approach that I'm not sure how to solve. I've done as you suggested and "set the operationId to null on the DSRequest before proceeding to execute() it." I then use addToTemplateContext() to put what was originally passed in the operationId into a Velocity variable so I can use it in the ds.xml

                      That works fine for the fetch, but for an update request, the actual update works, but SQLDatasource then does another "getLastRow" fetch after the update. That fetch gets routed back through the same DMI code, but now the operationId is null and the Velocity variable doesn't get setup.

                      Comment


                        #12
                        Store the value as a request attribute on the httpServletRequest, then anything during the same HTTP turnaround can access it.

                        Comment


                          #13
                          Thanks for that tip. That does seem to work, but I have a similar problem when using a server side DSRequest to perform an update. DSRequests created server side done have any httpServletRequest object so Velocity doesn't like the reference to it.
                          Code:
                          org.apache.velocity.exception.MethodInvocationException: Invocation of method 'get' in  class com.isomorphic.velocity.HttpAttributeHandler threw exception java.lang.Exception: Both request and session were null at fetch[line 2, column 63]
                          	at org.apache.velocity.runtime.parser.node.ASTIdentifier.execute(ASTIdentifier.java:223)
                          	at org.apache.velocity.runtime.parser.node.ASTReference.execute(ASTReference.java:252)
                          	at org.apache.velocity.runtime.parser.node.ASTReference.evaluate(ASTReference.java:460)
                          	at org.apache.velocity.runtime.parser.node.ASTExpression.evaluate(ASTExpression.java:62)
                          	at org.apache.velocity.runtime.parser.node.ASTIfStatement.render(ASTIfStatement.java:85)
                          	at org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:336)
                          	at org.apache.velocity.runtime.RuntimeInstance.render(RuntimeInstance.java:1277)
                          	at org.apache.velocity.runtime.RuntimeInstance.evaluate(RuntimeInstance.java:1216)
                          	at org.apache.velocity.runtime.RuntimeInstance.evaluate(RuntimeInstance.java:1165)
                          	at org.apache.velocity.app.VelocityEngine.evaluate(VelocityEngine.java:219)
                          	at com.isomorphic.velocity.Velocity.evaluate(Velocity.java:211)
                          	at com.isomorphic.velocity.Velocity.evaluateAsString(Velocity.java:182)
                          	at com.isomorphic.sql.SQLDataSource.generateSQLStatement(SQLDataSource.java:773)
                          	at com.isomorphic.sql.SQLDataSource.SQLExecute(SQLDataSource.java:1123)
                          	at com.isomorphic.sql.SQLDataSource.execute(SQLDataSource.java:251)
                          I can use addToTemplateContext() and that works fine for the update, but again, the automatic cache synch fetch that happens after the update no longer has that variable in the Velocity template context.

                          Where can I put it in this context so that it will be available both on the update and the cache synch fetch?

                          Comment


                            #14
                            If you are creating your own DSRequest via new DSRequest(), you can call setRPCManager() to provide it with the same context as the dsRequests that are being sent by the client.

                            You can alternatively put custom attributes on dsRequests via setAttribute() - this is intentionally a parallel API to the servletRequest.setAttribute() to allow you to keep servlet-specific stuff out of your data layer.

                            Comment


                              #15
                              I'd prefer to use DSRequest.setAttribute() but those attributes don't get carried over to the new DSRequest that is created to do the cache synch fetch. In fact nothing that I can see is carried over from the initial update or add DSRequest to the cache synch DSRequest.

                              If I understand things correctly, It seems that the only was to have something accessible to Velocity on both the update/add operation and the cache synch fetch that follows is to set it as an httpServletRequest attribute and then pass the same RPCManager around with setRPCManager(). Correct?

                              Comment

                              Working...
                              X