Heya,

Your basic problem here is that you can't have your XmlParserUtil return a 
Document object. The doc field will only be filled in when the async 
RequestBuilder request returns and the parser is finished with the XML string. 
By that time, your method has already returned.

The only way to solve this is to create something like a:

public interface Callback<V> {
        void callback(V value);
}

and have the XmlParserUtil look something more like this:

public class XmlParserUtil {
        String url;
        Document doc;
        public RequestBuilder requestBuilder;
        String xmlStr;

        public XmlParserUtil(String xmlFileName) {
                this.url = xmlFileName;
        }

        public void getDocument(Callback<Document> callback) {
                if(doc != null) {
                        callback.callback(doc);
                        return;
                }
                
                try {
                        requestBuilder = new 
RequestBuilder(RequestBuilder.GET,url);
                        requestBuilder.sendRequest(null,new RequestCallback()
                        {public void onResponseReceived(Request arg0, Response 
arg1) {
                                xmlStr = arg1.getText();
                                callback.callback(doc = 
XMLParser.parse(xmlStr));
                        }
                        public void onError(Request request, Throwable 
exception) {

                        }});
                }
                catch (RequestException ex) {
                        GWT.log(ex.getMessage(), ex);
            }
        }
}

For more information about async problems, it's related to RPC, but applicable 
to the RequestBuilder as well:

http://lemnik.wordpress.com/2008/07/04/gwt-rpc-is-called-aynchronous-for-a-reason/


mives29 wrote:
> okay, let me be clear on this, again, my code. (now posting full
> reworked source code)
> 
> // A composite w/c contains a tree.
> public class TreeX extends Composite {
>       Document doc;
>       Tree t = new Tree();
>       int imgUris;
>       XmlParserUtil xmlParser;
>       public TreePol() {
>               TreeItem tItem = getTreeItem();
>               t.addItem(tItem);
>               initWidget(t);
>       }
>       private TreeItem getTreeItem() {
>               doc = getDoc();
>               imgUris = doc.getElementsByTagName("Image").getLength();
>               TreeItem root = null;
>               root = new TreeItem("Image Names");
>               for (int i=0;i<imgUris;i++) {
>                       String tmpImgUri =
> doc.getElementsByTagName("Image").item(i).getChildNodes().item(1).toString();
>                       root.addItem(tmpImgUri);
>               }
>               return root;
>       }
>       public Document getDoc() {
>               xmlParser = new XmlParserUtil("image_uris.xml");
>                 while (doc==null) {
>                         doc = xmlParser.getDocument();
>                 }
>               return doc;
>       }
> }
> 
> //A class that i want to use as a utility class for parsing xml
> documents. intended to be reusable
> public class XmlParserUtil {
>       String url;
>       Document doc;
>       public RequestBuilder requestBuilder;
>       String xmlStr;
> 
>       public XmlParserUtil(String xmlFileName) {
>               this.url = xmlFileName;
>       }
> 
>       public Document getDocument() {
>               try {
>                       requestBuilder = new 
> RequestBuilder(RequestBuilder.GET,url);
>                       requestBuilder.sendRequest(null,new RequestCallback()
>                       {public void onResponseReceived(Request arg0, Response 
> arg1) {
>                               xmlStr = arg1.getText();
>                               doc = XMLParser.parse(xmlStr);
>                       }
>                       public void onError(Request request, Throwable 
> exception) {
> 
>                       }});
>               }
>               catch (RequestException ex) {
>                       GWT.log(ex.getMessage(), ex);
>           }
>               return doc;
>       }
> }
> 
> //my entrypoint's onModuleLoad(), which adds the various custom
> widgets i made to a tab panel
> 
> public void onModuleLoad() {
>         RichTextAreaX1 rtaPol = new RichTextAreaX1();
>         PictureViewer imgBrowser = new PictureViewer();
>         TreeX tree = new TreeX();
> 
>         TabPanel tp = new TabPanel();
>         tp.add(tree, "1");
>         tp.add(rtaPol, "2");
>         tp.add(imgBrowser, "3");
> 
>         tp.selectTab(0);
>         tp.setWidth("100%");
> 
>         RootPanel.get("leftpanel").add(tp);
>   }
> 
> as you can see, I intend the XmlParserUtil class to be reusable. If I
> place there various logic, then it would be out of scope for that
> classs, because I intend to use XmlParserUtil just to parse an XML
> file, and bring me back a parsed Document object. now how would I do
> that if XmlParserUtil, which contains the requestbuilder and callback,
> would be used by another class (which is a composite).
> 
> im new to this async thing, more so the  requestbuilder stuff. thank
> you for replying, i hope you could answer my question.
> 
> On Nov 10, 3:44 pm, "alex.d" <[EMAIL PROTECTED]> wrote:
>> You have to accept the asynchronous nature of RPC-Requests in GWT and
>> stop trying to build smth. synchronous around them. This code:
>> -----------------------------------
>> doc = getDoc(); //(where doc is a Document object)
>> String subject =
>> doc.getElementsByTagName("Image").item(0).getChildNodes().item(1).toString();
>> String subject2 =
>> doc.getElementsByTagName("Image").item(1).getFirstChild().getNodeValue();
>> -----------------------------------
>> should not be executed in the onload-routine but in the
>> onResponseReceived()-method (or in any other procedure that you call
>> out of it).
>>
>> On 10 Nov., 07:12, mives29 <[EMAIL PROTECTED]> wrote:
>>
>>> hi all. ive re-done my code just a while ago(been a busy week) and my
>>> code kinda bothers me.  here's the code re-done:
>>> Entrypoint onModuleLoad() method:
>>> doc = getDoc(); //(where doc is a Document object)
>>> String subject =
>>> doc.getElementsByTagName("Image").item(0).getChildNodes().item(1).toString();
>>> String subject2 =
>>> doc.getElementsByTagName("Image").item(1).getFirstChild().getNodeValue();
>>> Entrypoiny getDoc() method:
>>> public Document getDoc() {
>>>           XmlParserUtil xmlParser = new XmlParserUtil("image_uris.xml");
>>>           int i = 0;
>>>           while (doc==null) {
>>>                   doc = xmlParser.getDocument();
>>>           }
>>>         return doc;
>>>   }
>>> here's the service implementation:
>>> public class XmlParserUtil {
>>>         String url;
>>>         Document doc;
>>>         RequestBuilder requestBuilder;
>>>         public String xmlStr;
>>>         public XmlParserUtil(String xmlFileName) {
>>>                 this.url = xmlFileName;
>>>         }
>>>         public Document getDocument() {
>>>                 RequestCallback xmlRcb = new RequestCallback()
>>>                 {public void onResponseReceived(Request arg0, Response 
>>> arg1) {
>>>                         xmlStr = arg1.getText();
>>>                         doc = XMLParser.parse(xmlStr);
>>>                 }
>>>                 public void onError(Request request, Throwable exception) {
>>>                         // TODO Auto-generated method stub
>>>                 }};
>>>                 try {
>>>                         requestBuilder = new 
>>> RequestBuilder(RequestBuilder.GET,url);
>>>                         requestBuilder.sendRequest(null,xmlRcb);
>>>                 }
>>>                 catch (RequestException ex) {
>>>                         GWT.log(ex.getMessage(), ex);
>>>             }
>>>                 return doc;
>>>         }
>>> }
>>> my problem is on the Entrypoint logic. you see the getDoc() method
>>> there?
>>> it has this:
>>>           while (doc==null) {
>>>                   doc = xmlParser.getDocument();
>>>           }
>>> which just loops around until the service implementation has already
>>> populated the parsed document.
>>> what bothers me with this code is that it seems to break AJAX. the
>>> execution "stays" here until the document object is not null anymore,
>>> which kills the purpose of using AJAX (coz it seems not asynchronous
>>> anymore).
>>> is there any lister that i can implement on my entrypoint class that
>>> "listens" if the service has already received a reply? (or a listener
>>> of that sort)
>>> thanks in advance.
> > 
> 

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to Google-Web-Toolkit@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/Google-Web-Toolkit?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to