1. #1
    Sencha User
    Join Date
    Jan 2011
    Posts
    30
    Vote Rating
    0
    mxhn is on a distinguished road

      0  

    Default Mapping GWT RequestFactory proxies to GXT components

    Mapping GWT RequestFactory proxies to GXT components


    I'm trying to use TreeLoader and TreeBeanModelReader to directly map the returned beans from server. This is the code:

    Code:
    TreeBeanModelReader tbmr = new TreeBeanModelReader();
    BaseTreeLoader<ModelData> treeLoader = new BaseTreeLoader<ModelData>(tbmr);
    
    TreeStore<ModelData> store = new TreeStore<ModelData>(treeLoader);
    treePanel = new TreePanel(store);
    
    //do a Request to return a list of CityProxy that implement BeanModelTag
    req.getAllCities(cp, "extra_param_value").fire(
    				new Receiver<List<CityProxy>>() {
    
    					@Override
    					public void onSuccess(List<CityProxy> cities) {
    						treeLoader.load(data);
    					}
    
    				});
    The issue is that the returned list cities doesn't contain instances of CityProxy but instances of CityProxyAutoBean_com_google_gwt_requestfactory_shared_impl_EntityProxyCategory_com_google_gwt_requestfactory_shared_impl_ValueProxyCategory_com_google_gwt_requestfactory_shared_impl_BaseProxyCategory extends com.google.gwt.autobean.shared.impl.AbstractAutoBean<com.tion.shared.CityProxy>.

    All these instances are not implementing BeanModelTag since only my proxy, CityProxy implements it. TreeBeanModelReader tries to do this:

    Code:
    BeanModelFactory factory = BeanModelLookup.get().getFactory(beans.get(0).getClass());
    and it returns NULL because beans.get(0).getClass(), which returns the generated AutoBean class above, doesn't implement BeanModelTag.


    Is there any way to make this work?


    Thank you!

  2. #2
    Sencha User
    Join Date
    Jan 2011
    Posts
    30
    Vote Rating
    0
    mxhn is on a distinguished road

      0  

    Default


    No ideas? Anyone?

  3. #3
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,640
    Vote Rating
    80
    Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice

      0  

    Default


    RequestFactory is a new GWT feature that relies on knowing everything there is to know about the models it mocks at compile-time, whereas the current version of GXT allows for models to be somewhat more flexible, though admittedly this is not taken advantage of for BeanModels. This difference is what leads to the issue you are encountering - GXT expects to find types that have the BeanModelTag marker interface, and GWT's RF generators don't know to add that interface.

    That being said, it appears someone has come up with the changes required to make this possible with current versions of GXT. http://www.sencha.com/forum/showthre...toBean-support

    Full support for RequestFactory and AutoBeans should be available in the next version of GXT.

    Edit: Well now I feel stupid – you are the other individual in that other thread... Digging a little further, I'll reply again later if I come up with anything that can help.

  4. #4
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,640
    Vote Rating
    80
    Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice

      0  

    Default


    Okay, looking more precisely at your issue with TreeBeanModelReader, the issue appears to be that it is trying too hard to get too precise of an instance of the factory, when you think it should settle for one further away.

    The basic issue can be explained as this - If I make a model object, and tag it with the marker interface, then subclass it but do _not_ tag the subclass, the present system does not hunt it down and built it an factory - you didn't indicate that you wanted one, so it didnt make one. One can argue whether or not doing so would be a good idea on the merits of being rigorous or a bad one as it could make for some unnecessarily large code, but the point still stands - if you ask it to obtain a factory instance for you, it tries to be very precise.

    My suggestion to you would be to not use TreeBeanModelReader as is, but copy and change it, replacing the possibilities for loading a factory with a factory instance that you pass in. This way, when you create a factory, you will say
    TreeAutoBeanModalReader reader = new ...(BeanModelLookup.get().getFactory(MyModelProxy.class);
    Using that reader will ensure that you are always using the correct factory instance. Note that RequestFactory at this time does not appear to support polymorphism, so you shouldn't have an issue with the wrong subtype of MyModelProxy being requested.

    The read method in this TreeBeanModelReader could look like this:

    Code:
      public List<ModelData> read(Object loadConfig, Object data) {
        if (data instanceof List) {
          List<Object> beans = (List) data;
          if (beans.size() > 0) {
            return (List) factory.createModel(beans);
          }
          return (List) beans;
    
        }
    where factory is the factory passed in through the constructor.

    As in my last post, RequestFactory entities and AutoBean instances will be supported natively in the next version of GXT, so this will no longer be necessary. Sorry for the confusion in my first post, I am not generally in the habit of checking user names across various posts, but I will be now...

  5. #5
    Sencha User
    Join Date
    Jan 2011
    Posts
    30
    Vote Rating
    0
    mxhn is on a distinguished road

      0  

    Default


    Hello Colin,

    Thank you for taking the time and reply on my issue. I appreciate it.

    Until now I've tried to extend BeanModelGenerator with a custom generator that generates an implementation of BeanModelLookupImpl. This BeanModelLookupImpl would test the super-interface of the given class to getFactory. If it finds that class implements an interface extended from BeanModelTag then it would return an appropriate factory.
    This was my strategy and it seemed sound from the start, but unfortunatelly I've learned that GWT doesn't have a Class.getInterfaces() method implemented yet. So it's not possible to implement my idea.

    As of this moment, the implemented interfaces of a given GWT class can only be found out inside a Generator while at code generation stage. Since the BeanModelLookupImpl itself and the proxy implementations are generated by a generator, it is not possible to get the class parameter given to BeanModelLookupImpl.getFactory(Class clazz) and provide it to the generator. Nor it is possible to get all implementing generated classes of the proxy interface inside the generator because they're generated and don't exist statically(i.e. they're not included in the TypeOracle).

    Your idea sounds like a good way to go if the client would know that all beans returned are of the same type. But in a tree-like structure it is possible that you could have something like:
    * Folder [1]
    ** Melody
    ** Folder
    *** Melody

    so that the tree consists of multiple types of beans. If you expand the [1] folder, the list returned from server would contain different types. These would be returned as: {AutoBean_MelodyProxy, AutoBean_FolderProxy}. The issue here is that the client can't know which interface AutoBean_MelodyProxy implements, hence I don't know how to provide a factory like you said for this case. Since these classes are automatically generated by GWT's RequestFactory generator, I can't create a map like {AutoBean_MelodyProxy->MelodyProxy, AutoBean_FolderProxy->FolderProxy} and pass it to TreeBeanModelReader. One way perhaps to do this would be to have my server beans encode for each bean a property that specifies the name of the Proxy(i.e. getProxyName() -> FolderProxy). I'm not sure if you considered this case but if you did, I hope you could provide me with a bit more insight.

    Since I'm not a premium user yet, could you give me a rough estimate when the next GXT version will come out with RequestFactory and AutoBean support?

    Thank you!

  6. #6
    Sencha User
    Join Date
    Jan 2011
    Posts
    30
    Vote Rating
    0
    mxhn is on a distinguished road

      0  

    Default


    Giving it a another thought, I don't know if it makes sense to go down this "reinvent the wheel" road.

    I've talked with @Stigrv in this thread and while he said he upgraded to RequestFactory I don't have a clear understanding of how much work is involved.

    Even if I'd fix the above thing, I'd still have to modify the BaseLoader which uses this reader into something that works with RequestFactory. Now, BaseLoader uses the DataProxy interface which uses AsyncCallback that is RPC specific.

    If you could help me with this I'd appreciate it very much.

    Thank you!

  7. #7
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,640
    Vote Rating
    80
    Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice

      0  

    Default


    I'm going to try to reply to a lot of things here, not just your last reply, because there are lots of options available.
    Quote Originally Posted by mxhn View Post
    This BeanModelLookupImpl would test the super-interface of the given class to getFactory. If it finds that class implements an interface extended from BeanModelTag then it would return an appropriate factory.
    This was my strategy and it seemed sound from the start, but unfortunatelly I've learned that GWT doesn't have a Class.getInterfaces() method implemented yet. So it's not possible to implement my idea.
    While this is true at runtime (Class<?> data takes a ton of space, and including it at runtime is a great way to make your app huge), instanceof still works. Your approach here could be somewhat expensive though, at runtime looking at each supertype and interface... Something like this should belong in the generator, if at all.

    Quote Originally Posted by mxhn View Post
    As of this moment, the implemented interfaces of a given GWT class can only be found out inside a Generator while at code generation stage. Since the BeanModelLookupImpl itself and the proxy implementations are generated by a generator, it is not possible to get the class parameter given to BeanModelLookupImpl.getFactory(Class clazz) and provide it to the generator. Nor it is possible to get all implementing generated classes of the proxy interface inside the generator because they're generated and don't exist statically(i.e. they're not included in the TypeOracle).
    All correct, but you are still missing that this system is designed to be used at runtime, against the types it knows. The bean model wrapping/unwrapping code is somewhat stronger than RequestFactory or AutoBeans, as it can work with any set of classes, no matter the inheritance, not just interfaces. As a result of this, you must be more precise when referring to it at runtime – when getting a factory, as I mentioned, you must ask for the correct one.

    Quote Originally Posted by mxhn View Post
    Your idea sounds like a good way to go if the client would know that all beans returned are of the same type. But in a tree-like structure it is possible that you could have something like:
    * Folder [1]
    ** Melody
    ** Folder
    *** Melody

    so that the tree consists of multiple types of beans. If you expand the [1] folder, the list returned from server would contain different types. These would be returned as: {AutoBean_MelodyProxy, AutoBean_FolderProxy}. The issue here is that the client can't know which interface AutoBean_MelodyProxy implements, hence I don't know how to provide a factory like you said for this case. Since these classes are automatically generated by GWT's RequestFactory generator, I can't create a map like {AutoBean_MelodyProxy->MelodyProxy, AutoBean_FolderProxy->FolderProxy} and pass it to TreeBeanModelReader. One way perhaps to do this would be to have my server beans encode for each bean a property that specifies the name of the Proxy(i.e. getProxyName() -> FolderProxy). I'm not sure if you considered this case but if you did, I hope you could provide me with a bit more insight.
    Unfortunately, you are correct here – that is the big issue with the code I provided (and why my comment above doesn't help you).

    It gets a little deeper than this - BeanModelFactory.newInstance() is supposed to be able to construct new instances of the types it manages, which is clearly not possible out of the box when wrapping interfaces that will be implemented at runtime. Truly, this was intended for bean classes, and the new RF and AB stuff is a totally different mechanism.

    Before moving on, I'd like to point out a solution that still uses the idea I gave before, and fits the use case you just mentioned. Instead of passing in a single factory to a general RF-ready treereader, make a specialized treereader that expects only your two types. Have it then verify that any given instance is a Folder or Melody subclass before selecting the proper factory for it. I can help with the code if you don't yet see what I mean.

    Quote Originally Posted by mxhn View Post
    I've talked with @Stigrv in this thread and while he said he upgraded to RequestFactory I don't have a clear understanding of how much work is involved.

    Even if I'd fix the above thing, I'd still have to modify the BaseLoader which uses this reader into something that works with RequestFactory. Now, BaseLoader uses the DataProxy interface which uses AsyncCallback that is RPC specific.
    I think it is not that bad – as far as I can tell, BaseLoader just makes an AsyncCallback, and passes it to its proxy. If you were to extend any loader you want to pass a Receiver instead, and make a new DataProxy like object (or go the other way - make DataProxy wrap the AsyncCallback in a Receiver), you should be just fine. Nothing else in the store or loader are dependent on RPC except for the use of that success/fail interface.

    If you are using the loader/proxy to get data, there shouldn't be issues with violations going off, so just have receiver.onSuccess call asyncCallback.onSuccess, and the same for onFailure, plus some exception unwrapping code if you like.

    One final thought –
    final MyRequestFactory rf = GWT.create(MyReqyestFactory.class);
    rf.startMyRequest().loadSomeData().fire(new Receiver(){
    public void onSuccess(MyDataModel model) {
    EntityProxyId<MyDataModel> id = model.stableId();
    //what does this return:
    id.getProxyClass();
    }
    });
    If, as I suspect, this returns the interface that the EntityProxyImpl was created to wrap, you can pass that to getFactory(Class), and always get the correct factory. I make this assumption because:
    AbstractRequestContext (the superclass to any MyRequest interface) has create(Class), which calls
    IdFactory.allocateId (IDFactory is a superclass of AbstractRequestFactory), which calls
    IdFactory.createId(Class, int), which calls
    new SimpleProxyId(Class, int), which sets the SimpleProxyId's proxyClass field to that class object.

    This may only apply for creating new instances, but that would surprise me, as you can turn strings into instances with a little extra type info. Further, you can get history tokens from RF that refer to the proxy interface.

    Good luck! From the SenchaCon 2010 slides, GXT 3 is expected this summer, but that is all I know for certain.

  8. #8
    Sencha User
    Join Date
    Jan 2011
    Posts
    30
    Vote Rating
    0
    mxhn is on a distinguished road

      0  

    Default


    Thank you! You wrote a very comprehensive reply.

    I'll try to understand all you said, and I'll come with feedback later if anything's unclear.

    I appreciate it very much! Have a great day!

  9. #9
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,640
    Vote Rating
    80
    Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice

      0  

    Default


    Stop by #extgwt on irc.freenode.net if you want to chat.

  10. #10
    Sencha User
    Join Date
    Jan 2011
    Posts
    30
    Vote Rating
    0
    mxhn is on a distinguished road

      0  

    Default


    Sure, thank you!

Similar Threads

  1. Proxies?
    By dimebag in forum Ext 3.x: Help & Discussion
    Replies: 8
    Last Post: 12 Aug 2009, 3:44 AM
  2. Proxies and SPs/queries
    By rwo123gr in forum Ext 2.x: Help & Discussion
    Replies: 4
    Last Post: 6 Dec 2008, 3:03 PM
  3. Field mapping a Select and boolean data mapping
    By lucas in forum Ext 2.x: Help & Discussion
    Replies: 1
    Last Post: 8 Mar 2007, 5:35 AM
  4. Drag proxies?
    By sixten in forum Ext 1.x: Help & Discussion
    Replies: 1
    Last Post: 5 Mar 2007, 3:37 PM
  5. Annoying proxies!!
    By jay@moduscreate.com in forum Ext 1.x: Help & Discussion
    Replies: 2
    Last Post: 26 Nov 2006, 3:36 PM

Thread Participants: 2

Tags for this Thread

film izle

hd film izle

film sitesi

takipci kazanma sitesi

takipci kazanma sitesi

güzel olan herşey

takipci alma sitesi

komik eğlenceli videolar