KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > jsp > java > GenericTag


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.jsp.java;
31
32 import com.caucho.jsp.JspParseException;
33 import com.caucho.jsp.TagInstance;
34 import com.caucho.util.BeanUtil;
35 import com.caucho.vfs.WriteStream;
36 import com.caucho.xml.QName;
37
38 import javax.servlet.jsp.tagext.*;
39 import java.beans.BeanInfo JavaDoc;
40 import java.beans.Introspector JavaDoc;
41 import java.io.IOException JavaDoc;
42 import java.lang.reflect.Method JavaDoc;
43 import java.lang.reflect.Modifier JavaDoc;
44 import java.util.ArrayList JavaDoc;
45 import java.util.HashSet JavaDoc;
46 import java.util.Hashtable JavaDoc;
47 import java.util.logging.Level JavaDoc;
48
49 /**
50  * Represents a custom tag.
51  */

52 abstract public class GenericTag extends JspContainerNode
53 {
54   private static final String JavaDoc DEFAULT_VAR_TYPE = "java.lang.String";
55
56   private static final HashSet JavaDoc<String JavaDoc> _primTypes
57     = new HashSet JavaDoc<String JavaDoc>();
58   
59   protected TagInstance _tag;
60   protected TagInfo _tagInfo;
61   protected Class JavaDoc _tagClass;
62   protected VariableInfo []_varInfo;
63   
64   public GenericTag()
65   {
66   }
67   
68   public void setTagInfo(TagInfo tagInfo)
69   {
70     _tagInfo = tagInfo;
71   }
72
73   public TagInfo getTagInfo()
74   {
75     return _tagInfo;
76   }
77
78   public TagInstance getTag()
79   {
80     return _tag;
81   }
82
83   /**
84    * Returns the tag name for the current tag.
85    */

86   public String JavaDoc getCustomTagName()
87   {
88     return _tag.getId();
89   }
90
91   /**
92    * Returns true if the tag is a simple tag.
93    */

94   public boolean isSimple()
95   {
96     return _tag.isSimpleTag();
97   }
98
99   public void setTagClass(Class JavaDoc cl)
100   {
101     _tagClass = cl;
102   }
103
104   public VariableInfo []getVarInfo()
105   {
106     return _varInfo;
107   }
108
109   /**
110    * Returns the body content.
111    */

112   public String JavaDoc getBodyContent()
113   {
114     return _tagInfo.getBodyContent();
115   }
116   
117   /**
118    * Adds a child node.
119    */

120   public void addChild(JspNode node)
121     throws JspParseException
122   {
123     if (! "empty".equals(getBodyContent()))
124       super.addChild(node);
125     else if (node instanceof JspAttribute) {
126       super.addChild(node);
127     }
128     else if (node instanceof StaticText &&
129              ((StaticText) node).isWhitespace()) {
130     }
131     else {
132       throw error(L.l("<{0}> must be empty. Since <{0}> has a body-content of 'empty', it must not have any content.",
133                       getTagName()));
134     }
135   }
136
137   /**
138    * Completes the element
139    */

140   public void endElement()
141     throws Exception JavaDoc
142   {
143     if (_tagClass != null)
144       _gen.addDepend(_tagClass);
145     
146     Hashtable JavaDoc<String JavaDoc,Object JavaDoc> tags = new Hashtable JavaDoc<String JavaDoc,Object JavaDoc>();
147
148     for (int i = 0; i < _attributeNames.size(); i++) {
149       QName qName = _attributeNames.get(i);
150       Object JavaDoc value = _attributeValues.get(i);
151       String JavaDoc name = qName.getName();
152
153       if (value instanceof JspAttribute) {
154     JspAttribute attr = (JspAttribute) value;
155
156     if (attr.isStatic())
157       tags.put(name, attr.getStaticText());
158     else
159       tags.put(name, TagData.REQUEST_TIME_VALUE);
160       }
161       else if (value instanceof String JavaDoc && hasRuntimeAttribute((String JavaDoc) value))
162         tags.put(name, TagData.REQUEST_TIME_VALUE);
163       else
164         tags.put(name, value);
165
166       TagAttributeInfo attrInfo = getAttributeInfo(qName);
167
168       String JavaDoc typeName = null;
169
170       boolean isFragment = false;
171       Method JavaDoc method = getAttributeMethod(qName);
172       
173       Class JavaDoc type = null;
174
175       if (method != null)
176     type = method.getParameterTypes()[0];
177
178       if (attrInfo != null) {
179     typeName = attrInfo.getTypeName();
180     isFragment = attrInfo.isFragment();
181
182     if (isFragment &&
183         type != null && type.isAssignableFrom(JspFragment.class))
184       typeName = JspFragment.class.getName();
185       }
186       else if (method != null)
187     typeName = type.getName();
188
189       if (! isFragment && ! JspFragment.class.getName().equals(typeName)) {
190       }
191       else if (value instanceof JspAttribute) {
192     JspAttribute jspAttr = (JspAttribute) value;
193
194     jspAttr.setJspFragment(true);
195       }
196     }
197     
198     TagData tagData = new TagData(tags);
199     
200     _varInfo = _tagInfo.getVariableInfo(tagData);
201
202     if (_varInfo == null)
203       _varInfo = fillVariableInfo(_tagInfo.getTagVariableInfos(), tagData);
204
205     TagExtraInfo tei = _tagInfo.getTagExtraInfo();
206     ValidationMessage []messages;
207     if (tei != null) {
208       messages = tei.validate(tagData);
209
210       _gen.addDepend(tei.getClass());
211
212       if (messages != null && messages.length != 0) {
213     throw error(messages[0].getMessage());
214       }
215     }
216   }
217   
218   /**
219    * True if the node has scripting
220    */

221   public boolean hasScripting()
222   {
223     if (super.hasScripting())
224       return true;
225
226     // Any conflicting values must be set each time.
227
for (int i = 0; i < _attributeValues.size(); i++) {
228       QName name = _attributeNames.get(i);
229       Object JavaDoc value = _attributeValues.get(i);
230
231       try {
232     if (value instanceof String JavaDoc && hasRuntimeAttribute((String JavaDoc) value))
233       return true;
234       } catch (Throwable JavaDoc e) {
235     log.log(Level.WARNING, e.toString(), e);
236     return true;
237       }
238     }
239     
240     return false;
241   }
242   
243   /**
244    * Generates code before the actual JSP.
245    */

246   public void generatePrologue(JspJavaWriter out)
247     throws Exception JavaDoc
248   {
249     for (int i = 0; i < _attributeNames.size(); i++) {
250       QName name = _attributeNames.get(i);
251       Object JavaDoc value = _attributeValues.get(i);
252       
253       if (! (value instanceof JspFragmentNode))
254     continue;
255       
256       JspFragmentNode frag = (JspFragmentNode) value;
257       
258       TagAttributeInfo attribute = getAttributeInfo(name);
259       String JavaDoc typeName = null;
260
261       boolean isFragment = false;
262
263       if (attribute != null && attribute.isFragment())
264     isFragment = true;
265
266       String JavaDoc fragmentClass = JspFragment.class.getName();
267       
268       if (attribute != null && fragmentClass.equals(attribute.getTypeName()))
269     isFragment = true;
270
271       Method JavaDoc method = getAttributeMethod(name);
272
273       if (method != null) {
274     typeName = method.getParameterTypes()[0].getName();
275     if (fragmentClass.equals(typeName))
276       isFragment = true;
277       }
278
279       if (isFragment)
280     frag.generateFragmentPrologue(out);
281     }
282       
283     TagInstance parent = getParent().getTag();
284
285     boolean isBodyTag = BodyTag.class.isAssignableFrom(_tagClass);
286     boolean isEmpty = isEmpty();
287     boolean hasBodyContent = isBodyTag && ! isEmpty;
288     
289     _tag = parent.findTag(getQName(), _attributeNames,
290               hasBodyContent);
291
292     if (_tag == null || ! _parseState.isRecycleTags()) {
293       _tag = parent.addTag(getQName(), _tagInfo, _tagClass,
294                _attributeNames, _attributeValues,
295                hasBodyContent);
296
297       if (! JspTagFileSupport.class.isAssignableFrom(_tagClass)) {
298     out.printClass(_tagClass);
299     out.println(" " + _tag.getId() + " = null;");
300       }
301
302       /*
303       if (SimpleTag.class.isAssignableFrom(_tagClass) && hasCustomTag())
304         out.println("javax.servlet.jsp.tagext.Tag " + _tag.getId() + "_adapter = null;");
305       */

306     }
307     else {
308       // Any conflicting values must be set each time.
309
for (int i = 0; i < _attributeNames.size(); i++) {
310         QName name = _attributeNames.get(i);
311         Object JavaDoc value = _attributeValues.get(i);
312         
313         _tag.addAttribute(name, value);
314       }
315     }
316
317     if (_tag == null)
318       throw new NullPointerException JavaDoc();
319
320     /* already taken care of
321     if (! isEmpty())
322       _tag.setBodyContent(true);
323     */

324
325     generatePrologueDeclare(out);
326     generatePrologueChildren(out);
327   }
328
329   public void generatePrologueDeclare(JspJavaWriter out)
330     throws Exception JavaDoc
331   {
332     // Any AT_END variables
333
for (int i = 0; _varInfo != null && i < _varInfo.length; i++) {
334       VariableInfo var = _varInfo[i];
335
336       if (var == null) {
337       }
338       else if (! _gen.hasScripting()) {
339       }
340       else if ((var.getScope() == VariableInfo.AT_END
341                 || var.getScope() == VariableInfo.AT_BEGIN)
342                && var.getDeclare()
343                && ! _gen.isDeclared(var.getVarName())) {
344     String JavaDoc className = var.getClassName();
345
346     if (className == null)
347       className = DEFAULT_VAR_TYPE;
348
349     validateClass(className, var.getVarName());
350     
351         out.print(className + " " + var.getVarName() + " = ");
352
353         _gen.addDeclared(var.getVarName());
354         
355         if ("byte".equals(var.getClassName()) ||
356             "short".equals(var.getClassName()) ||
357             "char".equals(var.getClassName()) ||
358             "int".equals(var.getClassName()) ||
359             "long".equals(var.getClassName()) ||
360             "float".equals(var.getClassName()) ||
361             "double".equals(var.getClassName()))
362           out.println("0;");
363         else if ("boolean".equals(var.getClassName()))
364           out.println("false;");
365         else
366           out.println("null;");
367       }
368     }
369   }
370
371   /**
372    * Generates the XML text representation for the tag validation.
373    *
374    * @param os write stream to the generated XML.
375    */

376   public void printXml(WriteStream os)
377     throws IOException JavaDoc
378   {
379     TagInfo tag = getTagInfo();
380
381     String JavaDoc name = tag.getTagLibrary().getPrefixString() + ':' + tag.getTagName();
382
383     os.print("<" + name);
384     
385     printJspId(os);
386
387     for (int i = 0; i < _attributeNames.size(); i++) {
388       QName attrName = _attributeNames.get(i);
389       Object JavaDoc value = _attributeValues.get(i);
390
391       if (value instanceof String JavaDoc) {
392     String JavaDoc string = (String JavaDoc) value;
393     
394     os.print(" " + attrName.getName() + "=\"");
395
396     if (string.startsWith("<%=") && string.endsWith("%>")) {
397       os.print("%=");
398       os.print(xmlAttrText(string.substring(3, string.length() - 2)));
399       os.print("%");
400     }
401     else
402       os.print(xmlAttrText(string));
403     
404     os.print("\"");
405       }
406     }
407
408     os.print(">");
409
410     printXmlChildren(os);
411
412     os.print("</" + name + ">");
413   }
414
415   /**
416    * Generates the code for a custom tag.
417    *
418    * @param out the output writer for the generated java.
419    */

420   abstract public void generate(JspJavaWriter out)
421     throws Exception JavaDoc;
422
423   protected void fillAttributes(JspJavaWriter out, String JavaDoc name)
424     throws Exception JavaDoc
425   {
426     TagAttributeInfo attrs[] = _tagInfo.getAttributes();
427
428     // clear any attributes mentioned in the taglib that aren't set
429
for (int i = 0; attrs != null && i < attrs.length; i++) {
430       int p = getAttributeIndex(attrs[i].getName());
431       
432       if (p < 0 && attrs[i].isRequired()) {
433     throw error(L.l("required attribute '{0}' missing from <{1}>",
434                         attrs[i].getName(),
435                         getTagName()));
436       }
437     }
438
439     boolean isDynamic = DynamicAttributes.class.isAssignableFrom(_tagClass);
440     
441     // fill all mentioned attributes
442
for (int i = 0; i < _attributeNames.size(); i++) {
443       QName attrName = _attributeNames.get(i);
444       Object JavaDoc value = _attributeValues.get(i);
445       
446       TagAttributeInfo attribute = getAttributeInfo(attrName);
447       
448       if (attrs != null && attribute == null && ! isDynamic)
449     throw error(L.l("unexpected attribute '{0}' in <{1}>",
450                         attrName.getName(), getTagName()));
451
452       if (_tag.getAttribute(attrName) != null)
453         continue;
454
455       boolean isFragment = false;
456
457       if (attribute != null) {
458     isFragment = (attribute.isFragment() ||
459               attribute.getTypeName().equals(JspFragment.class.getName()));
460       }
461
462       if (value instanceof JspAttribute &&
463       ((JspAttribute) value).isJspFragment())
464     isFragment = true;
465
466       generateSetAttribute(out, name, attrName, value,
467                            attribute == null || attribute.canBeRequestTime(),
468                isFragment, attribute);
469     }
470   }
471
472   private TagAttributeInfo getAttributeInfo(QName attrName)
473   {
474     TagAttributeInfo attrs[] = _tagInfo.getAttributes();
475
476     int j = 0;
477     for (j = 0; attrs != null && j < attrs.length; j++) {
478       if (isNameMatch(attrs[j].getName(), attrName))
479     return attrs[j];
480     }
481
482     return null;
483   }
484
485   private int getAttributeIndex(String JavaDoc name)
486   {
487     for (int i = 0; i < _attributeNames.size(); i++) {
488       QName attrName = _attributeNames.get(i);
489
490       if (isNameMatch(name, attrName))
491     return i;
492     }
493
494     return -1;
495   }
496
497   private boolean isNameMatch(String JavaDoc defName, QName attrName)
498   {
499     if (defName.equals(attrName.getName())) {
500       return true;
501     }
502     else if (defName.equals(attrName.getLocalName()) &&
503          attrName.getPrefix().equals(getQName().getPrefix())) {
504       return true;
505     }
506     else
507       return false;
508   }
509
510   /**
511    * Sets an attribute for a tag
512    *
513    * @param info the tag's introspected information
514    * @param name the tag's Java variable name
515    * @param attrName the attribute name to set
516    * @param value the new value of the tag.
517    */

518   void generateSetAttribute(JspJavaWriter out,
519                             String JavaDoc name, QName attrName, Object JavaDoc value,
520                             boolean allowRtexpr, boolean isFragment,
521                 TagAttributeInfo attrInfo)
522     throws Exception JavaDoc
523   {
524     Method JavaDoc method = getAttributeMethod(attrName);
525
526     boolean isDynamic = DynamicAttributes.class.isAssignableFrom(_tagClass);
527     
528     if (method != null) {
529       // jsp/18cq
530
if (Modifier.isStatic(method.getModifiers()))
531     throw error(L.l("attribute '{0}' may not be a static method.",
532             method.getName()));
533
534       generateSetParameter(out, name, value, method,
535                allowRtexpr, "pageContext", isFragment, attrInfo);
536     }
537     else if (! isDynamic) {
538       throw error(L.l("attribute '{0}' in tag '{1}' has no corresponding set method in tag class '{2}'",
539                   attrName.getName(), getTagName(), _tagClass.getName()));
540     }
541     else if (isFragment) {
542       String JavaDoc uri = attrName.getNamespaceURI();
543       String JavaDoc local = attrName.getLocalName();
544
545       out.print(name + ".setDynamicAttribute(");
546
547       if (uri == null)
548     out.print("null, ");
549       else
550     out.print("\"" + escapeJavaString(uri) + "\", ");
551       
552       JspFragmentNode frag = (JspFragmentNode) value;
553       out.print("\"" + escapeJavaString(local) + "\", ");
554       out.print(frag.generateValue());
555       out.println(");");
556     }
557     else {
558       String JavaDoc uri = attrName.getNamespaceURI();
559       String JavaDoc local = attrName.getLocalName();
560       
561       out.print(name + ".setDynamicAttribute(");
562
563       if (uri == null)
564     out.print("null, ");
565       else
566     out.print("\"" + escapeJavaString(uri) + "\", ");
567       
568       out.print("\"" + escapeJavaString(local) + "\", ");
569       out.print(generateRTValue(Object JavaDoc.class, value));
570       out.println(");");
571     }
572   }
573
574   private Method JavaDoc getAttributeMethod(QName attrName)
575     throws Exception JavaDoc
576   {
577     Method JavaDoc method = null;
578     
579     try {
580       BeanInfo JavaDoc info = Introspector.getBeanInfo(_tagClass);
581
582       if (info != null)
583     method = BeanUtil.getSetMethod(info, attrName.getLocalName());
584
585       if (method != null)
586     return method;
587     } catch (Throwable JavaDoc e) {
588       log.log(Level.FINER, e.toString(), e);
589     }
590
591     /*
592     try {
593       method = BeanUtil.getSetMethod(_tagClass, attrName.getLocalName());
594
595       if (method != null)
596     return method;
597     } catch (Throwable e) {
598       log.log(Level.FINER, e.toString(), e);
599     }
600     */

601
602     return method;
603   }
604
605   /**
606    * Returns true if there is a tag variable declaration matching the scope.
607    */

608   protected boolean hasVarDeclaration(int scope)
609     throws Exception JavaDoc
610   {
611     for (int i = 0; _varInfo != null && i < _varInfo.length; i++) {
612       VariableInfo var = _varInfo[i];
613       
614       if (var != null && var.getScope() == scope)
615     return true;
616     }
617
618     return false;
619   }
620
621   /**
622    * Prints a tag variable declaration. Only the variables matching the
623    * scope will be printed.
624    *
625    * @param out the stream to the java code.
626    * @param scope the variable scope to print
627    */

628   protected void printVarDeclaration(JspJavaWriter out, int scope)
629     throws Exception JavaDoc
630   {
631     for (int i = 0; _varInfo != null && i < _varInfo.length; i++) {
632       VariableInfo var = _varInfo[i];
633       
634       if (var != null) {
635         printVarDeclare(out, scope, var);
636         printVarAssign(out, scope, var);
637       }
638     }
639   }
640
641   /**
642    * Prints a tag variable declaration. Only the variables matching the
643    * scope will be printed.
644    *
645    * @param out the stream to the java code.
646    * @param scope the variable scope to print
647    */

648   protected void printVarDeclare(JspJavaWriter out, int scope)
649     throws Exception JavaDoc
650   {
651     for (int i = 0; _varInfo != null && i < _varInfo.length; i++) {
652       VariableInfo var = _varInfo[i];
653
654       if (var != null)
655         printVarDeclare(out, scope, var);
656     }
657   }
658
659   /**
660    * Prints a tag variable declaration. Only the variables matching the
661    * scope will be printed.
662    *
663    * @param out the stream to the java code.
664    * @param scope the variable scope to print
665    */

666   protected void printVarAssign(JspJavaWriter out, int scope)
667     throws Exception JavaDoc
668   {
669     for (int i = 0; _varInfo != null && i < _varInfo.length; i++) {
670       VariableInfo var = _varInfo[i];
671
672       if (var != null)
673         printVarAssign(out, scope, var);
674     }
675   }
676
677   /**
678    * Returns the VariableInfo corresponding the to tag vars and the tag
679    * data. Mainly, this means looking up the variable names from the
680    * attributes for the name-from-attribute.
681    *
682    * @param tagVars the implicit tag variables for the tag
683    * @param tagData the parsed tag attributes
684    *
685    * @return an array of filled VariableInfo
686    */

687   protected VariableInfo []fillVariableInfo(TagVariableInfo []tagVars,
688                                             TagData tagData)
689     throws JspParseException
690   {
691     if (tagVars == null)
692       return null;
693
694     VariableInfo []vars = new VariableInfo[tagVars.length];
695
696     for (int i = 0; i < tagVars.length; i++) {
697       TagVariableInfo tagVar = tagVars[i];
698
699       String JavaDoc name = null;
700       if (tagVar.getNameGiven() != null)
701         name = tagVar.getNameGiven();
702       else {
703         String JavaDoc attributeName = tagVar.getNameFromAttribute();
704
705         name = tagData.getAttributeString(attributeName);
706
707         if (name == null)
708           continue;
709       }
710
711       vars[i] = new VariableInfo(name, tagVar.getClassName(),
712                                  tagVar.getDeclare(), tagVar.getScope());
713     }
714
715     return vars;
716   }
717
718   /**
719    * Prints a tag variable declaration. Only the variables matching the
720    * scope will be printed.
721    *
722    * @param out the stream to the java code.
723    * @param scope the variable scope to print
724    */

725   protected void printVarDeclare(JspJavaWriter out,
726                  int scope,
727                  VariableInfo var)
728     throws Exception JavaDoc
729   {
730     if (! _gen.hasScripting() || var == null)
731       return;
732     
733     if (var.getScope() == scope
734     || var.getScope() == VariableInfo.AT_BEGIN) {
735       if (var.getVarName() == null)
736         throw error(L.l("tag variable expects a name"));
737
738       String JavaDoc className = var.getClassName();
739
740       if (className == null)
741     className = DEFAULT_VAR_TYPE;
742
743       /*
744       if (var.getClassName() == null)
745         throw error(L.l("tag variable '{0}' expects a classname",
746                         var.getVarName()));
747       */

748
749       validateVarName(var.getVarName());
750
751       // jsp/107r
752
if (var.getDeclare()
753       && var.getScope() == scope
754       && (var.getScope() == VariableInfo.NESTED && hasScripting()
755           || var.getScope() == VariableInfo.AT_BEGIN)
756       && ! varAlreadyDeclared(var.getVarName())) {
757     validateClass(className, var.getVarName());
758     
759         out.println(className + " " + var.getVarName() + ";");
760       }
761     }
762   }
763
764   /**
765    * Prints a tag variable declaration. Only the variables matching the
766    * scope will be printed.
767    *
768    * @param out the stream to the java code.
769    * @param scope the variable scope to print
770    */

771   protected void printVarAssign(JspJavaWriter out, int scope, VariableInfo var)
772     throws Exception JavaDoc
773   {
774     if (var.getScope() == scope ||
775         var.getScope() == VariableInfo.AT_BEGIN) {
776       if (var.getVarName() == null)
777         throw error(L.l("tag variable expects a name"));
778
779       String JavaDoc className = var.getClassName();
780
781       if (className == null || className.equals("null"))
782     className = DEFAULT_VAR_TYPE;
783       
784       /*
785       if (var.getClassName() == null)
786         throw error(L.l("tag variable '{0}' expects a classname",
787                         var.getVarName()));
788       */

789
790       validateVarName(var.getVarName());
791
792       if (! _gen.hasScripting()) {
793       }
794       else if (var.getScope() != VariableInfo.NESTED || hasScripting()) {
795     out.setLocation(_filename, _startLine);
796     out.print(var.getVarName() + " = ");
797     String JavaDoc v = "pageContext.findAttribute(\"" + var.getVarName() + "\")";
798     convertParameterValue(out, className, v);
799     out.println(";");
800       }
801
802       _gen.addBeanClass(var.getVarName(), className);
803     }
804   }
805
806   private void validateVarName(String JavaDoc name)
807     throws JspParseException
808   {
809     if (! Character.isJavaIdentifierStart(name.charAt(0)))
810       throw error(L.l("tag variable '{0}' is an illegal Java identifier.", name));
811
812     for (int i = 0; i < name.length(); i++) {
813       if (! Character.isJavaIdentifierPart(name.charAt(i)))
814         throw error(L.l("tag variable '{0}' is an illegal Java identifier.", name));
815     }
816   }
817
818   /**
819    * Returns true if the variable has been declared.
820    */

821   private boolean varAlreadyDeclared(String JavaDoc varName)
822   {
823     if (_gen.isDeclared(varName))
824       return true;
825     
826     for (JspNode node = getParent();
827      node != null;
828      node = node.getParent()) {
829       if (! (node instanceof GenericTag))
830         continue;
831       if (node instanceof JspFragmentNode)
832         break;
833
834       GenericTag tag = (GenericTag) node;
835       
836       VariableInfo []varInfo = tag.getVarInfo();
837
838       for (int i = 0; varInfo != null && i < varInfo.length; i++) {
839         if (varInfo[i] == null)
840           continue;
841         else if (varInfo[i].getVarName().equals(varName))
842           return true;
843       }
844     }
845
846     return false;
847   }
848
849   /**
850    * Returns true if the tag instance has been declared
851    */

852   protected boolean isDeclared()
853   {
854     if (! _gen.getRecycleTags())
855       return false;
856
857     JspNode parent = getParent();
858
859     if (! (parent instanceof JspRoot) &&
860     ! (parent instanceof JspTop) &&
861         ! (parent instanceof GenericTag) &&
862         ! (parent instanceof JspAttribute))
863       return false;
864
865     boolean isDeclared = false;
866
867     ArrayList JavaDoc<JspNode> siblings = getParent().getChildren();
868     for (int i = 0; i < siblings.size(); i++) {
869       JspNode node = siblings.get(i);
870
871       if (node == this) {
872         return isDeclared;
873       }
874
875       if (hasScriptlet(node)) {
876         return false;
877       }
878
879       if (node instanceof GenericTag) {
880         GenericTag customTag = (GenericTag) node;
881
882         if (customTag.getTag() == getTag())
883           isDeclared = true;
884       }
885     }
886
887     return isDeclared;
888   }
889
890   /**
891    * Returns true if the node or one of its children is a scriptlet
892    */

893   protected boolean hasScriptlet(JspNode node)
894   {
895     if (node instanceof JspScriptlet || node instanceof JspExpression)
896       return true;
897
898     ArrayList JavaDoc<JspNode> children = node.getChildren();
899
900     if (children == null)
901       return false;
902
903     for (int i = 0; i < children.size(); i++) {
904       JspNode child = children.get(i);
905
906       if (hasScriptlet(child))
907     return true;
908     }
909
910     return false;
911   }
912
913   /**
914    * Checks that the given class is a valid variable class.
915    */

916   protected void validateClass(String JavaDoc className, String JavaDoc varName)
917     throws JspParseException
918   {
919     try {
920       if (_primTypes.contains(className))
921     return;
922       else if (className.endsWith("[]")) {
923     validateClass(className.substring(0, className.length() - 2), varName);
924     return;
925       }
926
927       Class JavaDoc cl = _gen.getBeanClass(className);
928     } catch (ClassNotFoundException JavaDoc e) {
929       throw error(L.l("'{0}' is an unknown class for tag variable '{1}'.",
930               className, varName));
931     }
932   }
933
934   static {
935     _primTypes.add("boolean");
936     _primTypes.add("byte");
937     _primTypes.add("short");
938     _primTypes.add("int");
939     _primTypes.add("long");
940     _primTypes.add("float");
941     _primTypes.add("double");
942     _primTypes.add("char");
943   }
944 }
945
Popular Tags