6 Replies Latest reply on Apr 9, 2006 5:58 AM by mirko27

    @DataModel design issues -- JSF/HTTP dependency in EJBs?

    uhyonc

      I've been playing around with the issues system and I had some questions regarding the way DataModel works.

      The examples only show datamodels in which the data list/factory/selection are all on the same object. However, there are many cases when you would want to go to the selection from many different lists.

      In the issues example there are two issues lists (IssueFinderBean, ProjectEditorBean), which when selected goes to IssueEditorBean. However, if you take a look at IssueEditorBean, it "knows" where the selection came from by having two different select methods : select(), and selectIssue(). This would mean that you need a new method for every list!!

      Is there a way to add a parameter to the select method (say select(String issueId)) and have the currently selected item automagically passed in as this parameter?


      Currently the only way to achieve the above AFAIK would be to use the @RequestParameter annotation, which seems like a hack to me. Maybe there is a way to override the default JSF EventListener to achieve it?

      On a related note, having EJB beans aware that it's in an HTTP environment (using @RequestParameter in IssueFinderBean for example), and even having access to FacesContext (and related externalContext method...) within an EJB would be mixing the UI layer with the Logic layer which is not a good idea.

      I think there needs to be layer that'll wrap the JSF dependency, and be able to convert request parameters to method parameters.
      Also it should be able convert Object hierarchies to SelectItems, TreeModel (tomahawk tree), and any other object types that JSF component libraries would require in the future.

        • 1. Re: @DataModel design issues -- JSF/HTTP dependency in EJBs?
          uhyonc

          One way I thought of is to have the backing bean that contains the @DataModel have a select method that calls the injected bean's select method.

          For example :

          class Main {
           @In(create=true) ItemEditor itemEditor;
           @DataModel List items;
           @DataModelSelection private Item selectedItem;
           String selectItem() { itemEditor.selectItem(selectedItem); }
          }
          
          class ItemFinder {
           @In(create=true) ItemEditor itemEditor;
           @DataModel List foundItems;
           @DataModelSelection private Item selectedItem;
           String selectItem() { itemEditor.selectItem(selectedItem); }
          }
          
          class ItemEditor {
           Item instance;
           public String selectItem(Item item) {
           instance = item;
           return "editItem";
           }
          }
          



          • 2. Re: @DataModel design issues -- JSF/HTTP dependency in EJBs?
            mirko27

            You should try this way:
            In one bean:
            @DataModel items;
            In other bean;
            @DataModelSelection(value="items")

            This seems to be logic way of doing it.
            The current select()-way-of-doing-things is needed because to Inject @datamodelselection object we need to use that bean.
            By the way you do not need
            this ugly solution:
            String selectItem() { itemEditor.selectItem(selectedItem); }

            You can replace it by
            @Out @DataModelSelection item; in one bean
            and @In item; in other bean.

            Hope it helps. My english is not the best virtue.

            • 3. Re: @DataModel design issues -- JSF/HTTP dependency in EJBs?
              uhyonc

              The first solution would work except that you'd have to make sure that the the @DataModel's names are all matched up. And it wouldn't work in cases where you have multiple items in a single bean, since that'd require two different selectedItem in the receiving bean.

              However, I hadn't realized that you could actually do it that way. I think it'll come in useful later.

              The second way would work, and is definitely prettier than the way I did it. I hadn't realized you could transfer data that way.

              Thanks

              - Luther

              • 4. Re: @DataModel design issues -- JSF/HTTP dependency in EJBs?
                uhyonc

                As to the selectedItem...

                It works, as long as you make sure that the bean is either a stateful session bean or it's in the page (or longer) scope and the same goes for the scope on the @Out annotation for the selectedItem.

                • 5. Re: @DataModel design issues -- JSF/HTTP dependency in EJBs?
                  uhyonc

                  The outjection is tougher than you'd think...

                  The problem is that I have 3 beans that will outject the selectedItem object...
                  I tried it with both the Page scope and the Session scope. Apparently, all 3 of the beans will outject the selectedItem, which means that a random item will get outjected... (in which case I get a NPE).

                  I tried the stateless/event scope, which doesn't propagate the selectedItem...

                  I also tried the conversation scope which doesn't propagate the selectedItem...

                  FYI :

                  @Stateful
                  class Bean1 {
                   @DataModel private List<Item> itemList;
                   @DataModelSelection("itemList")
                   @Out(required=false,scope=ScopeType.SESSION) private Item selectedItem;
                  }
                  @Stateful
                  class Bean2 {
                   @DataModel private List<Item> itemList;
                   @DataModelSelection("itemList")
                   @Out(required=false,scope=ScopeType.SESSION) private Item selectedItem;
                  }
                  @Scope(ScopeType.SESSION)
                  class Bean3 {
                   @DataModel private List<Item> itemList;
                   @DataModelSelection("itemList")
                   @Out(required=false,scope=ScopeType.SESSION) private Item selectedItem;
                  }
                  
                  class ReceivingBean {
                   @In(required=false) private Item selectedItem;
                   @Begin(nested=true)
                   public String selectItem() {
                   }
                  }
                  


                  I'd like to know what combination of scope types/annotation type settings will work in the above case...

                  Note :
                  outject in random order is because the BijectionInterceptor is called many times and there is probably not an order in how JBoss AOP calls it...


                  • 6. Re: @DataModel design issues -- JSF/HTTP dependency in EJBs?
                    mirko27

                    Use long-running conversation. You have to start thinking this way :D