Author: gvanmatre
Date: Fri May 12 11:52:01 2006
New Revision: 405832

URL: http://svn.apache.org/viewcvs?rev=405832&view=rev
Log:
Fix for bug SHALE-176 reported by Lucy Luo and Veit Guna.  Added summary and 
detail validation message overrides at the component level and resource bundle 
registered in the faces configuration file.
Modified:
    struts/shale/trunk/core-library/src/conf/taglib.tld
    
struts/shale/trunk/core-library/src/java/org/apache/shale/component/Token.java
    
struts/shale/trunk/core-library/src/java/org/apache/shale/resources/Bundle.properties
    
struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/TokenTag.java
    
struts/shale/trunk/core-library/src/test/org/apache/shale/util/TestBundle_en_US.properties
    
struts/shale/trunk/core-library/src/test/org/apache/shale/util/TokenProcessorTestCase.java

Modified: struts/shale/trunk/core-library/src/conf/taglib.tld
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/conf/taglib.tld?rev=405832&r1=405831&r2=405832&view=diff
==============================================================================
--- struts/shale/trunk/core-library/src/conf/taglib.tld (original)
+++ struts/shale/trunk/core-library/src/conf/taglib.tld Fri May 12 11:52:01 2006
@@ -140,6 +140,26 @@
       </description>
     </attribute>
 
+
+    <attribute>
+      <name>messageSummary</name>
+      <required>false</required>
+      <rtexprvalue>false</rtexprvalue>
+      <description>
+        Default messageSummary override used to reporting a token verification 
failure.
+      </description>
+    </attribute>
+
+
+    <attribute>
+      <name>messageDetail</name>
+      <required>false</required>
+      <rtexprvalue>false</rtexprvalue>
+      <description>
+        Default messageDetail override used to reporting a token verification 
failure.
+      </description>
+    </attribute>
+
   </tag>
 
   <tag>

Modified: 
struts/shale/trunk/core-library/src/java/org/apache/shale/component/Token.java
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/component/Token.java?rev=405832&r1=405831&r2=405832&view=diff
==============================================================================
--- 
struts/shale/trunk/core-library/src/java/org/apache/shale/component/Token.java 
(original)
+++ 
struts/shale/trunk/core-library/src/java/org/apache/shale/component/Token.java 
Fri May 12 11:52:01 2006
@@ -19,10 +19,12 @@
 import javax.faces.application.FacesMessage;
 import javax.faces.component.UIInput;
 import javax.faces.context.FacesContext;
+import javax.faces.el.ValueBinding;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.shale.faces.ShaleConstants;
+import org.apache.shale.util.LoadBundle;
 import org.apache.shale.util.Messages;
 import org.apache.shale.util.TokenProcessor;
 
@@ -45,6 +47,17 @@
 
 
     /**
+     * <p>The resource bundle <code>messageSummary</code> key.</p>
+     */
+    private static final String MESSAGE_SUMMARY_KEY = "token.summary.invalid";
+
+    /**
+     * <p>The resource bundle <code>messageDetail</code> key.</p>
+     */
+    private static final String MESSAGE_DETAIL_KEY = "token.detail.invalid";
+  
+        
+    /**
      * <p>Message resources for this class
      */
     private static Messages messages =
@@ -54,7 +67,64 @@
 
     // ------------------------------------------------------------ 
Constructors
 
+    /**
+     * <p>A validation message summary override that can be used to change the 
default 
+     * validation message summary when the token verification fails.</p>
+     */
+    private String messageSummary = null;
+    
+    /**
+     * <p>Returns the validation <code>messageSummary</code> used to create a 
+     * <code>FacesMessage.SEVERITY_ERROR</code>.</p>
+     */
+    public String getMessageSummary() {
+        if (null != messageSummary)
+            return messageSummary;
+        ValueBinding valuebinding = getValueBinding("messageSummary");
+        if (valuebinding != null)
+            return (String) valuebinding.getValue(getFacesContext());
+        else
+            return null;
+    }
+    
+    /**
+     * <p>Sets a <code>messageSummary</code> override used when reporting
+     * a token verification failure.</p>
+     */
+    public void setMessageSummary(String message) {
+       this.messageSummary = message;
+    }
 
+    
+    /**
+     * <p>A validation message detail override that can be used to change the 
default 
+     * validation message detail when the token verification fails.</p>
+     */
+    private String messageDetail = null;
+    
+    /**
+     * <p>Returns the validation <code>messageDetail</code> used to create a 
+     * <code>FacesMessage.SEVERITY_ERROR</code>.</p>
+     */
+    public String getMessageDetail() {
+        if (null != messageDetail)
+            return messageDetail;
+        ValueBinding valuebinding = getValueBinding("messageDetail");
+        if (valuebinding != null)
+            return (String) valuebinding.getValue(getFacesContext());
+        else
+            return null;
+    }
+    
+    /**
+     * <p>Sets a <code>messageDetail</code> override used when reporting
+     * a token verification failure.</p>
+     */
+    public void setMessageDetail(String message) {
+       this.messageDetail = message;
+    }
+    
+    
     /**
      * <p>Create a default instance of this component.</p>
      */
@@ -96,13 +166,91 @@
                 log.debug("  Validation failed!");
             }
             setValid(false);
-            String summary = messages.getMessage("token.invalid");
-            FacesMessage message = new FacesMessage(summary);
+            String summary = getErrorSummaryMessage(context);
+            String detail = getErrorDetailMessage(context);
+            FacesMessage message = new FacesMessage(summary, detail);
             message.setSeverity(FacesMessage.SEVERITY_ERROR);
             context.addMessage(getClientId(context), message);
         }
 
     }
+    
+    /**
+     * <p>Returns the validation summary message.  
+     * The validation <code>messageSummary</code> is evaluated in the 
following order:  
+     * <ol>
+     * <li><p>The <code>messageSummary</code> property on the [EMAIL 
PROTECTED] Token} component is the 
+     * first order of override.</p></li>
+     * <li><p>The next level of override is a custom resource bundled 
registered 
+     * in the faces-config.xml using the message key of 
<strong>token.summary.invalid</strong>.
+     * <br/><br/>
+     * <p><blockquote><pre>
+     *    &lt;application&gt;
+     *       
&lt;messageSummary-bundle&gt;org.acme.resources.Bundle&lt;/messageSummary-bundle&gt;
+     *    &lt;/application&gt;
+     *</pre></blockquote></p></li>
+     *<li>The default will be taken from 
<strong>org.apache.shale.resources.Bundle</strong> 
+     *packaged in the core shale java archive.  The default message summary is
+     *"<strong>Invalid resubmit of the same form</strong>".</p></li>
+     *</ol></p>
+     *
+     * @param context faces context
+     * @return invalid token message
+     */
+    private String getErrorSummaryMessage(FacesContext context) {
+       String msg = null;
+       if ((msg = getMessageSummary()) == null) {
+          String bundleName = null;
+          if ((bundleName = context.getApplication().getMessageBundle()) != 
null) {
+             LoadBundle loadBundle = new LoadBundle(bundleName);
+             msg = (String) loadBundle.getMap().get(MESSAGE_SUMMARY_KEY);
+          }
+       }
+       
+       if (msg == null)
+          msg = messages.getMessage(MESSAGE_SUMMARY_KEY);
+       
+       return msg;    
+    }
+
+    
+    /**
+     * <p>Returns the validation detail message.  
+     * The validation <code>messageDetail</code> is evaluated in the following 
order:  
+     * <ol>
+     * <li><p>The <code>messageDetail</code> property on the [EMAIL PROTECTED] 
Token} component is the 
+     * first order of override.</p></li>
+     * <li><p>The next level of override is a custom resource bundled 
registered 
+     * in the faces-config.xml using the message key of 
<strong>token.detail.invalid</strong>.
+     * <br/><br/>
+     * <p><blockquote><pre>
+     *    &lt;application&gt;
+     *       
&lt;messageSummary-bundle&gt;org.acme.resources.Bundle&lt;/messageSummary-bundle&gt;
+     *    &lt;/application&gt;
+     *</pre></blockquote></p></li>
+     *<li>The default will be taken from 
<strong>org.apache.shale.resources.Bundle</strong> 
+     *packaged in the core shale java archive.  The default message detail is
+     *an empty string, "".</p></li>
+     *</ol></p>
+     *
+     * @param context faces context
+     * @return invalid token message
+     */
+    private String getErrorDetailMessage(FacesContext context) {
+       String msg = null;
+       if ((msg = getMessageDetail()) == null) {
+          String bundleName = null;
+          if ((bundleName = context.getApplication().getMessageBundle()) != 
null) {
+             LoadBundle loadBundle = new LoadBundle(bundleName);
+             msg = (String) loadBundle.getMap().get(MESSAGE_DETAIL_KEY);
+          }
+       }
+       
+       if (msg == null)
+          msg = messages.getMessage(MESSAGE_DETAIL_KEY);
+       
+       return msg;    
+    }
 
 
     // ---------------------------------------------------------- Public 
Methods
@@ -147,6 +295,29 @@
          return tp;
 
      }
+
+    /**
+     * <p>Restores the components state.</p>
+     */
+    public void restoreState(FacesContext context, Object obj) {
+        Object[] aobj = (Object[]) obj;
+        super.restoreState(context, aobj[0]);
+        
+        messageSummary = ((String) aobj[1]);
+        messageDetail = ((String) aobj[2]);
+    }
+
+    /**
+     * <p>Saves the components state.</p>
+     */
+    public Object saveState(FacesContext context) {
+        Object[] aobj = new Object[3];
+        aobj[0] = super.saveState(context);
+        aobj[1] = messageSummary;
+        aobj[2] = messageDetail;
+        
+        return aobj;
+    }
 
 
 }

Modified: 
struts/shale/trunk/core-library/src/java/org/apache/shale/resources/Bundle.properties
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/resources/Bundle.properties?rev=405832&r1=405831&r2=405832&view=diff
==============================================================================
--- 
struts/shale/trunk/core-library/src/java/org/apache/shale/resources/Bundle.properties
 (original)
+++ 
struts/shale/trunk/core-library/src/java/org/apache/shale/resources/Bundle.properties
 Fri May 12 11:52:01 2006
@@ -44,7 +44,8 @@
 subview.noType=Managed bean for subview {0} is not a ViewController
 
 # org.apache.shale.component.Token
-token.invalid=Invalid resubmit of the same form
+token.summary.invalid=Invalid resubmit of the same form
+token.detail.invalid=
 
 # org.apache.shale.dialog.faces.DialogNavigationHandler
 dialog.noDialog=You have requested a dialog named "{0}" but no such dialog 
definition can be found.  Double check the spelling of the dialog name.

Modified: 
struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/TokenTag.java
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/TokenTag.java?rev=405832&r1=405831&r2=405832&view=diff
==============================================================================
--- 
struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/TokenTag.java 
(original)
+++ 
struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/TokenTag.java 
Fri May 12 11:52:01 2006
@@ -16,6 +16,9 @@
 
 package org.apache.shale.taglib;
 
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.el.ValueBinding;
 import javax.faces.webapp.UIComponentTag;
 
 import org.apache.shale.component.Token;
@@ -29,6 +32,35 @@
     
 
     /**
+     * <p>Pushs the tag attributes to the [EMAIL PROTECTED] Token}'s 
+     * component properties.</p>
+     */
+    protected void setProperties(UIComponent component) {
+        super.setProperties(component);
+        
+        FacesContext context = getFacesContext();
+        
+        if (messageSummary != null) {
+            if (this.isValueReference(messageSummary)) {
+                ValueBinding vb = 
context.getApplication().createValueBinding(messageSummary);
+                component.setValueBinding("messageSummary", vb);
+            } else
+                component.getAttributes().put("messageSummary", 
messageSummary);    
+        }
+
+        if (messageDetail != null) {
+            if (this.isValueReference(messageDetail)) {
+                ValueBinding vb = 
context.getApplication().createValueBinding(messageDetail);
+                component.setValueBinding("messageDetail", vb);
+            } else
+                component.getAttributes().put("messageDetail", messageDetail); 
   
+        }
+
+    
+    }
+
+
+    /**
      * <p>Return the required component type.</p>
      */
     public String getComponentType() {
@@ -43,5 +75,50 @@
         return "org.apache.shale.Token";
     }
 
+    /**
+     * <p>A validation messageSummary override that can be used to change the 
default 
+     * validation messageSummary when the token verification fails.</p>
+     */
+    private String messageSummary = null;
+    
+    /**
+     * <p>Sets a <code>messageSummary</code> override used when reporting
+     * a [EMAIL PROTECTED] org.apache.shale.component.Token} verification 
failure.</p>
+     */
+    public void setMessageSummary(String message) {
+       this.messageSummary = message;    
+    }
+
+    /**
+     * <p>Returns a <code>messageSummary</code> override used when reporting
+     * a [EMAIL PROTECTED] org.apache.shale.component.Token} verification 
failure.</p>
+     */
+    public String getMessageSummary() {
+       return messageSummary;    
+    }
+
+    
+    /**
+     * <p>A validation messageDetail override that can be used to change the 
default 
+     * validation messageDetail when the token verification fails.</p>
+     */
+    private String messageDetail = null;
+    
+    /**
+     * <p>Sets a <code>messageDetail</code> override used when reporting
+     * a [EMAIL PROTECTED] org.apache.shale.component.Token} verification 
failure.</p>
+     */
+    public void setMessageDetail(String message) {
+       this.messageDetail = message;    
+    }
 
+    /**
+     * <p>Returns a <code>messageDetail</code> override used when reporting
+     * a [EMAIL PROTECTED] org.apache.shale.component.Token} verification 
failure.</p>
+     */
+    public String getMessageDetail() {
+       return messageDetail;    
+    }
+
+    
 }

Modified: 
struts/shale/trunk/core-library/src/test/org/apache/shale/util/TestBundle_en_US.properties
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/test/org/apache/shale/util/TestBundle_en_US.properties?rev=405832&r1=405831&r2=405832&view=diff
==============================================================================
--- 
struts/shale/trunk/core-library/src/test/org/apache/shale/util/TestBundle_en_US.properties
 (original)
+++ 
struts/shale/trunk/core-library/src/test/org/apache/shale/util/TestBundle_en_US.properties
 Fri May 12 11:52:01 2006
@@ -2,3 +2,6 @@
 key1=English Key 1
 key2=English Key 2
 
+token.summary.invalid=Invalid resubmit of the same form is bad news Lucy Luo
+token.detail.invalid=This page has been mark as having durability of a single 
submit and this contract has been violated by the submission of a dirty page.
+

Modified: 
struts/shale/trunk/core-library/src/test/org/apache/shale/util/TokenProcessorTestCase.java
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/test/org/apache/shale/util/TokenProcessorTestCase.java?rev=405832&r1=405831&r2=405832&view=diff
==============================================================================
--- 
struts/shale/trunk/core-library/src/test/org/apache/shale/util/TokenProcessorTestCase.java
 (original)
+++ 
struts/shale/trunk/core-library/src/test/org/apache/shale/util/TokenProcessorTestCase.java
 Fri May 12 11:52:01 2006
@@ -16,13 +16,24 @@
 
 package org.apache.shale.util;
 
+import java.io.StringWriter;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
 import java.util.Set;
 
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIInput;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.ResponseWriter;
+
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
+import org.apache.shale.component.Token;
+import org.apache.shale.renderer.TokenRenderer;
 import org.apache.shale.test.base.AbstractJsfTestCase;
 
 /**
@@ -50,7 +61,12 @@
 
         // Set up the instance we will be testing
         tp = new TokenProcessor();
-
+        
+        //register the Token component
+        application.addComponent("org.apache.shale.Token", 
"org.apache.shale.component.Token");
+        facesContext.getRenderKit().addRenderer("org.apache.shale.Token", 
+                "org.apache.shale.Token",
+                new TokenRenderer());
     }
 
 
@@ -115,5 +131,243 @@
 
     }
 
+    public void testMessagePropertyOverride() throws Exception {
+
+       final String SUMMARY_MESSAGE = "This page is dirty.  Evil browser back 
button."; 
+       final String DETAIL_MESSAGE = "This page has been mark as having 
durability of a single submit and this contract has been violated by the 
submission of a dirty page.";
+
+       Token token = (Token) 
facesContext.getApplication().createComponent("org.apache.shale.Token");
+       assertNotNull(token);
+       
+       UIViewRoot root = facesContext.getViewRoot();
+       assertNotNull(root);
+       
+       // add token to the component tree
+       root.getChildren().add(root.getChildCount(), token);
+             
+       token.setId("messagePropertyOverride");
+       token.setMessageSummary(SUMMARY_MESSAGE);
+       token.setMessageDetail(DETAIL_MESSAGE);
+       
+       StringBuffer htmlSnippet = encode(token);       
+       // check rendered markup
+       String id = getAttribute(htmlSnippet, "id");
+       assertEquals("id", token.getClientId(facesContext), id);
+
+       String name = getAttribute(htmlSnippet, "name");
+       assertEquals("id", token.getClientId(facesContext), name);
+
+       String type = getAttribute(htmlSnippet, "type");
+       assertEquals("id", "hidden", type);
+
+       String value = getAttribute(htmlSnippet, "value");
+       assertNotNull("value", value);
+       
+       // simulate form post on dirty page
+       Map map = facesContext.getExternalContext().getRequestParameterMap();
+       map.put(id, value);
+       
+       // simulate apply values
+       token.decode(facesContext);
+       assertEquals("value", value, token.getSubmittedValue());
+        
+       // simulate validation and invalidates token
+       token.validate(facesContext);
+       
+       checkNoMessages(token);
+       
+       // simulate double post
+       token.validate(facesContext);
+       
+       // check for the custom message
+       checkMessage(SUMMARY_MESSAGE, DETAIL_MESSAGE, token);
+       
+    }
+        
+    public void testMessageFacesConfigBundleOverride() throws Exception {
+        
+        // simulate a faces config resource bundle override
+        application.setDefaultLocale(new Locale("en", "US"));
+        application.setMessageBundle("org.apache.shale.util.TestBundle");
+
+        //value of the "token.invalid" key in the 
"org.apache.shale.util.TestBundle"
+        final String SUMMARY_MESSAGE = "Invalid resubmit of the same form is 
bad news Lucy Luo"; 
+        final String DETAIL_MESSAGE = "This page has been mark as having 
durability of a single submit and this contract has been violated by the 
submission of a dirty page.";
+                
+        Token token = (Token) 
facesContext.getApplication().createComponent("org.apache.shale.Token");
+        assertNotNull(token);
+        
+        UIViewRoot root = facesContext.getViewRoot();
+        assertNotNull(root);
+        
+        // add token to the component tree
+        root.getChildren().add(root.getChildCount(), token);
+              
+        token.setId("messageFacesConfigBundleOverride");
+        token.setMessageSummary(null);  // no message property override
+        token.setMessageDetail(null);   // no message property override
+        
+        
+        StringBuffer htmlSnippet = encode(token);       
+        // check rendered markup
+        String id = getAttribute(htmlSnippet, "id");
+        assertEquals("id", token.getClientId(facesContext), id);
+
+        String name = getAttribute(htmlSnippet, "name");
+        assertEquals("id", token.getClientId(facesContext), name);
+
+        String type = getAttribute(htmlSnippet, "type");
+        assertEquals("id", "hidden", type);
+
+        String value = getAttribute(htmlSnippet, "value");
+        assertNotNull("value", value);
+        
+        // simulate form post on dirty page
+        Map map = facesContext.getExternalContext().getRequestParameterMap();
+        map.put(id, value);
+        
+        // simulate apply values
+        token.decode(facesContext);
+        assertEquals("value", value, token.getSubmittedValue());
+         
+        // simulate validation and invalidates token
+        token.validate(facesContext);
+        
+        checkNoMessages(token);
+        
+        // simulate double post
+        token.validate(facesContext);
+        
+        // check for the custom message
+        checkMessage(SUMMARY_MESSAGE, DETAIL_MESSAGE, token);
+        
+     }
+
+    public void testMessageDefault() throws Exception {
+        
+        //value of the "token.invalid" key in the 
"org.apache.shale.resources.Bundle"
+        final String SUMMARY_MESSAGE = "Invalid resubmit of the same form"; 
+        final String DETAIL_MESSAGE = "";  // none by detault
+                
+        Token token = (Token) 
facesContext.getApplication().createComponent("org.apache.shale.Token");
+        assertNotNull(token);
+        
+        UIViewRoot root = facesContext.getViewRoot();
+        assertNotNull(root);
+        
+        // add token to the component tree
+        root.getChildren().add(root.getChildCount(), token);
+              
+        token.setId("messageDefault");
+        token.setMessageSummary(null);  // no message property override
+        
+        StringBuffer htmlSnippet = encode(token);       
+        // check rendered markup
+        String id = getAttribute(htmlSnippet, "id");
+        assertEquals("id", token.getClientId(facesContext), id);
+
+        String name = getAttribute(htmlSnippet, "name");
+        assertEquals("id", token.getClientId(facesContext), name);
+
+        String type = getAttribute(htmlSnippet, "type");
+        assertEquals("id", "hidden", type);
 
+        String value = getAttribute(htmlSnippet, "value");
+        assertNotNull("value", value);
+        
+        // simulate form post on dirty page
+        Map map = facesContext.getExternalContext().getRequestParameterMap();
+        map.put(id, value);
+        
+        // simulate apply values
+        token.decode(facesContext);
+        assertEquals("value", value, token.getSubmittedValue());
+         
+        // simulate validation and invalidates token
+        token.validate(facesContext);
+        
+        checkNoMessages(token);
+        
+        // simulate double post
+        token.validate(facesContext);
+        
+        // check for the custom message
+        checkMessage(SUMMARY_MESSAGE, DETAIL_MESSAGE, token);
+        
+     }
+    
+    
+    
+    //looks for an html attribute in a markup snippet
+    private String getAttribute(StringBuffer htmlSnippet, String 
attributeName) {
+        String sarg = attributeName + "=\"";
+        int s = htmlSnippet.indexOf(sarg);
+        String value = null;
+        if (s > -1) {
+           s += sarg.length();
+           int e = htmlSnippet.indexOf("\"", s);
+           if (e > -1 && e > s) {
+              value = htmlSnippet.substring(s, e);
+           }
+           
+        }
+        return value;
+    }
+    
+    //looks for an error message added in validation 
+    private void checkMessage(String expectedSummary, String expectedDetail, 
UIInput component) {
+        String id = component.getClientId(facesContext);
+        Iterator mi = facesContext.getMessages(id);
+        boolean hasMessage = false;
+        while (mi.hasNext()) {
+           FacesMessage message = (FacesMessage) mi.next();    
+           String summary = message.getSummary();
+           String detail = message.getDetail();
+           assertEquals(expectedSummary, summary);
+           assertEquals(expectedDetail, detail);
+           hasMessage = true;
+        }
+        
+        assertTrue(id + " has messages", hasMessage);   
+    }
+    
+    //checks to make sure there are no error messages after validation
+    private void checkNoMessages(UIInput component) {
+        String id = component.getClientId(facesContext);
+        Iterator mi = facesContext.getMessages(id);
+        boolean hasMessage = false;
+        while (mi.hasNext()) {
+           hasMessage = true;
+        }
+        
+        assertFalse(id + " has messages", hasMessage);   
+       
+    }
+
+    
+    //render and return the results
+    private StringBuffer encode(UIComponent component) throws Exception {
+        //builds a buffer to write the page to
+        StringWriter writer = new StringWriter();
+        //create a buffered response writer
+        ResponseWriter buffResponsewriter = facesContext.getRenderKit()
+                        .createResponseWriter(writer, null, 
response.getCharacterEncoding());
+        //push buffered writer to the faces context
+        facesContext.setResponseWriter(buffResponsewriter);
+        //start a document
+        buffResponsewriter.startDocument();
+        
+        //render HTML
+        component.encodeBegin(facesContext);
+        component.encodeChildren(facesContext);
+        component.encodeEnd(facesContext);
+        
+        //end the document
+        buffResponsewriter.endDocument();
+        
+        return writer.getBuffer();
+    }
+
+    
+    
 }


Reply via email to