Announcement

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

    Update request structure for foreign key field

    Hi,
    I have SmartClientOperation based WSDL services exposing Person and Pet pojo classes.
    In SmartGWT I created corresponding WS datasources:
    Code:
        private static class PersonDS extends WSDataSource {
    
            private static PersonDS instance;
    
            public static PersonDS getInstance() {
                if (instance == null)
                    instance = new PersonDS("Person");
                return instance;
            }
    
            public PersonDS(String id) {
    
                setID(id);
                setServiceNamespace("urn:operations.smartclient.com");
                setDataFormat(DSDataFormat.XML);
                setDataURL("/axis2/services/SmartClientOperations");
    
                OperationBinding fetchBinding = new OperationBinding();
                fetchBinding.setOperationType(DSOperationType.FETCH);
                fetchBinding.setWsOperation("fetch");
                fetchBinding.setRecordXPath("//data/*");
                fetchBinding.setRecordName("arg");
    
                OperationBinding updateBinding = new OperationBinding();
                updateBinding.setOperationType(DSOperationType.UPDATE);
                updateBinding.setWsOperation("update");
                updateBinding.setRecordXPath("//data/*");
                updateBinding.setRecordName("arg");
    
                setOperationBindings(fetchBinding,updateBinding);
    
                DataSourceField idField = new DataSourceIntegerField("id", "ID", 5, false);
                idField.setPrimaryKey(true);
    
                DataSourceField nameField = new DataSourceTextField("name", "Name", 30, true);
                DataSourceField ageField = new DataSourceField("age", FieldType.INTEGER, "Age", 3);
    
                setFields(idField,nameField,ageField);
            }
        }
    
        private static class PetDS extends WSDataSource {
    
            private static PetDS instance;
    
            public static PetDS getInstance() {
                if (instance == null)
                    instance = new PetDS("Pet");
                return instance;
            }
    
            public PetDS(String id) {
    
                setID(id);
                setServiceNamespace("urn:operations.smartclient.com");
                setDataFormat(DSDataFormat.XML);
                setDataURL("/axis2/services/SmartClientOperations");
    
                OperationBinding fetchBinding = new OperationBinding();
                fetchBinding.setOperationType(DSOperationType.FETCH);
                fetchBinding.setWsOperation("fetch");
                fetchBinding.setRecordXPath("//data/*");
                fetchBinding.setRecordName("arg");
    
                OperationBinding updateBinding = new OperationBinding();
                updateBinding.setOperationType(DSOperationType.UPDATE);
                updateBinding.setWsOperation("update");
                updateBinding.setRecordXPath("//data/*");
                updateBinding.setRecordName("arg");
    
                setOperationBindings(fetchBinding,updateBinding);
    
                DataSourceField idField = new DataSourceIntegerField("id", "ID", 5, false);
                idField.setPrimaryKey(true);
    
                DataSourceField animalField = new DataSourceTextField("animal", "Animal", 30, true);
                DataSourceField colourField = new DataSourceTextField("colour", "Colour", 10, true);
                DataSourceField sexField = new DataSourceField("sex", FieldType.BOOLEAN, "Sex", 5);
                DataSourceField personField = new DataSourceIntegerField("person", "PresonID", 5, false);
                personField.setForeignKey("Person.id");
                personField.setValueXPath("person/id");
    
                setFields(idField,animalField,colourField,sexField,personField);
            }
        }
    Fetch operation on Pet datasource is working fine with the following server response:
    Code:
    <data>
      <pet>
        <id>458752</id>
        <person>
          <id>491520</id>
          ..
        </person>
       ..
      </pet>
    However I am not able to get the same hierarchical Update request (required by server side) from SmartGWT.
    Instead I got the following flat xml structure:
    Code:
    <data>
      <pet>
        <id>458752</id>
        <person>491520</person>
       ..
      </pet>
    Am I missing somethig ?
    Thanks,
    MichalG

    #2
    Hi Michal,

    You've got kind of a mishmash of concepts here..

    WSDataSource is specifically for use with SmartClientOperations.wsdl. If you use SmartClientOperations.wsdl with Axis you don't need any other client-side settings (xpaths et al), attempting to set those would just break the built-in behavior. Instead all of your integration should be done server-side.

    Your samples didn't include any XML namespaces so not sure if those are real or just intended as fragments..

    If you want SmartGWT to adapt to a pre-existing WSDL of your own with nested message formats, use DataSource not WSDataSource as your starting point. At this point you would actually fill in either recordName or recordXPath to indicate to SmartGWT what parts of the WSDL responses you want to use as DataSource records.

    As far as forming SOAP messages, to have SmartGWT automatically fill in hierarchical structures (by using the XML Schema from your WSDL), see the useFlatFields setting (on operationBinding and WSRequest).

    Comment


      #3
      Hello Isomorphic

      Yes, this is SmartClientOperations.wsdl and many thanks for correcting and simplifying my datasource definition which looks now:
      setServiceNamespace("urn:operations.smartclient.com");
      setDataURL("/axis2/services/UmowyOperations");
      thats all.

      What I still can't get through is sending Person record/object as a part of Pet update request.
      I created datasource field in Pets datasource:
      Code:
              DataSourceField personField = new DataSourceField();
              personField.setName("person");
              personField.setTitle("Person");
              personField.setLength(30);
              personField.setForeignKey("Person.id");
              personField.setType(Person.getInstance());
      and additionally created drop-down-grid on Pet form:
      Code:
              ComboBoxItem personItem = new ComboBoxItem("comboPerson");
              personItem.setOptionDataSource(PersonDS.getInstance());
              personItem.setDisplayField("name");
              personItem.setValueField("person");
              personItem.setPickListFields(PersonDS.getInstance().getListGridFields());
              personItem.addChangedHandler(new ChangedHandler() {
                  public void onChanged(ChangedEvent event) {
      //?                personFormField.setValue(personItem.getSelectedRecord());
                  }
              });
      What I need is: get selected record from drop-down-grid and set it as person form field value. I can't do this as there is no such method (setValue(record)).
      Obviously, there should be a way to choose a person and save pet object with person set, but I can't see it ?
      Can you help/suggest something ?
      MichalG
      Last edited by michalg; 20 Apr 2009, 01:58.

      Comment


        #4
        The intent of optionDataSource is that it would fetch people and allow you to assign the id of some person as the value of the "person" field on a pet.

        Are you trying to send the entire person record instead?

        Comment


          #5
          Not necessary entire record - id is enough, but properly formated:
          Code:
          <data>
            <pet>
              <id>458752</id>
              <person>
                <id>491520</id>
              </person>
             ..
            </pet>
          </data>
          instead of what I am able to get now:
          Code:
          <data>
            <pet>
              <id>458752</id>
              <person>491520</person>
             ..
            </pet>
          </data>

          Comment


            #6
            I'm not sure why you would consider that "properly" formatted - there's no place where the docs say that would happen :)

            You can either just use a <personId> field instead of that nested structure, or if that creates issues, override transformRequest to serialize the data how you want.

            Comment


              #7
              Do you mean something like this :?
              Code:
              public Object transformRequest(DSRequest dsRequest) {
                        if (dsRequest.getOperationType().equals(DSOperationType.ADD)) {
                            JSOHelper.setAttribute(dsRequest.getData(), "person", "<id>"+JSOHelper.getAttribute(dsRequest.getData(), "person")+"</id>");
                        }
                         return super.transformRequest(dsRequest);
              }
              but I got the following on the server side:
              Code:
              <data>
                    <person>&lt;id>333&lt;/id></person>
              </data>
              What would be the proper way to form nested xml response ?
              MichalG

              Comment


                #8
                You would create nested structures in JavaScript. But again, suggest you switch the client-side declarations such that a simple <personId> element is produces, then handle this server-side, where it seems unlikely to cause either more or less code than the nested structure you're looking for.

                Comment


                  #9
                  Understood.
                  Thanks, Isomorphic.

                  Comment

                  Working...
                  X