[seam-commits] Seam SVN: r9233 - in trunk: examples/ui/src/org/jboss/seam/example/ui and 3 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Wed Oct 8 15:37:16 EDT 2008


Author: danielc.roth
Date: 2008-10-08 15:37:15 -0400 (Wed, 08 Oct 2008)
New Revision: 9233

Added:
   trunk/examples/ui/src/org/jboss/seam/example/ui/EqualityValidatorBean.java
   trunk/examples/ui/view/equalityValidator.xhtml
   trunk/ui/src/main/config/component/equalityValidator.xml
   trunk/ui/src/main/java/org/jboss/seam/ui/validator/EqualityValidator.java
Modified:
   trunk/doc/Seam_Reference_Guide/en-US/Controls.xml
   trunk/examples/ui/view/template.xhtml
Log:
JBSEAM-2809 
EqualityValidator + example + docs

Modified: trunk/doc/Seam_Reference_Guide/en-US/Controls.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Controls.xml	2008-10-08 18:43:43 UTC (rev 9232)
+++ trunk/doc/Seam_Reference_Guide/en-US/Controls.xml	2008-10-08 19:37:15 UTC (rev 9233)
@@ -474,7 +474,47 @@
 </h:outputText>]]></programlisting>
          </section>
          
+		 
          <section>
+            <title><literal>&lt;s:equalityValidator&gt;</literal></title>
+            
+            <para><emphasis>Description</emphasis></para>
+            <para>
+				Tag to nest inside an input control to validate that its parent's
+				value is the same as the referenced control's id.
+            </para>
+            
+            <para><emphasis>Attributes</emphasis></para>
+            <itemizedlist>
+               <listitem>
+                  <para>
+                     <literal>for</literal> &#8212; The id of a control to validate against.
+                  </para>
+               </listitem>
+               <listitem>
+                  <para>
+                     <literal>message</literal> &#8212; Message to show on failure.
+                  </para>
+               </listitem>
+               <listitem>
+                  <para>
+                     <literal>messageId</literal> &#8212; Message id to show on failure.
+                  </para>
+               </listitem>
+            </itemizedlist>
+            
+            <para><emphasis>Usage</emphasis></para>
+            <programlisting><![CDATA[<h:inputText id="name" value="#{bean.name}"/>
+<h:inputText id="nameVerification" >
+   <s:validateEquality for="name" />
+</h:inputText>]]></programlisting>
+         </section>		 
+		 
+		 
+
+		 
+		 
+         <section>
             <title><literal>&lt;s:validate&gt;</literal></title>
           
             <para><emphasis>Description</emphasis></para>
@@ -933,6 +973,7 @@
           
          </section>
 
+		 
          <section>
             <title><literal>&lt;s:fileUpload&gt;</literal></title>
 

Added: trunk/examples/ui/src/org/jboss/seam/example/ui/EqualityValidatorBean.java
===================================================================
--- trunk/examples/ui/src/org/jboss/seam/example/ui/EqualityValidatorBean.java	                        (rev 0)
+++ trunk/examples/ui/src/org/jboss/seam/example/ui/EqualityValidatorBean.java	2008-10-08 19:37:15 UTC (rev 9233)
@@ -0,0 +1,59 @@
+package org.jboss.seam.example.ui;
+
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.international.StatusMessages;
+import org.jboss.seam.international.StatusMessage.Severity;
+import org.jboss.seam.util.Strings;
+
+ at Name("equalityValidatorBean")
+ at Scope(ScopeType.SESSION)
+public class EqualityValidatorBean
+{
+   
+   private String name;
+   
+   private String nameVerification;
+   
+   @In
+   private StatusMessages statusMessages;
+   
+   public String getName()
+   {
+      return name;
+   }
+   
+   public void setName(String name)
+   {
+      this.name = name;
+   }
+   
+   public String getNameVerification()
+   {
+      return nameVerification;
+   }
+
+   public void setNameVerification(String nameVerification)
+   {
+      this.nameVerification = nameVerification;
+   }
+   
+   public void check()
+   {
+      if (Strings.isEmpty(name))
+      {
+         statusMessages.addToControl("name", Severity.WARN, "Enter a name!");
+      }
+      if (Strings.isEmpty(nameVerification))
+      {
+         statusMessages.addToControl("nameVerification", Severity.WARN, "Enter a name verification!");
+      }
+      if (name != null && nameVerification != null && !name.equals(nameVerification))
+      {
+         statusMessages.addToControl("nameVerification", Severity.WARN, "Name and Name Verification not equal (should have been caught by equality validator!)");
+      }
+   }
+   
+}

Added: trunk/examples/ui/view/equalityValidator.xhtml
===================================================================
--- trunk/examples/ui/view/equalityValidator.xhtml	                        (rev 0)
+++ trunk/examples/ui/view/equalityValidator.xhtml	2008-10-08 19:37:15 UTC (rev 9233)
@@ -0,0 +1,25 @@
+<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<ui:composition xmlns="http://www.w3.org/1999/xhtml"
+	xmlns:ui="http://java.sun.com/jsf/facelets"
+	xmlns:f="http://java.sun.com/jsf/core"
+	xmlns:h="http://java.sun.com/jsf/html"
+	xmlns:s="http://jboss.com/products/seam/taglib"
+	template="template.xhtml">
+	<ui:param name="tagName" value="s:validateEquality" />
+	<ui:define name="body">
+		<p>Validates that two inputs are equal</p>
+		<h:form>
+			<h:panelGrid columns="3">
+				<s:label for="name">Name</s:label>
+				<h:inputText id="name" value="#{equalityValidatorBean.name}" />
+				<h:message for="name" />
+				<s:label for="nameVerification">Name Verification</s:label>
+				<h:inputText id="nameVerification" value="#{equalityValidatorBean.nameVerification}">
+					<s:validateEquality for="name" />
+				</h:inputText>
+				<h:message for="nameVerification" />
+				<h:commandButton action="#{equalityValidatorBean.check}" value="Check name" />
+			</h:panelGrid>
+		</h:form>
+	</ui:define>
+</ui:composition>

Modified: trunk/examples/ui/view/template.xhtml
===================================================================
--- trunk/examples/ui/view/template.xhtml	2008-10-08 18:43:43 UTC (rev 9232)
+++ trunk/examples/ui/view/template.xhtml	2008-10-08 19:37:15 UTC (rev 9233)
@@ -97,6 +97,11 @@
 			<code>s:graphicImage</code>
 			<f:param name="personId" value="1" />
 		</s:link></li>
+		
+		<li><s:link view="/equalityValidator.xhtml">
+			<code>s:equalityValidator</code>
+		</s:link></li>
+	
 	</ul>
 </s:div>
 <s:div styleClass="content">

Added: trunk/ui/src/main/config/component/equalityValidator.xml
===================================================================
--- trunk/ui/src/main/config/component/equalityValidator.xml	                        (rev 0)
+++ trunk/ui/src/main/config/component/equalityValidator.xml	2008-10-08 19:37:15 UTC (rev 9233)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN"  "http://jboss.org/jbossrichfaces/component-config.dtd" >
+<components>
+	<validator generate="false">
+		<id>org.jboss.seam.ui.EqualityValidator</id>
+		<classname>org.jboss.seam.ui.validator.EqualityValidator</classname>
+		<description>
+			<![CDATA[Validate that the value of two components are equal]]>
+		</description>
+		<tag>
+			<name>validateEquality</name>
+			<classname>org.jboss.seam.ui.taglib.ModelValidatorTag</classname>
+			<superclass>javax.faces.webapp.ValidatorELTag</superclass>
+		</tag>
+	</validator>
+</components>

Added: trunk/ui/src/main/java/org/jboss/seam/ui/validator/EqualityValidator.java
===================================================================
--- trunk/ui/src/main/java/org/jboss/seam/ui/validator/EqualityValidator.java	                        (rev 0)
+++ trunk/ui/src/main/java/org/jboss/seam/ui/validator/EqualityValidator.java	2008-10-08 19:37:15 UTC (rev 9233)
@@ -0,0 +1,295 @@
+package org.jboss.seam.ui.validator;
+
+import javax.el.ELException;
+import javax.el.ValueExpression;
+import javax.faces.FacesException;
+import javax.faces.application.Application;
+import javax.faces.component.EditableValueHolder;
+import javax.faces.component.StateHolder;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+import javax.faces.convert.ConverterException;
+import javax.faces.render.Renderer;
+import javax.faces.validator.Validator;
+import javax.faces.validator.ValidatorException;
+
+import org.jboss.seam.faces.FacesMessages;
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
+
+/**
+ * Validate two fields are equal
+ * 
+ * @author pmuir
+ *
+ */
+public class EqualityValidator implements Validator, StateHolder
+{
+   
+   private static LogProvider log = Logging.getLogProvider(EqualityValidator.class);
+   
+   public static final String MESSAGE_ID = "org.jboss.seam.ui.validator.NOT_EQUAL";
+   
+   public static final String VALIDATOR_ID = "org.jboss.seam.ui.validator.Equality";
+
+   private String forId;
+   
+   private String message;
+   private String messageId;
+   
+   public EqualityValidator() 
+   {
+      this.message = "Value does not equal that in #0";
+      this.messageId = MESSAGE_ID;
+   }
+   
+   public EqualityValidator(String forId)
+   {
+      this();
+      setFor(forId);
+   }
+   
+   public EqualityValidator(String forId, String message, String messageId)
+   {
+      this(forId);
+      if (message != null)
+      {
+         setMessage(message);
+      }
+      if (messageId != null)
+      {
+         setMessageId(messageId);
+      }
+   }
+   
+   public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException
+   {
+      if (!(component instanceof EditableValueHolder))
+      {
+         throw new FacesException("Must attach an equality validator to an input component");
+      }
+      String forId = getFor();
+      if (forId == null)
+      {
+         throw new FacesException("Must specify a component to validate equality against");
+      }
+      UIComponent otherComponent = component.findComponent(forId);
+      Object other = new OtherComponent(context, otherComponent).getValue();
+      if (value == null && other == null)
+      {
+         // Thats fine
+      }
+      else if (value != null)
+      {
+         if (!value.equals(other))
+         {
+            String otherComponentId = otherComponent.getId();
+            throw new ValidatorException(FacesMessages.createFacesMessage(javax.faces.application.FacesMessage.SEVERITY_ERROR, getMessageId(), getMessage(), otherComponentId, value, other));
+         }
+      }
+   }
+   
+   public String getFor()
+   {
+      return forId;
+   } 
+   
+   public void setFor(String forId)
+   {
+      this.forId = forId;
+   }
+   
+   public String getMessage()
+   {
+      return message;
+   }
+   
+   public void setMessage(String message)
+   {
+      this.message = message;
+   }
+   
+   public String getMessageId()
+   {
+      return messageId;
+   }
+   
+   public void setMessageId(String messageId)
+   {
+      this.messageId = messageId;
+   }
+
+   public boolean isTransient()
+   {
+      return false;
+   }
+
+   public void restoreState(FacesContext context, Object state)
+   {
+      Object[] fields = (Object []) state;
+      forId = (String) fields[0];
+      message = (String) fields[1];
+      messageId = (String) fields[2];
+   }
+
+   public Object saveState(FacesContext context)
+   {
+      Object[] state = new Object[3];
+      state[0] = forId;
+      state[1] = message;
+      state[2] = messageId;
+      return state;
+   }
+
+   public void setTransient(boolean newTransientValue)
+   {
+      // No-op
+   }
+
+   
+   /**
+    * Simple data strcuture to hold info on the "other" component
+    * @author pmuir
+    *
+    */
+   private class OtherComponent 
+   {
+      
+      private FacesContext context;
+      private UIComponent component;
+      private EditableValueHolder editableValueHolder;
+      
+      private Renderer renderer;
+      private Converter converter;
+      
+      public OtherComponent(FacesContext facesContext, UIComponent component)
+      {
+         this.component = component;
+         this.context = facesContext;
+         if (!(component instanceof EditableValueHolder))
+         {
+            throw new IllegalStateException("forId must reference an EditableValueHolder (\"input\") component");
+         }
+         editableValueHolder = (EditableValueHolder) component;
+         initRenderer();
+         initConverter();
+      }
+      
+      private void initRenderer() 
+      {
+         if (renderer == null)
+         {
+            String rendererType = component.getRendererType();
+            if (rendererType != null) 
+            {
+               renderer = context.getRenderKit().getRenderer(component.getFamily(), rendererType);
+               if (null == renderer) 
+               {
+                  log.trace("Can't get Renderer for type " + rendererType);
+               }
+            } 
+            else
+            {
+               if (log.isTraceEnabled()) 
+               {
+                  String id = component.getId();
+                  id = (null != id) ? id : component.getClass().getName();
+                  log.trace("No renderer-type for component " + id);
+               }
+            }
+         }
+      }
+      
+      private void initConverter() {
+         converter = editableValueHolder.getConverter();
+         if (converter != null) {
+             return;
+         }
+
+         ValueExpression valueExpression = component.getValueExpression("value");
+         if (valueExpression == null) {
+             return;
+         }
+
+         Class converterType;
+         try {
+             converterType = valueExpression.getType(context.getELContext());
+         }
+         catch (ELException e) {
+             throw new FacesException(e);
+         }
+
+         // if converterType is null, String, or Object, assume
+         // no conversion is needed
+         if (converterType == null || converterType == String.class || converterType == Object.class) 
+         {
+             return;
+         }
+
+         // if getType returns a type for which we support a default
+         // conversion, acquire an appropriate converter instance.
+         try 
+         {
+             Application application = context.getApplication();
+             converter = application.createConverter(converterType);
+         }
+         catch (Exception e) 
+         {
+            throw new FacesException(e);
+         }
+      }
+      
+      private Object getConvertedValue(Object newSubmittedValue) throws ConverterException 
+      {
+         
+         Object newValue;
+
+         if (renderer != null) 
+         {
+            newValue = renderer.getConvertedValue(context, component, newSubmittedValue);
+         } 
+         else if (newSubmittedValue instanceof String) 
+         {
+            // If there's no Renderer, and we've got a String, run it through the Converter (if any)
+            if (converter != null) {
+               newValue = converter.getAsObject(context, component,
+                     (String) newSubmittedValue);
+            } 
+            else
+            {
+               newValue = newSubmittedValue;
+            }
+         } 
+         else 
+         {
+            newValue = newSubmittedValue;
+         }
+         return newValue;
+      }
+      
+      public Object getValue()
+      {
+         Object submittedValue = editableValueHolder.getLocalValue();
+         if (submittedValue == null) 
+         {
+            return null;
+         }
+
+         Object newValue = null;
+
+         try 
+         {
+            newValue = getConvertedValue(submittedValue);
+         }
+         catch (ConverterException ce) 
+         {
+            // Any errors will be attached by JSF
+            return null;
+         }
+
+         return newValue;
+      }
+      
+   }
+}




More information about the seam-commits mailing list