Announcement

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

    Problem with RestDataSource xml responses processing

    I am using SmartGWT 3.0 LGPL Edition and encountered the following problem.
    ListGrid with RestDataSource

    Code:
    ListGrid grid= new ListGrid();
    grid.setUseAllDataSourceFields(true);
    grid.setAutoSaveEdits(false);
    grid.setDataFetchMode(FetchMode.PAGED);
    grid.setCanEdit(true);
    grid.setDataSource(CommonDataSource.getInstance("test"));
    CommonDataSource is descendant of RestDataSource. After adding 2 record in grid and calling grid.savaAllEdits(); CommonDataSource returns XML response on two merged requests, the following error occurs on the client side:

    Uncaught JavaScript exception [this.$89g is not a function] in http://127.0.0.1:8888/tmorder/sc/mod...DataBinding.js, line 1250

    17:50:48.617 [ERROR] [tmorder] 17:50:48.643:XRP3:WARN:Log:TypeError: this.$89g is not a function
    RPCManager._performTransactionReply(2) @ tmorder/sc/modules/ISC_DataBinding.js:1250
    [c]RPCManager.performTransactionReply(_1=>2, _2=>"<response><status>0</status><data><reco..."[ 407], _3=>undef) @ tmorder/sc/modules/ISC_DataBinding.js:1228
    anonymous(2, [object XMLHttpRequest]) @ tmorder/sc/modules/ISC_Core.js:38
    [c]Class.fireCallback(_1=>"isc.RPCManager.performTransactionReply(..."[ 67], _2=>"transactionNum,results,wd", _3=>[object Array]) @ tmorder/sc/modules/ISC_Core.js:301
    [c]Comm.performXmlTransactionReply(_1=>2, _2=>[object XMLHttpRequest]) @ tmorder/sc/modules/ISC_Core.js:1268
    anonymous([object XMLHttpRequest]) @ tmorder/sc/modules/ISC_Core.js:38
    [c]Class.fireCallback(_1=>"isc.Comm.performXmlTransactionReply(2, ..."[ 56], _2=>"xmlHttpRequest", _3=>[object Array], _4=>[object Proxy], _5=>true) @ tmorder/sc/modules/ISC_Core.js:301
    Comm._fireXMLCallback([object XMLHttpRequest], "isc.Comm.performXmlTransactionReply(2, ..."[ 56]) @ tmorder/sc/modules/ISC_Core.js:1244
    unnamed([object Event]) @ tmorder/sc/modules/ISC_Core.js:1256
    unnamed() @

    Request postMessage:
    Code:
    <transaction transactionNum="2">
    	<operations>
    		<request>
    			<data>
    				<TEST_ID>40</TEST_ID>
    				<INT_VAL>331</INT_VAL>
    			</data>
    			<oldValues>
    				<CHAR_VAL></CHAR_VAL>
    				<DATE_VAL>2012-01-17T00:00:00</DATE_VAL>
    				<NUM_VAL></NUM_VAL>
    				<TEST_ID>40</TEST_ID>
    				<INT_VAL>33</INT_VAL>
    			</oldValues>
    			<dataSource>test</dataSource>
    			<operationType>update</operationType>
    			<componentId>isc_ListGrid_0</componentId>
    		</request>
    		<request>
    			<data>
    				<TEST_ID>42</TEST_ID>
    				<INT_VAL>41</INT_VAL>
    			</data>
    			<oldValues>
    				<CHAR_VAL></CHAR_VAL>
    				<DATE_VAL>2012-01-19T00:00:00</DATE_VAL>
    				<NUM_VAL></NUM_VAL>
    				<TEST_ID>42</TEST_ID>
    				<INT_VAL>4</INT_VAL>
    			</oldValues>
    			<dataSource>test</dataSource>
    			<operationType>update</operationType>
    			<componentId>isc_ListGrid_0</componentId>
    		</request>
    	</operations>
    </transaction>
    Response:
    Code:
    <responses>
    	<response>
    		<status>0</status>
    		<data>
    			<record>
    				<CHAR_VAL></CHAR_VAL>
    				<DATE_VAL>2012-01-17T00:00:00</DATE_VAL>
    				<NUM_VAL></NUM_VAL>
    				<TEST_ID>40</TEST_ID>
    				<INT_VAL>331</INT_VAL>
    			</record>
    		</data>
    		<errors />
    	</response>
    	<response>
    		<status>0</status>
    		<data>
    			<record>
    				<CHAR_VAL></CHAR_VAL>
    				<DATE_VAL>2012-01-19T00:00:00</DATE_VAL>
    				<NUM_VAL></NUM_VAL>
    				<TEST_ID>42</TEST_ID>
    				<INT_VAL>41</INT_VAL>
    			</record>
    		</data>
    		<errors />
    	</response>
    </responses>
    Thus, if request (and response) consists of one element, then the error does not occur.

    Then I try to use SmartGWT 3.0 EE Evaluation , and the error also does not occur. The difference between two edition is in generated file \com\smartclient\public\sc\modules\ISC_DataBinding.js.

    Enterprise edititon has the following entries in this file with function name $89g:
    Code:
    line 1295: ,isc.A.$89g=function isc_c_RPCManager__getXMLResponses(_1)...
    line 1300: return}else{_2.results=this.$89g(_2.results);_3=_2.results!=null}}}}
    And LGPL edition has only one entry:
    Code:
    line 1250: return}else{_2.results=this.$89g(_2.results);_3=_2.results!=null}}}}
    In the second case, there is no function declaration with the name of $89g but it is used.
    Is this bug in SmartGWT 3.0 LGPL edition??
    Or may be processing of several responses in XML is not supported for RestDataSource in LGPL edition?
    Last edited by mv200580; 18 Jan 2012, 07:55.

    #2
    Sample project here (5 mb)
    http://aws-test.dyndns.org/rds-test.zip
    with jdom jar
    http://aws-test.dyndns.org/jdom-1.1.2.jar

    If update 1 record and click 'save', then it's ok. But if update 2 records, then error occurs.

    If change rds_test.gwt.xml
    from
    <inherits name="com.smartgwt.SmartGwt"/>
    to
    <inherits name="com.smartgwtee.SmartGwtEE"/>

    no error occurs, even when updating 2 records

    Comment


      #3
      What exact version are you using (see FAQ for how to get it)? If it's not the latest patched version (see smartclient.com/builds) please re-try with the latest patched version.

      Comment


        #4
        SmartGWT 3.0
        SmartClient Version: SC_SNAPSHOT-2011-12-05/LGPL Development Only (built 2011-12-05)
        GWT 2.4.0
        Eclipse 3.6
        browser Firefox 8.0.1, Chrome 16
        Windows 7 x64 Enterprise Service Pack 1

        Tried to use version
        3.0p http://www.smartclient.com/builds/SmartGWT/3.0p/LGPL/2012-01-18
        and
        3.1d http://www.smartclient.com/builds/SmartGWT/3.1d/LGPL/2012-01-18
        , but it appears the same error.

        The same behavior demonstrated in the compiled form.

        Comment


          #5
          OK thanks. To eliminate any problems coming from your subclasses, can you please put together a minimal test case - this means just one .java file containing onModuleLoad() and, in this case, using dataURL to point to an XML response, not your complete project.

          Comment


            #6
            Rds_test.java
            Code:
            package com.mstar.client;
            
            import com.google.gwt.core.client.EntryPoint;
            import com.smartgwt.client.widgets.Button;
            import com.smartgwt.client.widgets.events.ClickEvent;
            import com.smartgwt.client.widgets.events.ClickHandler;
            import com.smartgwt.client.widgets.grid.ListGrid;
            import com.smartgwt.client.widgets.layout.VLayout;
            
            /**
             * Entry point classes define <code>onModuleLoad()</code>.
             */
            public class Rds_test implements EntryPoint {
            	CommonDataSource ds = new CommonDataSource();
            	
            	public void onModuleLoad() {
            		VLayout panel = new VLayout();
            		panel.setSize("100%", "100%");
            		
            		final ListGrid grid = new ListGrid();
            		grid.setUseAllDataSourceFields(true);
            		grid.setAutoSaveEdits(false);
            		grid.setCanEdit(true);
            		grid.setDataSource(ds);
            		grid.fetchData();
            		
            		panel.addMember(grid);
            		
            		Button b0 = new Button("refresh");
            		b0.addClickHandler(new ClickHandler() {
            			public void onClick(ClickEvent event) {
            				grid.setDataSource(ds);
            				grid.fetchData();
            			}
            		});
            		panel.addMember(b0);
            
            		Button b2 = new Button("save");
            		b2.addClickHandler(new ClickHandler() {
            			public void onClick(ClickEvent event) {
            				grid.saveAllEdits();
            			}
            		});
            		panel.addMember(b2);
            		
            		panel.draw();
            	}
            }

            Comment


              #7
              And CommonDataSource.java extends RestDataSource
              Code:
              package com.mstar.client;
              
              import com.smartgwt.client.data.DataSourceField;
              import com.smartgwt.client.data.OperationBinding;
              import com.smartgwt.client.data.RestDataSource;
              import com.smartgwt.client.types.DSOperationType;
              import com.smartgwt.client.types.DSProtocol;
              import com.smartgwt.client.types.FieldType;
              
              public class CommonDataSource extends RestDataSource {
              	public CommonDataSource() {
              		setID("test");  
              		setDataURL("CommonDataSourceServlet");
              		
              		// set operations DSProtocol to POSTXML
              		OperationBinding op_fetch = new OperationBinding();
              		op_fetch.setOperationType(DSOperationType.FETCH);
              		op_fetch.setDataProtocol(DSProtocol.POSTMESSAGE);
              		OperationBinding op_add = new OperationBinding();
              		op_add.setOperationType(DSOperationType.ADD);
              		op_add.setDataProtocol(DSProtocol.POSTMESSAGE);
              		OperationBinding op_update = new OperationBinding();
              		op_update.setOperationType(DSOperationType.UPDATE);
              		op_update.setDataProtocol(DSProtocol.POSTMESSAGE);
              		OperationBinding op_remove = new OperationBinding();
              		op_remove.setOperationType(DSOperationType.REMOVE);
              		op_remove.setDataProtocol(DSProtocol.POSTMESSAGE);
              		setOperationBindings(new OperationBinding[] {op_fetch, op_add, op_update, op_remove});
              		
              		DataSourceField f1 = new DataSourceField("pk", FieldType.INTEGER, "Primary key");
              		f1.setPrimaryKey(true);
              		f1.setCanEdit(false);
              		DataSourceField f2 = new DataSourceField("field", FieldType.TEXT, "Field");
              		this.setFields(f1, f2);
              		
              	}
              
              }

              Comment


                #8
                CommonDataSourceServlet.java, returns the same number of responses as there were requests (for 'update' operation)
                Code:
                package com.mstar.server;
                
                import java.util.Iterator;
                
                import javax.servlet.ServletException;
                import javax.servlet.http.HttpServlet;
                import javax.servlet.http.HttpServletRequest;
                import javax.servlet.http.HttpServletResponse;
                
                import org.jdom.Document;
                import org.jdom.Element;
                import org.jdom.JDOMException;
                import org.jdom.filter.Filter;
                import org.jdom.input.SAXBuilder;
                import org.jdom.output.Format;
                import org.jdom.output.XMLOutputter;
                
                public class CommonDataSourceServlet extends HttpServlet {
                
                	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, java.io.IOException {
                		SAXBuilder builder = new SAXBuilder();
                		Document document = null;
                		try {
                			document = (Document) builder.build(req.getInputStream());
                		} catch (JDOMException e) {
                			e.printStackTrace();
                		}
                		
                		Iterator requests = document.getDescendants(new Filter() {  
                			public boolean matches(Object arg0) {
                				if (arg0 instanceof Element && ((Element) arg0).getName().equals("request")) {   
                					return true;
                				}
                				else
                					return false;
                			}
                		});
                		
                		Element responses = new Document(new Element("responses")).getRootElement();
                		while (requests.hasNext()) {
                			Element request = (Element) requests.next();
                			String operationType = request.getChildText("operationType");
                			String dataSource = request.getChildText("dataSource");
                			
                			try {
                				// 
                				// fetch
                				//
                				if (operationType.equals("fetch")) {
                					Element data = new Element("data");
                					data.addContent(new Element("record")
                							.addContent(new Element("pk").setText("1"))
                							.addContent(new Element("field").setText("111")));
                					data.addContent(new Element("record")
                							.addContent(new Element("pk").setText("2"))
                							.addContent(new Element("field").setText("111111")));
                					Element response = new Element("response").setContent(data);
                					responses.addContent(response);
                				}
                	
                				// 
                				// add
                				//
                				if (operationType.equals("add")) {
                				}
                	
                				// 
                				// update
                				//
                				if (operationType.equals("update")) {
                					Element data = new Element("data");
                					
                					data.addContent(new Element("record")
                							.addContent(new Element("pk").setText(request.getChild("data").getChildText("pk")))
                							.addContent(new Element("field").setText(request.getChild("data").getChildText("field"))));
                					Element response = new Element("response").setContent(data).addContent(new Element("status").setText("0"));
                					responses.addContent(response);
                				}
                	
                				// 
                				// remove
                				//
                				if (operationType.equals("remove")) {
                				}
                			}
                			catch (Exception e) {
                				e.printStackTrace();
                			}
                		}
                		
                		XMLOutputter outputter = new XMLOutputter(Format.getRawFormat());
                		if (responses.getChildren().size() == 1) {
                			outputter.output(responses.getChild("response"), resp.getOutputStream());
                		}
                		else
                			outputter.output(responses, resp.getOutputStream());
                				
                		
                		
                		
                	}
                
                }
                Last edited by mv200580; 18 Jan 2012, 21:09.

                Comment


                  #9
                  Here is minimal test case - java file with onModuleLoad , using setFetchDataURL and setUpdateDataURL. And sample xml files for this urls.
                  Change values in Field for two records, click 'save' and see the error in console.
                  Attached Files

                  Comment


                    #10
                    Is there a way to avoid such errors in the LGPL version, or the only way - to use Pro edition ??

                    Comment


                      #11
                      Thanks for the clear test case. This problem is now corrected, but the fix is unlikely to make it into today's LGPL builds. Look for it in tomorrow's 3.0p and 3.1d builds.

                      Comment


                        #12
                        Thanks

                        Hi Isomorphic,
                        this was exactly my problem too. After downloading the newest nightly build it works :-)
                        Thanks for great support

                        Comment

                        Working...
                        X