4 Replies Latest reply on Aug 16, 2007 1:11 PM by Matthew Lieder

    Starting arbitrary jPDL pageflows from a

    Matthew Lieder Apprentice

      Say I have the following jPDL pageflows:
      PF1: page1.xhtml -> page2.xhtml
      PF2: page1.xhtml -> page3.xhtml
      PF3: page4.xhtml -> page5.xhtml

      What I want to happen is that when the user goes to "controller.seam?flow=PF?", they'll automatically be redirected to the right page and start the right flow. Unfortunately, though that seems a simple task, in reality it's a big pain to do.

      Ideally, I'd like to be able to do:

       <page view-id="/controller.xhtml" action="#{controller.getFlow}">
       <param name="flow" value="#{controller.flow}" />
      
       <navigation>
       <rule if-outcome="PF1">
       <begin-conversation join="true" pageflow="PF1" />
       </rule>
       <rule if-outcome="PF2">
       <begin-conversation join="true" pageflow="PF2" />
       </rule>
       ...
       </navigation>
       </page>
      
      (even that in an ideal world would be more concise, as you can most likely envision)

      However, that doesn't work! If the pageflow has a <start-page> node, Seam doesn't like that its view-id is different than the current page (the controller). If the pageflow has a <start-state> node (automatically going to the first page in the flow), Seam complains that it can't do that while in a RENDER_RESPONSE phase.

      It would seem the following might get around those issues (though add even more duplicate code):
       <rule if-outcome="PF1">
       <redirect view-id="page1.xhtml" />
       <begin-conversation join="true" pageflow="PF1" />
       </rule>
      


      However, that doesn't work either! Seam doesn't allow multiple elements inside a rule element.

      Currently, I'm solving the problem by doing the following; it works, but has lots of ugly duplication (antithema to Seam's goals):
       <page view-id="/controller.xhtml" action="#{controller.getFlow}">
       <param name="flow" value="#{controller.flow}" />
      
       <navigation>
       <rule if-outcome="PF1">
       <redirect view-id="/page1.xhtml" />
       </rule>
       <rule if-outcome="PF2">
       <redirect view-id="/page1.xhtml" />
       </rule>
       <rule if-outcome="PF3">
       <redirect view-id="/page4.xhtml" />
       </rule>
       </navigation>
       </page>
      
       <page view-id="/page1.xhtml" action="#{controller.getFlow}">
       <navigation>
       <rule if-outcome="PF1">
       <begin-conversation join="true" pageflow="PF1" />
       </rule>
       </navigation>
       </page>
      
       <page view-id="/page1.xhtml" action="#{controller.getFlow}">
       <navigation>
       <rule if-outcome="PF2">
       <begin-conversation join="true" pageflow="PF2" />
       </rule>
       </navigation>
       </page>
      
       <page view-id="/page4.xhtml" action="#{controller.getFlow}">
       <navigation>
       <rule if-outcome="PF3">
       <begin-conversation join="true" pageflow="PF3" />
       </rule>
       </navigation>
       </page>
      


      Should I submit a feature request for a solution to this issue?

        • 1. Re: Starting arbitrary jPDL pageflows from a
          Matthew Lieder Apprentice

          (off-topic: I hate the short cut-off on thread titles and/or the painful lack of any "Edit Post" functionality :( )

          • 2. Re: Starting arbitrary jPDL pageflows from a
            Pete Muir Master

            Currently supported, you could do this (which helps a bit):

            <page view-id="/controller.xhtml">
             <navigation evaluate="#{param.flow}">
             <rule if-outcome="PF1">
             <redirect view-id="/page1.xhtml" />
             </rule>
             <rule if-outcome="PF2">
             <redirect view-id="/page1.xhtml" />
             </rule>
             <rule if-outcome="PF3">
             <redirect view-id="/page4.xhtml" />
             </rule>
            </navigation>
            </page>


            or

            <page view-id="/controller.xhtml">
             <navigation>
             <rule if="#{param.flow eq 'PF1'}">
             <redirect view-id="/page1.xhtml" />
             </rule>
             ...
             </navigation>
            </page>


            Will look at the rest later.

            • 3. Re: Starting arbitrary jPDL pageflows from a
              Matthew Lieder Apprentice

              I still need the param element to pass the value onto the page handler for page1.xhtml, so that just rearranges things without reducing code. And, unfortunately, not even that works: the action attribute is needed, otherwise the navigation rules are never evaluated.

              • 4. Re: Starting arbitrary jPDL pageflows from a
                Matthew Lieder Apprentice

                Well, I found out that Seam does allow multiple elements inside a root element, but only if they're in the right order! For instance, this doesn't work:

                 <rule if-outcome="FP1">
                 <redirect view-id="page1.xhtml" />
                 <begin-conversation join="true" pageflow="PF1" />
                 </rule>
                

                but this does:
                 <rule if-outcome="FP1">
                 <begin-conversation join="true" pageflow="PF1" />
                 <redirect view-id="page1.xhtml" />
                 </rule>
                


                So, with that discovery, I was able to greatly reduce the configuration needed, to the point that I'm pretty much satisfied now :). Only unfortunate things are that I still need a controller JavaBean to force the navigation rules to be evaluated on page load and that beginning a pageflow doesn't automatically redirect to its start-page.

                The solution:
                 <page view-id="/controller.xhtml" action="#{controller.getFlow}">
                 <param name="flow" value="#{controller.flow}" />
                
                 <navigation>
                 <rule if-outcome="PF1">
                 <begin-conversation join="true" pageflow="PF1" />
                 <redirect view-id="page1.xhtml" />
                 </rule>
                 <rule if-outcome="PF2">
                 <begin-conversation join="true" pageflow="PF2" />
                 <redirect view-id="page1.xhtml" />
                 </rule>
                 <rule if-outcome="PF3">
                 <begin-conversation join="true" pageflow="PF3" />
                 <redirect view-id="page4.xhtml" />
                 </rule>
                 </navigation>
                 </page>