[jboss-cvs] jboss-seam/src/main/org/jboss/seam/core ...

Gavin King gavin.king at jboss.com
Sun Dec 17 12:45:37 EST 2006


  User: gavin   
  Date: 06/12/17 12:45:37

  Modified:    src/main/org/jboss/seam/core     Events.java Exceptions.java
                        Page.java Pages.java
  Log:
  JBSEAM-607, begin-conversation/end-conversation on an outcome
  
  Revision  Changes    Path
  1.17      +4 -10     jboss-seam/src/main/org/jboss/seam/core/Events.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: Events.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/core/Events.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -b -r1.16 -r1.17
  --- Events.java	16 Dec 2006 14:06:57 -0000	1.16
  +++ Events.java	17 Dec 2006 17:45:37 -0000	1.17
  @@ -10,12 +10,8 @@
   import java.util.List;
   import java.util.Map;
   
  -import org.jboss.seam.log.LogProvider;
  -import org.jboss.seam.log.Logging;
  -import org.dom4j.Document;
   import org.dom4j.DocumentException;
   import org.dom4j.Element;
  -import org.dom4j.io.SAXReader;
   import org.jboss.seam.Component;
   import org.jboss.seam.ScopeType;
   import org.jboss.seam.Seam;
  @@ -27,8 +23,10 @@
   import org.jboss.seam.contexts.Contexts;
   import org.jboss.seam.core.Expressions.MethodBinding;
   import org.jboss.seam.core.Init.ObserverMethod;
  -import org.jboss.seam.util.DTDEntityResolver;
  +import org.jboss.seam.log.LogProvider;
  +import org.jboss.seam.log.Logging;
   import org.jboss.seam.util.Resources;
  +import org.jboss.seam.util.XML;
   
   @Scope(ScopeType.APPLICATION)
   @Intercept(NEVER)
  @@ -52,11 +50,7 @@
         else
         {
            log.info("reading events.xml");
  -         SAXReader saxReader = new SAXReader();
  -         saxReader.setEntityResolver( new DTDEntityResolver() );
  -         saxReader.setMergeAdjacentText(true);
  -         Document doc = saxReader.read(stream);
  -         List<Element> elements = doc.getRootElement().elements("event");
  +         List<Element> elements = XML.getRootElement(stream).elements("event");
            for (Element event: elements)
            {
               String type = event.attributeValue("type");
  
  
  
  1.20      +2 -8      jboss-seam/src/main/org/jboss/seam/core/Exceptions.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: Exceptions.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/core/Exceptions.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -b -r1.19 -r1.20
  --- Exceptions.java	17 Dec 2006 02:39:17 -0000	1.19
  +++ Exceptions.java	17 Dec 2006 17:45:37 -0000	1.20
  @@ -10,9 +10,7 @@
   import javax.faces.context.FacesContext;
   import javax.faces.event.PhaseId;
   
  -import org.dom4j.Document;
   import org.dom4j.Element;
  -import org.dom4j.io.SAXReader;
   import org.jboss.seam.Component;
   import org.jboss.seam.ScopeType;
   import org.jboss.seam.annotations.Create;
  @@ -28,11 +26,11 @@
   import org.jboss.seam.contexts.Lifecycle;
   import org.jboss.seam.log.LogProvider;
   import org.jboss.seam.log.Logging;
  -import org.jboss.seam.util.DTDEntityResolver;
   import org.jboss.seam.util.Reflections;
   import org.jboss.seam.util.Resources;
   import org.jboss.seam.util.Strings;
   import org.jboss.seam.util.Transactions;
  +import org.jboss.seam.util.XML;
   
   /**
    * Holds metadata for pages defined in pages.xml, including
  @@ -74,11 +72,7 @@
         else
         {
            log.info("reading exceptions.xml");
  -         SAXReader saxReader = new SAXReader();
  -         saxReader.setEntityResolver( new DTDEntityResolver() );
  -         saxReader.setMergeAdjacentText(true);
  -         Document doc = saxReader.read(stream);
  -         List<Element> elements = doc.getRootElement().elements("exception");
  +         List<Element> elements = XML.getRootElement(stream).elements("exception");
            for (Element exception: elements)
            {
               String className = exception.attributeValue("class");
  
  
  
  1.12      +111 -146  jboss-seam/src/main/org/jboss/seam/core/Page.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: Page.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/core/Page.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -b -r1.11 -r1.12
  --- Page.java	17 Dec 2006 16:04:09 -0000	1.11
  +++ Page.java	17 Dec 2006 17:45:37 -0000	1.12
  @@ -14,23 +14,23 @@
   import org.jboss.seam.core.Expressions.ValueBinding;
   
   /**
  - * Metadata about page actions, page parameters, resource bundle
  - * etc, for a particular JSF view id.
  + * Metadata about page actions, page parameters, action navigation,
  + * resource bundle, etc, for a particular JSF view id.
    */
   public final class Page
   {
  -   public static final class PageParameter
  +   public static final class Param
      {
  -      PageParameter(String name)
  -      {
  -         this.name = name;
  -      }
  -      
         private final String name;
         private ValueBinding valueBinding;
         private ValueBinding converterValueBinding;
         private String converterId;
         
  +      Param(String name)
  +      {
  +         this.name = name;
  +      }
  +      
         Converter getConverter()
         {
            if (converterId!=null)
  @@ -95,25 +95,25 @@
   
      }
      
  -   public static final class Navigation
  +   public static final class ActionNavigation
      {
         private ValueBinding<Object> outcomeValueBinding;
  -      private Map<String, Case> cases = new HashMap<String, Case>();
  -      private Case nullCase;
  -      private Case anyCase;
  +      private Map<String, Outcome> outcomes = new HashMap<String, Outcome>();
  +      private Outcome nullOutcome;
  +      private Outcome anyOutcome;
         
  -      public Map<String, Case> getCases()
  +      public Map<String, Outcome> getOutcomes()
         {
  -         return cases;
  +         return outcomes;
         }
         
  -      void setNullCase(Case defaultCase)
  +      void setNullOutcome(Outcome outcome)
         {
  -         this.nullCase = defaultCase;
  +         this.nullOutcome = outcome;
         }
  -      public Case getNullCase()
  +      public Outcome getNullOutcome()
         {
  -         return nullCase;
  +         return nullOutcome;
         }
         
         void setOutcomeValueBinding(ValueBinding<Object> outcomeValueBinding)
  @@ -125,19 +125,40 @@
            return outcomeValueBinding;
         }
   
  -      public Case getAnyCase()
  +      public Outcome getAnyOutcome()
         {
  -         return anyCase;
  +         return anyOutcome;
         }
  -      void setAnyCase(Case elseCase)
  +      void setAnyOutcome(Outcome outcome)
         {
  -         this.anyCase = elseCase;
  +         this.anyOutcome = outcome;
         }
      }
      
  -   public static final class Case
  +   public static final class Outcome
  +   {
  +      private NavigationHandler navigationHandler;
  +      private ConversationControl conversationControl = new ConversationControl();
  +
  +      protected NavigationHandler getNavigationHandler()
      {
  -      private Result result;
  +         return navigationHandler;
  +      }
  +
  +      protected void setNavigationHandler(NavigationHandler result)
  +      {
  +         this.navigationHandler = result;
  +      }
  +
  +      protected ConversationControl getConversationControl()
  +      {
  +         return conversationControl;
  +      }
  +   }
  +   
  +   public static class ConversationControl
  +   {
  +   
         private boolean isBeginConversation;
         private boolean isEndConversation;
         private boolean join;
  @@ -145,65 +166,92 @@
         private FlushModeType flushMode;
         private String pageflow;
         
  -      void setResult(Result result)
  -      {
  -         this.result = result;
  -      }
  -      Result getResult()
  +      public boolean isBeginConversation()
         {
  -         return result;
  +         return isBeginConversation;
         }
  +   
         void setBeginConversation(boolean isBeginConversation)
         {
            this.isBeginConversation = isBeginConversation;
         }
  -      boolean isBeginConversation()
  +   
  +      public boolean isEndConversation()
         {
  -         return isBeginConversation;
  +         return isEndConversation;
         }
  +   
         void setEndConversation(boolean isEndConversation)
         {
            this.isEndConversation = isEndConversation;
         }
  -      boolean isEndConversation()
  +      
  +      public void beginOrEndConversation()
         {
  -         return isEndConversation;
  -      }
  -      void setJoin(boolean join)
  +         if ( isEndConversation )
         {
  -         this.join = join;
  +            Conversation.instance().end();
         }
  -      boolean isJoin()
  +         if ( isBeginConversation )
         {
  -         return join;
  +            boolean begun = Conversation.instance().begin(join, nested);
  +            if (begun)
  +            {
  +               if (flushMode!=null)
  +               {
  +                  Conversation.instance().changeFlushMode(flushMode);
         }
  -      void setNested(boolean nested)
  +               if ( pageflow!=null  )
         {
  -         this.nested = nested;
  +                  Pageflow.instance().begin(pageflow);
         }
  -      boolean isNested()
  +            }
  +         }
  +      }
  +   
  +      public FlushModeType getFlushMode()
         {
  -         return nested;
  +         return flushMode;
         }
  +   
         void setFlushMode(FlushModeType flushMode)
         {
            this.flushMode = flushMode;
         }
  -      FlushModeType getFlushMode()
  +   
  +      public boolean isJoin()
         {
  -         return flushMode;
  +         return join;
         }
  -      void setPageflow(String pageflow)
  +   
  +      void setJoin(boolean join)
         {
  -         this.pageflow = pageflow;
  +         this.join = join;
  +      }
  +   
  +      public boolean isNested()
  +      {
  +         return nested;
  +      }
  +   
  +      void setNested(boolean nested)
  +      {
  +         this.nested = nested;
         }
  -      String getPageflow()
  +   
  +      public String getPageflow()
         {
            return pageflow;
         }
  +   
  +      void setPageflow(String pageflow)
  +      {
  +         this.pageflow = pageflow;
      }
      
  -   public interface Result
  +   }
  +
  +   public static interface NavigationHandler
      {
         public void navigate(FacesContext context);
      }
  @@ -216,16 +264,11 @@
      private String noConversationViewId;
      private String resourceBundleName;
      private boolean switchEnabled = true;
  -   private List<PageParameter> pageParameters = new ArrayList<PageParameter>();
  -   private Map<String, Navigation> navigations = new HashMap<String, Navigation>();
  -   private Navigation defaultNavigation;
  -   private boolean isBeginConversation;
  -   private boolean isEndConversation;
  -   private boolean join;
  -   private boolean nested;
  -   private FlushModeType flushMode;
  -   private String pageflow;
  +   private List<Param> pageParameters = new ArrayList<Param>();
  +   private Map<String, ActionNavigation> navigations = new HashMap<String, ActionNavigation>();
  +   private ActionNavigation defaultNavigation;
      private boolean conversationRequired;
  +   private ConversationControl conversationControl = new ConversationControl();
      
      Page(String viewId)
      {
  @@ -350,12 +393,12 @@
         return switchEnabled;
      }
   
  -   public List<Page.PageParameter> getPageParameters()
  +   public List<Page.Param> getPageParameters()
      {
         return pageParameters;
      }
   
  -   public Map<String, Page.Navigation> getNavigations()
  +   public Map<String, Page.ActionNavigation> getNavigations()
      {
         return navigations;
      }
  @@ -365,89 +408,6 @@
         return description!=null;
      }
   
  -   public boolean isBeginConversation()
  -   {
  -      return isBeginConversation;
  -   }
  -
  -   void setBeginConversation(boolean isBeginConversation)
  -   {
  -      this.isBeginConversation = isBeginConversation;
  -   }
  -
  -   public boolean isEndConversation()
  -   {
  -      return isEndConversation;
  -   }
  -
  -   void setEndConversation(boolean isEndConversation)
  -   {
  -      this.isEndConversation = isEndConversation;
  -   }
  -   
  -   public void beginOrEndConversation()
  -   {
  -      if ( isEndConversation )
  -      {
  -         Conversation.instance().end();
  -      }
  -      if ( isBeginConversation )
  -      {
  -         boolean begun = Conversation.instance().begin(join, nested);
  -         if (begun)
  -         {
  -            if (flushMode!=null)
  -            {
  -               Conversation.instance().changeFlushMode(flushMode);
  -            }
  -            if ( pageflow!=null  )
  -            {
  -               Pageflow.instance().begin(pageflow);
  -            }
  -         }
  -      }
  -   }
  -
  -   public FlushModeType getFlushMode()
  -   {
  -      return flushMode;
  -   }
  -
  -   void setFlushMode(FlushModeType flushMode)
  -   {
  -      this.flushMode = flushMode;
  -   }
  -
  -   public boolean isJoin()
  -   {
  -      return join;
  -   }
  -
  -   void setJoin(boolean join)
  -   {
  -      this.join = join;
  -   }
  -
  -   public boolean isNested()
  -   {
  -      return nested;
  -   }
  -
  -   void setNested(boolean nested)
  -   {
  -      this.nested = nested;
  -   }
  -
  -   public String getPageflow()
  -   {
  -      return pageflow;
  -   }
  -
  -   void setPageflow(String pageflow)
  -   {
  -      this.pageflow = pageflow;
  -   }
  -
      public boolean isConversationRequired()
      {
         return conversationRequired;
  @@ -458,14 +418,19 @@
         this.conversationRequired = conversationRequired;
      }
   
  -   public Navigation getDefaultNavigation()
  +   public ActionNavigation getDefaultNavigation()
      {
         return defaultNavigation;
      }
   
  -   void setDefaultNavigation(Navigation defaultActionOutcomeMapping)
  +   void setDefaultNavigation(ActionNavigation defaultActionOutcomeMapping)
      {
         this.defaultNavigation = defaultActionOutcomeMapping;
      }
   
  +   protected ConversationControl getConversationControl()
  +   {
  +      return conversationControl;
  +   }
  +
   }
  \ No newline at end of file
  
  
  
  1.66      +317 -265  jboss-seam/src/main/org/jboss/seam/core/Pages.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: Pages.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/core/Pages.java,v
  retrieving revision 1.65
  retrieving revision 1.66
  diff -u -b -r1.65 -r1.66
  --- Pages.java	17 Dec 2006 16:04:09 -0000	1.65
  +++ Pages.java	17 Dec 2006 17:45:37 -0000	1.66
  @@ -19,10 +19,8 @@
   import javax.faces.context.FacesContext;
   import javax.faces.convert.Converter;
   
  -import org.dom4j.Document;
   import org.dom4j.DocumentException;
   import org.dom4j.Element;
  -import org.dom4j.io.SAXReader;
   import org.jboss.seam.Component;
   import org.jboss.seam.ScopeType;
   import org.jboss.seam.annotations.Create;
  @@ -34,12 +32,13 @@
   import org.jboss.seam.contexts.Contexts;
   import org.jboss.seam.core.Expressions.MethodBinding;
   import org.jboss.seam.core.Expressions.ValueBinding;
  -import org.jboss.seam.core.Page.PageParameter;
  +import org.jboss.seam.core.Page.ConversationControl;
  +import org.jboss.seam.core.Page.Param;
   import org.jboss.seam.log.LogProvider;
   import org.jboss.seam.log.Logging;
  -import org.jboss.seam.util.DTDEntityResolver;
   import org.jboss.seam.util.Parameters;
   import org.jboss.seam.util.Resources;
  +import org.jboss.seam.util.XML;
   
   /**
    * Holds metadata for pages defined in pages.xml, including
  @@ -86,246 +85,13 @@
         }
      }
   
  -   private void parse(InputStream stream)
  -   {
  -      Element root = getDocumentRoot(stream);
  -      if (noConversationViewId==null) //let the setting in components.xml override the pages.xml
  -      {
  -         noConversationViewId = root.attributeValue("no-conversation-view-id");
  -      }
  -      List<Element> elements = root.elements("page");
  -      for (Element page: elements)
  -      {
  -         parse( page, page.attributeValue("view-id") );
  -      } 
  -   }
  -
  -   private void parse(InputStream stream, String viewId)
  -   {
  -      parse( getDocumentRoot(stream), viewId );
  -   }
  -
  -   private Element getDocumentRoot(InputStream stream)
  -   {
  -      Document doc;
  -      SAXReader saxReader = new SAXReader();
  -      saxReader.setEntityResolver( new DTDEntityResolver() );
  -      saxReader.setMergeAdjacentText(true);
  -      try
  -      {
  -         doc = saxReader.read(stream);
  -      }
  -      catch (DocumentException de)
  -      {
  -         throw new RuntimeException(de);
  -      }
  -      Element root = doc.getRootElement();
  -      return root;
  -   }
  -
  -   private void parse(Element element, String viewId)
  -   {
  -      Page page = parsePage(element, viewId);
  -      
  -      List<Element> children = element.elements("param");
  -      for (Element param: children)
  -      {
  -         page.getPageParameters().add( parsePageParameter(param) );
  -      }
  -      
  -      List<Element> moreChildren = element.elements("action-navigation");
  -      for (Element fromAction: moreChildren)
  -      {
  -         parseNavigation(page, fromAction);
  -      }
  -   }
  -
  -   private Page parsePage(Element element, String viewId)
  -   {
  -      if (viewId==null)
  -      {
  -         throw new IllegalStateException("Must specify view-id for <page/> declaration");
  -      }
  -      
  -      if ( viewId.endsWith("*") )
  -      {
  -         wildcardViewIds.add(viewId);
  -      }
  -      Page page = new Page(viewId);
  -      pagesByViewId.put(viewId, page);
  -      
  -      page.setSwitchEnabled( !"disabled".equals( element.attributeValue("switch") ) );
  -      
  -      Element optionalElement = element.element("description");
  -      String description = optionalElement==null ? 
  -               element.getTextTrim() : optionalElement.getTextTrim();
  -      if (description!=null && description.length()>0)
  -      {
  -         page.setDescription(description);
  -      }
  -      
  -      String timeoutString = element.attributeValue("timeout");
  -      if (timeoutString!=null)
  -      {
  -         page.setTimeout(Integer.parseInt(timeoutString));
  -      }
  -      
  -      page.setNoConversationViewId( element.attributeValue("no-conversation-view-id") );
  -      page.setConversationRequired( "true".equals( element.attributeValue("conversation-required") ) );
  -      
  -      String action = element.attributeValue("action");
  -      if (action!=null)
  -      {
  -         if ( action.startsWith("#{") )
  -         {
  -            MethodBinding methodBinding = Expressions.instance().createMethodBinding(action);
  -            page.setAction(methodBinding);
  -         }
  -         else
  -         {
  -            page.setOutcome(action);
  -         }
  -      }
  -      
  -      Element endConversation = element.element("end-conversation");
  -      if ( endConversation!=null )
  -      {
  -         page.setEndConversation(true);
  -      }
  -      
  -      Element beginConversation = element.element("begin-conversation");
  -      if ( beginConversation!=null )
  -      {
  -         page.setBeginConversation(true);
  -         page.setJoin( "true".equals( beginConversation.attributeValue("join") ) );
  -         page.setNested( "true".equals( beginConversation.attributeValue("nested") ) );
  -         page.setPageflow( beginConversation.attributeValue("pageflow") );
  -         String flushMode = beginConversation.attributeValue("flush-mode");
  -         if (flushMode!=null)
  -         {
  -            page.setFlushMode( FlushModeType.valueOf( flushMode.toUpperCase() ) );
  -         }
  -      }
  -      
  -      if ( page.isBeginConversation() && page.isEndConversation() )
  -      {
  -         throw new IllegalStateException("cannot use both <begin-conversation/> and <end-conversation/>");
  -      }
  -      
  -      String bundle = element.attributeValue("bundle");
  -      if (bundle!=null)
  -      {
  -         page.setResourceBundleName(bundle);
  -      }
  -      return page;
  -   }
  -
  -   private void parseNavigation(Page entry, Element element)
  -   {
  -      Page.Navigation navigation = new Page.Navigation(); 
  -      String outcomeExpression = element.attributeValue("outcome");
  -      if (outcomeExpression!=null)
  -      {
  -         navigation.setOutcomeValueBinding( Expressions.instance().createValueBinding(outcomeExpression) );
  -      }
  -      List<Element> cases = element.elements("outcome");
  -      for (Element childElement: cases)
  -      {
  -         Page.Case caze = parseCase(childElement);
  -         String value = childElement.attributeValue("value");
  -         if (value==null)
  -         {
  -            throw new IllegalStateException("Must specify value for <outcome/> declaration");
  -         }
  -         navigation.getCases().put(value, caze);
  -      }
  -      Element childElement = element.element("any-outcome");
  -      if (childElement!=null)
  -      {
  -         navigation.setAnyCase( parseCase(childElement) );
  -      }
  -      childElement = element.element("null-outcome");
  -      if (childElement!=null)
  -      {
  -         navigation.setNullCase( parseCase(childElement) );
  -      }
  -      
  -      String expression = element.attributeValue("action");
  -      if (expression==null)
  -      {
  -         entry.setDefaultNavigation(navigation);
  -      }
  -      else
  -      {
  -         entry.getNavigations().put(expression, navigation);
  -      }
  -   }
  -
  -   private Page.PageParameter parsePageParameter(Element element)
  -   {
  -      String valueExpression = element.attributeValue("value");
  -      String name = element.attributeValue("name");
  -      if (name==null)
  -      {
  -         if (valueExpression==null)
  -         {
  -            throw new IllegalArgumentException("must specify name or value for page <param/> declaration");
  -         }
  -         name = valueExpression.substring(2, valueExpression.length()-1);
  -      }
  -      Page.PageParameter pageParameter = new Page.PageParameter(name);
  -      if (valueExpression!=null)
  -      {
  -         pageParameter.setValueBinding(Expressions.instance().createValueBinding(valueExpression));
  -      }
  -      pageParameter.setConverterId(element.attributeValue("converterId"));
  -      String converterExpression = element.attributeValue("converter");
  -      if (converterExpression!=null)
  -      {
  -         pageParameter.setConverterValueBinding(Expressions.instance().createValueBinding(converterExpression));
  -      }
  -      return pageParameter;
  -   }
  -
  -   private Page.Case parseCase(Element element)
  -   {
  -      Page.Case caze = new Page.Case();
  -      Element render = element.element("render");
  -      if (render!=null)
  -      {
  -         final String viewId = render.attributeValue("view-id");
  -         caze.setResult(new Page.Result() {
  -            public void navigate(FacesContext context)
  -            {
  -               render(viewId);
  -            }
  -         });
  -      }
  -      Element redirect = element.element("redirect");
  -      if (redirect!=null)
  -      {
  -         List<Element> children = redirect.elements("param");
  -         final List<PageParameter> pageParameters = new ArrayList<PageParameter>();
  -         for (Element child: children)
  -         {
  -            pageParameters.add( parsePageParameter(child) );
  -         }
  -         final String viewId = redirect.attributeValue("view-id");
  -         caze.setResult(new Page.Result() {
  -            public void navigate(FacesContext context)
  -            {
  -               Map<String, Object> parameters = new HashMap<String, Object>();
  -               for ( PageParameter pageParameter: pageParameters )
  -               {
  -                  parameters.put( pageParameter.getName(), getParameterValue(context, pageParameter) );
  -               }
  -               redirect(viewId, parameters);
  -            }
  -         });
  -      }
  -      return caze;
  -   }
  -
  +   /**
  +    * Run any navigation rule defined in pages.xml
  +    * 
  +    * @param actionExpression the action method binding expression
  +    * @param actionOutcome the outcome of the action method
  +    * @return true if a navigation rule was found
  +    */
      public boolean navigate(FacesContext context, String actionExpression, final String actionOutcome)
      {
         String viewId = context.getViewRoot().getViewId();
  @@ -335,7 +101,7 @@
            for (int i=stack.size()-1; i>=0; i--)
            {
               Page page = stack.get(i);
  -            Page.Navigation navigation = page.getNavigations().get(actionExpression);
  +            Page.ActionNavigation navigation = page.getNavigations().get(actionExpression);
               if (navigation==null)
               {
                  navigation = page.getDefaultNavigation();
  @@ -355,23 +121,23 @@
                     outcome = value==null ? null : value.toString();
                  }
                  
  -               Page.Case caze;
  +               Page.Outcome caze;
                  if (outcome==null) 
                  {
                     //JSF navhandler says ignore all rules when null outcome.
                     //so we have a special case for that
  -                  caze = navigation.getNullCase();
  +                  caze = navigation.getNullOutcome();
                  }
                  else
                  {
  -                  caze = navigation.getCases().get(outcome);
  -                  if (caze==null) caze = navigation.getAnyCase();
  +                  caze = navigation.getOutcomes().get(outcome);
  +                  if (caze==null) caze = navigation.getAnyOutcome();
                  }
                  
                  if (caze!=null)
                  {
  -                  //TODO: begin/end conversation, etc!!
  -                  caze.getResult().navigate(context);
  +                  caze.getConversationControl().beginOrEndConversation();
  +                  caze.getNavigationHandler().navigate(context);
                     return true;
                  }
                  
  @@ -408,6 +174,10 @@
         }
      }
   
  +   /**
  +    * Create a new Page object for a JSF view id,
  +    * by searching for a viewId.page.xml file.
  +    */
      private Page createPage(String viewId)
      {
         String resourceName = replaceExtension(viewId, ".page.xml");
  @@ -464,6 +234,9 @@
         return stack;
      }
   
  +   /**
  +    * Create the stack of pages that match a JSF view id
  +    */
      private List<Page> createPageStack(String viewId)
      {
         List<Page> stack = new ArrayList<Page>(1);
  @@ -483,9 +256,10 @@
      }
      
      /**
  -    * Call page actions, from most general view id to most specific
  +    * Call page actions, and validate the existence of a conversation
  +    * for pages which require a long-running conversation
       */
  -   public boolean callActions(FacesContext facesContext)
  +   public boolean callActionsAndValidateConversation(FacesContext facesContext)
      {
         boolean result = false;
         String viewId = facesContext.getViewRoot().getViewId();
  @@ -504,11 +278,14 @@
         return result;
      }
   
  +   /**
  +    * Call page actions, from most general view id to most specific
  +    */
      private boolean callAction(Page page, FacesContext facesContext)
      {
         boolean result = false;
         
  -      page.beginOrEndConversation();
  +      page.getConversationControl().beginOrEndConversation();
   
         String outcome = page.getOutcome();
         String fromAction = outcome;
  @@ -538,13 +315,13 @@
         return returnValue == null ? null : returnValue.toString();
      }
   
  +   /**
  +    * Call the JSF navigation handler
  +    */
      private static void handleOutcome(FacesContext facesContext, String outcome, String fromAction)
      {
  -      /*if (outcome!=null)
  -      {*/
            facesContext.getApplication().getNavigationHandler()
                  .handleNavigation(facesContext, fromAction, outcome);
  -      //}
      }
      
      public static Pages instance()
  @@ -635,7 +412,7 @@
         Map<String, Object> parameters = new HashMap<String, Object>();
         for ( Page page: getPageStack(viewId) )
         {
  -         for ( Page.PageParameter pageParameter: page.getPageParameters() )
  +         for ( Page.Param pageParameter: page.getPageParameters() )
            {
               ValueBinding valueBinding = pageParameter.getValueBinding();
               Object value;
  @@ -669,7 +446,7 @@
         Map<String, Object> parameters = new HashMap<String, Object>();
         for ( Page page: getPageStack(viewId) )
         {
  -         for ( Page.PageParameter pageParameter: page.getPageParameters() )
  +         for ( Page.Param pageParameter: page.getPageParameters() )
            {
               if ( !overridden.contains( pageParameter.getName() ) )
               {
  @@ -684,7 +461,11 @@
         return parameters;
      }
   
  -   private Object getPageParameterValue(FacesContext facesContext, Page.PageParameter pageParameter)
  +   /**
  +    * Get the current value of a page parameter, looking in the page context
  +    * if there is no value binding
  +    */
  +   private Object getPageParameterValue(FacesContext facesContext, Page.Param pageParameter)
      {
         ValueBinding valueBinding = pageParameter.getValueBinding();
         if (valueBinding==null)
  @@ -697,7 +478,10 @@
         }
      }
   
  -   private Object getParameterValue(FacesContext facesContext, Page.PageParameter pageParameter)
  +   /**
  +    * Get the current value of a page or redirection parameter
  +    */
  +   private static Object getParameterValue(FacesContext facesContext, Page.Param pageParameter)
      {
         Object value = pageParameter.getValueBinding().getValue();
         if (value==null)
  @@ -731,7 +515,7 @@
         Map<String, String[]> requestParameters = Parameters.getRequestParameters();
         for ( Page page: getPageStack(viewId) )
         {
  -         for ( Page.PageParameter pageParameter: page.getPageParameters() )
  +         for ( Page.Param pageParameter: page.getPageParameters() )
            {  
               
               String[] parameterValues = requestParameters.get(pageParameter.getName());
  @@ -781,7 +565,7 @@
         String viewId = facesContext.getViewRoot().getViewId();
         for ( Page page: getPageStack(viewId) )
         {
  -         for ( Page.PageParameter pageParameter: page.getPageParameters() )
  +         for ( Page.Param pageParameter: page.getPageParameters() )
            {         
               ValueBinding valueBinding = pageParameter.getValueBinding();
               if (valueBinding!=null)
  @@ -884,4 +668,272 @@
      
      }
   
  +   /**
  +    * Parse a pages.xml file
  +    */
  +   private void parse(InputStream stream)
  +   {
  +      Element root = getDocumentRoot(stream);
  +      if (noConversationViewId==null) //let the setting in components.xml override the pages.xml
  +      {
  +         noConversationViewId = root.attributeValue("no-conversation-view-id");
  +      }
  +      List<Element> elements = root.elements("page");
  +      for (Element page: elements)
  +      {
  +         parse( page, page.attributeValue("view-id") );
  +      } 
  +   }
  +
  +   /**
  +    * Parse a viewId.page.xml file
  +    */
  +   private void parse(InputStream stream, String viewId)
  +   {
  +      parse( getDocumentRoot(stream), viewId );
  +   }
  +
  +   /**
  +    * Get the root element of the document
  +    */
  +   private static Element getDocumentRoot(InputStream stream)
  +   {
  +      try
  +      {
  +         return XML.getRootElement(stream);
  +      }
  +      catch (DocumentException de)
  +      {
  +         throw new RuntimeException(de);
  +      }
  +   }
  +
  +   /**
  +    * Parse a page element and add a Page to the map
  +    */
  +   private void parse(Element element, String viewId)
  +   {
  +      if (viewId==null)
  +      {
  +         throw new IllegalStateException("Must specify view-id for <page/> declaration");
  +      }
  +      
  +      if ( viewId.endsWith("*") )
  +      {
  +         wildcardViewIds.add(viewId);
  +      }
  +      Page page = new Page(viewId);
  +      pagesByViewId.put(viewId, page);
  +
  +      parsePage(page, element, viewId);
  +      parseConversationControl( element, page.getConversationControl() );
  +
  +      List<Element> children = element.elements("param");
  +      for (Element param: children)
  +      {
  +         page.getPageParameters().add( parsePageParameter(param) );
  +      }
  +      
  +      List<Element> moreChildren = element.elements("action-navigation");
  +      for (Element fromAction: moreChildren)
  +      {
  +         parseActionNavigation(page, fromAction);
  +      }
  +   }
  +
  +   /**
  +    * Parse the attributes of page
  +    */
  +   private static Page parsePage(Page page, Element element, String viewId)
  +   {
  +      
  +      page.setSwitchEnabled( !"disabled".equals( element.attributeValue("switch") ) );
  +      
  +      Element optionalElement = element.element("description");
  +      String description = optionalElement==null ? 
  +               element.getTextTrim() : optionalElement.getTextTrim();
  +      if (description!=null && description.length()>0)
  +      {
  +         page.setDescription(description);
  +      }
  +      
  +      String timeoutString = element.attributeValue("timeout");
  +      if (timeoutString!=null)
  +      {
  +         page.setTimeout(Integer.parseInt(timeoutString));
  +      }
  +      
  +      page.setNoConversationViewId( element.attributeValue("no-conversation-view-id") );
  +      page.setConversationRequired( "true".equals( element.attributeValue("conversation-required") ) );
  +      
  +      String action = element.attributeValue("action");
  +      if (action!=null)
  +      {
  +         if ( action.startsWith("#{") )
  +         {
  +            MethodBinding methodBinding = Expressions.instance().createMethodBinding(action);
  +            page.setAction(methodBinding);
  +         }
  +         else
  +         {
  +            page.setOutcome(action);
  +         }
  +      }
  +            
  +      String bundle = element.attributeValue("bundle");
  +      if (bundle!=null)
  +      {
  +         page.setResourceBundleName(bundle);
  +      }
  +      return page;
  +   }
  +
  +   /**
  +    * Parse end-conversation and begin-conversation
  +    */
  +   private static void parseConversationControl(Element element, ConversationControl control)
  +   {
  +      Element endConversation = element.element("end-conversation");
  +      if ( endConversation!=null )
  +      {
  +         control.setEndConversation(true);
  +      }
  +      
  +      Element beginConversation = element.element("begin-conversation");
  +      if ( beginConversation!=null )
  +      {
  +         control.setBeginConversation(true);
  +         control.setJoin( "true".equals( beginConversation.attributeValue("join") ) );
  +         control.setNested( "true".equals( beginConversation.attributeValue("nested") ) );
  +         control.setPageflow( beginConversation.attributeValue("pageflow") );
  +         String flushMode = beginConversation.attributeValue("flush-mode");
  +         if (flushMode!=null)
  +         {
  +            control.setFlushMode( FlushModeType.valueOf( flushMode.toUpperCase() ) );
  +         }
  +      }
  +      
  +      if ( control.isBeginConversation() && control.isEndConversation() )
  +      {
  +         throw new IllegalStateException("cannot use both <begin-conversation/> and <end-conversation/>");
  +      }
  +   }
  +
  +   /**
  +    * Parse action-navigation
  +    */
  +   private static void parseActionNavigation(Page entry, Element element)
  +   {
  +      Page.ActionNavigation navigation = new Page.ActionNavigation(); 
  +      String outcomeExpression = element.attributeValue("outcome");
  +      if (outcomeExpression!=null)
  +      {
  +         navigation.setOutcomeValueBinding( Expressions.instance().createValueBinding(outcomeExpression) );
  +      }
  +      List<Element> cases = element.elements("outcome");
  +      for (Element childElement: cases)
  +      {
  +         Page.Outcome caze = parseOutcome(childElement);
  +         String value = childElement.attributeValue("value");
  +         if (value==null)
  +         {
  +            throw new IllegalStateException("Must specify value for <outcome/> declaration");
  +         }
  +         navigation.getOutcomes().put(value, caze);
  +      }
  +      Element childElement = element.element("any-outcome");
  +      if (childElement!=null)
  +      {
  +         navigation.setAnyOutcome( parseOutcome(childElement) );
  +      }
  +      childElement = element.element("null-outcome");
  +      if (childElement!=null)
  +      {
  +         navigation.setNullOutcome( parseOutcome(childElement) );
  +      }
  +      
  +      String expression = element.attributeValue("action");
  +      if (expression==null)
  +      {
  +         entry.setDefaultNavigation(navigation);
  +      }
  +      else
  +      {
  +         entry.getNavigations().put(expression, navigation);
  +      }
  +   }
  +
  +   /**
  +    * Parse param
  +    */
  +   private static Page.Param parsePageParameter(Element element)
  +   {
  +      String valueExpression = element.attributeValue("value");
  +      String name = element.attributeValue("name");
  +      if (name==null)
  +      {
  +         if (valueExpression==null)
  +         {
  +            throw new IllegalArgumentException("must specify name or value for page <param/> declaration");
  +         }
  +         name = valueExpression.substring(2, valueExpression.length()-1);
  +      }
  +      Page.Param param = new Page.Param(name);
  +      if (valueExpression!=null)
  +      {
  +         param.setValueBinding(Expressions.instance().createValueBinding(valueExpression));
  +      }
  +      param.setConverterId(element.attributeValue("converterId"));
  +      String converterExpression = element.attributeValue("converter");
  +      if (converterExpression!=null)
  +      {
  +         param.setConverterValueBinding(Expressions.instance().createValueBinding(converterExpression));
  +      }
  +      return param;
  +   }
  +
  +   /**
  +    * parse outcome, any-outcome, null-outcome
  +    */
  +   private static Page.Outcome parseOutcome(Element element)
  +   {
  +      Page.Outcome caze = new Page.Outcome();
  +      parseConversationControl( element, caze.getConversationControl() );
  +      
  +      Element render = element.element("render");
  +      if (render!=null)
  +      {
  +         final String viewId = render.attributeValue("view-id");
  +         caze.setNavigationHandler(new Page.NavigationHandler() {
  +            public void navigate(FacesContext context)
  +            {
  +               render(viewId);
  +            }
  +         });
  +      }
  +      Element redirect = element.element("redirect");
  +      if (redirect!=null)
  +      {
  +         List<Element> children = redirect.elements("param");
  +         final List<Param> pageParameters = new ArrayList<Param>();
  +         for (Element child: children)
  +         {
  +            pageParameters.add( parsePageParameter(child) );
  +         }
  +         final String viewId = redirect.attributeValue("view-id");
  +         caze.setNavigationHandler(new Page.NavigationHandler() {
  +            public void navigate(FacesContext context)
  +            {
  +               Map<String, Object> parameters = new HashMap<String, Object>();
  +               for ( Param pageParameter: pageParameters )
  +               {
  +                  parameters.put( pageParameter.getName(), getParameterValue(context, pageParameter) );
  +               }
  +               redirect(viewId, parameters);
  +            }
  +         });
  +      }
  +      return caze;
  +   }
  +
   }
  
  
  



More information about the jboss-cvs-commits mailing list