View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.custom.clientvalidation.common;
20  
21  import java.io.IOException;
22  import java.util.List;
23  import java.util.Locale;
24  
25  import javax.faces.component.UIComponent;
26  import javax.faces.component.UIData;
27  import javax.faces.component.UIInput;
28  import javax.faces.component.html.HtmlMessages;
29  import javax.faces.context.ExternalContext;
30  import javax.faces.context.FacesContext;
31  import javax.faces.context.ResponseWriter;
32  import javax.faces.convert.Converter;
33  import javax.faces.validator.Validator;
34  
35  import org.apache.myfaces.custom.clientvalidation.validationscript.ValidationScript;
36  import org.apache.myfaces.custom.util.ComponentUtils;
37  import org.apache.myfaces.renderkit.html.util.AddResource;
38  import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
39  import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
40  
41  /**
42   * @author cagatay (latest modification by $Author: skitching $)
43   * @version $Revision: 673833 $ $Date: 2008-07-03 16:58:05 -0500 (Thu, 03 Jul 2008) $
44   */
45  public class CVUtils {
46      
47      public final static String BYPASS_CLIENT_VALIDATION_FIELD = "tomahawk.bypassClientValidation";
48  
49      private CVUtils() {
50          // nope
51      }
52      
53      public static void addCVCall(CVCall call) {
54          getCVCallsHolder( FacesContext.getCurrentInstance() ).addCVCall( call );
55      }
56      
57      public static CVCall createCVCall(UIInput input) {
58          CVCall call = new CVCall();
59          call.setId( input.getId() );
60          call.setClientId( input.getClientId( FacesContext.getCurrentInstance() ) );
61          call.setRequired( input.isRequired() );        
62          
63          //converter
64          Converter converter = RendererUtils.findUIOutputConverter( FacesContext.getCurrentInstance(), input );
65          if( converter instanceof ClientConverter ) {
66              call.setConverterScriptFunction( ( (ClientConverter) converter ).getScriptFunction() );
67              call.setConverterScriptResource( ( (ClientConverter) converter ).getScriptResource() );
68          }
69          
70          //validators
71          int numberOfValidators = input.getValidators().length;
72          call.setValidatorScriptFunctions( ( new String[numberOfValidators] ) );
73          call.setValidatorScriptResources( ( new String[numberOfValidators] ) );
74          for( int i = 0; i < numberOfValidators; i++ ) {
75              Validator validator = input.getValidators()[i];
76              if( validator instanceof ClientValidator ) {
77                  call.getValidatorScriptFunctions()[i] = ((ClientValidator) validator).getScriptFunction();
78                  call.getValidatorScriptResources()[i] = ((ClientValidator) validator).getScriptResource();
79              }
80          }
81          return call;
82      }
83  
84      public static CVCallsHolder getCVCallsHolder(FacesContext facesContext) {
85          return (CVCallsHolder) facesContext.getApplication().createValueBinding("#{CVCallsHolder}").getValue( facesContext );
86      }
87  
88      public static boolean isCVEnabled() {
89          ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
90          if(context.getInitParameter("org.apache.myfaces.ENABLE_CLIENT_SIDE_VALIDATION") == null)
91              return false;
92          else
93              return Boolean.valueOf(context.getInitParameter("org.apache.myfaces.ENABLE_CLIENT_SIDE_VALIDATION")).booleanValue();
94      }
95  
96      //Traverses the component tree recursively, queues validation calls starting from the root
97      public static void queueCVCalls(UIComponent root) {
98          if( !root.isRendered() )
99              return;
100         
101         if( root.getChildCount() > 0 ) {
102             for( int i = 0; i< root.getChildCount() ; i++ ) {
103                 UIComponent component = (UIComponent) root.getChildren().get( i );
104                 
105                 if( ! (component instanceof UIData) )
106                     queueCVCalls( component);
107             }
108         } else {
109             //TODO: Replace uiinput with editablevalueholder
110             if( root instanceof UIInput ) {
111                 UIInput input = (UIInput) root;
112                 addCVCall( createCVCall( input ) );
113             }
114         }
115     }
116     
117     public static void encodeValidationScript(FacesContext facesContext) throws IOException{
118         ResponseWriter writer = facesContext.getResponseWriter();
119         writer.write("\n<script type=\"text/javascript\" >\n");
120     
121         encodeCreateViewFunction(facesContext);
122         encodeRenderResponseFunction(facesContext);
123         
124         writer.write("</script>");
125     }
126     
127     public static String getJSMessageBundle(FacesContext facesContext) throws IOException{
128         Locale locale = facesContext.getViewRoot().getLocale();
129         String bundleName = "messages/Messages_" + locale.getLanguage() + ".js";
130         return bundleName;
131     }
132     
133     public static void encodeCreateViewFunction(FacesContext facesContext) throws IOException {
134         ResponseWriter writer = facesContext.getResponseWriter();
135         
136         writer.write("\t tomahawk.createView = function(facesContext) {\n");
137         writer.write("\t\t facesContext.clearMessages();\n");
138         writer.write("\t\t facesContext.viewRoot = new tomahawk.UIViewRoot();\n");
139         
140         List cvCalls = getCVCallsHolder( facesContext ).getCvCalls();
141         for( int i = 0; i < cvCalls.size() ; i++ ) {
142             CVCall call = (CVCall) cvCalls.get( i );
143             
144             writer.write( "\t\t facesContext.viewRoot.addChild((new tomahawk.UIInput('" + call.getId() + "'," );        //id
145             writer.write( "'" + call.getClientId() + "'," );                //clientId
146             writer.write( call.isRequired() + ",");                            //required
147             
148             //Converter
149             if(call.getConverterScriptFunction() != null )
150                 writer.write( "new " + call.getConverterScriptFunction() + ", ");
151             else
152                 writer.write( "null,");
153             
154             //Validators
155             writer.write( "new Array(");
156             String[] validators = call.getValidatorScriptFunctions();
157             if(validators == null )
158                 writer.write( ")");
159             else {
160                 for(int j=0 ; j < validators.length ; j++ ) {
161                     writer.write( "new " + validators[j] );
162                     if( (j + 1) != validators.length )
163                         writer.write( "," );
164                 }
165             }
166             writer.write(" ) ) ) );\n");
167         }
168         writer.write("\t }\n");
169     }
170     
171     public static void encodeRenderResponseFunction(FacesContext facesContext) throws IOException {
172         ResponseWriter writer = facesContext.getResponseWriter();
173         writer.write("\t tomahawk.renderResponse = function(facesContext) {\n");
174         
175         HtmlMessages htmlMessages = (HtmlMessages) ComponentUtils.findFirstMessagesComponent( facesContext, facesContext.getViewRoot() );
176         
177         if(htmlMessages != null) {
178             writer.write("\t\t var uimessages = new tomahawk.UIMessages('" + htmlMessages.getClientId(facesContext) + "','" + htmlMessages.getLayout() + "'," + htmlMessages.isShowSummary() + "," + htmlMessages.isShowDetail() + ");\n");
179             writer.write("\t\t tomahawk.RendererUtils.renderMessages(facesContext,uimessages); \n");
180         }
181         
182         writer.write("\t\t viewRoot = facesContext.viewRoot;\n");
183         writer.write("\t\t for(var i = 0; i < viewRoot.children.length ; i ++) { \n");
184         writer.write("\t\t\t\t  var uiinput = viewRoot.children[i]; \n");
185         writer.write("\t\t\t\t tomahawk.RendererUtils.renderMessage(facesContext,uiinput.clientId); \n");
186         writer.write("\t\t\t }\n");
187         writer.write("\t\t }\n");
188     }
189      
190     //renders included resources
191     public static void encodeJavascript(FacesContext context)throws IOException {
192         AddResource addResource = AddResourceFactory.getInstance(context);
193         
194         //Common
195         addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN,ValidationScript.class, "common.js");
196         
197         //MessageBundle
198         addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN,ValidationScript.class, CVUtils.getJSMessageBundle(context));
199         
200         //Converters and Validators
201         addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN,ValidationScript.class, "converters.js");
202         addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN,ValidationScript.class, "validators.js");
203     }
204 
205 }