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.shared.renderkit.html.util;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  import org.apache.myfaces.shared.config.MyfacesConfig;
24  
25  import javax.faces.context.ExternalContext;
26  import javax.servlet.http.HttpSession;
27  import java.io.UnsupportedEncodingException;
28  import java.util.Arrays;
29  import java.util.HashSet;
30  import java.util.Set;
31  
32  /***
33   * @author Manfred Geiler (latest modification by $Author: lu4242 $)
34   * @author Anton Koinov
35   * @version $Revision: 684009 $ $Date: 2008-08-08 11:07:53 -0500 (Fri, 08 Aug 2008) $
36   */
37  public final class JavascriptUtils
38  {
39      private static final Log log = LogFactory.getLog(JavascriptUtils.class);
40  
41      public static final String JAVASCRIPT_DETECTED = JavascriptUtils.class.getName() + ".JAVASCRIPT_DETECTED";
42  
43      private static final String AUTO_SCROLL_PARAM = "autoScroll";
44      private static final String AUTO_SCROLL_FUNCTION = "getScrolling()";
45  
46      private static final String OLD_VIEW_ID = JavascriptUtils.class + ".OLD_VIEW_ID";
47  
48  
49      private JavascriptUtils()
50      {
51          // utility class, do not instantiate
52      }
53  
54      private static final Set RESERVED_WORDS =
55          new HashSet(Arrays.asList(new String[]{
56              "abstract",
57              "boolean",
58              "break",
59              "byte",
60              "case",
61              "catch",
62              "char",
63              "class",
64              "const",
65              "continue",
66              "default",
67              "delete",
68              "do",
69              "double",
70              "else",
71              "export",
72              "extends",
73              "false",
74              "final",
75              "finally",
76              "float",
77              "for",
78              "function",
79              "goto",
80              "if",
81              "implements",
82              "in",
83              "instanceof",
84              "int",
85              "long",
86              "native",
87              "new",
88              "null",
89              "package",
90              "private",
91              "protected",
92              "public",
93              "return",
94              "short",
95              "static",
96              "super",
97              "switch",
98              "synchronized",
99              "this",
100             "throw",
101             "throws",
102             "transient",
103             "true",
104             "try",
105             "typeof",
106             "var",
107             "void",
108             "while",
109             "with"
110         }));
111 
112     /***Don't use this function - except when compatibility with the RI is a must,
113      * as in the name for the clear form parameters script.
114      */
115     public static String getValidJavascriptNameAsInRI(String origIdentifier)
116     {
117         return origIdentifier.replaceAll("-", "//$_");
118     }
119 
120     public static String getValidJavascriptName(String s, boolean checkForReservedWord)
121     {
122         if (checkForReservedWord && RESERVED_WORDS.contains(s))
123         {
124             return s + "_";
125         }
126 
127         StringBuffer buf = null;
128         for (int i = 0, len = s.length(); i < len; i++)
129         {
130             char c = s.charAt(i);
131 
132             if (Character.isLetterOrDigit(c))
133             {
134                 // allowed char
135                 if (buf != null) buf.append(c);
136             }
137             else
138             {
139                 if (buf == null)
140                 {
141                     buf = new StringBuffer(s.length() + 10);
142                     buf.append(s.substring(0, i));
143                 }
144 
145                 buf.append('_');
146                 if (c < 16)
147                 {
148                     // pad single hex digit values with '0' on the left
149                     buf.append('0');
150                 }
151 
152                 if (c < 128)
153                 {
154                     // first 128 chars match their byte representation in UTF-8
155                     buf.append(Integer.toHexString(c).toUpperCase());
156                 }
157                 else
158                 {
159                     byte[] bytes;
160                     try
161                     {
162                         bytes = Character.toString(c).getBytes("UTF-8");
163                     }
164                     catch (UnsupportedEncodingException e)
165                     {
166                         throw new RuntimeException(e);
167                     }
168 
169                     for (int j = 0; j < bytes.length; j++)
170                     {
171                         int intVal = bytes[j];
172                         if (intVal < 0)
173                         {
174                             // intVal will be >= 128
175                             intVal = 256 + intVal;
176                         }
177                         else if (intVal < 16)
178                         {
179                             // pad single hex digit values with '0' on the left
180                             buf.append('0');
181                         }
182                         buf.append(Integer.toHexString(intVal).toUpperCase());
183                     }
184                 }
185             }
186 
187         }
188 
189         return buf == null ? s : buf.toString();
190     }
191 
192 
193     public static String encodeString(String string)
194     {
195         if (string == null)
196         {
197             return "";
198         }
199         StringBuffer sb = null;    //create later on demand
200         String app;
201         char c;
202         for (int i = 0; i < string.length (); ++i)
203         {
204             app = null;
205             c = string.charAt(i);
206             switch (c)
207             {
208                 case '//' : app = "////";  break;
209                 case '"' : app = "//\"";  break;
210                 case '\'' : app = "//'";  break;
211                 case '\n' : app = "//n";  break;
212                 case '\r' : app = "//r";  break;
213             }
214             if (app != null)
215             {
216                 if (sb == null)
217                 {
218                     sb = new StringBuffer(string.substring(0, i));
219                 }
220                 sb.append(app);
221             } else {
222                 if (sb != null)
223                 {
224                     sb.append(c);
225                 }
226             }
227         }
228 
229         if (sb == null)
230         {
231             return string;
232         }
233         else
234         {
235             return sb.toString();
236         }
237     }
238 
239     public static boolean isJavascriptAllowed(ExternalContext externalContext)
240     {
241         MyfacesConfig myfacesConfig = MyfacesConfig.getCurrentInstance(externalContext);
242         if (myfacesConfig.isAllowJavascript())
243         {
244             if (myfacesConfig.isDetectJavascript())
245             {
246                 return isJavascriptDetected(externalContext);
247             }
248             else
249             {
250                 return true;
251             }
252         }
253         else
254         {
255             return false;
256         }
257     }
258     
259     public static boolean isRenderClearJavascriptOnButton(ExternalContext externalContext)
260     {
261         MyfacesConfig myfacesConfig = MyfacesConfig.getCurrentInstance(externalContext);
262         if (myfacesConfig.isRenderClearJavascriptOnButton())
263         {
264             return true;
265         }
266         else
267         {
268             return false;
269         }
270     }
271     
272     public static boolean isSaveFormSubmitLinkIE(ExternalContext externalContext)
273     {
274         MyfacesConfig myfacesConfig = MyfacesConfig.getCurrentInstance(externalContext);
275         if (myfacesConfig.isSaveFormSubmitLinkIE())
276         {
277             return true;
278         }
279         else
280         {
281             return false;
282         }
283     }    
284 
285     public static void setJavascriptDetected(HttpSession session, boolean value)
286     {
287         session.setAttribute(JAVASCRIPT_DETECTED, Boolean.valueOf(value));
288     }
289     
290     public static boolean isJavascriptDetected(ExternalContext externalContext)
291     {
292         //TODO/FIXME (manolito): This info should be better stored in the viewroot component and not in the session
293         Boolean sessionValue = (Boolean)externalContext.getSessionMap().get(JAVASCRIPT_DETECTED);
294         return sessionValue != null && sessionValue.booleanValue();
295     }
296 
297 
298     public static void setOldViewId(ExternalContext externalContext, String viewId)
299     {
300         externalContext.getRequestMap().put(OLD_VIEW_ID, viewId);
301     }
302 
303     public static String getOldViewId(ExternalContext externalContext)
304     {
305         return (String)externalContext.getRequestMap().get(OLD_VIEW_ID);
306     }
307 }