[seam-commits] Seam SVN: r12896 - in modules/faces/trunk: api/src/main/java/org/jboss/seam/faces and 3 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Fri May 28 19:06:52 EDT 2010


Author: dan.j.allen
Date: 2010-05-28 19:06:51 -0400 (Fri, 28 May 2010)
New Revision: 12896

Added:
   modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/
   modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/ClientId.java
   modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/MethodBindingMethodExpressionAdapter.java
   modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/UIInputContainer.java
   modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/UIValidateForm.java
   modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/UIViewAction.java
   modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/ValueExpressionAnalyzer.java
   modules/faces/trunk/api/src/main/resources/META-INF/faces-config.xml
Removed:
   modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/component/MethodBindingMethodExpressionAdapter.java
   modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/component/UIValidateForm.java
   modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/component/UIViewAction.java
Modified:
   modules/faces/trunk/pom.xml
Log:
SEAMFACES-22
also, move components to api


Added: modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/ClientId.java
===================================================================
--- modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/ClientId.java	                        (rev 0)
+++ modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/ClientId.java	2010-05-28 23:06:51 UTC (rev 12896)
@@ -0,0 +1,21 @@
+package org.jboss.seam.faces.component;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import javax.enterprise.util.Nonbinding;
+import javax.inject.Qualifier;
+
+/**
+ * @author Dan Allen
+ */
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
+ at Qualifier
+public @interface ClientId {
+   /**
+    * The search expression that matches one or more UIComponent instances by its clientId.
+    */
+   @Nonbinding String value() default "";
+}

Copied: modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/MethodBindingMethodExpressionAdapter.java (from rev 12895, modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/component/MethodBindingMethodExpressionAdapter.java)
===================================================================
--- modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/MethodBindingMethodExpressionAdapter.java	                        (rev 0)
+++ modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/MethodBindingMethodExpressionAdapter.java	2010-05-28 23:06:51 UTC (rev 12896)
@@ -0,0 +1,339 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.faces.component;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.ExpressionFactory;
+import javax.el.MethodExpression;
+import javax.el.MethodInfo;
+import javax.el.ValueExpression;
+import javax.faces.component.StateHolder;
+import javax.faces.context.FacesContext;
+import javax.faces.el.EvaluationException;
+import javax.faces.el.MethodBinding;
+import javax.faces.el.MethodNotFoundException;
+
+/**
+ * <p>
+ * Wrap a MethodExpression instance and expose it as a MethodBinding
+ * </p>
+ * 
+ */
+class MethodBindingMethodExpressionAdapter extends MethodBinding implements StateHolder, Serializable
+{
+
+   private static final long serialVersionUID = 7334926223014401689L;
+   private MethodExpression methodExpression = null;
+   private boolean tranzient;
+
+   public MethodBindingMethodExpressionAdapter()
+   {
+   } // for StateHolder
+
+   MethodBindingMethodExpressionAdapter(final MethodExpression methodExpression)
+   {
+      this.methodExpression = methodExpression;
+   }
+
+   @Override
+   @SuppressWarnings("deprecation")
+   public Object invoke(final FacesContext context, final Object params[]) throws EvaluationException, MethodNotFoundException
+   {
+      assert (null != methodExpression);
+      if (context == null)
+      {
+         throw new NullPointerException("FacesConext -> null");
+      }
+
+      Object result = null;
+      try
+      {
+         result = methodExpression.invoke(context.getELContext(), params);
+      }
+      catch (javax.el.MethodNotFoundException e)
+      {
+         throw new javax.faces.el.MethodNotFoundException(e);
+      }
+      catch (javax.el.PropertyNotFoundException e)
+      {
+         throw new EvaluationException(e);
+      }
+      catch (ELException e)
+      {
+         Throwable cause = e.getCause();
+         if (cause == null)
+         {
+            cause = e;
+         }
+         throw new EvaluationException(cause);
+      }
+      catch (NullPointerException e)
+      {
+         throw new MethodNotFoundException(e);
+      }
+      return result;
+   }
+
+   @Override
+   @SuppressWarnings("deprecation")
+   public Class<?> getType(final FacesContext context) throws MethodNotFoundException
+   {
+      assert (null != methodExpression);
+      if (context == null)
+      {
+         throw new NullPointerException("FacesConext -> null");
+      }
+      Class<?> result = null;
+      if (context == null)
+      {
+         throw new NullPointerException();
+      }
+
+      try
+      {
+         MethodInfo mi = methodExpression.getMethodInfo(context.getELContext());
+         result = mi.getReturnType();
+      }
+      catch (javax.el.PropertyNotFoundException e)
+      {
+         throw new MethodNotFoundException(e);
+      }
+      catch (javax.el.MethodNotFoundException e)
+      {
+         throw new MethodNotFoundException(e);
+      }
+      catch (ELException e)
+      {
+         throw new MethodNotFoundException(e);
+      }
+      return result;
+   }
+
+   @Override
+   public String getExpressionString()
+   {
+      assert (null != methodExpression);
+      return methodExpression.getExpressionString();
+   }
+
+   @Override
+   @SuppressWarnings("deprecation")
+   public boolean equals(final Object other)
+   {
+      if (this == other)
+      {
+         return true;
+      }
+      if (other instanceof MethodBindingMethodExpressionAdapter)
+      {
+         return methodExpression.equals(((MethodBindingMethodExpressionAdapter) other).getWrapped());
+      }
+      else if (other instanceof MethodBinding)
+      {
+         MethodBinding binding = (MethodBinding) other;
+
+         // We'll need to do a little leg work to determine
+         // if the MethodBinding is equivalent to the
+         // wrapped MethodExpression
+         String expr = binding.getExpressionString();
+         int idx = expr.indexOf('.');
+         String target = expr.substring(0, idx).substring(2);
+         String t = expr.substring(idx + 1);
+         String method = t.substring(0, (t.length() - 1));
+
+         FacesContext context = FacesContext.getCurrentInstance();
+         ELContext elContext = context.getELContext();
+         MethodInfo controlInfo = methodExpression.getMethodInfo(elContext);
+
+         // ensure the method names are the same
+         if (!controlInfo.getName().equals(method))
+         {
+            return false;
+         }
+
+         // Using the target, create an expression and evaluate
+         // it.
+         ExpressionFactory factory = context.getApplication().getExpressionFactory();
+         ValueExpression ve = factory.createValueExpression(elContext, "#{" + target + '}', Object.class);
+         if (ve == null)
+         {
+            return false;
+         }
+
+         Object result = ve.getValue(elContext);
+
+         if (result == null)
+         {
+            return false;
+         }
+
+         // Get all of the methods with the matching name and try
+         // to find a match based on controlInfo's return and parameter
+         // types
+         Class<?> type = binding.getType(context);
+         Method[] methods = result.getClass().getMethods();
+         for (Method meth : methods)
+         {
+            if (meth.getName().equals(method) && type.equals(controlInfo.getReturnType()) && Arrays.equals(meth.getParameterTypes(), controlInfo.getParamTypes()))
+            {
+               return true;
+            }
+         }
+      }
+
+      return false;
+
+   }
+
+   @Override
+   public int hashCode()
+   {
+      assert (null != methodExpression);
+
+      return methodExpression.hashCode();
+   }
+
+   public boolean isTransient()
+   {
+      return this.tranzient;
+   }
+
+   public void setTransient(final boolean tranzient)
+   {
+      this.tranzient = tranzient;
+   }
+
+   public Object saveState(final FacesContext context)
+   {
+      if (context == null)
+      {
+         throw new NullPointerException();
+      }
+      Object result = null;
+      if (!tranzient)
+      {
+         if (methodExpression instanceof StateHolder)
+         {
+            Object[] stateStruct = new Object[2];
+
+            // save the actual state of our wrapped methodExpression
+            stateStruct[0] = ((StateHolder) methodExpression).saveState(context);
+            // save the class name of the methodExpression impl
+            stateStruct[1] = methodExpression.getClass().getName();
+
+            result = stateStruct;
+         }
+         else
+         {
+            result = methodExpression;
+         }
+      }
+
+      return result;
+
+   }
+
+   public void restoreState(final FacesContext context, final Object state)
+   {
+      if (context == null)
+      {
+         throw new NullPointerException();
+      }
+      // if we have state
+      if (null == state)
+      {
+         return;
+      }
+
+      if (!(state instanceof MethodExpression))
+      {
+         Object[] stateStruct = (Object[]) state;
+         Object savedState = stateStruct[0];
+         String className = stateStruct[1].toString();
+         MethodExpression result = null;
+
+         Class<?> toRestoreClass = null;
+         if (null != className)
+         {
+            try
+            {
+               toRestoreClass = loadClass(className, this);
+            }
+            catch (ClassNotFoundException e)
+            {
+               throw new IllegalStateException(e.getMessage());
+            }
+
+            if (null != toRestoreClass)
+            {
+               try
+               {
+                  result = (MethodExpression) toRestoreClass.newInstance();
+               }
+               catch (InstantiationException e)
+               {
+                  throw new IllegalStateException(e.getMessage());
+               }
+               catch (IllegalAccessException a)
+               {
+                  throw new IllegalStateException(a.getMessage());
+               }
+            }
+
+            if ((null != result) && (null != savedState))
+            {
+               // don't need to check transient, since that was
+               // done on the saving side.
+               ((StateHolder) result).restoreState(context, savedState);
+            }
+            methodExpression = result;
+         }
+      }
+      else
+      {
+         methodExpression = (MethodExpression) state;
+      }
+   }
+
+   public MethodExpression getWrapped()
+   {
+      return methodExpression;
+   }
+
+   //
+   // Helper methods for StateHolder
+   //
+   private static Class<?> loadClass(final String name, final Object fallbackClass) throws ClassNotFoundException
+   {
+      ClassLoader loader = Thread.currentThread().getContextClassLoader();
+      if (loader == null)
+      {
+         loader = fallbackClass.getClass().getClassLoader();
+      }
+      return Class.forName(name, true, loader);
+   }
+}
\ No newline at end of file

Added: modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/UIInputContainer.java
===================================================================
--- modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/UIInputContainer.java	                        (rev 0)
+++ modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/UIInputContainer.java	2010-05-28 23:06:51 UTC (rev 12896)
@@ -0,0 +1,520 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.faces.component;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.el.ValueReference;
+import javax.faces.FacesException;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.EditableValueHolder;
+import javax.faces.component.FacesComponent;
+import javax.faces.component.NamingContainer;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIComponentBase;
+import javax.faces.component.UIMessage;
+import javax.faces.component.UINamingContainer;
+import javax.faces.component.UIViewRoot;
+import javax.faces.component.html.HtmlOutputLabel;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.BeanValidator;
+import javax.validation.Validation;
+import javax.validation.ValidationException;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+
+/**
+ * <strong>UIInputContainer</strong> is a supplamental component for a JSF 2.0 composite component
+ * encapsulating one or more input components (<strong>EditableValueHolder</strong>),
+ * their corresponding message components (<strong>UIMessage</strong>) and
+ * a label (<strong>HtmlOutputLabel</strong>). This component takes care of wiring the
+ * label to the first input and the messages to each input in sequence. It also
+ * assigns two implicit attribute values, "required" and "invalid" to indicate that
+ * a required input field is present and whether there are any validation errors, respectively.
+ * To determine if a input field is required, both the required attribute is consulted and
+ * whether the property has Bean Validation constraints.
+ * Finally, if the "label" attribute is not provided on the composite component, the
+ * label value will be derived from the id of the composite component, for convenience.
+ *
+ * <p>Composite component definition example (minus layout):</p>
+ * <pre>
+ * &lt;cc:interface componentType="org.jboss.seam.faces.InputContainer"/>
+ * &lt;cc:implementation>
+ *   &lt;h:outputLabel id="label" value="#{cc.attrs.label}:" styleClass="#{cc.attrs.invalid ? 'invalid' : ''}">
+ *     &lt;h:ouputText styleClass="required" rendered="#{cc.attrs.required}" value="*"/>
+ *   &lt;/h:outputLabel>
+ *   &lt;cc:insertChildren/>
+ *   &lt;h:message id="message" errorClass="invalid message" rendered="#{cc.attrs.invalid}"/>
+ * &lt;/cc:implementation>
+ * </pre>
+ *
+ * <p>Composite component usage example:</p>
+ * <pre>
+ * &lt;example:inputContainer id="name">
+ *   &lt;h:inputText id="input" value="#{person.name}"/>
+ * &lt;/example:inputContainer>
+ * </pre>
+ *
+ * <p>Possible enhancements:</p>
+ * <ul>
+ * <li>append styleClass "invalid" to label, inputs and messages when invalid</li>
+ * </ul>
+ *
+ * @author Dan Allen
+ */
+ at FacesComponent(UIInputContainer.COMPONENT_TYPE)
+public class UIInputContainer extends UIComponentBase implements NamingContainer
+{
+   /**
+    * The standard component type for this component.
+    */
+   public static final String COMPONENT_TYPE = "org.jboss.seam.faces.InputContainer";
+
+   protected static final String HTML_ID_ATTR_NAME = "id";
+   protected static final String HTML_CLASS_ATTR_NAME = "class";
+   protected static final String HTML_STYLE_ATTR_NAME = "style";
+
+   private boolean beanValidationPresent = false;
+
+   public UIInputContainer()
+   {
+      beanValidationPresent = isClassPresent("javax.validation.Validator");
+   }
+   
+   public String getFamily()
+   {
+      return UINamingContainer.COMPONENT_FAMILY;
+   }
+
+   /**
+    * The name of the auto-generated composite component attribute
+    * that holds a boolean indicating whether the the template contains
+    * an invalid input.
+    */
+   public String getInvalidAttributeName()
+   {
+      return "invalid";
+   }
+
+   /**
+    * The name of the auto-generated composite component attribute
+    * that holds a boolean indicating whether the template contains
+    * a required input.
+    */
+   public String getRequiredAttributeName()
+   {
+      return "required";
+   }
+
+   /**
+    * The name of the composite component attribute that
+    * holds the string label for this set of inputs. If the
+    * label attribute is not provided, one will be generated
+    * from the id of the composite component or, if the id is
+    * defaulted, the name of the property bound to the first input.
+    */
+   public String getLabelAttributeName()
+   {
+      return "label";
+   }
+
+   /**
+    * The name of the auto-generated composite component attribute
+    * that holds the elements in this input container. The
+    * elements include the label, a list of inputs and a cooresponding
+    * list of messages.
+    */
+   public String getElementsAttributeName()
+   {
+      return "elements";
+   }
+
+   /**
+    * The name of the composite component attribute that holds a boolean
+    * indicating whether the component template should be enclosed in
+    * an HTML element, so that it be referenced from JavaScript.
+    */
+   public String getEncloseAttributeName()
+   {
+      return "enclose";
+   }
+
+   public String getContainerElementName()
+   {
+      return "div";
+   }
+
+   public String getDefaultLabelId()
+   {
+      return "label";
+   }
+
+   public String getDefaultInputId()
+   {
+      return "input";
+   }
+
+   public String getDefaultMessageId()
+   {
+      return "message";
+   }
+
+   @Override
+   public void encodeBegin(FacesContext context) throws IOException
+   {
+      if (!isRendered())
+      {
+         return;
+      }
+
+      super.encodeBegin(context);
+
+      InputContainerElements elements = scan(getFacet(UIComponent.COMPOSITE_FACET_NAME), null, context);
+      //assignIds(elements, context);
+      wire(elements, context);
+
+      getAttributes().put(getElementsAttributeName(), elements);
+
+      if (elements.hasValidationError())
+      {
+         getAttributes().put(getInvalidAttributeName(), true);
+      }
+
+      // set the required attribute, but only if the user didn't already assign it
+      if (!getAttributes().containsKey(getRequiredAttributeName()) && elements.hasRequiredInput())
+      {
+         getAttributes().put(getRequiredAttributeName(), true);
+      }
+
+      if (!getAttributes().containsKey(getLabelAttributeName()))
+      {
+         getAttributes().put(getLabelAttributeName(), generateLabel(elements, context));
+      }
+
+      if (Boolean.TRUE.equals(getAttributes().get(getEncloseAttributeName())))
+      {
+         startContainerElement(context);
+      }
+   }
+
+   @Override
+   public void encodeEnd(FacesContext context) throws IOException
+   {
+      if (!isRendered())
+      {
+         return;
+      }
+
+      super.encodeEnd(context);
+
+      if (Boolean.TRUE.equals(getAttributes().get(getEncloseAttributeName())))
+      {
+         endContainerElement(context);
+      }
+   }
+
+   protected void startContainerElement(FacesContext context) throws IOException
+   {
+      context.getResponseWriter().startElement(getContainerElementName(), this);
+      String style = (getAttributes().get("style") != null ? getAttributes().get("style").toString().trim() : null);
+      if (style.length() > 0)
+      {
+         context.getResponseWriter().writeAttribute(HTML_STYLE_ATTR_NAME, style, HTML_STYLE_ATTR_NAME);
+      }
+      String styleClass = (getAttributes().get("styleClass") != null ? getAttributes().get("styleClass").toString().trim() : null);
+      if (styleClass.length() > 0)
+      {
+         context.getResponseWriter().writeAttribute(HTML_CLASS_ATTR_NAME, styleClass, HTML_CLASS_ATTR_NAME);
+      }
+      context.getResponseWriter().writeAttribute(HTML_ID_ATTR_NAME, getClientId(context), HTML_ID_ATTR_NAME);
+   }
+
+   protected void endContainerElement(FacesContext context) throws IOException
+   {
+      context.getResponseWriter().endElement(getContainerElementName());
+   }
+
+   protected String generateLabel(InputContainerElements elements, FacesContext context)
+   {
+      String name = getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX) ? elements.getPropertyName(context) : getId();
+      return name.substring(0, 1).toUpperCase() + name.substring(1);
+   }
+
+   /**
+    * Walk the component tree branch built by the composite component and locate
+    * the input container elements.
+    *
+    * @return a composite object of the input container elements
+    */
+   protected InputContainerElements scan(UIComponent component, InputContainerElements elements, FacesContext context)
+   {
+      if (elements == null) {
+         elements = new InputContainerElements();
+      }
+
+      // NOTE we need to walk the tree ignoring rendered attribute because it's condition
+      // could be based on what we discover
+      if (elements.getLabel() == null && component instanceof HtmlOutputLabel)
+      {
+         elements.setLabel((HtmlOutputLabel) component);
+      }
+      else if (component instanceof EditableValueHolder)
+      {
+         elements.registerInput((EditableValueHolder) component, getDefaultValidator(context), context);
+      }
+      else if (component instanceof UIMessage)
+      {
+         elements.registerMessage((UIMessage) component);
+      }
+      // may need to walk smarter to ensure "element of least suprise"
+      for (UIComponent child : component.getChildren())
+      {
+         scan(child, elements, context);
+      }
+
+      return elements;
+   }
+
+   // assigning ids seems to break form submissions, but I don't know why
+   public void assignIds(InputContainerElements elements, FacesContext context)
+   {
+      boolean refreshIds = false;
+      if (getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
+      {
+         setId(elements.getPropertyName(context));
+         refreshIds = true;
+      }
+      UIComponent label = elements.getLabel();
+      if (label != null)
+      {
+         if (label.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
+         {
+            label.setId(getDefaultLabelId());
+         }
+         else if (refreshIds) {
+            label.setId(label.getId());
+         }
+      }
+      for (int i = 0, len = elements.getInputs().size(); i < len; i++)
+      {
+         UIComponent input = (UIComponent) elements.getInputs().get(i);
+         if (input.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
+         {
+            input.setId(getDefaultInputId() + (i == 0 ? "" : (i + 1)));
+         }
+         else if (refreshIds) {
+            input.setId(input.getId());
+         }
+      }
+      for (int i = 0, len = elements.getMessages().size(); i < len; i++)
+      {
+         UIComponent msg = elements.getMessages().get(i);
+         if (msg.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
+         {
+            msg.setId(getDefaultMessageId() + (i == 0 ? "" : (i + 1)));
+         }
+         else if (refreshIds) {
+            msg.setId(msg.getId());
+         }
+      }
+   }
+
+   /**
+    * Wire the label and messages to the input(s)
+    */
+   protected void wire(InputContainerElements elements, FacesContext context)
+   {
+      elements.wire(context);
+   }
+
+   /**
+    * Get the default Bean Validation Validator to read the contraints for a property.
+    */
+   private Validator getDefaultValidator(FacesContext context) throws FacesException
+   {
+      if (!beanValidationPresent) {
+         return null;
+      }
+
+      ValidatorFactory validatorFactory;
+      Object cachedObject = context.getExternalContext().getApplicationMap().get(BeanValidator.VALIDATOR_FACTORY_KEY);
+      if (cachedObject instanceof ValidatorFactory)
+      {
+         validatorFactory = (ValidatorFactory) cachedObject;
+      }
+      else
+      {
+         try
+         {
+            validatorFactory = Validation.buildDefaultValidatorFactory();
+         }
+         catch (ValidationException e)
+         {
+            throw new FacesException("Could not build a default Bean Validator factory", e);
+         }
+         context.getExternalContext().getApplicationMap().put(BeanValidator.VALIDATOR_FACTORY_KEY, validatorFactory);
+      }
+      return validatorFactory.getValidator();
+   }
+
+   private boolean isClassPresent(String fqcn)
+   {
+      try
+      {
+         if (Thread.currentThread().getContextClassLoader() != null)
+         {
+            return Thread.currentThread().getContextClassLoader().loadClass(fqcn) != null;
+         }
+         else
+         {
+            return Class.forName(fqcn) != null;
+         }
+      }
+      catch (ClassNotFoundException e)
+      {
+         return false;
+      }
+      catch (NoClassDefFoundError e)
+      {
+         return false;
+      }
+   }
+
+   public static class InputContainerElements
+   {
+      private String propertyName;
+      private HtmlOutputLabel label;
+      private List<EditableValueHolder> inputs = new ArrayList<EditableValueHolder>();
+      private List<UIMessage> messages = new ArrayList<UIMessage>();
+      private boolean validationError = false;
+      private boolean requiredInput = false;
+
+      public HtmlOutputLabel getLabel()
+      {
+         return label;
+      }
+
+      public void setLabel(HtmlOutputLabel label)
+      {
+         this.label = label;
+      }
+
+      public List<EditableValueHolder> getInputs()
+      {
+         return inputs;
+      }
+
+      public void registerInput(EditableValueHolder input, Validator validator, FacesContext context)
+      {
+         inputs.add(input);
+         if (input.isRequired() || isRequiredByConstraint(input, validator, context))
+         {
+            requiredInput = true;
+         }
+         if (!input.isValid())
+         {
+            validationError = true;
+         }
+         // optimization to avoid loop if already flagged
+         else if (!validationError)
+         {
+            Iterator<FacesMessage> it = context.getMessages(((UIComponent) input).getClientId(context));
+            while (it.hasNext())
+            {
+               if (it.next().getSeverity().compareTo(FacesMessage.SEVERITY_WARN) >= 0)
+               {
+                  validationError = true;
+                  break;
+               }
+            }
+         }
+      }
+
+      public List<UIMessage> getMessages()
+      {
+         return messages;
+      }
+
+      public void registerMessage(UIMessage message)
+      {
+         messages.add(message);
+      }
+
+      public boolean hasValidationError()
+      {
+         return validationError;
+      }
+
+      public boolean hasRequiredInput()
+      {
+         return requiredInput;
+      }
+
+      private boolean isRequiredByConstraint(EditableValueHolder input, Validator validator, FacesContext context)
+      {
+         if (validator == null) {
+            return false;
+         }
+
+         // NOTE believe it or not, getValueReference on ValueExpression is broken, so we have to do it ourselves
+         ValueReference vref = new ValueExpressionAnalyzer(((UIComponent) input).getValueExpression("value"))
+               .getValueReference(context.getELContext());
+         return validator.getConstraintsForClass(vref.getBase().getClass())
+               .getConstraintsForProperty((String) vref.getProperty()).hasConstraints();
+      }
+
+      public String getPropertyName(FacesContext context) {
+         if (propertyName != null) {
+            return propertyName;
+         }
+
+         if (inputs.size() == 0) {
+            return null;
+         }
+
+         propertyName = (String) new ValueExpressionAnalyzer(((UIComponent) inputs.get(0)).getValueExpression("value"))
+               .getValueReference(context.getELContext()).getProperty();
+         return propertyName;
+      }
+
+      public void wire(FacesContext context)
+      {
+         int numInputs = inputs.size();
+         if (numInputs > 0)
+         {
+            if (label != null)
+            {
+               label.setFor(((UIComponent) inputs.get(0)).getClientId(context));
+            }
+            for (int i = 0, len = messages.size(); i < len; i++)
+            {
+               if (i < numInputs)
+               {
+                  messages.get(i).setFor(((UIComponent) inputs.get(i)).getClientId(context));
+               }
+            }
+         }
+      }
+   }
+}

Copied: modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/UIValidateForm.java (from rev 12895, modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/component/UIValidateForm.java)
===================================================================
--- modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/UIValidateForm.java	                        (rev 0)
+++ modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/UIValidateForm.java	2010-05-28 23:06:51 UTC (rev 12896)
@@ -0,0 +1,183 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.seam.faces.component;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.util.AnnotationLiteral;
+import javax.faces.component.FacesComponent;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIForm;
+import javax.faces.component.UIInput;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PostValidateEvent;
+import javax.faces.event.PreValidateEvent;
+import javax.faces.validator.Validator;
+import javax.faces.validator.ValidatorException;
+
+import org.jboss.seam.faces.event.qualifier.After;
+import org.jboss.seam.faces.event.qualifier.Before;
+import org.jboss.weld.extensions.beanManager.BeanManagerAccessor;
+
+/**
+ * @author <a href="mailto:lincolnbaxter at gmail.com>Lincoln Baxter, III</a>
+ * 
+ */
+ at FacesComponent(UIValidateForm.COMPONENT_TYPE)
+public class UIValidateForm extends UIInput
+{
+   private static final AnnotationLiteral<Before> BEFORE = new AnnotationLiteral<Before>()
+   {
+      private static final long serialVersionUID = 7631699535063526392L;
+   };
+   private static final AnnotationLiteral<After> AFTER = new AnnotationLiteral<After>()
+   {
+      private static final long serialVersionUID = -929128236303355107L;
+   };
+
+   public static final String COMPONENT_TYPE = "org.jboss.seam.faces.ValidateForm";
+   public static final String COMPONENT_FAMILY = "org.jboss.seam.faces.ValidateForm";
+
+   private String validatorId = "";
+   private String fields = "";
+   private Map<String, UIInput> components = new HashMap<String, UIInput>();
+
+   @Override
+   public String getFamily()
+   {
+      return COMPONENT_FAMILY;
+   }
+
+   @Override
+   public void validate(final FacesContext context)
+   {
+      context.getApplication().publishEvent(context, PreValidateEvent.class, UIValidateForm.class, this);
+      BeanManager manager = BeanManagerAccessor.getManager();
+      manager.fireEvent(this, BEFORE);
+
+      Validator validator = context.getApplication().createValidator(validatorId);
+      if (validator == null)
+      {
+         throw new IllegalArgumentException("Could not create Validator with id: [" + validatorId + "]");
+      }
+
+      try
+      {
+         UIComponent parent = this.getParent();
+         validator.validate(context, parent, components);
+      }
+      catch (ValidatorException e)
+      {
+         setValid(false);
+         for (UIInput comp : components.values())
+         {
+            comp.setValid(false);
+            // TODO Put this back when attributes can control it
+            // context.addMessage(comp.getClientId(), e.getFacesMessage());
+         }
+         context.addMessage(null, e.getFacesMessage());
+      }
+
+      manager.fireEvent(this, AFTER);
+      context.getApplication().publishEvent(context, PostValidateEvent.class, UIValidateForm.class, this);
+   }
+
+   /**
+    * Attempt to locate the form in which this component resides. If the
+    * component is not within a UIForm tag, throw an exception.
+    */
+   public UIForm locateForm()
+   {
+      UIComponent parent = this.getParent();
+      while (!(parent instanceof UIForm))
+      {
+         if ((parent == null) || (parent instanceof UIViewRoot))
+         {
+            throw new IllegalStateException("The UIValidateForm (<s:validateForm />) component must be placed within a UIForm (<h:form>)");
+         }
+         parent = parent.getParent();
+      }
+      return (UIForm) parent;
+   }
+
+   /*
+    * Prevent any rendered output.
+    */
+
+   @Override
+   public void encodeAll(final FacesContext context) throws IOException
+   {
+      locateForm();
+   }
+
+   @Override
+   public void encodeBegin(final FacesContext context) throws IOException
+   {
+   }
+
+   @Override
+   public void encodeEnd(final FacesContext context) throws IOException
+   {
+   }
+
+   @Override
+   public void encodeChildren(final FacesContext context) throws IOException
+   {
+   }
+
+   /*
+    * Getters & Setters
+    */
+
+   public String getFields()
+   {
+      return fields;
+   }
+
+   public void setFields(final String fields)
+   {
+      this.fields = fields;
+   }
+
+   public String getValidatorId()
+   {
+      return validatorId;
+   }
+
+   public void setValidatorId(final String validatorId)
+   {
+      this.validatorId = validatorId;
+   }
+
+   /**
+    * @param components
+    */
+   public void setComponents(final Map<String, UIInput> components)
+   {
+      this.components = components;
+   }
+}

Copied: modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/UIViewAction.java (from rev 12895, modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/component/UIViewAction.java)
===================================================================
--- modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/UIViewAction.java	                        (rev 0)
+++ modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/UIViewAction.java	2010-05-28 23:06:51 UTC (rev 12896)
@@ -0,0 +1,677 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.faces.component;
+
+import javax.el.MethodExpression;
+import javax.faces.FacesException;
+import javax.faces.FactoryFinder;
+import javax.faces.application.NavigationHandler;
+import javax.faces.component.ActionSource2;
+import javax.faces.component.FacesComponent;
+import javax.faces.component.UICommand;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIComponentBase;
+import javax.faces.component.UIViewParameter;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+import javax.faces.context.FacesContextWrapper;
+import javax.faces.el.MethodBinding;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.ActionEvent;
+import javax.faces.event.ActionListener;
+import javax.faces.event.FacesEvent;
+import javax.faces.event.PhaseId;
+import javax.faces.event.PreRenderViewEvent;
+import javax.faces.lifecycle.Lifecycle;
+import javax.faces.lifecycle.LifecycleFactory;
+import javax.faces.view.ViewMetadata;
+import javax.faces.webapp.FacesServlet;
+
+/**
+ * <p>
+ * <strong>UIViewAction</strong> is an {@link ActionSource2} {@link UIComponent}
+ * that specifies an application-specific command (or action)--defined as an EL
+ * method expression--to be invoked during one of the JSF lifecycle phases that
+ * proceeds view rendering. This component must be declared as a child of the
+ * {@link ViewMetadata} facet of the {@link UIViewRoot} so that it gets
+ * incorporated into the JSF lifecycle on both non-faces (initial) requests and
+ * faces (postback) requests.
+ * </p>
+ * 
+ * <p>
+ * The purpose of this component is to provide a light-weight front-controller
+ * solution for executing code upon the loading of a JSF view to support the
+ * integration of system services, content retrieval, view management, and
+ * navigation. This functionality is especially useful for non-faces (initial)
+ * requests.
+ * </p>
+ * 
+ * <p>
+ * The {@link UIViewAction} component is closely tied to the
+ * {@link UIViewParameter} component. The {@link UIViewParameter} component
+ * binds a request parameter to a model property. Most of the time, this binding
+ * is used to populate the model with data that supports the method being
+ * invoked by a {@link UIViewAction} component, much like form inputs populate
+ * the model with data to support the method being invoked by a
+ * {@link UICommand} component.
+ * </p>
+ * 
+ * <p>
+ * When the <literal>decode()</literal> method of the {@link UIViewAction} is
+ * invoked, it will queue an {@link ActionEvent} to be broadcast to all
+ * interested listeners when the <literal>broadcast()</literal> method is
+ * invoked.
+ * </p>
+ * 
+ * <p>
+ * If the value of the component's <literal>immediate</literal> attribute is
+ * <literal>true</literal>, the action will be invoked during the Apply Request
+ * Values JSF lifecycle phase. Otherwise, the action will be invoked during the
+ * Invoke Application phase, the default behavior. The phase cannot be set
+ * explicitly in the <literal>phase</literal> attribute, which takes precedence
+ * over the <literal>immediate</literal> attribute.
+ * </p>
+ * 
+ * <p>
+ * The invocation of the action is normally suppressed (meaning the
+ * {@link ActionEvent} is not queued) on a faces request. It can be enabled by
+ * setting the component's <literal>onPostback</literal> attribute to
+ * <literal>true</literal>. Execution of the method can be subject to a required
+ * condition for all requests by assigning an EL value expression of expected
+ * type boolean to the component's <literal>if</literal> attribute, which must
+ * evaluate to <literal>true</literal> for the action to be invoked.
+ * </p>
+ * 
+ * <p>
+ * The {@link NavigationHandler} is consulted after the action is invoked to
+ * carry out the navigation case that matches the action signature and outcome.
+ * If a navigation case is matched, or the response is marked complete by the
+ * action, subsequent {@link UIViewAction} components associated with the
+ * current view are short-circuited. The lifecycle then advances appropriately.
+ * </p>
+ * 
+ * <p>
+ * It's important to note that the full component tree is not built before the
+ * UIViewAction components are processed on an non-faces (initial) request.
+ * Rather, the component tree only contains the {@link ViewMetadata}, an
+ * important part of the optimization of this component and what sets it apart
+ * from a {@link PreRenderViewEvent} listener.
+ * </p>
+ * 
+ * @author Dan Allen
+ * @author Andy Schwartz
+ * 
+ * @see UIViewParameter
+ */
+ at FacesComponent(
+// tagName = "viewAction",
+// namespace = "http://jboss.org/seam/faces",
+// (see
+// https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=594)
+value = UIViewAction.COMPONENT_TYPE)
+public class UIViewAction extends UIComponentBase implements ActionSource2
+{
+
+   // ------------------------------------------------------ Manifest Constants
+
+   /**
+    * <p>
+    * The standard component type for this component.
+    * </p>
+    */
+   public static final String COMPONENT_TYPE = "org.jboss.seam.faces.ViewAction";
+
+   /**
+    * <p>
+    * The standard component family for this component.
+    * </p>
+    */
+   public static final String COMPONENT_FAMILY = "org.jboss.seam.faces.ViewAction";
+
+   /**
+    * Properties that are tracked by state saving.
+    */
+   enum PropertyKeys
+   {
+
+      onPostback, actionExpression, immediate, phase, ifAttr("if");
+      private String name;
+
+      PropertyKeys()
+      {
+      }
+
+      PropertyKeys(final String name)
+      {
+         this.name = name;
+      }
+
+      @Override
+      public String toString()
+      {
+         return name != null ? name : super.toString();
+      }
+   }
+
+   // ------------------------------------------------------------ Constructors
+   /**
+    * <p>
+    * Create a new {@link UIViewAction} instance with default property values.
+    * </p>
+    */
+   public UIViewAction()
+   {
+      super();
+      setRendererType(null);
+   }
+
+   // -------------------------------------------------------------- Properties
+   @Override
+   public String getFamily()
+   {
+      return COMPONENT_FAMILY;
+   }
+
+   /**
+    * {@inheritDoc}
+    * 
+    * @deprecated This has been replaced by {@link #getActionExpression}.
+    */
+   @Deprecated
+   public MethodBinding getAction()
+   {
+      MethodBinding result = null;
+      MethodExpression me;
+
+      if (null != (me = getActionExpression()))
+      {
+         result = new MethodBindingMethodExpressionAdapter(me);
+      }
+      return result;
+   }
+
+   /**
+    * {@inheritDoc}
+    * 
+    * @deprecated This has been replaced by
+    *             {@link #setActionExpression(javax.el.MethodExpression)}.
+    * @throws UnsupportedOperationException if called
+    */
+   @Deprecated
+   public void setAction(final MethodBinding action)
+   {
+      throw new UnsupportedOperationException("Not supported.");
+   }
+
+   /**
+    * Action listeners are not supported by the {@link UIViewAction} component.
+    * 
+    * @throws UnsupportedOperationException if called
+    */
+   @SuppressWarnings("deprecation")
+   public MethodBinding getActionListener()
+   {
+      throw new UnsupportedOperationException("Not supported.");
+   }
+
+   /**
+    * Action listeners are not supported by the {@link UIViewAction} component.
+    * 
+    * @throws UnsupportedOperationException if called
+    */
+   @SuppressWarnings("deprecation")
+   public void setActionListener(final MethodBinding actionListener)
+   {
+      throw new UnsupportedOperationException("Not supported.");
+   }
+
+   /**
+    * Returns the value which dictates the JSF lifecycle phase in which the
+    * action is invoked. If the value of this attribute is
+    * <literal>true</literal>, the action will be invoked in the Apply Request
+    * Values phase. If the value of this attribute is <literal>false</literal>,
+    * the default, the action will be invoked in the Invoke Application Phase.
+    */
+   public boolean isImmediate()
+   {
+      return (Boolean) getStateHelper().eval(PropertyKeys.immediate, false);
+   }
+
+   /**
+    * Sets the immediate flag, which controls the JSF lifecycle in which the
+    * action is invoked.
+    */
+   public void setImmediate(final boolean immediate)
+   {
+      getStateHelper().put(PropertyKeys.immediate, immediate);
+   }
+
+   /**
+    * <p>
+    * Returns the name of the phase in which the action is to be queued. Only
+    * the following phases are supported (case does not matter):
+    * </p>
+    * <ul>
+    * <li>APPLY_REQUEST_VALUES</li>
+    * <li>PROCESS_VALIDATIONS</li>
+    * <li>UPDATE_MODEL_VALUES</li>
+    * <li>INVOKE_APPLICATION</li>
+    * </ul>
+    * <p>
+    * If the phase is set, it takes precedence over the immediate flag.
+    * </p>
+    */
+   public String getPhase()
+   {
+      String phase = (String) getStateHelper().eval(PropertyKeys.phase);
+      if (phase != null)
+      {
+         phase = phase.toUpperCase();
+      }
+      return phase;
+   }
+
+   /**
+    * Set the name of the phase in which the action is to be queued.
+    */
+   public void setPhase(final String phase)
+   {
+      getStateHelper().put(PropertyKeys.phase, phase);
+   }
+
+   public PhaseId getPhaseId()
+   {
+      String phase = getPhase();
+      if (phase == null)
+      {
+         return null;
+      }
+      if ("APPLY_REQUEST_VALUES".equals(phase))
+      {
+         return PhaseId.APPLY_REQUEST_VALUES;
+      }
+      else if ("PROCESS_VALIDATIONS".equals(phase))
+      {
+         return PhaseId.PROCESS_VALIDATIONS;
+      }
+      else if ("UPDATE_MODEL_VALUES".equals(phase))
+      {
+         return PhaseId.UPDATE_MODEL_VALUES;
+      }
+      else if ("INVOKE_APPLICATION".equals(phase))
+      {
+         return PhaseId.INVOKE_APPLICATION;
+      }
+      else if ("ANY_PHASE".equals(phase) || "RESTORE_VIEW".equals(phase) || "RENDER_REPONSE".equals(phase))
+      {
+         throw new FacesException("View actions cannot be executed in specified phase: [" + phase + "]");
+      }
+      else
+      {
+         throw new FacesException("Not a valid phase [" + phase + "]");
+      }
+   }
+
+   /**
+    * Action listeners are not supported by the {@link UIViewAction} component.
+    * 
+    * @throws UnsupportedOperationException if called
+    */
+   public void addActionListener(final ActionListener listener)
+   {
+      throw new UnsupportedOperationException("Not supported.");
+   }
+
+   /**
+    * Action listeners are not supported by the {@link UIViewAction} component.
+    */
+   public ActionListener[] getActionListeners()
+   {
+      return new ActionListener[0];
+   }
+
+   /**
+    * Action listeners are not supported by the {@link UIViewAction} component.
+    * 
+    * @throws UnsupportedOperationException if called
+    */
+   public void removeActionListener(final ActionListener listener)
+   {
+      throw new UnsupportedOperationException("Not supported.");
+   }
+
+   /**
+    * Returns the action, represented as an EL method expression, to invoke.
+    */
+   public MethodExpression getActionExpression()
+   {
+      return (MethodExpression) getStateHelper().get(PropertyKeys.actionExpression);
+   }
+
+   /**
+    * Sets the action, represented as an EL method expression, to invoke.
+    */
+   public void setActionExpression(final MethodExpression actionExpression)
+   {
+      getStateHelper().put(PropertyKeys.actionExpression, actionExpression);
+   }
+
+   /**
+    * Returns a boolean value that controls whether the action is invoked during
+    * faces (postback) request. The default is false.
+    */
+   public boolean isOnPostback()
+   {
+      return (Boolean) getStateHelper().eval(PropertyKeys.onPostback, false);
+   }
+
+   /**
+    * Set the bookean flag that controls whether the action is invoked during a
+    * faces (postback) request.
+    */
+   public void setOnPostback(final boolean onPostback)
+   {
+      getStateHelper().put(PropertyKeys.onPostback, onPostback);
+   }
+
+   /**
+    * Returns a condition, represented as an EL value expression, that must
+    * evaluate to true for the action to be invoked.
+    */
+   public boolean isIf()
+   {
+      return (Boolean) getStateHelper().eval(PropertyKeys.ifAttr, true);
+   }
+
+   /**
+    * Sets the condition, represented as an EL value expression, that must
+    * evaluate to true for the action to be invoked.
+    */
+   public void setIf(final boolean condition)
+   {
+      getStateHelper().put(PropertyKeys.ifAttr, condition);
+   }
+
+   // ----------------------------------------------------- UIComponent Methods
+   /**
+    * <p>
+    * In addition to to the default {@link UIComponent#broadcast} processing,
+    * pass the {@link ActionEvent} being broadcast to the default
+    * {@link ActionListener} registered on the
+    * {@link javax.faces.application.Application}.
+    * </p>
+    * 
+    * @param event {@link FacesEvent} to be broadcast
+    * 
+    * @throws AbortProcessingException Signal the JavaServer Faces
+    *            implementation that no further processing on the current event
+    *            should be performed
+    * @throws IllegalArgumentException if the implementation class of this
+    *            {@link FacesEvent} is not supported by this component
+    * @throws NullPointerException if <code>event</code> is <code>null</code>
+    */
+   @Override
+   public void broadcast(final FacesEvent event) throws AbortProcessingException
+   {
+
+      super.broadcast(event);
+
+      FacesContext context = getFacesContext();
+
+      // OPEN QUESTION: should we consider a navigation to the same view as a
+      // no-op navigation?
+
+      // only proceed if the response has not been marked complete and
+      // navigation to another view has not occurred
+      if ((event instanceof ActionEvent) && !context.getResponseComplete() && (context.getViewRoot() == getViewRootOf(event)))
+      {
+         ActionListener listener = context.getApplication().getActionListener();
+         if (listener != null)
+         {
+            UIViewRoot viewRootBefore = context.getViewRoot();
+            InstrumentedFacesContext instrumentedContext = new InstrumentedFacesContext(context);
+            // defer the call to renderResponse() that happens in
+            // ActionListener#processAction(ActionEvent)
+            instrumentedContext.disableRenderResponseControl().set();
+            listener.processAction((ActionEvent) event);
+            instrumentedContext.restore();
+            // if the response is marked complete, the story is over
+            if (!context.getResponseComplete())
+            {
+               UIViewRoot viewRootAfter = context.getViewRoot();
+               // if the view id changed as a result of navigation, then execute
+               // the JSF lifecycle for the new view id
+               if (viewRootBefore != viewRootAfter)
+               {
+                  /*
+                   * // execute the JSF lifecycle by dispatching a forward
+                   * request // this approach is problematic because it throws a
+                   * wrench in the event broadcasting try {
+                   * context.getExternalContext
+                   * ().dispatch(context.getApplication()
+                   * .getViewHandler().getActionURL(context,
+                   * viewRootAfter.getViewId())
+                   * .substring(context.getExternalContext
+                   * ().getRequestContextPath().length())); // kill this
+                   * lifecycle execution context.responseComplete(); } catch
+                   * (IOException e) { throw new
+                   * FacesException("Dispatch to viewId failed: " +
+                   * viewRootAfter.getViewId(), e); }
+                   */
+
+                  // manually execute the JSF lifecycle on the new view id
+                  // certain tweaks have to be made to the FacesContext to allow
+                  // us to reset the lifecycle
+                  Lifecycle lifecycle = getLifecycle(context);
+                  instrumentedContext = new InstrumentedFacesContext(context);
+                  instrumentedContext.pushViewIntoRequestMap().clearViewRoot().clearPostback().set();
+                  lifecycle.execute(instrumentedContext);
+                  instrumentedContext.restore();
+
+                  /*
+                   * Another approach would be to register a phase listener in
+                   * the decode() method for the phase in which the action is
+                   * set to invoke. The phase listener would performs a servlet
+                   * forward if a non-redirect navigation occurs after the
+                   * phase.
+                   */
+               }
+               else
+               {
+                  // apply the deferred call (relevant when immediate is true)
+                  context.renderResponse();
+               }
+            }
+         }
+      }
+   }
+
+   /**
+    * First, determine if the action should be invoked by evaluating this
+    * components pre-conditions. If this is a faces (postback) request and the
+    * evaluated value of the postback attribute is false, take no action. If the
+    * evaluated value of the if attribute is false, take no action. If both
+    * conditions pass, proceed with creating an {@link ActionEvent}.
+    * 
+    * Set the phaseId in which the queued {@link ActionEvent} should be
+    * broadcast by assigning the appropriate value to the phaseId property of
+    * the {@link ActionEvent} according to the evaluated value of the immediate
+    * attribute. If the value is <literal>true</literal>, set the phaseId to
+    * {@link PhaseId#APPLY_REQUEST_VALUES}. Otherwise, set the phaseId to to
+    * {@link PhaseId#INVOKE_APPLICATION}.
+    * 
+    * Finally, queue the event by calling <literal>queueEvent()</literal> and
+    * passing the {@link ActionEvent} just created.
+    */
+   @Override
+   public void decode(final FacesContext context)
+   {
+      if (context == null)
+      {
+         throw new NullPointerException();
+      }
+
+      if ((context.isPostback() && !isOnPostback()) || !isIf())
+      {
+         return;
+      }
+
+      ActionEvent e = new ActionEvent(this);
+      PhaseId phaseId = getPhaseId();
+      if (phaseId != null)
+      {
+         e.setPhaseId(phaseId);
+      }
+      else if (isImmediate())
+      {
+         e.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
+      }
+      else
+      {
+         e.setPhaseId(PhaseId.INVOKE_APPLICATION);
+      }
+
+      queueEvent(e);
+   }
+
+   private UIViewRoot getViewRootOf(final FacesEvent e)
+   {
+      UIComponent c = e.getComponent();
+      do
+      {
+         if (c instanceof UIViewRoot)
+         {
+            return (UIViewRoot) c;
+         }
+         c = c.getParent();
+      }
+      while (c != null);
+      return null;
+   }
+
+   private Lifecycle getLifecycle(final FacesContext context)
+   {
+      LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
+      String lifecycleId = context.getExternalContext().getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR);
+      if (lifecycleId == null)
+      {
+         lifecycleId = LifecycleFactory.DEFAULT_LIFECYCLE;
+      }
+      return lifecycleFactory.getLifecycle(lifecycleId);
+   }
+
+   /**
+    * A FacesContext delegator that gives us the necessary controls over the
+    * FacesContext to allow the execution of the lifecycle to accomodate the
+    * UIViewAction sequence.
+    */
+   private class InstrumentedFacesContext extends FacesContextWrapper
+   {
+
+      private final FacesContext wrapped;
+      private boolean viewRootCleared = false;
+      private boolean renderedResponseControlDisabled = false;
+      private Boolean postback = null;
+
+      public InstrumentedFacesContext(final FacesContext wrapped)
+      {
+         this.wrapped = wrapped;
+      }
+
+      @Override
+      public FacesContext getWrapped()
+      {
+         return wrapped;
+      }
+
+      @Override
+      public UIViewRoot getViewRoot()
+      {
+         if (viewRootCleared)
+         {
+            return null;
+         }
+
+         return wrapped.getViewRoot();
+      }
+
+      @Override
+      public void setViewRoot(final UIViewRoot viewRoot)
+      {
+         viewRootCleared = false;
+         wrapped.setViewRoot(viewRoot);
+      }
+
+      @Override
+      public boolean isPostback()
+      {
+         return postback == null ? wrapped.isPostback() : postback;
+      }
+
+      @Override
+      public void renderResponse()
+      {
+         if (!renderedResponseControlDisabled)
+         {
+            wrapped.renderResponse();
+         }
+      }
+
+      /**
+       * Make it look like we have dispatched a request using the include
+       * method.
+       */
+      public InstrumentedFacesContext pushViewIntoRequestMap()
+      {
+         getExternalContext().getRequestMap().put("javax.servlet.include.servlet_path", wrapped.getViewRoot().getViewId());
+         return this;
+      }
+
+      public InstrumentedFacesContext clearPostback()
+      {
+         postback = false;
+         return this;
+      }
+
+      public InstrumentedFacesContext clearViewRoot()
+      {
+         viewRootCleared = true;
+         return this;
+      }
+
+      public InstrumentedFacesContext disableRenderResponseControl()
+      {
+         renderedResponseControlDisabled = true;
+         return this;
+      }
+
+      public void set()
+      {
+         setCurrentInstance(this);
+      }
+
+      public void restore()
+      {
+         setCurrentInstance(wrapped);
+      }
+   }
+}

Added: modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/ValueExpressionAnalyzer.java
===================================================================
--- modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/ValueExpressionAnalyzer.java	                        (rev 0)
+++ modules/faces/trunk/api/src/main/java/org/jboss/seam/faces/component/ValueExpressionAnalyzer.java	2010-05-28 23:06:51 UTC (rev 12896)
@@ -0,0 +1,175 @@
+package org.jboss.seam.faces.component;
+
+import java.beans.FeatureDescriptor;
+import java.util.Iterator;
+import java.util.Locale;
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.ELResolver;
+import javax.el.FunctionMapper;
+import javax.el.ValueExpression;
+import javax.el.ValueReference;
+import javax.el.VariableMapper;
+import javax.faces.el.CompositeComponentExpressionHolder;
+
+/**
+ * Analyzes a {@link ValueExpression} and provides access to the base object and property
+ * name to which the expression maps via the getReference() method.
+ */
+class ValueExpressionAnalyzer
+{
+   private ValueExpression expression;
+
+   public ValueExpressionAnalyzer(ValueExpression expression)
+   {
+      this.expression = expression;
+   }
+
+   public ValueReference getValueReference(ELContext elContext)
+   {
+      InterceptingResolver resolver = new InterceptingResolver(elContext.getELResolver());
+      try
+      {
+         expression.setValue(decorateELContext(elContext, resolver), null);
+      }
+      catch (ELException ele)
+      {
+         return null;
+      }
+      ValueReference reference = resolver.getValueReference();
+      if (reference != null)
+      {
+         Object base = reference.getBase();
+         if (base instanceof CompositeComponentExpressionHolder)
+         {
+            ValueExpression ve = ((CompositeComponentExpressionHolder) base).getExpression((String) reference.getProperty());
+            if (ve != null)
+            {
+               this.expression = ve;
+               reference = getValueReference(elContext);
+            }
+         }
+      }
+      return reference;
+   }
+
+   private ELContext decorateELContext(final ELContext context, final ELResolver resolver)
+   {
+      return new ELContext()
+      {
+         // punch in our new ELResolver
+         @Override
+         public ELResolver getELResolver()
+         {
+            return resolver;
+         }
+
+         // The rest of the methods simply delegate to the existing context
+         @Override
+         public Object getContext(Class key)
+         {
+            return context.getContext(key);
+         }
+
+         @Override
+         public Locale getLocale()
+         {
+            return context.getLocale();
+         }
+
+         @Override
+         public boolean isPropertyResolved()
+         {
+            return context.isPropertyResolved();
+         }
+
+         @Override
+         public void putContext(Class key, Object contextObject)
+         {
+            context.putContext(key, contextObject);
+         }
+
+         @Override
+         public void setLocale(Locale locale)
+         {
+            context.setLocale(locale);
+         }
+
+         @Override
+         public void setPropertyResolved(boolean resolved)
+         {
+            context.setPropertyResolved(resolved);
+         }
+
+         @Override
+         public FunctionMapper getFunctionMapper()
+         {
+            return context.getFunctionMapper();
+         }
+
+         @Override
+         public VariableMapper getVariableMapper()
+         {
+            return context.getVariableMapper();
+         }
+      };
+   }
+
+   private static class InterceptingResolver extends ELResolver
+   {
+      private ELResolver delegate;
+      private ValueReference valueReference;
+
+      public InterceptingResolver(ELResolver delegate)
+      {
+         this.delegate = delegate;
+      }
+
+      public ValueReference getValueReference()
+      {
+         return valueReference;
+      }
+
+      // Capture the base and property rather than write the value
+      @Override
+      public void setValue(ELContext context, Object base, Object property, Object value)
+      {
+         if (base != null && property != null)
+         {
+            context.setPropertyResolved(true);
+            valueReference = new ValueReference(base, property.toString());
+         }
+      }
+
+      // The rest of the methods simply delegate to the existing context
+      @Override
+      public Object getValue(ELContext context, Object base, Object property)
+      {
+         return delegate.getValue(context, base, property);
+      }
+
+      @Override
+      public Class<?> getType(ELContext context, Object base, Object property)
+      {
+         return delegate.getType(context, base, property);
+      }
+
+      @Override
+      public boolean isReadOnly(ELContext context, Object base, Object property)
+      {
+         return delegate.isReadOnly(context, base, property);
+      }
+
+      @Override
+      public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base)
+      {
+         return delegate.getFeatureDescriptors(context, base);
+      }
+
+      @Override
+      public Class<?> getCommonPropertyType(ELContext context, Object base)
+      {
+         return delegate.getCommonPropertyType(context, base);
+      }
+   }
+}

Added: modules/faces/trunk/api/src/main/resources/META-INF/faces-config.xml
===================================================================
--- modules/faces/trunk/api/src/main/resources/META-INF/faces-config.xml	                        (rev 0)
+++ modules/faces/trunk/api/src/main/resources/META-INF/faces-config.xml	2010-05-28 23:06:51 UTC (rev 12896)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
+   version="2.0">
+   <!-- This file is present to allow annotated component classes to be discovered and registered -->
+</faces-config>

Deleted: modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/component/MethodBindingMethodExpressionAdapter.java
===================================================================
--- modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/component/MethodBindingMethodExpressionAdapter.java	2010-05-28 20:39:48 UTC (rev 12895)
+++ modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/component/MethodBindingMethodExpressionAdapter.java	2010-05-28 23:06:51 UTC (rev 12896)
@@ -1,339 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2010, Red Hat, Inc., and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.seam.faces.component;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-
-import javax.el.ELContext;
-import javax.el.ELException;
-import javax.el.ExpressionFactory;
-import javax.el.MethodExpression;
-import javax.el.MethodInfo;
-import javax.el.ValueExpression;
-import javax.faces.component.StateHolder;
-import javax.faces.context.FacesContext;
-import javax.faces.el.EvaluationException;
-import javax.faces.el.MethodBinding;
-import javax.faces.el.MethodNotFoundException;
-
-/**
- * <p>
- * Wrap a MethodExpression instance and expose it as a MethodBinding
- * </p>
- * 
- */
-class MethodBindingMethodExpressionAdapter extends MethodBinding implements StateHolder, Serializable
-{
-
-   private static final long serialVersionUID = 7334926223014401689L;
-   private MethodExpression methodExpression = null;
-   private boolean tranzient;
-
-   public MethodBindingMethodExpressionAdapter()
-   {
-   } // for StateHolder
-
-   MethodBindingMethodExpressionAdapter(final MethodExpression methodExpression)
-   {
-      this.methodExpression = methodExpression;
-   }
-
-   @Override
-   @SuppressWarnings("deprecation")
-   public Object invoke(final FacesContext context, final Object params[]) throws EvaluationException, MethodNotFoundException
-   {
-      assert (null != methodExpression);
-      if (context == null)
-      {
-         throw new NullPointerException("FacesConext -> null");
-      }
-
-      Object result = null;
-      try
-      {
-         result = methodExpression.invoke(context.getELContext(), params);
-      }
-      catch (javax.el.MethodNotFoundException e)
-      {
-         throw new javax.faces.el.MethodNotFoundException(e);
-      }
-      catch (javax.el.PropertyNotFoundException e)
-      {
-         throw new EvaluationException(e);
-      }
-      catch (ELException e)
-      {
-         Throwable cause = e.getCause();
-         if (cause == null)
-         {
-            cause = e;
-         }
-         throw new EvaluationException(cause);
-      }
-      catch (NullPointerException e)
-      {
-         throw new MethodNotFoundException(e);
-      }
-      return result;
-   }
-
-   @Override
-   @SuppressWarnings("deprecation")
-   public Class<?> getType(final FacesContext context) throws MethodNotFoundException
-   {
-      assert (null != methodExpression);
-      if (context == null)
-      {
-         throw new NullPointerException("FacesConext -> null");
-      }
-      Class<?> result = null;
-      if (context == null)
-      {
-         throw new NullPointerException();
-      }
-
-      try
-      {
-         MethodInfo mi = methodExpression.getMethodInfo(context.getELContext());
-         result = mi.getReturnType();
-      }
-      catch (javax.el.PropertyNotFoundException e)
-      {
-         throw new MethodNotFoundException(e);
-      }
-      catch (javax.el.MethodNotFoundException e)
-      {
-         throw new MethodNotFoundException(e);
-      }
-      catch (ELException e)
-      {
-         throw new MethodNotFoundException(e);
-      }
-      return result;
-   }
-
-   @Override
-   public String getExpressionString()
-   {
-      assert (null != methodExpression);
-      return methodExpression.getExpressionString();
-   }
-
-   @Override
-   @SuppressWarnings("deprecation")
-   public boolean equals(final Object other)
-   {
-      if (this == other)
-      {
-         return true;
-      }
-      if (other instanceof MethodBindingMethodExpressionAdapter)
-      {
-         return methodExpression.equals(((MethodBindingMethodExpressionAdapter) other).getWrapped());
-      }
-      else if (other instanceof MethodBinding)
-      {
-         MethodBinding binding = (MethodBinding) other;
-
-         // We'll need to do a little leg work to determine
-         // if the MethodBinding is equivalent to the
-         // wrapped MethodExpression
-         String expr = binding.getExpressionString();
-         int idx = expr.indexOf('.');
-         String target = expr.substring(0, idx).substring(2);
-         String t = expr.substring(idx + 1);
-         String method = t.substring(0, (t.length() - 1));
-
-         FacesContext context = FacesContext.getCurrentInstance();
-         ELContext elContext = context.getELContext();
-         MethodInfo controlInfo = methodExpression.getMethodInfo(elContext);
-
-         // ensure the method names are the same
-         if (!controlInfo.getName().equals(method))
-         {
-            return false;
-         }
-
-         // Using the target, create an expression and evaluate
-         // it.
-         ExpressionFactory factory = context.getApplication().getExpressionFactory();
-         ValueExpression ve = factory.createValueExpression(elContext, "#{" + target + '}', Object.class);
-         if (ve == null)
-         {
-            return false;
-         }
-
-         Object result = ve.getValue(elContext);
-
-         if (result == null)
-         {
-            return false;
-         }
-
-         // Get all of the methods with the matching name and try
-         // to find a match based on controlInfo's return and parameter
-         // types
-         Class<?> type = binding.getType(context);
-         Method[] methods = result.getClass().getMethods();
-         for (Method meth : methods)
-         {
-            if (meth.getName().equals(method) && type.equals(controlInfo.getReturnType()) && Arrays.equals(meth.getParameterTypes(), controlInfo.getParamTypes()))
-            {
-               return true;
-            }
-         }
-      }
-
-      return false;
-
-   }
-
-   @Override
-   public int hashCode()
-   {
-      assert (null != methodExpression);
-
-      return methodExpression.hashCode();
-   }
-
-   public boolean isTransient()
-   {
-      return this.tranzient;
-   }
-
-   public void setTransient(final boolean tranzient)
-   {
-      this.tranzient = tranzient;
-   }
-
-   public Object saveState(final FacesContext context)
-   {
-      if (context == null)
-      {
-         throw new NullPointerException();
-      }
-      Object result = null;
-      if (!tranzient)
-      {
-         if (methodExpression instanceof StateHolder)
-         {
-            Object[] stateStruct = new Object[2];
-
-            // save the actual state of our wrapped methodExpression
-            stateStruct[0] = ((StateHolder) methodExpression).saveState(context);
-            // save the class name of the methodExpression impl
-            stateStruct[1] = methodExpression.getClass().getName();
-
-            result = stateStruct;
-         }
-         else
-         {
-            result = methodExpression;
-         }
-      }
-
-      return result;
-
-   }
-
-   public void restoreState(final FacesContext context, final Object state)
-   {
-      if (context == null)
-      {
-         throw new NullPointerException();
-      }
-      // if we have state
-      if (null == state)
-      {
-         return;
-      }
-
-      if (!(state instanceof MethodExpression))
-      {
-         Object[] stateStruct = (Object[]) state;
-         Object savedState = stateStruct[0];
-         String className = stateStruct[1].toString();
-         MethodExpression result = null;
-
-         Class<?> toRestoreClass = null;
-         if (null != className)
-         {
-            try
-            {
-               toRestoreClass = loadClass(className, this);
-            }
-            catch (ClassNotFoundException e)
-            {
-               throw new IllegalStateException(e.getMessage());
-            }
-
-            if (null != toRestoreClass)
-            {
-               try
-               {
-                  result = (MethodExpression) toRestoreClass.newInstance();
-               }
-               catch (InstantiationException e)
-               {
-                  throw new IllegalStateException(e.getMessage());
-               }
-               catch (IllegalAccessException a)
-               {
-                  throw new IllegalStateException(a.getMessage());
-               }
-            }
-
-            if ((null != result) && (null != savedState))
-            {
-               // don't need to check transient, since that was
-               // done on the saving side.
-               ((StateHolder) result).restoreState(context, savedState);
-            }
-            methodExpression = result;
-         }
-      }
-      else
-      {
-         methodExpression = (MethodExpression) state;
-      }
-   }
-
-   public MethodExpression getWrapped()
-   {
-      return methodExpression;
-   }
-
-   //
-   // Helper methods for StateHolder
-   //
-   private static Class<?> loadClass(final String name, final Object fallbackClass) throws ClassNotFoundException
-   {
-      ClassLoader loader = Thread.currentThread().getContextClassLoader();
-      if (loader == null)
-      {
-         loader = fallbackClass.getClass().getClassLoader();
-      }
-      return Class.forName(name, true, loader);
-   }
-}
\ No newline at end of file

Deleted: modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/component/UIValidateForm.java
===================================================================
--- modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/component/UIValidateForm.java	2010-05-28 20:39:48 UTC (rev 12895)
+++ modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/component/UIValidateForm.java	2010-05-28 23:06:51 UTC (rev 12896)
@@ -1,183 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2010, Red Hat, Inc., and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.seam.faces.component;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.util.AnnotationLiteral;
-import javax.faces.component.FacesComponent;
-import javax.faces.component.UIComponent;
-import javax.faces.component.UIForm;
-import javax.faces.component.UIInput;
-import javax.faces.component.UIViewRoot;
-import javax.faces.context.FacesContext;
-import javax.faces.event.PostValidateEvent;
-import javax.faces.event.PreValidateEvent;
-import javax.faces.validator.Validator;
-import javax.faces.validator.ValidatorException;
-
-import org.jboss.seam.faces.event.qualifier.After;
-import org.jboss.seam.faces.event.qualifier.Before;
-import org.jboss.weld.extensions.beanManager.BeanManagerAccessor;
-
-/**
- * @author <a href="mailto:lincolnbaxter at gmail.com>Lincoln Baxter, III</a>
- * 
- */
- at FacesComponent(UIValidateForm.COMPONENT_TYPE)
-public class UIValidateForm extends UIInput
-{
-   private static final AnnotationLiteral<Before> BEFORE = new AnnotationLiteral<Before>()
-   {
-      private static final long serialVersionUID = 7631699535063526392L;
-   };
-   private static final AnnotationLiteral<After> AFTER = new AnnotationLiteral<After>()
-   {
-      private static final long serialVersionUID = -929128236303355107L;
-   };
-
-   public static final String COMPONENT_TYPE = "org.jboss.seam.faces.ValidateForm";
-   public static final String COMPONENT_FAMILY = "org.jboss.seam.faces.ValidateForm";
-
-   private String validatorId = "";
-   private String fields = "";
-   private Map<String, UIInput> components = new HashMap<String, UIInput>();
-
-   @Override
-   public String getFamily()
-   {
-      return COMPONENT_FAMILY;
-   }
-
-   @Override
-   public void validate(final FacesContext context)
-   {
-      context.getApplication().publishEvent(context, PreValidateEvent.class, UIValidateForm.class, this);
-      BeanManager manager = BeanManagerAccessor.getManager();
-      manager.fireEvent(this, BEFORE);
-
-      Validator validator = context.getApplication().createValidator(validatorId);
-      if (validator == null)
-      {
-         throw new IllegalArgumentException("Could not create Validator with id: [" + validatorId + "]");
-      }
-
-      try
-      {
-         UIComponent parent = this.getParent();
-         validator.validate(context, parent, components);
-      }
-      catch (ValidatorException e)
-      {
-         setValid(false);
-         for (UIInput comp : components.values())
-         {
-            comp.setValid(false);
-            // TODO Put this back when attributes can control it
-            // context.addMessage(comp.getClientId(), e.getFacesMessage());
-         }
-         context.addMessage(null, e.getFacesMessage());
-      }
-
-      manager.fireEvent(this, AFTER);
-      context.getApplication().publishEvent(context, PostValidateEvent.class, UIValidateForm.class, this);
-   }
-
-   /**
-    * Attempt to locate the form in which this component resides. If the
-    * component is not within a UIForm tag, throw an exception.
-    */
-   public UIForm locateForm()
-   {
-      UIComponent parent = this.getParent();
-      while (!(parent instanceof UIForm))
-      {
-         if ((parent == null) || (parent instanceof UIViewRoot))
-         {
-            throw new IllegalStateException("The UIValidateForm (<s:validateForm />) component must be placed within a UIForm (<h:form>)");
-         }
-         parent = parent.getParent();
-      }
-      return (UIForm) parent;
-   }
-
-   /*
-    * Prevent any rendered output.
-    */
-
-   @Override
-   public void encodeAll(final FacesContext context) throws IOException
-   {
-      locateForm();
-   }
-
-   @Override
-   public void encodeBegin(final FacesContext context) throws IOException
-   {
-   }
-
-   @Override
-   public void encodeEnd(final FacesContext context) throws IOException
-   {
-   }
-
-   @Override
-   public void encodeChildren(final FacesContext context) throws IOException
-   {
-   }
-
-   /*
-    * Getters & Setters
-    */
-
-   public String getFields()
-   {
-      return fields;
-   }
-
-   public void setFields(final String fields)
-   {
-      this.fields = fields;
-   }
-
-   public String getValidatorId()
-   {
-      return validatorId;
-   }
-
-   public void setValidatorId(final String validatorId)
-   {
-      this.validatorId = validatorId;
-   }
-
-   /**
-    * @param components
-    */
-   public void setComponents(final Map<String, UIInput> components)
-   {
-      this.components = components;
-   }
-}

Deleted: modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/component/UIViewAction.java
===================================================================
--- modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/component/UIViewAction.java	2010-05-28 20:39:48 UTC (rev 12895)
+++ modules/faces/trunk/impl/src/main/java/org/jboss/seam/faces/component/UIViewAction.java	2010-05-28 23:06:51 UTC (rev 12896)
@@ -1,677 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2010, Red Hat, Inc., and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.seam.faces.component;
-
-import javax.el.MethodExpression;
-import javax.faces.FacesException;
-import javax.faces.FactoryFinder;
-import javax.faces.application.NavigationHandler;
-import javax.faces.component.ActionSource2;
-import javax.faces.component.FacesComponent;
-import javax.faces.component.UICommand;
-import javax.faces.component.UIComponent;
-import javax.faces.component.UIComponentBase;
-import javax.faces.component.UIViewParameter;
-import javax.faces.component.UIViewRoot;
-import javax.faces.context.FacesContext;
-import javax.faces.context.FacesContextWrapper;
-import javax.faces.el.MethodBinding;
-import javax.faces.event.AbortProcessingException;
-import javax.faces.event.ActionEvent;
-import javax.faces.event.ActionListener;
-import javax.faces.event.FacesEvent;
-import javax.faces.event.PhaseId;
-import javax.faces.event.PreRenderViewEvent;
-import javax.faces.lifecycle.Lifecycle;
-import javax.faces.lifecycle.LifecycleFactory;
-import javax.faces.view.ViewMetadata;
-import javax.faces.webapp.FacesServlet;
-
-/**
- * <p>
- * <strong>UIViewAction</strong> is an {@link ActionSource2} {@link UIComponent}
- * that specifies an application-specific command (or action)--defined as an EL
- * method expression--to be invoked during one of the JSF lifecycle phases that
- * proceeds view rendering. This component must be declared as a child of the
- * {@link ViewMetadata} facet of the {@link UIViewRoot} so that it gets
- * incorporated into the JSF lifecycle on both non-faces (initial) requests and
- * faces (postback) requests.
- * </p>
- * 
- * <p>
- * The purpose of this component is to provide a light-weight front-controller
- * solution for executing code upon the loading of a JSF view to support the
- * integration of system services, content retrieval, view management, and
- * navigation. This functionality is especially useful for non-faces (initial)
- * requests.
- * </p>
- * 
- * <p>
- * The {@link UIViewAction} component is closely tied to the
- * {@link UIViewParameter} component. The {@link UIViewParameter} component
- * binds a request parameter to a model property. Most of the time, this binding
- * is used to populate the model with data that supports the method being
- * invoked by a {@link UIViewAction} component, much like form inputs populate
- * the model with data to support the method being invoked by a
- * {@link UICommand} component.
- * </p>
- * 
- * <p>
- * When the <literal>decode()</literal> method of the {@link UIViewAction} is
- * invoked, it will queue an {@link ActionEvent} to be broadcast to all
- * interested listeners when the <literal>broadcast()</literal> method is
- * invoked.
- * </p>
- * 
- * <p>
- * If the value of the component's <literal>immediate</literal> attribute is
- * <literal>true</literal>, the action will be invoked during the Apply Request
- * Values JSF lifecycle phase. Otherwise, the action will be invoked during the
- * Invoke Application phase, the default behavior. The phase cannot be set
- * explicitly in the <literal>phase</literal> attribute, which takes precedence
- * over the <literal>immediate</literal> attribute.
- * </p>
- * 
- * <p>
- * The invocation of the action is normally suppressed (meaning the
- * {@link ActionEvent} is not queued) on a faces request. It can be enabled by
- * setting the component's <literal>onPostback</literal> attribute to
- * <literal>true</literal>. Execution of the method can be subject to a required
- * condition for all requests by assigning an EL value expression of expected
- * type boolean to the component's <literal>if</literal> attribute, which must
- * evaluate to <literal>true</literal> for the action to be invoked.
- * </p>
- * 
- * <p>
- * The {@link NavigationHandler} is consulted after the action is invoked to
- * carry out the navigation case that matches the action signature and outcome.
- * If a navigation case is matched, or the response is marked complete by the
- * action, subsequent {@link UIViewAction} components associated with the
- * current view are short-circuited. The lifecycle then advances appropriately.
- * </p>
- * 
- * <p>
- * It's important to note that the full component tree is not built before the
- * UIViewAction components are processed on an non-faces (initial) request.
- * Rather, the component tree only contains the {@link ViewMetadata}, an
- * important part of the optimization of this component and what sets it apart
- * from a {@link PreRenderViewEvent} listener.
- * </p>
- * 
- * @author Dan Allen
- * @author Andy Schwartz
- * 
- * @see UIViewParameter
- */
- at FacesComponent(
-// tagName = "viewAction",
-// namespace = "http://jboss.org/seam/faces",
-// (see
-// https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=594)
-value = UIViewAction.COMPONENT_TYPE)
-public class UIViewAction extends UIComponentBase implements ActionSource2
-{
-
-   // ------------------------------------------------------ Manifest Constants
-
-   /**
-    * <p>
-    * The standard component type for this component.
-    * </p>
-    */
-   public static final String COMPONENT_TYPE = "org.jboss.seam.faces.ViewAction";
-
-   /**
-    * <p>
-    * The standard component family for this component.
-    * </p>
-    */
-   public static final String COMPONENT_FAMILY = "org.jboss.seam.faces.ViewAction";
-
-   /**
-    * Properties that are tracked by state saving.
-    */
-   enum PropertyKeys
-   {
-
-      onPostback, actionExpression, immediate, phase, ifAttr("if");
-      private String name;
-
-      PropertyKeys()
-      {
-      }
-
-      PropertyKeys(final String name)
-      {
-         this.name = name;
-      }
-
-      @Override
-      public String toString()
-      {
-         return name != null ? name : super.toString();
-      }
-   }
-
-   // ------------------------------------------------------------ Constructors
-   /**
-    * <p>
-    * Create a new {@link UIViewAction} instance with default property values.
-    * </p>
-    */
-   public UIViewAction()
-   {
-      super();
-      setRendererType(null);
-   }
-
-   // -------------------------------------------------------------- Properties
-   @Override
-   public String getFamily()
-   {
-      return COMPONENT_FAMILY;
-   }
-
-   /**
-    * {@inheritDoc}
-    * 
-    * @deprecated This has been replaced by {@link #getActionExpression}.
-    */
-   @Deprecated
-   public MethodBinding getAction()
-   {
-      MethodBinding result = null;
-      MethodExpression me;
-
-      if (null != (me = getActionExpression()))
-      {
-         result = new MethodBindingMethodExpressionAdapter(me);
-      }
-      return result;
-   }
-
-   /**
-    * {@inheritDoc}
-    * 
-    * @deprecated This has been replaced by
-    *             {@link #setActionExpression(javax.el.MethodExpression)}.
-    * @throws UnsupportedOperationException if called
-    */
-   @Deprecated
-   public void setAction(final MethodBinding action)
-   {
-      throw new UnsupportedOperationException("Not supported.");
-   }
-
-   /**
-    * Action listeners are not supported by the {@link UIViewAction} component.
-    * 
-    * @throws UnsupportedOperationException if called
-    */
-   @SuppressWarnings("deprecation")
-   public MethodBinding getActionListener()
-   {
-      throw new UnsupportedOperationException("Not supported.");
-   }
-
-   /**
-    * Action listeners are not supported by the {@link UIViewAction} component.
-    * 
-    * @throws UnsupportedOperationException if called
-    */
-   @SuppressWarnings("deprecation")
-   public void setActionListener(final MethodBinding actionListener)
-   {
-      throw new UnsupportedOperationException("Not supported.");
-   }
-
-   /**
-    * Returns the value which dictates the JSF lifecycle phase in which the
-    * action is invoked. If the value of this attribute is
-    * <literal>true</literal>, the action will be invoked in the Apply Request
-    * Values phase. If the value of this attribute is <literal>false</literal>,
-    * the default, the action will be invoked in the Invoke Application Phase.
-    */
-   public boolean isImmediate()
-   {
-      return (Boolean) getStateHelper().eval(PropertyKeys.immediate, false);
-   }
-
-   /**
-    * Sets the immediate flag, which controls the JSF lifecycle in which the
-    * action is invoked.
-    */
-   public void setImmediate(final boolean immediate)
-   {
-      getStateHelper().put(PropertyKeys.immediate, immediate);
-   }
-
-   /**
-    * <p>
-    * Returns the name of the phase in which the action is to be queued. Only
-    * the following phases are supported (case does not matter):
-    * </p>
-    * <ul>
-    * <li>APPLY_REQUEST_VALUES</li>
-    * <li>PROCESS_VALIDATIONS</li>
-    * <li>UPDATE_MODEL_VALUES</li>
-    * <li>INVOKE_APPLICATION</li>
-    * </ul>
-    * <p>
-    * If the phase is set, it takes precedence over the immediate flag.
-    * </p>
-    */
-   public String getPhase()
-   {
-      String phase = (String) getStateHelper().eval(PropertyKeys.phase);
-      if (phase != null)
-      {
-         phase = phase.toUpperCase();
-      }
-      return phase;
-   }
-
-   /**
-    * Set the name of the phase in which the action is to be queued.
-    */
-   public void setPhase(final String phase)
-   {
-      getStateHelper().put(PropertyKeys.phase, phase);
-   }
-
-   public PhaseId getPhaseId()
-   {
-      String phase = getPhase();
-      if (phase == null)
-      {
-         return null;
-      }
-      if ("APPLY_REQUEST_VALUES".equals(phase))
-      {
-         return PhaseId.APPLY_REQUEST_VALUES;
-      }
-      else if ("PROCESS_VALIDATIONS".equals(phase))
-      {
-         return PhaseId.PROCESS_VALIDATIONS;
-      }
-      else if ("UPDATE_MODEL_VALUES".equals(phase))
-      {
-         return PhaseId.UPDATE_MODEL_VALUES;
-      }
-      else if ("INVOKE_APPLICATION".equals(phase))
-      {
-         return PhaseId.INVOKE_APPLICATION;
-      }
-      else if ("ANY_PHASE".equals(phase) || "RESTORE_VIEW".equals(phase) || "RENDER_REPONSE".equals(phase))
-      {
-         throw new FacesException("View actions cannot be executed in specified phase: [" + phase + "]");
-      }
-      else
-      {
-         throw new FacesException("Not a valid phase [" + phase + "]");
-      }
-   }
-
-   /**
-    * Action listeners are not supported by the {@link UIViewAction} component.
-    * 
-    * @throws UnsupportedOperationException if called
-    */
-   public void addActionListener(final ActionListener listener)
-   {
-      throw new UnsupportedOperationException("Not supported.");
-   }
-
-   /**
-    * Action listeners are not supported by the {@link UIViewAction} component.
-    */
-   public ActionListener[] getActionListeners()
-   {
-      return new ActionListener[0];
-   }
-
-   /**
-    * Action listeners are not supported by the {@link UIViewAction} component.
-    * 
-    * @throws UnsupportedOperationException if called
-    */
-   public void removeActionListener(final ActionListener listener)
-   {
-      throw new UnsupportedOperationException("Not supported.");
-   }
-
-   /**
-    * Returns the action, represented as an EL method expression, to invoke.
-    */
-   public MethodExpression getActionExpression()
-   {
-      return (MethodExpression) getStateHelper().get(PropertyKeys.actionExpression);
-   }
-
-   /**
-    * Sets the action, represented as an EL method expression, to invoke.
-    */
-   public void setActionExpression(final MethodExpression actionExpression)
-   {
-      getStateHelper().put(PropertyKeys.actionExpression, actionExpression);
-   }
-
-   /**
-    * Returns a boolean value that controls whether the action is invoked during
-    * faces (postback) request. The default is false.
-    */
-   public boolean isOnPostback()
-   {
-      return (Boolean) getStateHelper().eval(PropertyKeys.onPostback, false);
-   }
-
-   /**
-    * Set the bookean flag that controls whether the action is invoked during a
-    * faces (postback) request.
-    */
-   public void setOnPostback(final boolean onPostback)
-   {
-      getStateHelper().put(PropertyKeys.onPostback, onPostback);
-   }
-
-   /**
-    * Returns a condition, represented as an EL value expression, that must
-    * evaluate to true for the action to be invoked.
-    */
-   public boolean isIf()
-   {
-      return (Boolean) getStateHelper().eval(PropertyKeys.ifAttr, true);
-   }
-
-   /**
-    * Sets the condition, represented as an EL value expression, that must
-    * evaluate to true for the action to be invoked.
-    */
-   public void setIf(final boolean condition)
-   {
-      getStateHelper().put(PropertyKeys.ifAttr, condition);
-   }
-
-   // ----------------------------------------------------- UIComponent Methods
-   /**
-    * <p>
-    * In addition to to the default {@link UIComponent#broadcast} processing,
-    * pass the {@link ActionEvent} being broadcast to the default
-    * {@link ActionListener} registered on the
-    * {@link javax.faces.application.Application}.
-    * </p>
-    * 
-    * @param event {@link FacesEvent} to be broadcast
-    * 
-    * @throws AbortProcessingException Signal the JavaServer Faces
-    *            implementation that no further processing on the current event
-    *            should be performed
-    * @throws IllegalArgumentException if the implementation class of this
-    *            {@link FacesEvent} is not supported by this component
-    * @throws NullPointerException if <code>event</code> is <code>null</code>
-    */
-   @Override
-   public void broadcast(final FacesEvent event) throws AbortProcessingException
-   {
-
-      super.broadcast(event);
-
-      FacesContext context = getFacesContext();
-
-      // OPEN QUESTION: should we consider a navigation to the same view as a
-      // no-op navigation?
-
-      // only proceed if the response has not been marked complete and
-      // navigation to another view has not occurred
-      if ((event instanceof ActionEvent) && !context.getResponseComplete() && (context.getViewRoot() == getViewRootOf(event)))
-      {
-         ActionListener listener = context.getApplication().getActionListener();
-         if (listener != null)
-         {
-            UIViewRoot viewRootBefore = context.getViewRoot();
-            InstrumentedFacesContext instrumentedContext = new InstrumentedFacesContext(context);
-            // defer the call to renderResponse() that happens in
-            // ActionListener#processAction(ActionEvent)
-            instrumentedContext.disableRenderResponseControl().set();
-            listener.processAction((ActionEvent) event);
-            instrumentedContext.restore();
-            // if the response is marked complete, the story is over
-            if (!context.getResponseComplete())
-            {
-               UIViewRoot viewRootAfter = context.getViewRoot();
-               // if the view id changed as a result of navigation, then execute
-               // the JSF lifecycle for the new view id
-               if (viewRootBefore != viewRootAfter)
-               {
-                  /*
-                   * // execute the JSF lifecycle by dispatching a forward
-                   * request // this approach is problematic because it throws a
-                   * wrench in the event broadcasting try {
-                   * context.getExternalContext
-                   * ().dispatch(context.getApplication()
-                   * .getViewHandler().getActionURL(context,
-                   * viewRootAfter.getViewId())
-                   * .substring(context.getExternalContext
-                   * ().getRequestContextPath().length())); // kill this
-                   * lifecycle execution context.responseComplete(); } catch
-                   * (IOException e) { throw new
-                   * FacesException("Dispatch to viewId failed: " +
-                   * viewRootAfter.getViewId(), e); }
-                   */
-
-                  // manually execute the JSF lifecycle on the new view id
-                  // certain tweaks have to be made to the FacesContext to allow
-                  // us to reset the lifecycle
-                  Lifecycle lifecycle = getLifecycle(context);
-                  instrumentedContext = new InstrumentedFacesContext(context);
-                  instrumentedContext.pushViewIntoRequestMap().clearViewRoot().clearPostback().set();
-                  lifecycle.execute(instrumentedContext);
-                  instrumentedContext.restore();
-
-                  /*
-                   * Another approach would be to register a phase listener in
-                   * the decode() method for the phase in which the action is
-                   * set to invoke. The phase listener would performs a servlet
-                   * forward if a non-redirect navigation occurs after the
-                   * phase.
-                   */
-               }
-               else
-               {
-                  // apply the deferred call (relevant when immediate is true)
-                  context.renderResponse();
-               }
-            }
-         }
-      }
-   }
-
-   /**
-    * First, determine if the action should be invoked by evaluating this
-    * components pre-conditions. If this is a faces (postback) request and the
-    * evaluated value of the postback attribute is false, take no action. If the
-    * evaluated value of the if attribute is false, take no action. If both
-    * conditions pass, proceed with creating an {@link ActionEvent}.
-    * 
-    * Set the phaseId in which the queued {@link ActionEvent} should be
-    * broadcast by assigning the appropriate value to the phaseId property of
-    * the {@link ActionEvent} according to the evaluated value of the immediate
-    * attribute. If the value is <literal>true</literal>, set the phaseId to
-    * {@link PhaseId#APPLY_REQUEST_VALUES}. Otherwise, set the phaseId to to
-    * {@link PhaseId#INVOKE_APPLICATION}.
-    * 
-    * Finally, queue the event by calling <literal>queueEvent()</literal> and
-    * passing the {@link ActionEvent} just created.
-    */
-   @Override
-   public void decode(final FacesContext context)
-   {
-      if (context == null)
-      {
-         throw new NullPointerException();
-      }
-
-      if ((context.isPostback() && !isOnPostback()) || !isIf())
-      {
-         return;
-      }
-
-      ActionEvent e = new ActionEvent(this);
-      PhaseId phaseId = getPhaseId();
-      if (phaseId != null)
-      {
-         e.setPhaseId(phaseId);
-      }
-      else if (isImmediate())
-      {
-         e.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
-      }
-      else
-      {
-         e.setPhaseId(PhaseId.INVOKE_APPLICATION);
-      }
-
-      queueEvent(e);
-   }
-
-   private UIViewRoot getViewRootOf(final FacesEvent e)
-   {
-      UIComponent c = e.getComponent();
-      do
-      {
-         if (c instanceof UIViewRoot)
-         {
-            return (UIViewRoot) c;
-         }
-         c = c.getParent();
-      }
-      while (c != null);
-      return null;
-   }
-
-   private Lifecycle getLifecycle(final FacesContext context)
-   {
-      LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
-      String lifecycleId = context.getExternalContext().getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR);
-      if (lifecycleId == null)
-      {
-         lifecycleId = LifecycleFactory.DEFAULT_LIFECYCLE;
-      }
-      return lifecycleFactory.getLifecycle(lifecycleId);
-   }
-
-   /**
-    * A FacesContext delegator that gives us the necessary controls over the
-    * FacesContext to allow the execution of the lifecycle to accomodate the
-    * UIViewAction sequence.
-    */
-   private class InstrumentedFacesContext extends FacesContextWrapper
-   {
-
-      private final FacesContext wrapped;
-      private boolean viewRootCleared = false;
-      private boolean renderedResponseControlDisabled = false;
-      private Boolean postback = null;
-
-      public InstrumentedFacesContext(final FacesContext wrapped)
-      {
-         this.wrapped = wrapped;
-      }
-
-      @Override
-      public FacesContext getWrapped()
-      {
-         return wrapped;
-      }
-
-      @Override
-      public UIViewRoot getViewRoot()
-      {
-         if (viewRootCleared)
-         {
-            return null;
-         }
-
-         return wrapped.getViewRoot();
-      }
-
-      @Override
-      public void setViewRoot(final UIViewRoot viewRoot)
-      {
-         viewRootCleared = false;
-         wrapped.setViewRoot(viewRoot);
-      }
-
-      @Override
-      public boolean isPostback()
-      {
-         return postback == null ? wrapped.isPostback() : postback;
-      }
-
-      @Override
-      public void renderResponse()
-      {
-         if (!renderedResponseControlDisabled)
-         {
-            wrapped.renderResponse();
-         }
-      }
-
-      /**
-       * Make it look like we have dispatched a request using the include
-       * method.
-       */
-      public InstrumentedFacesContext pushViewIntoRequestMap()
-      {
-         getExternalContext().getRequestMap().put("javax.servlet.include.servlet_path", wrapped.getViewRoot().getViewId());
-         return this;
-      }
-
-      public InstrumentedFacesContext clearPostback()
-      {
-         postback = false;
-         return this;
-      }
-
-      public InstrumentedFacesContext clearViewRoot()
-      {
-         viewRootCleared = true;
-         return this;
-      }
-
-      public InstrumentedFacesContext disableRenderResponseControl()
-      {
-         renderedResponseControlDisabled = true;
-         return this;
-      }
-
-      public void set()
-      {
-         setCurrentInstance(this);
-      }
-
-      public void restore()
-      {
-         setCurrentInstance(wrapped);
-      }
-   }
-}

Modified: modules/faces/trunk/pom.xml
===================================================================
--- modules/faces/trunk/pom.xml	2010-05-28 20:39:48 UTC (rev 12895)
+++ modules/faces/trunk/pom.xml	2010-05-28 23:06:51 UTC (rev 12896)
@@ -102,6 +102,11 @@
          <scope>provided</scope>
       </dependency>
       <dependency>
+         <groupId>javax.validation</groupId>
+         <artifactId>validation-api</artifactId>
+         <scope>provided</scope>
+      </dependency>
+      <dependency>
          <groupId>org.jboss.weld</groupId>
          <artifactId>weld-extensions</artifactId>
          <version>${weldx.version}</version>



More information about the seam-commits mailing list