Announcement

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

    Setting up XML DS for DataSource.performCustomOperation()

    1) How do I set up an an XML datasource to support this method. If there's an example/sample; that'll much appreciated.

    2) We are currently using SmartGWT Pro 2.1 - we do not have access to this method, yet. Is there a sample/example on how we can accomplish the same feature of our existing XML based datasource. BTW - we are using serverType="generic" and lookup style of "New".


    Thanks.

    #2
    What are you trying to accomplish? performCustomOperation() is usually something you'd use for SQL, but you're using DMI.

    Comment


      #3
      Thanks for a prompt reply. I'm using DMI to call a (@Service method) e.g. to send an email or JMS message etc. The most convenient way I could think of is to simply add a custom method to an already existing DS and DMI class (on top of CRUD methods).

      Is there another way to accomplish this?

      Thanks!

      Comment


        #4
        It's reasonable to represent that as an operation of type="custom", however, while performCustomOperation is still being added, you can also just use an operationBinding with operationType="fetch" and invoke it via DataSource.fetchData().

        Comment


          #5
          Thanks! It sounds like you're suggesting the ff. pattern in the short term:

          1. Create a regular DMI DS (e.g. assetDS in assetDS.ds.xml) for CRUD operations; and then

          2. Create a 'Service' DMI DS (e.g. assetServiceDS in assetServiceDS.ds.xml) for service methods, and override 'fetch' operationId that maps to a service method - as you suggested in your previous note. Then call this method from assetServiceDS.fetchData().

          The reason I'm going this way is that I cannot have more than one 'fetch' operationBinding's in the same DS. Or can I?

          Comment


            #6
            You can have multiple operstionBindings for the same operationType so long as they have different operationIds. So you don't need a separate DS unless you choose to do so for organizational purposes.

            Comment


              #7
              So if I have a method in my datasource called say doFoo(), I would then add it to my ds.xml with a type="custom" and a name="doFoo"?

              Let's say I want doFoo to return void, do I still need to pass around dsResponses etc.?

              The call from the client is a bit confusing in this instance as well. For example would I call DataSource.performCustomOperation("doFoo")?

              There is only one signature on the performCustomOperation and it requires a String, Record, DSCallBack, DSRequest).

              How can I just call the doFoo method with a button click?

              Thanks,

              Comment


                #8
                You declare an <operationBinding> and include a <serverObject> like with any DMI. Set operationType="custom" on the <operationBinding>. The first parameter to performCustomOperation is the operationId you put on the <operationBinding>. You can pass null for the Record parameter if you don't want to send any data to the server. You are not required to return a dsResponse.

                Comment


                  #9
                  Thanks for the quick response. To clarify a little further:

                  The performCustomOperation api is as follows:

                  public void performCustomOperation(String operationId,
                  Record data,
                  DSCallback callback,
                  DSRequest requestProperties)

                  I know what to pass for the operationId and the record (null) but what about the other two parameters (DSCallBack and DSRequest)?

                  The use case I'm targeting does not require a callback or dsrequest. I just want to start a process on the server. The only thing the client should care about in this case is a successful rpc call.

                  Thanks

                  Comment


                    #10
                    If you don't need to use either of those parameters, you can pass nulls for those as well. However you mentioned being notified of success - that's what the callback is for.

                    Comment


                      #11
                      Great, thanks. I've implemented it on the client, but I get the following error when I try to invoke the method....

                      "Uncaught exception escaped : com.google.gwt.event.shared.UmbrellaException
                      One or more exceptions caught, see full set in UmbrellaException#getCauses
                      See the Development console log for details.
                      Register a GWT.setUncaughtExceptionHandler(..) for custom uncaught exception handling"

                      I'm not using Eclipse, so the development console isn't handy (is there a way to see this in the SmartGWT developer console?).

                      My DS.xml file is as follows:

                      <DataSource ID="logType" serverConstructor="com.isomorphic.jpa.JPA2DataSource" beanClassName="com.sncorp.gs2.jee.entities.protolog.LogType">
                      <fields>
                      <field name="name" type="text" title="name"/>
                      <field name="logtypeId" title="Log Type Id"/>
                      </fields>
                      <dropExtraFields>true</dropExtraFields>
                      <serverObject className="com.sncorp.gs2.ui.server.LogTypeDMI"/>
                      <operationBindings>
                      <!--<operationBinding operationType="fetch" serverMethod="fetch"/>-->
                      <operationBinding operationType="add" serverMethod="add"/>
                      <operationBinding operationType="update" serverMethod="update"/>
                      <operationBinding operationType="remove" serverMethod="remove"/>
                      <operationBinding operationType="custom" operationId="startLogThread" serverMethod="startLogThread">
                      <serverObject className="com.sncorp.gs2.ui.server.LogTypeDMI"/>
                      </operationBinding>
                      </operationBindings>
                      </DataSource>

                      DataSource instantiation in client code:
                      //set the datasource object(s) for this component
                      dsLogTypes = DataSource.get("logType");

                      Custom method invocation:
                      IButton ibtn = new IButton();
                      ibtn.setID("ibtnTest");
                      ibtn.setTitle("Test");
                      ibtn.addClickHandler(new ClickHandler()
                      {
                      @Override
                      public void onClick(ClickEvent clickEvent)
                      {
                      dsLogTypes.performCustomOperation("startLogThread",null,null,null);
                      }
                      });

                      DMI call server side:

                      public DSResponse startLogThread()
                      {
                      //create an empty DSResponse to send back to the client
                      DSResponse dsResponse = new DSResponse();
                      System.out.println("\n\n\n\n\nRPC MADE IT\n\n\n\n\n");
                      try
                      {

                      dsResponse.setSuccess();
                      //spawn the new thread and have it pump messages to a queue or subscription
                      new Thread(new Runnable()
                      {
                      @Override
                      public void run()
                      {
                      while(true)
                      {
                      try
                      {
                      Thread.sleep(1000);
                      System.out.println("\n\n I DID SOMETHING \n\n");
                      }
                      catch(InterruptedException ie)
                      {
                      System.out.println("thread interrupted");
                      }
                      }
                      }
                      }).start();
                      }
                      catch(Exception ex)
                      {
                      ex.printStackTrace();
                      }
                      return dsResponse;
                      }

                      Comment


                        #12
                        Trapping the error produces the following message btw:

                        "Invoking an instance method on a null reference"

                        I'm not sure how the data source is null. The fetch method works fine to populate a ComboBoxItem

                        Comment


                          #13
                          Sorry, we indicated you could pass null for the Record param, in reality you need to pass an empty Record (just new Record() will do).

                          Comment


                            #14
                            It appears that the only parameter that can be null is the callback. I got the same issue until I passed an instance of a DSRequest as well. Can you confirm?

                            dsLogTypes.performCustomOperation("startLogThread", new Record(), null, new DSRequest());

                            Thanks

                            Comment


                              #15
                              We'll allow both parameters to be null in the future. Thanks for pointing this out.

                              Comment

                              Working...
                              X