KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > jsp > TagInstance


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  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.jsp;
30
31 import com.caucho.jsp.java.JspTagFileSupport;
32 import com.caucho.log.Log;
33 import com.caucho.util.L10N;
34 import com.caucho.xml.QName;
35
36 import javax.servlet.jsp.tagext.SimpleTag JavaDoc;
37 import javax.servlet.jsp.tagext.TagAttributeInfo JavaDoc;
38 import javax.servlet.jsp.tagext.TagInfo JavaDoc;
39 import javax.servlet.jsp.tagext.VariableInfo JavaDoc;
40 import java.util.ArrayList JavaDoc;
41 import java.util.Iterator JavaDoc;
42 import java.util.logging.Logger JavaDoc;
43
44 /**
45  * Describes a single tag instance.
46  */

47 public class TagInstance {
48   static final L10N L = new L10N(TagInstance.class);
49   static final Logger JavaDoc log = Log.open(TagInstance.class);
50
51   // Special object to note that the attribute varies
52
private static final Object JavaDoc VARIES = new Varies();
53
54   public static final String JavaDoc TOP_TAG = null;
55   public static final String JavaDoc FRAGMENT_WITH_TAG_PARENT = "top_tag_fragment";
56   public static final String JavaDoc FRAGMENT_WITH_SIMPLE_PARENT = "top_simple_fragment";
57
58   private ParseTagManager _manager;
59
60   private TagInstance _top;
61   private TagInfo JavaDoc _tagInfo;
62   private int _maxId;
63   
64   private TagInstance _parent;
65   private ArrayList JavaDoc<TagInstance> _children = new ArrayList JavaDoc<TagInstance>();
66   private ArrayList JavaDoc<TagInstance> _tags = new ArrayList JavaDoc<TagInstance>();
67
68   private String JavaDoc _tagId = null;
69   private QName _qname;
70   private Class JavaDoc _cl;
71   private VariableInfo JavaDoc []_varInfo;
72   private boolean _needsAdapter;
73   private boolean _hasAdapterDeclaration;
74
75   private AnalyzedTag _analyzedTag;
76
77   private ArrayList JavaDoc<QName> _attributeNames = new ArrayList JavaDoc<QName>();
78   private ArrayList JavaDoc<Object JavaDoc> _attributeValues = new ArrayList JavaDoc<Object JavaDoc>();
79
80   private boolean _hasBodyContent;
81   
82   public TagInstance(ParseTagManager manager)
83   {
84     _manager = manager;
85     
86     _top = this;
87     _tagId = null;
88   }
89   
90   public TagInstance(ParseTagManager manager, String JavaDoc id)
91   {
92     _manager = manager;
93     _top = this;
94     _tagId = id;
95   }
96   
97   TagInstance(TagInstance parent, TagInfo JavaDoc tagInfo, QName qname, Class JavaDoc cl)
98   {
99     _qname = qname;
100     _parent = parent;
101     _manager = parent._manager;
102     _tagInfo = tagInfo;
103     _cl = cl;
104     
105     _top = parent._top;
106     parent._children.add(this);
107     _top._tags.add(this);
108
109     if (tagInfo != null) {
110       String JavaDoc className = tagInfo.getTagClassName();
111       int p = className.lastIndexOf('.');
112       if (p >= 0)
113     className = className.substring(p + 1);
114       _tagId = "_jsp_" + className + "_" + _top._maxId++;
115
116     }
117     
118     _analyzedTag = _manager.analyzeTag(cl);
119   }
120
121   /**
122    * Returns the tag name
123    */

124   public QName getQName()
125   {
126     return _qname;
127   }
128
129   /**
130    * Returns the tag name
131    */

132   public String JavaDoc getName()
133   {
134     return _qname.getName();
135   }
136   
137   public String JavaDoc getId()
138   {
139     return _tagId;
140   }
141
142   public void setId(String JavaDoc id)
143   {
144     _tagId = id;
145   }
146
147   public boolean generateAdapterDeclaration()
148   {
149     if (_hasAdapterDeclaration) {
150       return false;
151     }
152     else {
153       _hasAdapterDeclaration = true;
154       
155       return true;
156     }
157   }
158
159   public TagInstance getParent()
160   {
161     return _parent;
162   }
163
164   /**
165    * Returns true for a top tag.
166    */

167   public boolean isTop()
168   {
169     return _tagId == null || _tagId.startsWith("top_");
170   }
171
172   /**
173    * Returns the tag class.
174    */

175   public Class JavaDoc getTagClass()
176   {
177     return _cl;
178   }
179
180   /**
181    * Returns true if it's a simple tag.
182    */

183   public boolean isSimpleTag()
184   {
185     return _cl != null && SimpleTag JavaDoc.class.isAssignableFrom(_cl);
186   }
187
188   /**
189    * Returns true if it's a simple tag.
190    */

191   public boolean isTagFileTag()
192   {
193     return _cl != null && JspTagFileSupport.class.isAssignableFrom(_cl);
194   }
195   
196   public TagInfo JavaDoc getTagInfo()
197   {
198     return _tagInfo;
199   }
200
201   /**
202    * Returns the analyzed tag.
203    */

204   public AnalyzedTag getAnalyzedTag()
205   {
206     return _analyzedTag;
207   }
208
209   void setVarInfo(VariableInfo JavaDoc []varInfo)
210   {
211     _varInfo = varInfo;
212   }
213
214   public VariableInfo JavaDoc []getVarInfo()
215   {
216     return _varInfo;
217   }
218
219   public int size()
220   {
221     return _top._maxId;
222   }
223
224   /**
225    * Returns true if there are children.
226    */

227   public boolean hasChildren()
228   {
229     return _children != null && _children.size() > 0;
230   }
231
232   /**
233    * Set true if needs an adapter.
234    */

235   public boolean getNeedsAdapter()
236   {
237     return _needsAdapter || isSimpleTag() && hasChildren();
238   }
239
240   /**
241    * if needs an adapter.
242    */

243   public void setNeedsAdapter(boolean needsAdapter)
244   {
245     _needsAdapter = needsAdapter;
246   }
247
248   /**
249    * Iterates through the children.
250    */

251   public Iterator JavaDoc<TagInstance> iterator()
252   {
253     return _children.iterator();
254   }
255
256   /**
257    * Iterates through the children.
258    */

259   public TagInstance get(int i)
260   {
261     return _top._tags.get(i);
262   }
263
264   /**
265    * Returns the tag's attribute names.
266    */

267   public ArrayList JavaDoc<QName> getAttributeNames()
268   {
269     return _attributeNames;
270   }
271
272   /**
273    * Set true if the tag has a body content.
274    */

275   public void setBodyContent(boolean hasBodyContent)
276   {
277     _hasBodyContent = hasBodyContent;
278   }
279
280   /**
281    * Get true if the tag has a body content.
282    */

283   public boolean getBodyContent()
284   {
285     return _hasBodyContent;
286   }
287
288   /**
289    * Adds a child tag. If the tag exists, just reuse it.
290    *
291    * @param tagName the JSP name of the tag
292    * @param tagInfo the TagInfo structure for the tag
293    * @param cl the tag's implementation class
294    * @param names the array of attribute names
295    * @param values the array of attribute values
296    */

297   public TagInstance addTag(QName tagName, TagInfo JavaDoc tagInfo,
298                             Class JavaDoc cl,
299                             ArrayList JavaDoc<QName> names,
300                             ArrayList JavaDoc<Object JavaDoc> values,
301                 boolean hasBodyContent)
302   {
303     TagInstance child = null;//findTag(tagName, names);
304
if (child == null)
305       child = new TagInstance(this, tagInfo, tagName, cl);
306
307     child.setBodyContent(hasBodyContent);
308
309     for (int i = 0; i < names.size(); i++) {
310       QName name = names.get(i);
311       Object JavaDoc value = values.get(i);
312       
313       if (value instanceof String JavaDoc) {
314         String JavaDoc strValue = (String JavaDoc) value;
315
316         // runtime and EL expressions can't have shared values
317
if (strValue.startsWith("<%=") || strValue.startsWith("%="))
318           value = null;
319         else if (strValue.indexOf("${") >= 0)
320           value = null;
321
322         child.addAttribute(name, value);
323       } else {
324         child.addAttribute(name, null);
325       }
326     }
327
328     return child;
329   }
330
331   /**
332    * Adds a new tag. Always create a new tag.
333    */

334   public TagInstance addNewTag(QName tagName, TagInfo JavaDoc tagInfo,
335                                Class JavaDoc cl,
336                    ArrayList JavaDoc<QName> names,
337                                ArrayList JavaDoc<String JavaDoc> values,
338                    boolean hasBodyContent)
339   {
340     TagInstance child = null;
341     if (child == null)
342       child = new TagInstance(this, tagInfo, tagName, cl);
343
344     child.setBodyContent(hasBodyContent);
345
346     for (int i = 0; i < names.size(); i++) {
347       QName name = names.get(i);
348       String JavaDoc value = values.get(i);
349
350       if (value.startsWith("<%=") || value.startsWith("%="))
351         value = null;
352
353       child.addAttribute(name, value);
354     }
355
356     return child;
357   }
358
359   /**
360    * Sets the attribute. Null values can't be pre-cached.
361    */

362   public void addAttribute(QName name, Object JavaDoc value)
363   {
364     for (int i = 0; i < _attributeNames.size(); i++) {
365       QName attrName = _attributeNames.get(i);
366       
367       if (attrName.equals(name)) {
368         Object JavaDoc oldValue = _attributeValues.get(i);
369         if (value == null || oldValue == null || ! value.equals(oldValue))
370           _attributeValues.set(i, null);
371
372         return;
373       }
374     }
375
376     if (name == null)
377       throw new NullPointerException JavaDoc();
378     
379     _attributeNames.add(name);
380     _attributeValues.add(value);
381   }
382
383   public String JavaDoc getAttribute(QName name)
384   {
385     for (int i = 0; i < _attributeNames.size(); i++) {
386       if (name.equals(_attributeNames.get(i)))
387         return (String JavaDoc) _attributeValues.get(i);
388     }
389
390     return null;
391   }
392
393   boolean canBeRequestTime(String JavaDoc name)
394   {
395     TagAttributeInfo JavaDoc attrs[] = _tagInfo.getAttributes();
396
397     if (attrs == null)
398       return true;
399
400     for (int i = 0; i < attrs.length; i++) {
401       if (name.equals(attrs[i].getName()))
402         return attrs[i].canBeRequestTime();
403     }
404
405     return false;
406   }
407
408   public TagAttributeInfo JavaDoc getAttributeInfo(String JavaDoc name)
409   {
410     TagAttributeInfo JavaDoc attrs[] = _tagInfo.getAttributes();
411
412     if (attrs == null)
413       return null;
414
415     for (int i = 0; i < attrs.length; i++) {
416       if (name.equals(attrs[i].getName()))
417         return attrs[i];
418     }
419
420     return null;
421   }
422
423   /**
424    * Finds the matching tag.
425    */

426   public TagInstance findTag(QName tagName,
427                  ArrayList JavaDoc<QName> names,
428                  boolean hasBodyContent)
429   {
430     for (int i = 0; i < _children.size(); i++) {
431       TagInstance child = _children.get(i);
432
433       if (child.match(tagName, names, hasBodyContent))
434         return child;
435     }
436
437     return null;
438   }
439   
440   /**
441    * Returns true for matching instances.
442    */

443   boolean match(QName tagName, ArrayList JavaDoc<QName> names, boolean hasBodyContent)
444   {
445     if (! _qname.equals(tagName))
446       return false;
447
448     if (_attributeNames.size() != names.size())
449       return false;
450
451     if (_hasBodyContent != hasBodyContent)
452       return false;
453     
454     for (int i = 0; i < _attributeNames.size(); i++) {
455       QName attrName = _attributeNames.get(i);
456
457       if (names.indexOf(attrName) < 0)
458         return false;
459     }
460
461     for (int i = 0; i < names.size(); i++) {
462       QName name = names.get(i);
463
464       if (_attributeNames.indexOf(name) < 0)
465         return false;
466     }
467
468     return true;
469   }
470
471   static class Varies {
472     public String JavaDoc toString()
473     {
474       return "Value-Varies[]";
475     }
476   }
477 }
478
Popular Tags