Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: renderkits/util/Util.java


1   /*
2    * The contents of this file are subject to the terms
3    * of the Common Development and Distribution License
4    * (the License). You may not use this file except in
5    * compliance with the License.
6    * 
7    * You can obtain a copy of the License at
8    * https://javaserverfaces.dev.java.net/CDDL.html or
9    * legal/CDDLv1.0.txt. 
10   * See the License for the specific language governing
11   * permission and limitations under the License.
12   * 
13   * When distributing Covered Code, include this CDDL
14   * Header Notice in each file and include the License file
15   * at legal/CDDLv1.0.txt.    
16   * If applicable, add the following below the CDDL Header,
17   * with the fields enclosed by brackets [] replaced by
18   * your own identifying information:
19   * "Portions Copyrighted [year] [name of copyright owner]"
20   * 
21   * [Name of File] [ver.__] [Date]
22   * 
23   * Copyright 2005 Sun Microsystems Inc. All Rights Reserved
24   */
25  
26  package renderkits.util;
27  
28  import javax.faces.FactoryFinder;
29  import javax.faces.application.Application;
30  import javax.faces.application.ApplicationFactory;
31  import javax.faces.component.UIComponent;
32  import javax.faces.convert.Converter;
33  
34  import java.io.IOException;
35  import java.io.UnsupportedEncodingException;
36  import java.io.Writer;
37  import java.util.logging.Logger;
38  
39  public class Util extends Object {
40  
41      //
42      // Private/Protected Constants
43      //
44      public static final String FACES_LOGGER = "javax.enterprise.resource.jsf.";
45      public static final String RENDERKIT_LOGGER = "renderkit";
46      public static final String TAGLIB_LOGGER = "taglib";
47  
48  
49      public static final String FACES_LOG_STRINGS =
50            "com.sun.faces.LogStrings";
51  
52      // Log instance for this class
53      private static Logger logger;
54  
55      static {
56          logger = getLogger(FACES_LOGGER);
57      }
58  
59      public static Logger getLogger(String loggerName) {
60          return Logger.getLogger(loggerName, FACES_LOG_STRINGS);
61      }
62  
63      /** Utility method for determining if a component is 'disabled' or 'readonly' */
64      public static boolean componentIsDisabledOnReadonly(UIComponent component) {
65          Object disabledOrReadonly = null;
66          boolean result = false;
67          if (null !=
68              (disabledOrReadonly = component.getAttributes().get("disabled"))) {
69              if (disabledOrReadonly instanceof String) {
70                  result = ((String) disabledOrReadonly).equalsIgnoreCase("true");
71              } else {
72                  result = disabledOrReadonly.equals(Boolean.TRUE);
73              }
74          }
75          if ((result == false) &&
76              null !=
77              (disabledOrReadonly = component.getAttributes().get("readonly"))) {
78              if (disabledOrReadonly instanceof String) {
79                  result = ((String) disabledOrReadonly).equalsIgnoreCase("true");
80              } else {
81                  result = disabledOrReadonly.equals(Boolean.TRUE);
82              }
83          }
84  
85          return result;
86      }
87  
88      public static Converter getConverterForClass(Class converterClass) {
89          if (converterClass == null) {
90              return null;
91          }
92          try {
93              ApplicationFactory aFactory =
94                    (ApplicationFactory) FactoryFinder.getFactory(
95                          FactoryFinder.APPLICATION_FACTORY);
96              Application application = aFactory.getApplication();
97              return (application.createConverter(converterClass));
98          } catch (Exception e) {
99              return (null);
100         }
101     }
102 
103 
104     //----------------------------------------------------------
105     // The following is used to verify encodings
106     //----------------------------------------------------------
107     //
108     static public void validateEncoding(String encoding)
109           throws UnsupportedEncodingException {
110         if (encoding != null) {
111             // Try creating a string off of the default encoding
112             new String(encodingTestBytes, encoding);
113         }
114     }
115 
116     // Private array used simply to verify character encodings
117     static private final byte[] encodingTestBytes = new byte[]{(byte) 65};
118 
119     /**
120      * Write a string attribute.  Note that this code
121      * is duplicated below for character arrays - change both
122      * places if you make any changes!!!
123      */
124     static public void writeAttribute(Writer out,
125                                       char[] buff,
126                                       String text) throws IOException {
127         int buffLength = buff.length;
128         int buffIndex = 0;
129 
130         int length = text.length();
131         for (int i = 0; i < length; i++) {
132             char ch = text.charAt(i);
133 
134             // Tilde or less...
135             if (ch < 0xA0) {
136                 // If "?" or over, no escaping is needed (this covers
137                 // most of the Latin alphabet)
138                 if (ch >= 0x3f) {
139                     buffIndex = addToBuffer(out, buff, buffIndex,
140                                             buffLength, ch);
141                 } else if (ch >= 0x27) { // If above "'"...
142                     // If between "'" and ";", no escaping is needed
143                     if (ch < 0x3c) {
144                         buffIndex = addToBuffer(out, buff, buffIndex,
145                                                 buffLength, ch);
146                         // Note - "<" isn't escaped in attributes, as per
147                         // HTML spec
148                     } else if (ch == '>') {
149                         buffIndex = flushBuffer(out, buff, buffIndex);
150 
151                         out.write("&gt;");
152                     } else {
153                         buffIndex = addToBuffer(out, buff, buffIndex,
154                                                 buffLength, ch);
155                     }
156                 } else {
157                     if (ch == '&') {
158                         buffIndex = flushBuffer(out, buff, buffIndex);
159 
160                         // HTML 4.0, section B.7.1: ampersands followed by
161                         // an open brace don't get escaped
162                         if ((i + 1 < length) && (text.charAt(i + 1) == '{')) {
163                             out.write(ch);
164                         } else {
165                             out.write("&amp;");
166                         }
167                     } else if (ch == '"') {
168                         buffIndex = flushBuffer(out, buff, buffIndex);
169 
170                         out.write("&quot;");
171                     } else {
172                         buffIndex = addToBuffer(out, buff, buffIndex,
173                                                 buffLength, ch);
174                     }
175                 }
176             } else {
177                 buffIndex = flushBuffer(out, buff, buffIndex);
178 
179                 // Double-byte characters to encode.
180                 // PENDING: when outputting to an encoding that
181                 // supports double-byte characters (UTF-8, for example),
182                 // we should not be encoding
183                 _writeDecRef(out, ch);
184             }
185         }
186 
187         flushBuffer(out, buff, buffIndex);
188     }
189 
190     static public void writeAttribute(Writer out,
191                                       char[] buffer,
192                                       char[] text) throws IOException {
193         writeAttribute(out, buffer, text, 0, text.length);
194     }
195 
196     /**
197      * Write a character array attribute.  Note that this code
198      * is duplicated above for string - change both places if you make
199      * any changes!!!
200      */
201     static public void writeAttribute(Writer out,
202                                       char[] buff,
203                                       char[] text,
204                                       int start,
205                                       int length) throws IOException {
206         int buffLength = buff.length;
207         int buffIndex = 0;
208 
209         int end = start + length;
210         for (int i = start; i < end; i++) {
211             char ch = text[i];
212 
213             // Tilde or less...
214             if (ch < 0xA0) {
215                 // If "?" or over, no escaping is needed (this covers
216                 // most of the Latin alphabet)
217                 if (ch >= 0x3f) {
218                     buffIndex = addToBuffer(out, buff, buffIndex,
219                                             buffLength, ch);
220                 } else if (ch >= 0x27) { // If above "'"...
221                     if (ch < 0x3c) {
222                         // If between "'" and ";", no escaping is needed
223                         buffIndex = addToBuffer(out, buff, buffIndex,
224                                                 buffLength, ch);
225                         // Note - "<" isn't escaped in attributes, as per HTML spec
226                     } else if (ch == '>') {
227                         buffIndex = flushBuffer(out, buff, buffIndex);
228 
229                         out.write("&gt;");
230                     } else {
231                         buffIndex = addToBuffer(out, buff, buffIndex,
232                                                 buffLength, ch);
233                     }
234                 } else {
235                     if (ch == '&') {
236                         buffIndex = flushBuffer(out, buff, buffIndex);
237 
238                         // HTML 4.0, section B.7.1: ampersands followed by
239                         // an open brace don't get escaped
240                         if ((i + 1 < end) && (text[i + 1] == '{')) {
241                             out.write(ch);
242                         } else {
243                             out.write("&amp;");
244                         }
245                     } else if (ch == '"') {
246                         buffIndex = flushBuffer(out, buff, buffIndex);
247 
248                         out.write("&quot;");
249                     } else {
250                         buffIndex = addToBuffer(out, buff, buffIndex,
251                                                 buffLength, ch);
252                     }
253                 }
254             } else {
255                 buffIndex = flushBuffer(out, buff, buffIndex);
256 
257                 // Double-byte characters to encode.
258                 // PENDING: when outputting to an encoding that
259                 // supports double-byte characters (UTF-8, for example),
260                 // we should not be encoding
261                 _writeDecRef(out, ch);
262             }
263         }
264 
265         flushBuffer(out, buff, buffIndex);
266     }
267 
268     //-------------------------------------------------
269     // The following methods include the handling of
270     // escape characters....
271     //-------------------------------------------------
272 
273     static public void writeText(Writer out,
274                                  char[] buffer,
275                                  char[] text) throws IOException {
276         writeText(out, buffer, text, 0, text.length);
277     }
278 
279 
280     /**
281      * Write char array text.  Note that this code is duplicated below
282      * for Strings - change both places if you make any changes!!!
283      */
284     static public void writeText(Writer out,
285                                  char[] buff,
286                                  char[] text,
287                                  int start,
288                                  int length) throws IOException {
289         int buffLength = buff.length;
290         int buffIndex = 0;
291 
292         int end = start + length;
293         for (int i = start; i < end; i++) {
294             char ch = text[i];
295 
296             // Tilde or less...
297             if (ch < 0xA0) {
298                 // If "?" or over, no escaping is needed (this covers
299                 // most of the Latin alphabet)
300                 if (ch >= 0x3f) {
301                     buffIndex = addToBuffer(out, buff, buffIndex,
302                                             buffLength, ch);
303                 } else if (ch >= 0x27) { // If above "'"...
304                     // If between "'" and ";", no escaping is needed
305                     if (ch < 0x3c) {
306                         buffIndex = addToBuffer(out, buff, buffIndex,
307                                                 buffLength, ch);
308                     } else if (ch == '<') {
309                         buffIndex = flushBuffer(out, buff, buffIndex);
310 
311                         out.write("&lt;");
312                     } else if (ch == '>') {
313                         buffIndex = flushBuffer(out, buff, buffIndex);
314 
315                         out.write("&gt;");
316                     } else {
317                         buffIndex = addToBuffer(out, buff, buffIndex,
318                                                 buffLength, ch);
319                     }
320                 } else {
321                     if (ch == '&') {
322                         buffIndex = flushBuffer(out, buff, buffIndex);
323 
324                         out.write("&amp;");
325                     } else {
326                         buffIndex = addToBuffer(out, buff, buffIndex,
327                                                 buffLength, ch);
328                     }
329                 }
330             } else {
331                 // Double-byte characters to encode.
332                 // PENDING: when outputting to an encoding that
333                 // supports double-byte characters (UTF-8, for example),
334                 // we should not be encoding
335                 buffIndex = flushBuffer(out, buff, buffIndex);
336                 _writeDecRef(out, ch);
337             }
338         }
339 
340         flushBuffer(out, buff, buffIndex);
341     }
342 
343 
344     /**
345      * Write String text.  Note that this code is duplicated above for
346      * character arrays - change both places if you make any changes!!!
347      */
348     static public void writeText(Writer out,
349                                  char[] buff,
350                                  String text) throws IOException {
351         int buffLength = buff.length;
352         int buffIndex = 0;
353 
354         int length = text.length();
355 
356         for (int i = 0; i < length; i++) {
357             char ch = text.charAt(i);
358 
359             // Tilde or less...
360             if (ch < 0xA0) {
361                 // If "?" or over, no escaping is needed (this covers
362                 // most of the Latin alphabet)
363                 if (ch >= 0x3f) {
364                     buffIndex = addToBuffer(out, buff, buffIndex,
365                                             buffLength, ch);
366                 } else if (ch >= 0x27) {  // If above "'"...
367                     // If between "'" and ";", no escaping is needed
368                     if (ch < 0x3c) {
369                         buffIndex = addToBuffer(out, buff, buffIndex,
370                                                 buffLength, ch);
371                     } else if (ch == '<') {
372                         buffIndex = flushBuffer(out, buff, buffIndex);
373                         out.write("&lt;");
374                     } else if (ch == '>') {
375                         buffIndex = flushBuffer(out, buff, buffIndex);
376                         out.write("&gt;");
377                     } else {
378                         buffIndex = addToBuffer(out, buff, buffIndex,
379                                                 buffLength, ch);
380                     }
381                 } else {
382                     if (ch == '&') {
383                         buffIndex = flushBuffer(out, buff, buffIndex);
384 
385                         out.write("&amp;");
386                     } else {
387                         buffIndex = addToBuffer(out, buff, buffIndex,
388                                                 buffLength, ch);
389                     }
390                 }
391             } else {
392                 // Double-byte characters to encode.
393                 // PENDING: when outputting to an encoding that
394                 // supports double-byte characters (UTF-8, for example),
395                 // we should not be encoding
396                 buffIndex = flushBuffer(out, buff, buffIndex);
397                 _writeDecRef(out, ch);
398             }
399         }
400 
401         flushBuffer(out, buff, buffIndex);
402     }
403 
404     /**
405      * Writes a character as a decimal escape.  Hex escapes are smaller than
406      * the decimal version, but Netscape didn't support hex escapes until
407      * 4.7.4.
408      */
409     static private void _writeDecRef(Writer out, char ch) throws IOException {
410         if (ch == '\u20ac') {
411             out.write("&euro;");
412             return;
413         }
414         out.write("&#");
415         // Formerly used String.valueOf().  This version tests out
416         // about 40% faster in a microbenchmark (and on systems where GC is
417         // going gonzo, it should be even better)
418         int i = (int) ch;
419         if (i > 10000) {
420             out.write('0' + (i / 10000));
421             i = i % 10000;
422             out.write('0' + (i / 1000));
423             i = i % 1000;
424             out.write('0' + (i / 100));
425             i = i % 100;
426             out.write('0' + (i / 10));
427             i = i % 10;
428             out.write('0' + i);
429         } else if (i > 1000) {
430             out.write('0' + (i / 1000));
431             i = i % 1000;
432             out.write('0' + (i / 100));
433             i = i % 100;
434             out.write('0' + (i / 10));
435             i = i % 10;
436             out.write('0' + i);
437         } else {
438             out.write('0' + (i / 100));
439             i = i % 100;
440             out.write('0' + (i / 10));
441             i = i % 10;
442             out.write('0' + i);
443         }
444 
445         out.write(';');
446     }
447 
448     /**
449      * Flush the contents of the buffer to the output stream
450      * and return the reset buffer index
451      */
452     private static int flushBuffer(Writer out,
453                                    char[] buffer,
454                                    int bufferIndex) throws IOException {
455         if (bufferIndex > 0) {
456             out.write(buffer, 0, bufferIndex);
457         }
458 
459         return 0;
460     }
461 
462     /**
463      * Add a character to the buffer, flushing the buffer if the buffer is
464      * full, and returning the new buffer index
465      */
466     private static int addToBuffer(Writer out,
467                                    char[] buffer,
468                                    int bufferIndex,
469                                    int bufferLength,
470                                    char ch) throws IOException {
471         if (bufferIndex >= bufferLength) {
472             out.write(buffer, 0, bufferIndex);
473             bufferIndex = 0;
474         }
475 
476         buffer[bufferIndex] = ch;
477 
478         return bufferIndex + 1;
479     }
480 
481 
482 }
483