You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by gv...@apache.org on 2006/04/06 04:46:37 UTC

svn commit: r391884 - in /struts/shale/trunk/core-library/src: conf/ java/org/apache/shale/component/ java/org/apache/shale/faces/ java/org/apache/shale/renderer/ java/org/apache/shale/view/faces/

Author: gvanmatre
Date: Wed Apr  5 19:46:34 2006
New Revision: 391884

URL: http://svn.apache.org/viewcvs?rev=391884&view=rev
Log:
Fix for bugs 37932, 39171 and 39156 reported by Mark Shifman and Paul Devine.

Added:
    struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ValidatorRenderKit.java   (with props)
    struts/shale/trunk/core-library/src/java/org/apache/shale/renderer/ValidatorCommandRenderer.java   (with props)
    struts/shale/trunk/core-library/src/java/org/apache/shale/renderer/ValidatorInputRenderer.java   (with props)
Modified:
    struts/shale/trunk/core-library/src/conf/validator-rules.xml
    struts/shale/trunk/core-library/src/java/org/apache/shale/component/ValidatorScript.java
    struts/shale/trunk/core-library/src/java/org/apache/shale/view/faces/ViewViewHandler.java

Modified: struts/shale/trunk/core-library/src/conf/validator-rules.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/conf/validator-rules.xml?rev=391884&r1=391883&r2=391884&view=diff
==============================================================================
--- struts/shale/trunk/core-library/src/conf/validator-rules.xml (original)
+++ struts/shale/trunk/core-library/src/conf/validator-rules.xml Wed Apr  5 19:46:34 2006
@@ -419,7 +419,7 @@
       <validator name="float"
             classname="org.apache.commons.validator.GenericValidator"
                method="isDouble"
-         methodParams="double"
+         methodParams="java.lang.String"
               depends=""
                   msg="errors.float"
        jsFunctionName="FloatValidations">

Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/component/ValidatorScript.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/component/ValidatorScript.java?rev=391884&r1=391883&r2=391884&view=diff
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/component/ValidatorScript.java (original)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/component/ValidatorScript.java Wed Apr  5 19:46:34 2006
@@ -21,6 +21,7 @@
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.StringTokenizer;
 
 import javax.faces.component.EditableValueHolder;
@@ -31,6 +32,7 @@
 import javax.faces.el.ValueBinding;
 
 import org.apache.commons.validator.ValidatorAction;
+import org.apache.shale.renderer.ValidatorInputRenderer;
 import org.apache.shale.validator.CommonsValidator;
 
 /**
@@ -147,11 +149,11 @@
 
     /**
      * <p>Recursively finds all Commons validators for the all of the
-	  *    components in a component hierarchy and adds them to a map. 
+	  *    components in a component hierarchy and adds them to a map.</p> 
 	  * <p>If a validator's type is required, this method sets the 
 	  *    associated component's required property to true. This is 
 	  *    necessary because JSF does not validate empty fields unless 
-	  *    a component's required property is true.
+	  *    a component's required property is true.</p>
      *
      * @param c The component at the root of the component tree
      * @param context The FacesContext for this request
@@ -164,16 +166,39 @@
             if (vs[i] instanceof CommonsValidator) {
                CommonsValidator v = (CommonsValidator) vs[i];
                if (Boolean.TRUE.equals(v.getClient())) {
-                  String id = c.getClientId(context);
-                  addValidator(v.getType(), id, v);
-
-                  ValidatorAction action = v.getValidatorAction();
-                  List list = action.getDependencyList();
-                  Iterator iter = list.iterator();
-                  while (iter.hasNext()) {
-                     String type = (String) iter.next();
-                     addValidator(type, id, v);
-                  }
+                   
+                   //look for the clientId set 
+                   Set clientIds = (Set) c.getAttributes().get(ValidatorInputRenderer.VALIDATOR_CLIENTIDS_ATTR);
+                   if (clientIds != null) {
+                      Iterator ci = clientIds.iterator();
+                      while (ci.hasNext()) {
+                         String id = (String) ci.next();
+                         addValidator(v.getType(), id, v);
+                         
+                         ValidatorAction action = v.getValidatorAction();
+                         List list = action.getDependencyList();
+                         Iterator iter = list.iterator();
+                         while (iter.hasNext()) {
+                             String type = (String) iter.next();
+                             addValidator(type, id, v);
+                         }
+                       
+                      }
+                       
+                   } else {
+                       //otherwise just try using the client id
+                       String id = c.getClientId(context);
+                       addValidator(v.getType(), id, v);
+                       
+                       ValidatorAction action = v.getValidatorAction();
+                       List list = action.getDependencyList();
+                       Iterator iter = list.iterator();
+                       while (iter.hasNext()) {
+                           String type = (String) iter.next();
+                           addValidator(type, id, v);
+                       }
+                   }
+             
                }
                if (Boolean.TRUE.equals(v.getServer())) {
                   // Fields with empty values are not validated, so

Added: struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ValidatorRenderKit.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ValidatorRenderKit.java?rev=391884&view=auto
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ValidatorRenderKit.java (added)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ValidatorRenderKit.java Wed Apr  5 19:46:34 2006
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.shale.faces;
+
+import java.io.OutputStream;
+import java.io.Writer;
+
+import javax.faces.context.ResponseStream;
+import javax.faces.context.ResponseWriter;
+import javax.faces.render.RenderKit;
+import javax.faces.render.Renderer;
+import javax.faces.render.ResponseStateManager;
+
+import org.apache.shale.renderer.ValidatorCommandRenderer;
+import org.apache.shale.renderer.ValidatorInputRenderer;
+
+/**
+ * <p>Decorates the original <code>RenderKit</code> passed by the
+ * overloaded constructor in the {@link org.apache.shale.view.faces.ViewViewHandler}.
+ * The majority of the implementation is passed on the the original 
+ * <code>RenderKit</code> but requests for renderers registered with the 
+ * "javax.faces.Command" and "javax.faces.Input" families are decorated.
+ * The wrapper adds special behavior for the 
+ * {@link org.apache.shale.validator.CommonsValidator} validator and
+ * {@link org.apache.shale.component.ValidatorScript} component.</p>
+ */
+public class ValidatorRenderKit extends RenderKit {
+
+    private static String COMMAND_FAMILY = "javax.faces.Command";
+    private static String INPUT_FAMILY = "javax.faces.Input";
+    
+    
+    /**
+     * <p>The original RenderKit.</p>
+     */
+    private RenderKit defaultRenderKit = null;
+    /**
+     * <p>This constructor is overloaded to pass the original
+     * <code>RenderKit</p>.
+     */
+    public ValidatorRenderKit(RenderKit defaultRenderKit) {
+       this.defaultRenderKit = defaultRenderKit;    
+    }
+    
+    // Specified by default RenderKit
+    public void addRenderer(String componentFamily, String rendererType, Renderer renderer) {
+       this.defaultRenderKit.addRenderer(componentFamily, rendererType, renderer);   
+    }
+
+    /**
+     * <p>If the component family is not "javax.faces.Command" or
+     * "javax.faces.Input", the <code>defaultRenderKit</code> handles the 
+     * request.  If the family is "javax.faces.Command", the default
+     * renderer is decorated with {@link org.apache.shale.renderer.ValidatorCommandRenderer}.
+     * If the component family is "javax.faces.Input", the default 
+     * renderer is decorated with {@link org.apache.shale.renderer.ValidatorInputRenderer}.
+     */
+    public Renderer getRenderer(String componentFamily, String rendererType) {
+        Renderer target = defaultRenderKit.getRenderer(componentFamily, rendererType);
+        if (componentFamily.equals(COMMAND_FAMILY)) {
+           if (!(target instanceof ValidatorCommandRenderer)) {
+               target = new ValidatorCommandRenderer(target);
+               addRenderer(componentFamily, rendererType, target);
+           }
+        } else if (componentFamily.equals(INPUT_FAMILY)) {
+            if (!(target instanceof ValidatorInputRenderer)) {
+                target = new ValidatorInputRenderer(target);
+                addRenderer(componentFamily, rendererType, target);
+            }
+         }
+        
+        return target;
+    }
+
+    // Specified by default RenderKit
+    public ResponseStateManager getResponseStateManager() {
+        return defaultRenderKit.getResponseStateManager();
+    }
+
+    // Specified by default RenderKit
+    public ResponseWriter createResponseWriter(Writer writer,
+            String contentTypeList,
+            String characterEncoding){
+        return defaultRenderKit.createResponseWriter(writer, contentTypeList, characterEncoding);
+    }
+
+    // Specified by default RenderKit
+    public ResponseStream createResponseStream(OutputStream outputStream) {
+        return defaultRenderKit.createResponseStream(outputStream);
+    }
+
+}

Propchange: struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ValidatorRenderKit.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ValidatorRenderKit.java
------------------------------------------------------------------------------
    svn:keywords = date author id rev

Added: struts/shale/trunk/core-library/src/java/org/apache/shale/renderer/ValidatorCommandRenderer.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/renderer/ValidatorCommandRenderer.java?rev=391884&view=auto
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/renderer/ValidatorCommandRenderer.java (added)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/renderer/ValidatorCommandRenderer.java Wed Apr  5 19:46:34 2006
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.shale.renderer;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import javax.faces.component.UICommand;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.convert.ConverterException;
+import javax.faces.render.Renderer;
+
+/**
+ * This renderer is a hybrid renderer decorator that is dynamically 
+ * registered by the {@link org.apache.shale.faces.ValidatorRenderKit} 
+ * for component renderers in the "javax.faces.Command" family.</p>
+ */
+public class ValidatorCommandRenderer extends Renderer {
+
+    /**
+     * <p>The Original Renderer.</p>
+     */
+    private Renderer defaultRenderer = null;
+    
+    /**
+     * <p>The overloaded constructor is passed the original
+     * <code>Renderer</code> for the family and component type.</p>
+     */
+    public ValidatorCommandRenderer(Renderer defaultRenderer) {
+       this.defaultRenderer = defaultRenderer;    
+    }
+    
+     
+    /**
+     * <p>Attribute name used to override the default behavior of how the immediate
+     * attribute effects the execution of client side javascript validation.</p>
+     */
+    public static final String OVERRIDE_IMMEDIATE = "org.apache.shale.validator.immediate";
+
+    private static final int ENCODE_BEGIN = 0;
+
+    private static final int ENCODE_CHILDREN = 1;
+
+    private static final int ENCODE_END = 2;
+
+    /**
+     * <b>Interrogates the component's immediate property and the component's
+     * immediate override attribute to determine if client side validation is
+     * invoked. If either the property or attribute override is false, client
+     * side validation is invoked. Otherwise, the response writer is hijacked
+     * and the original render is invoked. The result is buffered and a
+     * statement of javascript is injected into the onclick event which cancels
+     * client side validation. The original response writer is restored and the
+     * modified markup is written to the response writer. The
+     * <code>encodeSwitch</code> determines if the encodeBegin, encodeChildren
+     * or encodeEnd methods should be invoked on the decorated renderer.</b>
+     */
+    protected void encode(FacesContext context, UIComponent component,
+            int encodeSwitch) throws IOException {
+
+        UICommand command = (UICommand) component;
+
+        // look for a override to the default
+        boolean immediateOverride = true;
+        String attr = (String) component.getAttributes()
+                .get(OVERRIDE_IMMEDIATE);
+        if (attr != null) {
+            immediateOverride = Boolean.valueOf(attr).booleanValue();
+        }
+
+        if (command.isImmediate() && immediateOverride) {
+
+            ResponseWriter hijackedWriter = context.getResponseWriter();
+            // builds a buffer to write the page to
+            StringWriter writer = new StringWriter();
+            // create a buffered response writer
+            ResponseWriter buffResponsewriter = context.getRenderKit()
+                    .createResponseWriter(writer, null,
+                            hijackedWriter.getCharacterEncoding());
+            // push buffered writer to the faces context
+            context.setResponseWriter(buffResponsewriter);
+
+            if (encodeSwitch == ENCODE_BEGIN)
+                defaultRenderer.encodeBegin(context, component);
+            else if (encodeSwitch == ENCODE_CHILDREN)
+                defaultRenderer.encodeChildren(context, component);
+            else
+                defaultRenderer.encodeEnd(context, component);
+
+            buffResponsewriter.write(' ');
+            buffResponsewriter.flush();
+            buffResponsewriter.close();
+            writer.flush();
+            writer.close();
+            StringBuffer buff = writer.getBuffer();
+            int i = buff.indexOf("onclick=\"");
+            if (i > 0) {
+                buff.insert(i + "onclick=\"".length(), "bCancel=true;");
+            }
+
+            hijackedWriter.write(buff.toString());
+            context.setResponseWriter(hijackedWriter);
+
+        } else {
+            if (encodeSwitch == ENCODE_BEGIN)
+                defaultRenderer.encodeBegin(context, component);
+            else if (encodeSwitch == ENCODE_CHILDREN)
+                defaultRenderer.encodeChildren(context, component);
+            else
+                defaultRenderer.encodeEnd(context, component);
+        }
+    }
+
+    // Specified by original Renderer
+    public String convertClientId(FacesContext context, String id) {
+        return defaultRenderer.convertClientId(context, id);
+    }
+
+
+    // Specified by original Renderer
+    public Object getConvertedValue(FacesContext context, UIComponent component, Object o) throws ConverterException {
+        return defaultRenderer.getConvertedValue(context, component, o);
+    }
+
+    // Specified by original Renderer
+    public void decode(FacesContext context, UIComponent component) {
+        defaultRenderer.decode(context, component);
+    }
+
+    /**
+     * <p>
+     * Invokes the <code>encode</code> method passing
+     * <code>ENCODE_BEGIN</code> for the encodeSwitch parameter.
+     * </p>
+     */
+    public void encodeBegin(FacesContext context, UIComponent component)
+            throws IOException {
+        encode(context, component, ENCODE_BEGIN);
+    }
+
+    /**
+     * <p>Invokes the <code>encode</code> method passing
+     * <code>ENCODE_CHILDREN</code> for the encodeSwitch parameter.</p>
+     */
+    public void encodeChildren(FacesContext context, UIComponent component)
+            throws IOException {
+        encode(context, component, ENCODE_CHILDREN);
+    }
+
+    /**
+     * <p>Invokes the <code>encode</code> method passing <code>ENCODE_END</code>
+     * for the encodeSwitch parameter.</p>
+     */
+    public void encodeEnd(FacesContext context, UIComponent component)
+            throws IOException {
+        encode(context, component, ENCODE_END);
+    }
+
+    // Specified by original Renderer
+    public boolean getRendersChildren() {
+        return defaultRenderer.getRendersChildren();
+    }
+
+}

Propchange: struts/shale/trunk/core-library/src/java/org/apache/shale/renderer/ValidatorCommandRenderer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: struts/shale/trunk/core-library/src/java/org/apache/shale/renderer/ValidatorCommandRenderer.java
------------------------------------------------------------------------------
    svn:keywords = date author id rev

Added: struts/shale/trunk/core-library/src/java/org/apache/shale/renderer/ValidatorInputRenderer.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/renderer/ValidatorInputRenderer.java?rev=391884&view=auto
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/renderer/ValidatorInputRenderer.java (added)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/renderer/ValidatorInputRenderer.java Wed Apr  5 19:46:34 2006
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.shale.renderer;
+
+import java.io.IOException;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.ConverterException;
+import javax.faces.render.Renderer;
+
+/**
+ * This renderer is a hybrid renderer decorator that is dynamically 
+ * registered by the {@link org.apache.shale.faces.ValidatorRenderKit} 
+ * for component renderers in the "javax.faces.Input" family.</p>
+ */
+public class ValidatorInputRenderer extends Renderer {
+
+    private Renderer defaultRenderer = null;
+    
+    /**
+     * <p>This constant is the name of a reserved attribute that will hold
+     * a <code>Set</code> of clientId's for the component.</p>
+     */
+    public static final String VALIDATOR_CLIENTIDS_ATTR = "org.apache.shale.validator.clientIdSet";
+        
+    /**
+     * <p>Overloaded constructor is passed the original 
+     * <code>Renderer</code>.</p>
+     */
+    public ValidatorInputRenderer(Renderer defaultRenderer) {
+       this.defaultRenderer = defaultRenderer;    
+    }
+    
+    // Specified by original Renderer
+    public String convertClientId(FacesContext context, String id) {
+        return defaultRenderer.convertClientId(context, id);
+    }
+    
+    // Specified by original Renderer
+    public void decode(FacesContext context, UIComponent component) {
+        defaultRenderer.decode(context, component);
+    }
+    
+
+    /**
+     * <p>This override captures the clientId of the target component before 
+     * passing on to the original renderer.  The clientId is added to a Set 
+     * that is used by the {@link org.apache.shale.component.ValidatorScript} 
+     * component for adding client side JavaScript validation.  This hook is 
+     * needed when the {@link org.apache.shale.validator.CommonsValidator} 
+     * is added to a UIData subclass.  The components in this class are not 
+     * unique per row so the clientId can only be captured during the rendering 
+     * process.</p>
+     */
+    public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
+        
+        Set ids = (Set) component.getAttributes().get(VALIDATOR_CLIENTIDS_ATTR);
+        if (ids == null) {
+           ids = new TreeSet();
+           component.getAttributes().put(VALIDATOR_CLIENTIDS_ATTR, ids);
+        }
+        
+        ids.add(component.getClientId(context));
+        defaultRenderer.encodeBegin(context, component);
+    }
+    
+    // Specified by original Renderer
+    public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
+        defaultRenderer.encodeChildren(context, component);
+    }
+    
+    // Specified by original Renderer
+    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
+        defaultRenderer.encodeEnd(context, component);
+    }
+    
+    // Specified by original Renderer
+    public Object getConvertedValue(FacesContext context, UIComponent component, Object value) throws ConverterException {
+        return defaultRenderer.getConvertedValue(context, component, value);
+    }
+    
+    // Specified by original Renderer
+    public boolean getRendersChildren() {
+        return defaultRenderer.getRendersChildren();
+    }
+    
+}

Propchange: struts/shale/trunk/core-library/src/java/org/apache/shale/renderer/ValidatorInputRenderer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: struts/shale/trunk/core-library/src/java/org/apache/shale/renderer/ValidatorInputRenderer.java
------------------------------------------------------------------------------
    svn:keywords = date author id rev

Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/view/faces/ViewViewHandler.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/view/faces/ViewViewHandler.java?rev=391884&r1=391883&r2=391884&view=diff
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/view/faces/ViewViewHandler.java (original)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/view/faces/ViewViewHandler.java Wed Apr  5 19:46:34 2006
@@ -23,15 +23,18 @@
 import java.util.Map;
 
 import javax.faces.FacesException;
+import javax.faces.FactoryFinder;
 import javax.faces.application.ViewHandler;
 import javax.faces.component.UIViewRoot;
 import javax.faces.context.FacesContext;
 import javax.faces.el.EvaluationException;
-import javax.faces.el.ValueBinding;
 import javax.faces.el.VariableResolver;
+import javax.faces.render.RenderKit;
+import javax.faces.render.RenderKitFactory;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.shale.faces.ValidatorRenderKit;
 import org.apache.shale.util.Messages;
 import org.apache.shale.view.Constants;
 import org.apache.shale.view.ViewController;
@@ -124,6 +127,7 @@
     public UIViewRoot createView(FacesContext context, String viewId) {
         UIViewRoot view = original.createView(context, viewId);
         setupViewController(context, view, viewId, false);
+        setupRenderKit(context, view);
         return view;
     }
 
@@ -300,5 +304,18 @@
 
     }
 
+    /**
+     * <p>The default RenderKit is decorated with {@link org.apache.shale.faces.ValidatorRenderKit}.
+     * This wrapper intercepts component renderer's decorating them.</p>  
+     * 
+     * @param context <code>FacesContext</code> for the current request
+     * @param view <code>UIViewRoot</code> for the current component tree
+     */
+    private void setupRenderKit(FacesContext context, UIViewRoot view) {
+        RenderKitFactory factory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
+        RenderKit defaultRenderKit = factory.getRenderKit(context, view.getRenderKitId());
+        if (!(defaultRenderKit instanceof ValidatorRenderKit))
+            factory.addRenderKit(view.getRenderKitId(), new ValidatorRenderKit(defaultRenderKit));
+    }
 
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org