KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jasper > compiler > JspUtil


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.jasper.compiler;
19
20 import java.io.CharArrayWriter JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.InputStream JavaDoc;
23 import java.io.InputStreamReader JavaDoc;
24 import java.io.UnsupportedEncodingException JavaDoc;
25 import java.util.Vector JavaDoc;
26 import java.util.jar.JarFile JavaDoc;
27 import java.util.zip.ZipEntry JavaDoc;
28
29 import javax.el.FunctionMapper;
30 import javax.servlet.jsp.el.ELException JavaDoc;
31 import javax.servlet.jsp.el.ELParseException JavaDoc;
32 import javax.servlet.jsp.el.ExpressionEvaluator JavaDoc;
33
34
35 import org.apache.el.ExpressionFactoryImpl;
36 import org.apache.jasper.Constants;
37 import org.apache.jasper.JasperException;
38 import org.apache.jasper.JspCompilationContext;
39 import org.apache.jasper.el.ExpressionEvaluatorImpl;
40 import org.xml.sax.Attributes JavaDoc;
41
42 /**
43  * This class has all the utility method(s).
44  * Ideally should move all the bean containers here.
45  *
46  * @author Mandar Raje.
47  * @author Rajiv Mordani.
48  * @author Danno Ferrin
49  * @author Pierre Delisle
50  * @author Shawn Bayern
51  * @author Mark Roth
52  */

53 public class JspUtil {
54
55     private static final String JavaDoc WEB_INF_TAGS = "/WEB-INF/tags/";
56     private static final String JavaDoc META_INF_TAGS = "/META-INF/tags/";
57
58     // Delimiters for request-time expressions (JSP and XML syntax)
59
private static final String JavaDoc OPEN_EXPR = "<%=";
60     private static final String JavaDoc CLOSE_EXPR = "%>";
61     private static final String JavaDoc OPEN_EXPR_XML = "%=";
62     private static final String JavaDoc CLOSE_EXPR_XML = "%";
63
64     private static int tempSequenceNumber = 0;
65     
66     //private static ExpressionEvaluatorImpl expressionEvaluator
67
//= new ExpressionEvaluatorImpl();
68

69     //tc6
70
private final static ExpressionEvaluator JavaDoc expressionEvaluator =
71         new ExpressionEvaluatorImpl(new ExpressionFactoryImpl());
72
73     private static final String JavaDoc javaKeywords[] = {
74         "abstract", "assert", "boolean", "break", "byte", "case",
75         "catch", "char", "class", "const", "continue",
76         "default", "do", "double", "else", "enum", "extends",
77         "final", "finally", "float", "for", "goto",
78         "if", "implements", "import", "instanceof", "int",
79         "interface", "long", "native", "new", "package",
80         "private", "protected", "public", "return", "short",
81         "static", "strictfp", "super", "switch", "synchronized",
82         "this", "throws", "transient", "try", "void",
83         "volatile", "while" };
84
85     public static final int CHUNKSIZE = 1024;
86         
87     public static char[] removeQuotes(char []chars) {
88         CharArrayWriter JavaDoc caw = new CharArrayWriter JavaDoc();
89         for (int i = 0; i < chars.length; i++) {
90             if (chars[i] == '%' && chars[i+1] == '\\' &&
91                 chars[i+2] == '>') {
92                 caw.write('%');
93                 caw.write('>');
94                 i = i + 2;
95             } else {
96                 caw.write(chars[i]);
97             }
98         }
99         return caw.toCharArray();
100     }
101
102     public static char[] escapeQuotes (char []chars) {
103         // Prescan to convert %\> to %>
104
String JavaDoc s = new String JavaDoc(chars);
105         while (true) {
106             int n = s.indexOf("%\\>");
107             if (n < 0)
108                 break;
109             StringBuffer JavaDoc sb = new StringBuffer JavaDoc(s.substring(0, n));
110             sb.append("%>");
111             sb.append(s.substring(n + 3));
112             s = sb.toString();
113         }
114         chars = s.toCharArray();
115         return (chars);
116
117
118         // Escape all backslashes not inside a Java string literal
119
/*
120         CharArrayWriter caw = new CharArrayWriter();
121         boolean inJavaString = false;
122         for (int i = 0; i < chars.length; i++) {
123             if (chars[i] == '"') inJavaString = !inJavaString;
124             // escape out the escape character
125             if (!inJavaString && (chars[i] == '\\')) caw.write('\\');
126             caw.write(chars[i]);
127         }
128         return caw.toCharArray();
129         */

130     }
131
132     /**
133      * Checks if the token is a runtime expression.
134      * In standard JSP syntax, a runtime expression starts with '<%' and
135      * ends with '%>'. When the JSP document is in XML syntax, a runtime
136      * expression starts with '%=' and ends with '%'.
137      *
138      * @param token The token to be checked
139      * return whether the token is a runtime expression or not.
140      */

141     public static boolean isExpression(String JavaDoc token, boolean isXml) {
142     String JavaDoc openExpr;
143     String JavaDoc closeExpr;
144     if (isXml) {
145         openExpr = OPEN_EXPR_XML;
146         closeExpr = CLOSE_EXPR_XML;
147     } else {
148         openExpr = OPEN_EXPR;
149         closeExpr = CLOSE_EXPR;
150     }
151     if (token.startsWith(openExpr) && token.endsWith(closeExpr)) {
152         return true;
153     } else {
154         return false;
155     }
156     }
157
158     /**
159      * @return the "expression" part of a runtime expression,
160      * taking the delimiters out.
161      */

162     public static String JavaDoc getExpr (String JavaDoc expression, boolean isXml) {
163     String JavaDoc returnString;
164     String JavaDoc openExpr;
165     String JavaDoc closeExpr;
166     if (isXml) {
167         openExpr = OPEN_EXPR_XML;
168         closeExpr = CLOSE_EXPR_XML;
169     } else {
170         openExpr = OPEN_EXPR;
171         closeExpr = CLOSE_EXPR;
172     }
173     int length = expression.length();
174     if (expression.startsWith(openExpr) &&
175                 expression.endsWith(closeExpr)) {
176         returnString = expression.substring(
177                                openExpr.length(), length - closeExpr.length());
178     } else {
179         returnString = "";
180     }
181     return returnString;
182     }
183
184     /**
185      * Takes a potential expression and converts it into XML form
186      */

187     public static String JavaDoc getExprInXml(String JavaDoc expression) {
188         String JavaDoc returnString;
189         int length = expression.length();
190
191         if (expression.startsWith(OPEN_EXPR)
192                 && expression.endsWith(CLOSE_EXPR)) {
193             returnString = expression.substring (1, length - 1);
194         } else {
195             returnString = expression;
196         }
197
198         return escapeXml(returnString.replace(Constants.ESC, '$'));
199     }
200
201     /**
202      * Checks to see if the given scope is valid.
203      *
204      * @param scope The scope to be checked
205      * @param n The Node containing the 'scope' attribute whose value is to be
206      * checked
207      * @param err error dispatcher
208      *
209      * @throws JasperException if scope is not null and different from
210      * &quot;page&quot;, &quot;request&quot;, &quot;session&quot;, and
211      * &quot;application&quot;
212      */

213     public static void checkScope(String JavaDoc scope, Node n, ErrorDispatcher err)
214             throws JasperException {
215     if (scope != null && !scope.equals("page") && !scope.equals("request")
216         && !scope.equals("session") && !scope.equals("application")) {
217         err.jspError(n, "jsp.error.invalid.scope", scope);
218     }
219     }
220
221     /**
222      * Checks if all mandatory attributes are present and if all attributes
223      * present have valid names. Checks attributes specified as XML-style
224      * attributes as well as attributes specified using the jsp:attribute
225      * standard action.
226      */

227     public static void checkAttributes(String JavaDoc typeOfTag,
228                        Node n,
229                        ValidAttribute[] validAttributes,
230                        ErrorDispatcher err)
231                 throws JasperException {
232         Attributes JavaDoc attrs = n.getAttributes();
233         Mark start = n.getStart();
234     boolean valid = true;
235
236         // AttributesImpl.removeAttribute is broken, so we do this...
237
int tempLength = (attrs == null) ? 0 : attrs.getLength();
238     Vector JavaDoc temp = new Vector JavaDoc(tempLength, 1);
239         for (int i = 0; i < tempLength; i++) {
240             String JavaDoc qName = attrs.getQName(i);
241             if ((!qName.equals("xmlns")) && (!qName.startsWith("xmlns:")))
242                 temp.addElement(qName);
243         }
244
245         // Add names of attributes specified using jsp:attribute
246
Node.Nodes tagBody = n.getBody();
247         if( tagBody != null ) {
248             int numSubElements = tagBody.size();
249             for( int i = 0; i < numSubElements; i++ ) {
250                 Node node = tagBody.getNode( i );
251                 if( node instanceof Node.NamedAttribute ) {
252                     String JavaDoc attrName = node.getAttributeValue( "name" );
253                     temp.addElement( attrName );
254             // Check if this value appear in the attribute of the node
255
if (n.getAttributeValue(attrName) != null) {
256             err.jspError(n, "jsp.error.duplicate.name.jspattribute",
257                     attrName);
258             }
259                 }
260                 else {
261                     // Nothing can come before jsp:attribute, and only
262
// jsp:body can come after it.
263
break;
264                 }
265             }
266         }
267
268     /*
269      * First check to see if all the mandatory attributes are present.
270      * If so only then proceed to see if the other attributes are valid
271      * for the particular tag.
272      */

273     String JavaDoc missingAttribute = null;
274
275     for (int i = 0; i < validAttributes.length; i++) {
276         int attrPos;
277         if (validAttributes[i].mandatory) {
278                 attrPos = temp.indexOf(validAttributes[i].name);
279         if (attrPos != -1) {
280             temp.remove(attrPos);
281             valid = true;
282         } else {
283             valid = false;
284             missingAttribute = validAttributes[i].name;
285             break;
286         }
287         }
288     }
289
290     // If mandatory attribute is missing then the exception is thrown
291
if (!valid)
292         err.jspError(start, "jsp.error.mandatory.attribute", typeOfTag,
293              missingAttribute);
294
295     // Check to see if there are any more attributes for the specified tag.
296
int attrLeftLength = temp.size();
297     if (attrLeftLength == 0)
298         return;
299
300     // Now check to see if the rest of the attributes are valid too.
301
String JavaDoc attribute = null;
302
303     for (int j = 0; j < attrLeftLength; j++) {
304         valid = false;
305         attribute = (String JavaDoc) temp.elementAt(j);
306         for (int i = 0; i < validAttributes.length; i++) {
307         if (attribute.equals(validAttributes[i].name)) {
308             valid = true;
309             break;
310         }
311         }
312         if (!valid)
313         err.jspError(start, "jsp.error.invalid.attribute", typeOfTag,
314                  attribute);
315     }
316     // XXX *could* move EL-syntax validation here... (sb)
317
}
318     
319     public static String JavaDoc escapeQueryString(String JavaDoc unescString) {
320     if ( unescString == null )
321         return null;
322     
323     String JavaDoc escString = "";
324     String JavaDoc shellSpChars = "\\\"";
325     
326     for(int index=0; index<unescString.length(); index++) {
327         char nextChar = unescString.charAt(index);
328         
329         if( shellSpChars.indexOf(nextChar) != -1 )
330         escString += "\\";
331         
332         escString += nextChar;
333     }
334     return escString;
335     }
336  
337     /**
338      * Escape the 5 entities defined by XML.
339      */

340     public static String JavaDoc escapeXml(String JavaDoc s) {
341         if (s == null) return null;
342         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
343         for(int i=0; i<s.length(); i++) {
344             char c = s.charAt(i);
345             if (c == '<') {
346                 sb.append("&lt;");
347             } else if (c == '>') {
348                 sb.append("&gt;");
349             } else if (c == '\'') {
350                 sb.append("&apos;");
351             } else if (c == '&') {
352                 sb.append("&amp;");
353             } else if (c == '"') {
354                 sb.append("&quot;");
355             } else {
356                 sb.append(c);
357             }
358         }
359         return sb.toString();
360     }
361
362     /**
363      * Replaces any occurrences of the character <tt>replace</tt> with the
364      * string <tt>with</tt>.
365      */

366     public static String JavaDoc replace(String JavaDoc name, char replace, String JavaDoc with) {
367     StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
368     int begin = 0;
369     int end;
370     int last = name.length();
371
372     while (true) {
373         end = name.indexOf(replace, begin);
374         if (end < 0) {
375         end = last;
376         }
377         buf.append(name.substring(begin, end));
378         if (end == last) {
379         break;
380         }
381         buf.append(with);
382         begin = end + 1;
383     }
384     
385     return buf.toString();
386     }
387
388     public static class ValidAttribute {
389     String JavaDoc name;
390     boolean mandatory;
391     boolean rtexprvalue; // not used now
392

393     public ValidAttribute (String JavaDoc name, boolean mandatory,
394             boolean rtexprvalue )
395         {
396         this.name = name;
397         this.mandatory = mandatory;
398             this.rtexprvalue = rtexprvalue;
399         }
400
401        public ValidAttribute (String JavaDoc name, boolean mandatory) {
402             this( name, mandatory, false );
403     }
404
405     public ValidAttribute (String JavaDoc name) {
406         this (name, false);
407     }
408     }
409     
410     /**
411      * Convert a String value to 'boolean'.
412      * Besides the standard conversions done by
413      * Boolean.valueOf(s).booleanValue(), the value "yes"
414      * (ignore case) is also converted to 'true'.
415      * If 's' is null, then 'false' is returned.
416      *
417      * @param s the string to be converted
418      * @return the boolean value associated with the string s
419      */

420     public static boolean booleanValue(String JavaDoc s) {
421     boolean b = false;
422     if (s != null) {
423         if (s.equalsIgnoreCase("yes")) {
424         b = true;
425         } else {
426         b = Boolean.valueOf(s).booleanValue();
427         }
428     }
429     return b;
430     }
431
432     /**
433      * Returns the <tt>Class</tt> object associated with the class or
434      * interface with the given string name.
435      *
436      * <p> The <tt>Class</tt> object is determined by passing the given string
437      * name to the <tt>Class.forName()</tt> method, unless the given string
438      * name represents a primitive type, in which case it is converted to a
439      * <tt>Class</tt> object by appending ".class" to it (e.g., "int.class").
440      */

441     public static Class JavaDoc toClass(String JavaDoc type, ClassLoader JavaDoc loader)
442         throws ClassNotFoundException JavaDoc {
443
444     Class JavaDoc c = null;
445     int i0 = type.indexOf('[');
446     int dims = 0;
447     if (i0 > 0) {
448         // This is an array. Count the dimensions
449
for (int i = 0; i < type.length(); i++) {
450         if (type.charAt(i) == '[')
451             dims++;
452         }
453         type = type.substring(0, i0);
454     }
455
456     if ("boolean".equals(type))
457         c = boolean.class;
458     else if ("char".equals(type))
459         c = char.class;
460     else if ("byte".equals(type))
461         c = byte.class;
462     else if ("short".equals(type))
463         c = short.class;
464     else if ("int".equals(type))
465         c = int.class;
466     else if ("long".equals(type))
467         c = long.class;
468     else if ("float".equals(type))
469         c = float.class;
470     else if ("double".equals(type))
471         c = double.class;
472     else if (type.indexOf('[') < 0)
473         c = loader.loadClass(type);
474
475     if (dims == 0)
476         return c;
477
478     if (dims == 1)
479         return java.lang.reflect.Array.newInstance(c, 1).getClass();
480
481     // Array of more than i dimension
482
return java.lang.reflect.Array.newInstance(c, new int[dims]).getClass();
483     }
484     
485     /**
486      * Produces a String representing a call to the EL interpreter.
487      * @param expression a String containing zero or more "${}" expressions
488      * @param expectedType the expected type of the interpreted result
489      * @param fnmapvar Variable pointing to a function map.
490      * @param XmlEscape True if the result should do XML escaping
491      * @return a String representing a call to the EL interpreter.
492      */

493     public static String JavaDoc interpreterCall(boolean isTagFile,
494                      String JavaDoc expression,
495                                          Class JavaDoc expectedType,
496                                          String JavaDoc fnmapvar,
497                                          boolean XmlEscape )
498     {
499         /*
500          * Determine which context object to use.
501          */

502     String JavaDoc jspCtxt = null;
503     if (isTagFile)
504         jspCtxt = "this.getJspContext()";
505     else
506         jspCtxt = "_jspx_page_context";
507
508     /*
509          * Determine whether to use the expected type's textual name
510      * or, if it's a primitive, the name of its correspondent boxed
511      * type.
512          */

513     String JavaDoc targetType = expectedType.getName();
514     String JavaDoc primitiveConverterMethod = null;
515     if (expectedType.isPrimitive()) {
516         if (expectedType.equals(Boolean.TYPE)) {
517         targetType = Boolean JavaDoc.class.getName();
518         primitiveConverterMethod = "booleanValue";
519         } else if (expectedType.equals(Byte.TYPE)) {
520         targetType = Byte JavaDoc.class.getName();
521         primitiveConverterMethod = "byteValue";
522         } else if (expectedType.equals(Character.TYPE)) {
523         targetType = Character JavaDoc.class.getName();
524         primitiveConverterMethod = "charValue";
525         } else if (expectedType.equals(Short.TYPE)) {
526         targetType = Short JavaDoc.class.getName();
527         primitiveConverterMethod = "shortValue";
528         } else if (expectedType.equals(Integer.TYPE)) {
529         targetType = Integer JavaDoc.class.getName();
530         primitiveConverterMethod = "intValue";
531         } else if (expectedType.equals(Long.TYPE)) {
532         targetType = Long JavaDoc.class.getName();
533         primitiveConverterMethod = "longValue";
534         } else if (expectedType.equals(Float.TYPE)) {
535         targetType = Float JavaDoc.class.getName();
536         primitiveConverterMethod = "floatValue";
537         } else if (expectedType.equals(Double.TYPE)) {
538         targetType = Double JavaDoc.class.getName();
539         primitiveConverterMethod = "doubleValue";
540         }
541     }
542  
543     if (primitiveConverterMethod != null) {
544         XmlEscape = false;
545     }
546
547     /*
548          * Build up the base call to the interpreter.
549          */

550         // XXX - We use a proprietary call to the interpreter for now
551
// as the current standard machinery is inefficient and requires
552
// lots of wrappers and adapters. This should all clear up once
553
// the EL interpreter moves out of JSTL and into its own project.
554
// In the future, this should be replaced by code that calls
555
// ExpressionEvaluator.parseExpression() and then cache the resulting
556
// expression objects. The interpreterCall would simply select
557
// one of the pre-cached expressions and evaluate it.
558
// Note that PageContextImpl implements VariableResolver and
559
// the generated Servlet/SimpleTag implements FunctionMapper, so
560
// that machinery is already in place (mroth).
561
targetType = toJavaSourceType(targetType);
562     StringBuffer JavaDoc call = new StringBuffer JavaDoc(
563              "(" + targetType + ") "
564                + "org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate"
565                + "(" + Generator.quote(expression) + ", "
566                + targetType + ".class, "
567            + "(PageContext)" + jspCtxt
568                + ", " + fnmapvar
569            + ", " + XmlEscape
570                + ")");
571  
572     /*
573          * Add the primitive converter method if we need to.
574          */

575     if (primitiveConverterMethod != null) {
576         call.insert(0, "(");
577         call.append(")." + primitiveConverterMethod + "()");
578     }
579  
580     return call.toString();
581     }
582
583     /**
584      * Validates the syntax of all ${} expressions within the given string.
585      * @param where the approximate location of the expressions in the JSP page
586      * @param expressions a string containing zero or more "${}" expressions
587      * @param err an error dispatcher to use
588      * @deprecated now delegated to the org.apache.el Package
589      */

590     public static void validateExpressions(Mark where,
591                                            String JavaDoc expressions,
592                                            Class JavaDoc expectedType,
593                                            FunctionMapper functionMapper,
594                                            ErrorDispatcher err)
595             throws JasperException {
596
597 // try {
598
//
599
// JspUtil.expressionEvaluator.parseExpression( expressions,
600
// expectedType, functionMapper );
601
// }
602
// catch( ELParseException e ) {
603
// err.jspError(where, "jsp.error.invalid.expression", expressions,
604
// e.toString() );
605
// }
606
// catch( ELException e ) {
607
// err.jspError(where, "jsp.error.invalid.expression", expressions,
608
// e.toString() );
609
// }
610
}
611
612     /**
613      * Resets the temporary variable name.
614      * (not thread-safe)
615      */

616     public static void resetTemporaryVariableName() {
617         tempSequenceNumber = 0;
618     }
619
620     /**
621      * Generates a new temporary variable name.
622      * (not thread-safe)
623      */

624     public static String JavaDoc nextTemporaryVariableName() {
625         return Constants.TEMP_VARIABLE_NAME_PREFIX + (tempSequenceNumber++);
626     }
627
628     public static String JavaDoc coerceToPrimitiveBoolean(String JavaDoc s,
629                           boolean isNamedAttribute) {
630     if (isNamedAttribute) {
631         return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToBoolean(" + s + ")";
632     } else {
633         if (s == null || s.length() == 0)
634         return "false";
635         else
636         return Boolean.valueOf(s).toString();
637     }
638     }
639
640     public static String JavaDoc coerceToBoolean(String JavaDoc s, boolean isNamedAttribute) {
641     if (isNamedAttribute) {
642         return "(Boolean) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Boolean.class)";
643     } else {
644         if (s == null || s.length() == 0) {
645         return "new Boolean(false)";
646         } else {
647         // Detect format error at translation time
648
return "new Boolean(" + Boolean.valueOf(s).toString() + ")";
649         }
650     }
651     }
652
653     public static String JavaDoc coerceToPrimitiveByte(String JavaDoc s,
654                            boolean isNamedAttribute) {
655     if (isNamedAttribute) {
656         return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToByte(" + s + ")";
657     } else {
658         if (s == null || s.length() == 0)
659         return "(byte) 0";
660         else
661         return "((byte)" + Byte.valueOf(s).toString() + ")";
662     }
663     }
664
665     public static String JavaDoc coerceToByte(String JavaDoc s, boolean isNamedAttribute) {
666     if (isNamedAttribute) {
667         return "(Byte) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Byte.class)";
668     } else {
669         if (s == null || s.length() == 0) {
670         return "new Byte((byte) 0)";
671         } else {
672         // Detect format error at translation time
673
return "new Byte((byte)" + Byte.valueOf(s).toString() + ")";
674         }
675     }
676     }
677
678     public static String JavaDoc coerceToChar(String JavaDoc s, boolean isNamedAttribute) {
679     if (isNamedAttribute) {
680         return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToChar(" + s + ")";
681     } else {
682         if (s == null || s.length() == 0) {
683         return "(char) 0";
684         } else {
685         char ch = s.charAt(0);
686         // this trick avoids escaping issues
687
return "((char) " + (int) ch + ")";
688         }
689     }
690     }
691
692     public static String JavaDoc coerceToCharacter(String JavaDoc s, boolean isNamedAttribute) {
693     if (isNamedAttribute) {
694         return "(Character) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Character.class)";
695     } else {
696         if (s == null || s.length() == 0) {
697         return "new Character((char) 0)";
698         } else {
699         char ch = s.charAt(0);
700         // this trick avoids escaping issues
701
return "new Character((char) " + (int) ch + ")";
702         }
703     }
704     }
705
706     public static String JavaDoc coerceToPrimitiveDouble(String JavaDoc s,
707                          boolean isNamedAttribute) {
708     if (isNamedAttribute) {
709         return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToDouble(" + s + ")";
710     } else {
711         if (s == null || s.length() == 0)
712         return "(double) 0";
713         else
714         return Double.valueOf(s).toString();
715     }
716     }
717
718     public static String JavaDoc coerceToDouble(String JavaDoc s, boolean isNamedAttribute) {
719     if (isNamedAttribute) {
720         return "(Double) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Double.class)";
721     } else {
722         if (s == null || s.length() == 0) {
723         return "new Double(0)";
724         } else {
725         // Detect format error at translation time
726
return "new Double(" + Double.valueOf(s).toString() + ")";
727         }
728     }
729     }
730
731     public static String JavaDoc coerceToPrimitiveFloat(String JavaDoc s,
732                         boolean isNamedAttribute) {
733     if (isNamedAttribute) {
734         return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToFloat(" + s + ")";
735     } else {
736         if (s == null || s.length() == 0)
737         return "(float) 0";
738         else
739         return Float.valueOf(s).toString() + "f";
740     }
741     }
742
743     public static String JavaDoc coerceToFloat(String JavaDoc s, boolean isNamedAttribute) {
744     if (isNamedAttribute) {
745         return "(Float) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Float.class)";
746     } else {
747         if (s == null || s.length() == 0) {
748         return "new Float(0)";
749         } else {
750         // Detect format error at translation time
751
return "new Float(" + Float.valueOf(s).toString() + "f)";
752         }
753     }
754     }
755
756     public static String JavaDoc coerceToInt(String JavaDoc s, boolean isNamedAttribute) {
757     if (isNamedAttribute) {
758         return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToInt(" + s + ")";
759     } else {
760         if (s == null || s.length() == 0)
761         return "0";
762         else
763         return Integer.valueOf(s).toString();
764     }
765     }
766
767     public static String JavaDoc coerceToInteger(String JavaDoc s, boolean isNamedAttribute) {
768     if (isNamedAttribute) {
769         return "(Integer) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Integer.class)";
770     } else {
771         if (s == null || s.length() == 0) {
772         return "new Integer(0)";
773         } else {
774         // Detect format error at translation time
775
return "new Integer(" + Integer.valueOf(s).toString() + ")";
776         }
777     }
778     }
779
780     public static String JavaDoc coerceToPrimitiveShort(String JavaDoc s,
781                         boolean isNamedAttribute) {
782     if (isNamedAttribute) {
783         return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToShort(" + s + ")";
784     } else {
785         if (s == null || s.length() == 0)
786         return "(short) 0";
787         else
788         return "((short) " + Short.valueOf(s).toString() + ")";
789     }
790     }
791     
792     public static String JavaDoc coerceToShort(String JavaDoc s, boolean isNamedAttribute) {
793     if (isNamedAttribute) {
794         return "(Short) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Short.class)";
795     } else {
796         if (s == null || s.length() == 0) {
797         return "new Short((short) 0)";
798         } else {
799         // Detect format error at translation time
800
return "new Short(\"" + Short.valueOf(s).toString() + "\")";
801         }
802     }
803     }
804     
805     public static String JavaDoc coerceToPrimitiveLong(String JavaDoc s,
806                            boolean isNamedAttribute) {
807     if (isNamedAttribute) {
808         return "org.apache.jasper.runtime.JspRuntimeLibrary.coerceToLong(" + s + ")";
809     } else {
810         if (s == null || s.length() == 0)
811         return "(long) 0";
812         else
813         return Long.valueOf(s).toString() + "l";
814     }
815     }
816
817     public static String JavaDoc coerceToLong(String JavaDoc s, boolean isNamedAttribute) {
818     if (isNamedAttribute) {
819         return "(Long) org.apache.jasper.runtime.JspRuntimeLibrary.coerce(" + s + ", Long.class)";
820     } else {
821         if (s == null || s.length() == 0) {
822         return "new Long(0)";
823         } else {
824         // Detect format error at translation time
825
return "new Long(" + Long.valueOf(s).toString() + "l)";
826         }
827     }
828     }
829
830     public static InputStream JavaDoc getInputStream(String JavaDoc fname, JarFile JavaDoc jarFile,
831                          JspCompilationContext ctxt,
832                          ErrorDispatcher err)
833         throws JasperException, IOException JavaDoc {
834
835         InputStream JavaDoc in = null;
836
837     if (jarFile != null) {
838         String JavaDoc jarEntryName = fname.substring(1, fname.length());
839         ZipEntry JavaDoc jarEntry = jarFile.getEntry(jarEntryName);
840         if (jarEntry == null) {
841         err.jspError("jsp.error.file.not.found", fname);
842         }
843         in = jarFile.getInputStream(jarEntry);
844     } else {
845         in = ctxt.getResourceAsStream(fname);
846     }
847
848     if (in == null) {
849         err.jspError("jsp.error.file.not.found", fname);
850     }
851
852     return in;
853     }
854
855     /**
856      * Gets the fully-qualified class name of the tag handler corresponding to
857      * the given tag file path.
858      *
859      * @param path Tag file path
860      * @param err Error dispatcher
861      *
862      * @return Fully-qualified class name of the tag handler corresponding to
863      * the given tag file path
864      */

865     public static String JavaDoc getTagHandlerClassName(String JavaDoc path,
866                         ErrorDispatcher err)
867                 throws JasperException {
868
869         String JavaDoc className = null;
870         int begin = 0;
871         int index;
872         
873         index = path.lastIndexOf(".tag");
874         if (index == -1) {
875             err.jspError("jsp.error.tagfile.badSuffix", path);
876         }
877
878         //It's tempting to remove the ".tag" suffix here, but we can't.
879
//If we remove it, the fully-qualified class name of this tag
880
//could conflict with the package name of other tags.
881
//For instance, the tag file
882
// /WEB-INF/tags/foo.tag
883
//would have fully-qualified class name
884
// org.apache.jsp.tag.web.foo
885
//which would conflict with the package name of the tag file
886
// /WEB-INF/tags/foo/bar.tag
887

888         index = path.indexOf(WEB_INF_TAGS);
889         if (index != -1) {
890             className = "org.apache.jsp.tag.web.";
891             begin = index + WEB_INF_TAGS.length();
892         } else {
893         index = path.indexOf(META_INF_TAGS);
894         if (index != -1) {
895         className = "org.apache.jsp.tag.meta.";
896         begin = index + META_INF_TAGS.length();
897         } else {
898         err.jspError("jsp.error.tagfile.illegalPath", path);
899         }
900     }
901
902         className += makeJavaPackage(path.substring(begin));
903   
904        return className;
905     }
906
907     /**
908      * Converts the given path to a Java package or fully-qualified class name
909      *
910      * @param path Path to convert
911      *
912      * @return Java package corresponding to the given path
913      */

914     public static final String JavaDoc makeJavaPackage(String JavaDoc path) {
915         String JavaDoc classNameComponents[] = split(path,"/");
916         StringBuffer JavaDoc legalClassNames = new StringBuffer JavaDoc();
917         for (int i = 0; i < classNameComponents.length; i++) {
918             legalClassNames.append(makeJavaIdentifier(classNameComponents[i]));
919             if (i < classNameComponents.length - 1) {
920                 legalClassNames.append('.');
921             }
922         }
923         return legalClassNames.toString();
924     }
925
926     /**
927      * Splits a string into it's components.
928      * @param path String to split
929      * @param pat Pattern to split at
930      * @return the components of the path
931      */

932     private static final String JavaDoc [] split(String JavaDoc path, String JavaDoc pat) {
933         Vector JavaDoc comps = new Vector JavaDoc();
934         int pos = path.indexOf(pat);
935         int start = 0;
936         while( pos >= 0 ) {
937             if(pos > start ) {
938                 String JavaDoc comp = path.substring(start,pos);
939                 comps.add(comp);
940             }
941             start = pos + pat.length();
942             pos = path.indexOf(pat,start);
943         }
944         if( start < path.length()) {
945             comps.add(path.substring(start));
946         }
947         String JavaDoc [] result = new String JavaDoc[comps.size()];
948         for(int i=0; i < comps.size(); i++) {
949             result[i] = (String JavaDoc)comps.elementAt(i);
950         }
951         return result;
952     }
953             
954     /**
955      * Converts the given identifier to a legal Java identifier
956      *
957      * @param identifier Identifier to convert
958      *
959      * @return Legal Java identifier corresponding to the given identifier
960      */

961     public static final String JavaDoc makeJavaIdentifier(String JavaDoc identifier) {
962         StringBuffer JavaDoc modifiedIdentifier =
963             new StringBuffer JavaDoc(identifier.length());
964         if (!Character.isJavaIdentifierStart(identifier.charAt(0))) {
965             modifiedIdentifier.append('_');
966         }
967         for (int i = 0; i < identifier.length(); i++) {
968             char ch = identifier.charAt(i);
969             if (Character.isJavaIdentifierPart(ch) && ch != '_') {
970                 modifiedIdentifier.append(ch);
971             } else if (ch == '.') {
972                 modifiedIdentifier.append('_');
973             } else {
974                 modifiedIdentifier.append(mangleChar(ch));
975             }
976         }
977         if (isJavaKeyword(modifiedIdentifier.toString())) {
978             modifiedIdentifier.append('_');
979         }
980         return modifiedIdentifier.toString();
981     }
982     
983     /**
984      * Mangle the specified character to create a legal Java class name.
985      */

986     public static final String JavaDoc mangleChar(char ch) {
987         char[] result = new char[5];
988         result[0] = '_';
989         result[1] = Character.forDigit((ch >> 12) & 0xf, 16);
990         result[2] = Character.forDigit((ch >> 8) & 0xf, 16);
991         result[3] = Character.forDigit((ch >> 4) & 0xf, 16);
992         result[4] = Character.forDigit(ch & 0xf, 16);
993         return new String JavaDoc(result);
994     }
995
996     /**
997      * Test whether the argument is a Java keyword
998      */

999     public static boolean isJavaKeyword(String JavaDoc key) {
1000        int i = 0;
1001        int j = javaKeywords.length;
1002        while (i < j) {
1003            int k = (i+j)/2;
1004            int result = javaKeywords[k].compareTo(key);
1005            if (result == 0) {
1006                return true;
1007            }
1008            if (result < 0) {
1009                i = k+1;
1010            } else {
1011                j = k;
1012            }
1013        }
1014        return false;
1015    }
1016
1017    /**
1018     * Converts the given Xml name to a legal Java identifier. This is
1019     * slightly more efficient than makeJavaIdentifier in that we only need
1020     * to worry about '.', '-', and ':' in the string. We also assume that
1021     * the resultant string is further concatenated with some prefix string
1022     * so that we don't have to worry about it being a Java key word.
1023     *
1024     * @param name Identifier to convert
1025     *
1026     * @return Legal Java identifier corresponding to the given identifier
1027     */

1028    public static final String JavaDoc makeXmlJavaIdentifier(String JavaDoc name) {
1029        if (name.indexOf('-') >= 0)
1030            name = replace(name, '-', "$1");
1031        if (name.indexOf('.') >= 0)
1032            name = replace(name, '.', "$2");
1033        if (name.indexOf(':') >= 0)
1034            name = replace(name, ':', "$3");
1035        return name;
1036    }
1037
1038    static InputStreamReader JavaDoc getReader(String JavaDoc fname, String JavaDoc encoding,
1039                       JarFile JavaDoc jarFile,
1040                       JspCompilationContext ctxt,
1041                       ErrorDispatcher err)
1042        throws JasperException, IOException JavaDoc {
1043
1044        InputStreamReader JavaDoc reader = null;
1045    InputStream JavaDoc in = getInputStream(fname, jarFile, ctxt, err);
1046
1047    try {
1048            reader = new InputStreamReader JavaDoc(in, encoding);
1049    } catch (UnsupportedEncodingException JavaDoc ex) {
1050        err.jspError("jsp.error.unsupported.encoding", encoding);
1051    }
1052
1053    return reader;
1054    }
1055    
1056    /**
1057     * Handles taking input from TLDs
1058     * 'java.lang.Object' -> 'java.lang.Object.class'
1059     * 'int' -> 'int.class'
1060     * 'void' -> 'Void.TYPE'
1061     * 'int[]' -> 'int[].class'
1062     *
1063     * @param type
1064     * @return
1065     */

1066    public static String JavaDoc toJavaSourceTypeFromTld(String JavaDoc type) {
1067        if (type == null || "void".equals(type)) {
1068            return "Void.TYPE";
1069        }
1070        return type + ".class";
1071    }
1072
1073    /**
1074     * Class.getName() return arrays in the form "[[[<et>", where et,
1075     * the element type can be one of ZBCDFIJS or L<classname>;
1076     * It is converted into forms that can be understood by javac.
1077     */

1078    public static String JavaDoc toJavaSourceType(String JavaDoc type) {
1079
1080    if (type.charAt(0) != '[') {
1081        return type;
1082    }
1083
1084    int dims = 1;
1085    String JavaDoc t = null;
1086    for (int i = 1; i < type.length(); i++) {
1087        if (type.charAt(i) == '[') {
1088        dims++;
1089        } else {
1090        switch (type.charAt(i)) {
1091        case 'Z': t = "boolean"; break;
1092        case 'B': t = "byte"; break;
1093        case 'C': t = "char"; break;
1094        case 'D': t = "double"; break;
1095        case 'F': t = "float"; break;
1096        case 'I': t = "int"; break;
1097        case 'J': t = "long"; break;
1098        case 'S': t = "short"; break;
1099        case 'L': t = type.substring(i+1, type.indexOf(';')); break;
1100        }
1101        break;
1102        }
1103    }
1104    StringBuffer JavaDoc resultType = new StringBuffer JavaDoc(t);
1105    for (; dims > 0; dims--) {
1106        resultType.append("[]");
1107    }
1108    return resultType.toString();
1109    }
1110
1111    /**
1112     * Compute the canonical name from a Class instance. Note that a
1113     * simple replacment of '$' with '.' of a binary name would not work,
1114     * as '$' is a legal Java Identifier character.
1115     * @param c A instance of java.lang.Class
1116     * @return The canonical name of c.
1117     */

1118    public static String JavaDoc getCanonicalName(Class JavaDoc c) {
1119
1120        String JavaDoc binaryName = c.getName();
1121        c = c.getDeclaringClass();
1122
1123        if (c == null) {
1124            return binaryName;
1125        }
1126
1127        StringBuffer JavaDoc buf = new StringBuffer JavaDoc(binaryName);
1128        do {
1129            buf.setCharAt(c.getName().length(), '.');
1130            c = c.getDeclaringClass();
1131        } while ( c != null);
1132
1133        return buf.toString();
1134    }
1135}
Popular Tags