1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.struts2.jasper.compiler;
19
20 import org.apache.struts2.jasper.JasperException;
21 import org.apache.struts2.jasper.compiler.tagplugin.TagPluginContext;
22 import org.xml.sax.Attributes;
23
24 import javax.servlet.jsp.tagext.*;
25 import java.util.ArrayList;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Vector;
29
30
31 /***
32 * An internal data representation of a JSP page or a JSP docuement (XML).
33 * Also included here is a visitor class for tranversing nodes.
34 *
35 * @author Kin-man Chung
36 * @author Jan Luehe
37 * @author Shawn Bayern
38 * @author Mark Roth
39 */
40
41 abstract class Node implements TagConstants {
42
43 private static final VariableInfo[] ZERO_VARIABLE_INFO = {};
44
45 protected Attributes attrs;
46
47
48 protected Attributes taglibAttrs;
49
50
51
52
53
54 protected Attributes nonTaglibXmlnsAttrs;
55
56 protected Nodes body;
57 protected String text;
58 protected Mark startMark;
59 protected int beginJavaLine;
60 protected int endJavaLine;
61 protected Node parent;
62 protected Nodes namedAttributeNodes;
63 protected String qName;
64 protected String localName;
65
66
67
68
69
70
71 protected String innerClassName;
72
73 private boolean isDummy;
74
75 /***
76 * Zero-arg Constructor.
77 */
78 public Node() {
79 this.isDummy = true;
80 }
81
82 /***
83 * Constructor.
84 *
85 * @param start The location of the jsp page
86 * @param parent The enclosing node
87 */
88 public Node(Mark start, Node parent) {
89 this.startMark = start;
90 this.isDummy = (start == null);
91 addToParent(parent);
92 }
93
94 /***
95 * Constructor.
96 *
97 * @param qName The action's qualified name
98 * @param localName The action's local name
99 * @param start The location of the jsp page
100 * @param parent The enclosing node
101 */
102 public Node(String qName, String localName, Mark start, Node parent) {
103 this.qName = qName;
104 this.localName = localName;
105 this.startMark = start;
106 this.isDummy = (start == null);
107 addToParent(parent);
108 }
109
110 /***
111 * Constructor for Nodes parsed from standard syntax.
112 *
113 * @param qName The action's qualified name
114 * @param localName The action's local name
115 * @param attrs The attributes for this node
116 * @param start The location of the jsp page
117 * @param parent The enclosing node
118 */
119 public Node(String qName, String localName, Attributes attrs, Mark start,
120 Node parent) {
121 this.qName = qName;
122 this.localName = localName;
123 this.attrs = attrs;
124 this.startMark = start;
125 this.isDummy = (start == null);
126 addToParent(parent);
127 }
128
129 /***
130 * Constructor for Nodes parsed from XML syntax.
131 *
132 * @param qName The action's qualified name
133 * @param localName The action's local name
134 * @param attrs The action's attributes whose name does not start with
135 * xmlns
136 * @param nonTaglibXmlnsAttrs The action's xmlns attributes that do not
137 * represent tag libraries
138 * @param taglibAttrs The action's xmlns attributes that represent tag
139 * libraries
140 * @param start The location of the jsp page
141 * @param parent The enclosing node
142 */
143 public Node(String qName, String localName, Attributes attrs,
144 Attributes nonTaglibXmlnsAttrs, Attributes taglibAttrs,
145 Mark start, Node parent) {
146 this.qName = qName;
147 this.localName = localName;
148 this.attrs = attrs;
149 this.nonTaglibXmlnsAttrs = nonTaglibXmlnsAttrs;
150 this.taglibAttrs = taglibAttrs;
151 this.startMark = start;
152 this.isDummy = (start == null);
153 addToParent(parent);
154 }
155
156
157
158
159
160
161
162
163
164
165 public Node(String qName, String localName, String text, Mark start,
166 Node parent) {
167 this.qName = qName;
168 this.localName = localName;
169 this.text = text;
170 this.startMark = start;
171 this.isDummy = (start == null);
172 addToParent(parent);
173 }
174
175 public String getQName() {
176 return this.qName;
177 }
178
179 public String getLocalName() {
180 return this.localName;
181 }
182
183
184
185
186
187
188
189
190
191
192 public Attributes getAttributes() {
193 return this.attrs;
194 }
195
196
197
198
199
200 public Attributes getTaglibAttributes() {
201 return this.taglibAttrs;
202 }
203
204
205
206
207
208 public Attributes getNonTaglibXmlnsAttributes() {
209 return this.nonTaglibXmlnsAttrs;
210 }
211
212 public void setAttributes(Attributes attrs) {
213 this.attrs = attrs;
214 }
215
216 public String getAttributeValue(String name) {
217 return (attrs == null) ? null : attrs.getValue(name);
218 }
219
220 /***
221 * Get the attribute that is non request time expression, either
222 * from the attribute of the node, or from a jsp:attrbute
223 */
224 public String getTextAttribute(String name) {
225
226 String attr = getAttributeValue(name);
227 if (attr != null) {
228 return attr;
229 }
230
231 NamedAttribute namedAttribute = getNamedAttributeNode(name);
232 if (namedAttribute == null) {
233 return null;
234 }
235
236 return namedAttribute.getText();
237 }
238
239 /***
240 * Searches all subnodes of this node for jsp:attribute standard
241 * actions with the given name, and returns the NamedAttribute node
242 * of the matching named attribute, nor null if no such node is found.
243 * <p/>
244 * This should always be called and only be called for nodes that
245 * accept dynamic runtime attribute expressions.
246 */
247 public NamedAttribute getNamedAttributeNode(String name) {
248 NamedAttribute result = null;
249
250
251 Nodes nodes = getNamedAttributeNodes();
252 int numChildNodes = nodes.size();
253 for (int i = 0; i < numChildNodes; i++) {
254 NamedAttribute na = (NamedAttribute) nodes.getNode(i);
255 boolean found = false;
256 int index = name.indexOf(':');
257 if (index != -1) {
258
259 found = na.getName().equals(name);
260 } else {
261 found = na.getLocalName().equals(name);
262 }
263 if (found) {
264 result = na;
265 break;
266 }
267 }
268
269 return result;
270 }
271
272 /***
273 * Searches all subnodes of this node for jsp:attribute standard
274 * actions, and returns that set of nodes as a Node.Nodes object.
275 *
276 * @return Possibly empty Node.Nodes object containing any jsp:attribute
277 * subnodes of this Node
278 */
279 public Node.Nodes getNamedAttributeNodes() {
280
281 if (namedAttributeNodes != null) {
282 return namedAttributeNodes;
283 }
284
285 Node.Nodes result = new Node.Nodes();
286
287
288 Nodes nodes = getBody();
289 if (nodes != null) {
290 int numChildNodes = nodes.size();
291 for (int i = 0; i < numChildNodes; i++) {
292 Node n = nodes.getNode(i);
293 if (n instanceof NamedAttribute) {
294 result.add(n);
295 } else if (!(n instanceof Comment)) {
296
297
298 break;
299 }
300 }
301 }
302
303 namedAttributeNodes = result;
304 return result;
305 }
306
307 public Nodes getBody() {
308 return body;
309 }
310
311 public void setBody(Nodes body) {
312 this.body = body;
313 }
314
315 public String getText() {
316 return text;
317 }
318
319 public Mark getStart() {
320 return startMark;
321 }
322
323 public Node getParent() {
324 return parent;
325 }
326
327 public int getBeginJavaLine() {
328 return beginJavaLine;
329 }
330
331 public void setBeginJavaLine(int begin) {
332 beginJavaLine = begin;
333 }
334
335 public int getEndJavaLine() {
336 return endJavaLine;
337 }
338
339 public void setEndJavaLine(int end) {
340 endJavaLine = end;
341 }
342
343 public boolean isDummy() {
344 return isDummy;
345 }
346
347 public Node.Root getRoot() {
348 Node n = this;
349 while (!(n instanceof Node.Root)) {
350 n = n.getParent();
351 }
352 return (Node.Root) n;
353 }
354
355 public String getInnerClassName() {
356 return innerClassName;
357 }
358
359 public void setInnerClassName(String icn) {
360 innerClassName = icn;
361 }
362
363 /***
364 * Selects and invokes a method in the visitor class based on the node
365 * type. This is abstract and should be overrode by the extending classes.
366 *
367 * @param v The visitor class
368 */
369 abstract void accept(Visitor v) throws JasperException;
370
371
372 //**********************************************************************
373 // Private utility methods
374
375 /*
376 * Adds this Node to the body of the given parent.
377 */
378
379 private void addToParent(Node parent) {
380 if (parent != null) {
381 this.parent = parent;
382 Nodes parentBody = parent.getBody();
383 if (parentBody == null) {
384 parentBody = new Nodes();
385 parent.setBody(parentBody);
386 }
387 parentBody.add(this);
388 }
389 }
390
391
392 /**********************************************************************
393 * Child classes
394 */
395
396 /***
397 * Represents the root of a Jsp page or Jsp document
398 */
399 public static class Root extends Node {
400
401 private Root parentRoot;
402 private boolean isXmlSyntax;
403
404
405 private String pageEnc;
406
407
408 private String jspConfigPageEnc;
409
410
411
412
413
414
415
416
417
418
419
420 private boolean isDefaultPageEncoding;
421
422
423
424
425
426
427
428 private boolean isEncodingSpecifiedInProlog;
429
430
431
432
433 Root(Mark start, Node parent, boolean isXmlSyntax) {
434 super(start, parent);
435 this.isXmlSyntax = isXmlSyntax;
436 this.qName = JSP_ROOT_ACTION;
437 this.localName = ROOT_ACTION;
438
439
440 Node r = parent;
441 while ((r != null) && !(r instanceof Node.Root))
442 r = r.getParent();
443 parentRoot = (Node.Root) r;
444 }
445
446 public void accept(Visitor v) throws JasperException {
447 v.visit(this);
448 }
449
450 public boolean isXmlSyntax() {
451 return isXmlSyntax;
452 }
453
454
455
456
457
458 public void setJspConfigPageEncoding(String enc) {
459 jspConfigPageEnc = enc;
460 }
461
462
463
464
465
466 public String getJspConfigPageEncoding() {
467 return jspConfigPageEnc;
468 }
469
470 public void setPageEncoding(String enc) {
471 pageEnc = enc;
472 }
473
474 public String getPageEncoding() {
475 return pageEnc;
476 }
477
478 public void setIsDefaultPageEncoding(boolean isDefault) {
479 isDefaultPageEncoding = isDefault;
480 }
481
482 public boolean isDefaultPageEncoding() {
483 return isDefaultPageEncoding;
484 }
485
486 public void setIsEncodingSpecifiedInProlog(boolean isSpecified) {
487 isEncodingSpecifiedInProlog = isSpecified;
488 }
489
490 public boolean isEncodingSpecifiedInProlog() {
491 return isEncodingSpecifiedInProlog;
492 }
493
494 /***
495 * @return The enclosing root to this Root. Usually represents the
496 * page that includes this one.
497 */
498 public Root getParentRoot() {
499 return parentRoot;
500 }
501 }
502
503 /***
504 * Represents the root of a Jsp document (XML syntax)
505 */
506 public static class JspRoot extends Node {
507
508 public JspRoot(String qName, Attributes attrs,
509 Attributes nonTaglibXmlnsAttrs, Attributes taglibAttrs,
510 Mark start, Node parent) {
511 super(qName, ROOT_ACTION, attrs, nonTaglibXmlnsAttrs, taglibAttrs,
512 start, parent);
513 }
514
515 public void accept(Visitor v) throws JasperException {
516 v.visit(this);
517 }
518 }
519
520 /***
521 * Represents a page directive
522 */
523 public static class PageDirective extends Node {
524
525 private Vector imports;
526
527 public PageDirective(Attributes attrs, Mark start, Node parent) {
528 this(JSP_PAGE_DIRECTIVE_ACTION, attrs, null, null, start, parent);
529 }
530
531 public PageDirective(String qName, Attributes attrs,
532 Attributes nonTaglibXmlnsAttrs,
533 Attributes taglibAttrs, Mark start, Node parent) {
534 super(qName, PAGE_DIRECTIVE_ACTION, attrs, nonTaglibXmlnsAttrs,
535 taglibAttrs, start, parent);
536 imports = new Vector();
537 }
538
539 public void accept(Visitor v) throws JasperException {
540 v.visit(this);
541 }
542
543 /***
544 * Parses the comma-separated list of class or package names in the
545 * given attribute value and adds each component to this
546 * PageDirective's vector of imported classes and packages.
547 *
548 * @param value A comma-separated string of imports.
549 */
550 public void addImport(String value) {
551 int start = 0;
552 int index;
553 while ((index = value.indexOf(',', start)) != -1) {
554 imports.add(value.substring(start, index).trim());
555 start = index + 1;
556 }
557 if (start == 0) {
558
559 imports.add(value.trim());
560 } else {
561 imports.add(value.substring(start).trim());
562 }
563 }
564
565 public List getImports() {
566 return imports;
567 }
568 }
569
570 /***
571 * Represents an include directive
572 */
573 public static class IncludeDirective extends Node {
574
575 public IncludeDirective(Attributes attrs, Mark start, Node parent) {
576 this(JSP_INCLUDE_DIRECTIVE_ACTION, attrs, null, null, start,
577 parent);
578 }
579
580 public IncludeDirective(String qName, Attributes attrs,
581 Attributes nonTaglibXmlnsAttrs,
582 Attributes taglibAttrs, Mark start,
583 Node parent) {
584 super(qName, INCLUDE_DIRECTIVE_ACTION, attrs, nonTaglibXmlnsAttrs,
585 taglibAttrs, start, parent);
586 }
587
588 public void accept(Visitor v) throws JasperException {
589 v.visit(this);
590 }
591 }
592
593 /***
594 * Represents a custom taglib directive
595 */
596 public static class TaglibDirective extends Node {
597
598 public TaglibDirective(Attributes attrs, Mark start, Node parent) {
599 super(JSP_TAGLIB_DIRECTIVE_ACTION, TAGLIB_DIRECTIVE_ACTION, attrs,
600 start, parent);
601 }
602
603 public void accept(Visitor v) throws JasperException {
604 v.visit(this);
605 }
606 }
607
608 /***
609 * Represents a tag directive
610 */
611 public static class TagDirective extends Node {
612 private Vector imports;
613
614 public TagDirective(Attributes attrs, Mark start, Node parent) {
615 this(JSP_TAG_DIRECTIVE_ACTION, attrs, null, null, start, parent);
616 }
617
618 public TagDirective(String qName, Attributes attrs,
619 Attributes nonTaglibXmlnsAttrs,
620 Attributes taglibAttrs, Mark start, Node parent) {
621 super(qName, TAG_DIRECTIVE_ACTION, attrs, nonTaglibXmlnsAttrs,
622 taglibAttrs, start, parent);
623 imports = new Vector();
624 }
625
626 public void accept(Visitor v) throws JasperException {
627 v.visit(this);
628 }
629
630 /***
631 * Parses the comma-separated list of class or package names in the
632 * given attribute value and adds each component to this
633 * PageDirective's vector of imported classes and packages.
634 *
635 * @param value A comma-separated string of imports.
636 */
637 public void addImport(String value) {
638 int start = 0;
639 int index;
640 while ((index = value.indexOf(',', start)) != -1) {
641 imports.add(value.substring(start, index).trim());
642 start = index + 1;
643 }
644 if (start == 0) {
645
646 imports.add(value.trim());
647 } else {
648 imports.add(value.substring(start).trim());
649 }
650 }
651
652 public List getImports() {
653 return imports;
654 }
655 }
656
657 /***
658 * Represents an attribute directive
659 */
660 public static class AttributeDirective extends Node {
661
662 public AttributeDirective(Attributes attrs, Mark start, Node parent) {
663 this(JSP_ATTRIBUTE_DIRECTIVE_ACTION, attrs, null, null, start,
664 parent);
665 }
666
667 public AttributeDirective(String qName, Attributes attrs,
668 Attributes nonTaglibXmlnsAttrs,
669 Attributes taglibAttrs, Mark start,
670 Node parent) {
671 super(qName, ATTRIBUTE_DIRECTIVE_ACTION, attrs,
672 nonTaglibXmlnsAttrs, taglibAttrs, start, parent);
673 }
674
675 public void accept(Visitor v) throws JasperException {
676 v.visit(this);
677 }
678 }
679
680 /***
681 * Represents a variable directive
682 */
683 public static class VariableDirective extends Node {
684
685 public VariableDirective(Attributes attrs, Mark start, Node parent) {
686 this(JSP_VARIABLE_DIRECTIVE_ACTION, attrs, null, null, start,
687 parent);
688 }
689
690 public VariableDirective(String qName, Attributes attrs,
691 Attributes nonTaglibXmlnsAttrs,
692 Attributes taglibAttrs,
693 Mark start, Node parent) {
694 super(qName, VARIABLE_DIRECTIVE_ACTION, attrs, nonTaglibXmlnsAttrs,
695 taglibAttrs, start, parent);
696 }
697
698 public void accept(Visitor v) throws JasperException {
699 v.visit(this);
700 }
701 }
702
703 /***
704 * Represents a <jsp:invoke> tag file action
705 */
706 public static class InvokeAction extends Node {
707
708 public InvokeAction(Attributes attrs, Mark start, Node parent) {
709 this(JSP_INVOKE_ACTION, attrs, null, null, start, parent);
710 }
711
712 public InvokeAction(String qName, Attributes attrs,
713 Attributes nonTaglibXmlnsAttrs,
714 Attributes taglibAttrs, Mark start, Node parent) {
715 super(qName, INVOKE_ACTION, attrs, nonTaglibXmlnsAttrs,
716 taglibAttrs, start, parent);
717 }
718
719 public void accept(Visitor v) throws JasperException {
720 v.visit(this);
721 }
722 }
723
724 /***
725 * Represents a <jsp:doBody> tag file action
726 */
727 public static class DoBodyAction extends Node {
728
729 public DoBodyAction(Attributes attrs, Mark start, Node parent) {
730 this(JSP_DOBODY_ACTION, attrs, null, null, start, parent);
731 }
732
733 public DoBodyAction(String qName, Attributes attrs,
734 Attributes nonTaglibXmlnsAttrs,
735 Attributes taglibAttrs, Mark start, Node parent) {
736 super(qName, DOBODY_ACTION, attrs, nonTaglibXmlnsAttrs,
737 taglibAttrs, start, parent);
738 }
739
740 public void accept(Visitor v) throws JasperException {
741 v.visit(this);
742 }
743 }
744
745 /***
746 * Represents a Jsp comment
747 * Comments are kept for completeness.
748 */
749 public static class Comment extends Node {
750
751 public Comment(String text, Mark start, Node parent) {
752 super(null, null, text, start, parent);
753 }
754
755 public void accept(Visitor v) throws JasperException {
756 v.visit(this);
757 }
758 }
759
760 /***
761 * Represents an expression, declaration, or scriptlet
762 */
763 public static abstract class ScriptingElement extends Node {
764
765 public ScriptingElement(String qName, String localName, String text,
766 Mark start, Node parent) {
767 super(qName, localName, text, start, parent);
768 }
769
770 public ScriptingElement(String qName, String localName,
771 Attributes nonTaglibXmlnsAttrs,
772 Attributes taglibAttrs, Mark start,
773 Node parent) {
774 super(qName, localName, null, nonTaglibXmlnsAttrs, taglibAttrs,
775 start, parent);
776 }
777
778 /***
779 * When this node was created from a JSP page in JSP syntax, its text
780 * was stored as a String in the "text" field, whereas when this node
781 * was created from a JSP document, its text was stored as one or more
782 * TemplateText nodes in its body. This method handles either case.
783 *
784 * @return The text string
785 */
786 public String getText() {
787 String ret = text;
788 if ((ret == null) && (body != null)) {
789 StringBuffer buf = new StringBuffer();
790 for (int i = 0; i < body.size(); i++) {
791 buf.append(body.getNode(i).getText());
792 }
793 ret = buf.toString();
794 }
795 return ret;
796 }
797
798 /***
799 * For the same reason as above, the source line information in the
800 * contained TemplateText node should be used.
801 */
802 public Mark getStart() {
803 if (text == null && body != null && body.size() > 0) {
804 return body.getNode(0).getStart();
805 } else {
806 return super.getStart();
807 }
808 }
809 }
810
811 /***
812 * Represents a declaration
813 */
814 public static class Declaration extends ScriptingElement {
815
816 public Declaration(String text, Mark start, Node parent) {
817 super(JSP_DECLARATION_ACTION, DECLARATION_ACTION, text, start,
818 parent);
819 }
820
821 public Declaration(String qName, Attributes nonTaglibXmlnsAttrs,
822 Attributes taglibAttrs, Mark start,
823 Node parent) {
824 super(qName, DECLARATION_ACTION, nonTaglibXmlnsAttrs,
825 taglibAttrs, start, parent);
826 }
827
828 public void accept(Visitor v) throws JasperException {
829 v.visit(this);
830 }
831 }
832
833 /***
834 * Represents an expression. Expressions in attributes are embedded
835 * in the attribute string and not here.
836 */
837 public static class Expression extends ScriptingElement {
838
839 public Expression(String text, Mark start, Node parent) {
840 super(JSP_EXPRESSION_ACTION, EXPRESSION_ACTION, text, start,
841 parent);
842 }
843
844 public Expression(String qName, Attributes nonTaglibXmlnsAttrs,
845 Attributes taglibAttrs, Mark start,
846 Node parent) {
847 super(qName, EXPRESSION_ACTION, nonTaglibXmlnsAttrs, taglibAttrs,
848 start, parent);
849 }
850
851 public void accept(Visitor v) throws JasperException {
852 v.visit(this);
853 }
854 }
855
856 /***
857 * Represents a scriptlet
858 */
859 public static class Scriptlet extends ScriptingElement {
860
861 public Scriptlet(String text, Mark start, Node parent) {
862 super(JSP_SCRIPTLET_ACTION, SCRIPTLET_ACTION, text, start, parent);
863 }
864
865 public Scriptlet(String qName, Attributes nonTaglibXmlnsAttrs,
866 Attributes taglibAttrs, Mark start,
867 Node parent) {
868 super(qName, SCRIPTLET_ACTION, nonTaglibXmlnsAttrs, taglibAttrs,
869 start, parent);
870 }
871
872 public void accept(Visitor v) throws JasperException {
873 v.visit(this);
874 }
875 }
876
877 /***
878 * Represents an EL expression. Expressions in attributes are embedded
879 * in the attribute string and not here.
880 */
881 public static class ELExpression extends Node {
882
883 private ELNode.Nodes el;
884
885 public ELExpression(String text, Mark start, Node parent) {
886 super(null, null, text, start, parent);
887 }
888
889 public void accept(Visitor v) throws JasperException {
890 v.visit(this);
891 }
892
893 public void setEL(ELNode.Nodes el) {
894 this.el = el;
895 }
896
897 public ELNode.Nodes getEL() {
898 return el;
899 }
900 }
901
902 /***
903 * Represents a param action
904 */
905 public static class ParamAction extends Node {
906
907 JspAttribute value;
908
909 public ParamAction(Attributes attrs, Mark start, Node parent) {
910 this(JSP_PARAM_ACTION, attrs, null, null, start, parent);
911 }
912
913 public ParamAction(String qName, Attributes attrs,
914 Attributes nonTaglibXmlnsAttrs,
915 Attributes taglibAttrs, Mark start, Node parent) {
916 super(qName, PARAM_ACTION, attrs, nonTaglibXmlnsAttrs,
917 taglibAttrs, start, parent);
918 }
919
920 public void accept(Visitor v) throws JasperException {
921 v.visit(this);
922 }
923
924 public void setValue(JspAttribute value) {
925 this.value = value;
926 }
927
928 public JspAttribute getValue() {
929 return value;
930 }
931 }
932
933 /***
934 * Represents a params action
935 */
936 public static class ParamsAction extends Node {
937
938 public ParamsAction(Mark start, Node parent) {
939 this(JSP_PARAMS_ACTION, null, null, start, parent);
940 }
941
942 public ParamsAction(String qName,
943 Attributes nonTaglibXmlnsAttrs,
944 Attributes taglibAttrs,
945 Mark start, Node parent) {
946 super(qName, PARAMS_ACTION, null, nonTaglibXmlnsAttrs, taglibAttrs,
947 start, parent);
948 }
949
950 public void accept(Visitor v) throws JasperException {
951 v.visit(this);
952 }
953 }
954
955 /***
956 * Represents a fallback action
957 */
958 public static class FallBackAction extends Node {
959
960 public FallBackAction(Mark start, Node parent) {
961 this(JSP_FALLBACK_ACTION, null, null, start, parent);
962 }
963
964 public FallBackAction(String qName,
965 Attributes nonTaglibXmlnsAttrs,
966 Attributes taglibAttrs, Mark start,
967 Node parent) {
968 super(qName, FALLBACK_ACTION, null, nonTaglibXmlnsAttrs,
969 taglibAttrs, start, parent);
970 }
971
972 public void accept(Visitor v) throws JasperException {
973 v.visit(this);
974 }
975 }
976
977 /***
978 * Represents an include action
979 */
980 public static class IncludeAction extends Node {
981
982 private JspAttribute page;
983
984 public IncludeAction(Attributes attrs, Mark start, Node parent) {
985 this(JSP_INCLUDE_ACTION, attrs, null, null, start, parent);
986 }
987
988 public IncludeAction(String qName, Attributes attrs,
989 Attributes nonTaglibXmlnsAttrs,
990 Attributes taglibAttrs, Mark start, Node parent) {
991 super(qName, INCLUDE_ACTION, attrs, nonTaglibXmlnsAttrs,
992 taglibAttrs, start, parent);
993 }
994
995 public void accept(Visitor v) throws JasperException {
996 v.visit(this);
997 }
998
999 public void setPage(JspAttribute page) {
1000 this.page = page;
1001 }
1002
1003 public JspAttribute getPage() {
1004 return page;
1005 }
1006 }
1007
1008 /***
1009 * Represents a forward action
1010 */
1011 public static class ForwardAction extends Node {
1012
1013 private JspAttribute page;
1014
1015 public ForwardAction(Attributes attrs, Mark start, Node parent) {
1016 this(JSP_FORWARD_ACTION, attrs, null, null, start, parent);
1017 }
1018
1019 public ForwardAction(String qName, Attributes attrs,
1020 Attributes nonTaglibXmlnsAttrs,
1021 Attributes taglibAttrs, Mark start, Node parent) {
1022 super(qName, FORWARD_ACTION, attrs, nonTaglibXmlnsAttrs,
1023 taglibAttrs, start, parent);
1024 }
1025
1026 public void accept(Visitor v) throws JasperException {
1027 v.visit(this);
1028 }
1029
1030 public void setPage(JspAttribute page) {
1031 this.page = page;
1032 }
1033
1034 public JspAttribute getPage() {
1035 return page;
1036 }
1037 }
1038
1039 /***
1040 * Represents a getProperty action
1041 */
1042 public static class GetProperty extends Node {
1043
1044 public GetProperty(Attributes attrs, Mark start, Node parent) {
1045 this(JSP_GET_PROPERTY_ACTION, attrs, null, null, start, parent);
1046 }
1047
1048 public GetProperty(String qName, Attributes attrs,
1049 Attributes nonTaglibXmlnsAttrs,
1050 Attributes taglibAttrs, Mark start, Node parent) {
1051 super(qName, GET_PROPERTY_ACTION, attrs, nonTaglibXmlnsAttrs,
1052 taglibAttrs, start, parent);
1053 }
1054
1055 public void accept(Visitor v) throws JasperException {
1056 v.visit(this);
1057 }
1058 }
1059
1060 /***
1061 * Represents a setProperty action
1062 */
1063 public static class SetProperty extends Node {
1064
1065 private JspAttribute value;
1066
1067 public SetProperty(Attributes attrs, Mark start, Node parent) {
1068 this(JSP_SET_PROPERTY_ACTION, attrs, null, null, start, parent);
1069 }
1070
1071 public SetProperty(String qName, Attributes attrs,
1072 Attributes nonTaglibXmlnsAttrs,
1073 Attributes taglibAttrs, Mark start, Node parent) {
1074 super(qName, SET_PROPERTY_ACTION, attrs, nonTaglibXmlnsAttrs,
1075 taglibAttrs, start, parent);
1076 }
1077
1078 public void accept(Visitor v) throws JasperException {
1079 v.visit(this);
1080 }
1081
1082 public void setValue(JspAttribute value) {
1083 this.value = value;
1084 }
1085
1086 public JspAttribute getValue() {
1087 return value;
1088 }
1089 }
1090
1091 /***
1092 * Represents a useBean action
1093 */
1094 public static class UseBean extends Node {
1095
1096 JspAttribute beanName;
1097
1098 public UseBean(Attributes attrs, Mark start, Node parent) {
1099 this(JSP_USE_BEAN_ACTION, attrs, null, null, start, parent);
1100 }
1101
1102 public UseBean(String qName, Attributes attrs,
1103 Attributes nonTaglibXmlnsAttrs, Attributes taglibAttrs,
1104 Mark start, Node parent) {
1105 super(qName, USE_BEAN_ACTION, attrs, nonTaglibXmlnsAttrs,
1106 taglibAttrs, start, parent);
1107 }
1108
1109 public void accept(Visitor v) throws JasperException {
1110 v.visit(this);
1111 }
1112
1113 public void setBeanName(JspAttribute beanName) {
1114 this.beanName = beanName;
1115 }
1116
1117 public JspAttribute getBeanName() {
1118 return beanName;
1119 }
1120 }
1121
1122 /***
1123 * Represents a plugin action
1124 */
1125 public static class PlugIn extends Node {
1126
1127 private JspAttribute width;
1128 private JspAttribute height;
1129
1130 public PlugIn(Attributes attrs, Mark start, Node parent) {
1131 this(JSP_PLUGIN_ACTION, attrs, null, null, start, parent);
1132 }
1133
1134 public PlugIn(String qName, Attributes attrs,
1135 Attributes nonTaglibXmlnsAttrs, Attributes taglibAttrs,
1136 Mark start, Node parent) {
1137 super(qName, PLUGIN_ACTION, attrs, nonTaglibXmlnsAttrs,
1138 taglibAttrs, start, parent);
1139 }
1140
1141 public void accept(Visitor v) throws JasperException {
1142 v.visit(this);
1143 }
1144
1145 public void setHeight(JspAttribute height) {
1146 this.height = height;
1147 }
1148
1149 public void setWidth(JspAttribute width) {
1150 this.width = width;
1151 }
1152
1153 public JspAttribute getHeight() {
1154 return height;
1155 }
1156
1157 public JspAttribute getWidth() {
1158 return width;
1159 }
1160 }
1161
1162 /***
1163 * Represents an uninterpreted tag, from a Jsp document
1164 */
1165 public static class UninterpretedTag extends Node {
1166
1167 private JspAttribute[] jspAttrs;
1168
1169 public UninterpretedTag(String qName, String localName,
1170 Attributes attrs,
1171 Attributes nonTaglibXmlnsAttrs,
1172 Attributes taglibAttrs,
1173 Mark start, Node parent) {
1174 super(qName, localName, attrs, nonTaglibXmlnsAttrs, taglibAttrs,
1175 start, parent);
1176 }
1177
1178 public void accept(Visitor v) throws JasperException {
1179 v.visit(this);
1180 }
1181
1182 public void setJspAttributes(JspAttribute[] jspAttrs) {
1183 this.jspAttrs = jspAttrs;
1184 }
1185
1186 public JspAttribute[] getJspAttributes() {
1187 return jspAttrs;
1188 }
1189 }
1190
1191 /***
1192 * Represents a <jsp:element>.
1193 */
1194 public static class JspElement extends Node {
1195
1196 private JspAttribute[] jspAttrs;
1197 private JspAttribute nameAttr;
1198
1199 public JspElement(Attributes attrs, Mark start, Node parent) {
1200 this(JSP_ELEMENT_ACTION, attrs, null, null, start, parent);
1201 }
1202
1203 public JspElement(String qName, Attributes attrs,
1204 Attributes nonTaglibXmlnsAttrs,
1205 Attributes taglibAttrs, Mark start, Node parent) {
1206 super(qName, ELEMENT_ACTION, attrs, nonTaglibXmlnsAttrs,
1207 taglibAttrs, start, parent);
1208 }
1209
1210 public void accept(Visitor v) throws JasperException {
1211 v.visit(this);
1212 }
1213
1214 public void setJspAttributes(JspAttribute[] jspAttrs) {
1215 this.jspAttrs = jspAttrs;
1216 }
1217
1218 public JspAttribute[] getJspAttributes() {
1219 return jspAttrs;
1220 }
1221
1222
1223
1224
1225 public void setNameAttribute(JspAttribute nameAttr) {
1226 this.nameAttr = nameAttr;
1227 }
1228
1229
1230
1231
1232 public JspAttribute getNameAttribute() {
1233 return this.nameAttr;
1234 }
1235 }
1236
1237 /***
1238 * Represents a <jsp:output>.
1239 */
1240 public static class JspOutput extends Node {
1241
1242 public JspOutput(String qName, Attributes attrs,
1243 Attributes nonTaglibXmlnsAttrs,
1244 Attributes taglibAttrs,
1245 Mark start, Node parent) {
1246 super(qName, OUTPUT_ACTION, attrs, nonTaglibXmlnsAttrs,
1247 taglibAttrs, start, parent);
1248 }
1249
1250 public void accept(Visitor v) throws JasperException {
1251 v.visit(this);
1252 }
1253 }
1254
1255 /***
1256 * Collected information about child elements. Used by nodes like
1257 * CustomTag, JspBody, and NamedAttribute. The information is
1258 * set in the Collector.
1259 */
1260 public static class ChildInfo {
1261 private boolean scriptless;
1262
1263 private boolean hasUseBean;
1264 private boolean hasIncludeAction;
1265 private boolean hasParamAction;
1266 private boolean hasSetProperty;
1267 private boolean hasScriptingVars;
1268
1269 public void setScriptless(boolean s) {
1270 scriptless = s;
1271 }
1272
1273 public boolean isScriptless() {
1274 return scriptless;
1275 }
1276
1277 public void setHasUseBean(boolean u) {
1278 hasUseBean = u;
1279 }
1280
1281 public boolean hasUseBean() {
1282 return hasUseBean;
1283 }
1284
1285 public void setHasIncludeAction(boolean i) {
1286 hasIncludeAction = i;
1287 }
1288
1289 public boolean hasIncludeAction() {
1290 return hasIncludeAction;
1291 }
1292
1293 public void setHasParamAction(boolean i) {
1294 hasParamAction = i;
1295 }
1296
1297 public boolean hasParamAction() {
1298 return hasParamAction;
1299 }
1300
1301 public void setHasSetProperty(boolean s) {
1302 hasSetProperty = s;
1303 }
1304
1305 public boolean hasSetProperty() {
1306 return hasSetProperty;
1307 }
1308
1309 public void setHasScriptingVars(boolean s) {
1310 hasScriptingVars = s;
1311 }
1312
1313 public boolean hasScriptingVars() {
1314 return hasScriptingVars;
1315 }
1316 }
1317
1318 /***
1319 * Represents a custom tag
1320 */
1321 public static class CustomTag extends Node {
1322
1323 private String uri;
1324 private String prefix;
1325 private JspAttribute[] jspAttrs;
1326 private TagData tagData;
1327 private String tagHandlerPoolName;
1328 private TagInfo tagInfo;
1329 private TagFileInfo tagFileInfo;
1330 private Class tagHandlerClass;
1331 private VariableInfo[] varInfos;
1332 private int customNestingLevel;
1333 private ChildInfo childInfo;
1334 private boolean implementsIterationTag;
1335 private boolean implementsBodyTag;
1336 private boolean implementsTryCatchFinally;
1337 private boolean implementsSimpleTag;
1338 private boolean implementsDynamicAttributes;
1339 private Vector atBeginScriptingVars;
1340 private Vector atEndScriptingVars;
1341 private Vector nestedScriptingVars;
1342 private Node.CustomTag customTagParent;
1343 private Integer numCount;
1344 private boolean useTagPlugin;
1345 private TagPluginContext tagPluginContext;
1346
1347 /***
1348 * The following two fields are used for holding the Java
1349 * scriptlets that the tag plugins may generate. Meaningful
1350 * only if useTagPlugin is true;
1351 * Could move them into TagPluginContextImpl, but we'll need
1352 * to cast tagPluginContext to TagPluginContextImpl all the time...
1353 */
1354 private Nodes atSTag;
1355 private Nodes atETag;
1356
1357
1358
1359
1360 public CustomTag(String qName, String prefix, String localName,
1361 String uri, Attributes attrs, Mark start, Node parent,
1362 TagInfo tagInfo, Class tagHandlerClass) {
1363 this(qName, prefix, localName, uri, attrs, null, null, start,
1364 parent, tagInfo, tagHandlerClass);
1365 }
1366
1367
1368
1369
1370 public CustomTag(String qName, String prefix, String localName,
1371 String uri, Attributes attrs,
1372 Attributes nonTaglibXmlnsAttrs,
1373 Attributes taglibAttrs,
1374 Mark start, Node parent, TagInfo tagInfo,
1375 Class tagHandlerClass) {
1376 super(qName, localName, attrs, nonTaglibXmlnsAttrs, taglibAttrs,
1377 start, parent);
1378
1379 this.uri = uri;
1380 this.prefix = prefix;
1381 this.tagInfo = tagInfo;
1382 this.tagHandlerClass = tagHandlerClass;
1383 this.customNestingLevel = makeCustomNestingLevel();
1384 this.childInfo = new ChildInfo();
1385
1386 this.implementsIterationTag =
1387 IterationTag.class.isAssignableFrom(tagHandlerClass);
1388 this.implementsBodyTag =
1389 BodyTag.class.isAssignableFrom(tagHandlerClass);
1390 this.implementsTryCatchFinally =
1391 TryCatchFinally.class.isAssignableFrom(tagHandlerClass);
1392 this.implementsSimpleTag =
1393 SimpleTag.class.isAssignableFrom(tagHandlerClass);
1394 this.implementsDynamicAttributes =
1395 DynamicAttributes.class.isAssignableFrom(tagHandlerClass);
1396 }
1397
1398
1399
1400
1401 public CustomTag(String qName, String prefix, String localName,
1402 String uri, Attributes attrs, Mark start, Node parent,
1403 TagFileInfo tagFileInfo) {
1404 this(qName, prefix, localName, uri, attrs, null, null, start,
1405 parent, tagFileInfo);
1406 }
1407
1408
1409
1410
1411 public CustomTag(String qName, String prefix, String localName,
1412 String uri, Attributes attrs,
1413 Attributes nonTaglibXmlnsAttrs,
1414 Attributes taglibAttrs,
1415 Mark start, Node parent, TagFileInfo tagFileInfo) {
1416
1417 super(qName, localName, attrs, nonTaglibXmlnsAttrs, taglibAttrs,
1418 start, parent);
1419
1420 this.uri = uri;
1421 this.prefix = prefix;
1422 this.tagFileInfo = tagFileInfo;
1423 this.tagInfo = tagFileInfo.getTagInfo();
1424 this.customNestingLevel = makeCustomNestingLevel();
1425 this.childInfo = new ChildInfo();
1426
1427 this.implementsIterationTag = false;
1428 this.implementsBodyTag = false;
1429 this.implementsTryCatchFinally = false;
1430 this.implementsSimpleTag = true;
1431 this.implementsDynamicAttributes = tagInfo.hasDynamicAttributes();
1432 }
1433
1434 public void accept(Visitor v) throws JasperException {
1435 v.visit(this);
1436 }
1437
1438 /***
1439 * @return The URI namespace that this custom action belongs to
1440 */
1441 public String getURI() {
1442 return this.uri;
1443 }
1444
1445 /***
1446 * @return The tag prefix
1447 */
1448 public String getPrefix() {
1449 return prefix;
1450 }
1451
1452 public void setJspAttributes(JspAttribute[] jspAttrs) {
1453 this.jspAttrs = jspAttrs;
1454 }
1455
1456 public JspAttribute[] getJspAttributes() {
1457 return jspAttrs;
1458 }
1459
1460 public ChildInfo getChildInfo() {
1461 return childInfo;
1462 }
1463
1464 public void setTagData(TagData tagData) {
1465 this.tagData = tagData;
1466 this.varInfos = tagInfo.getVariableInfo(tagData);
1467 if (this.varInfos == null) {
1468 this.varInfos = ZERO_VARIABLE_INFO;
1469 }
1470 }
1471
1472 public TagData getTagData() {
1473 return tagData;
1474 }
1475
1476 public void setTagHandlerPoolName(String s) {
1477 tagHandlerPoolName = s;
1478 }
1479
1480 public String getTagHandlerPoolName() {
1481 return tagHandlerPoolName;
1482 }
1483
1484 public TagInfo getTagInfo() {
1485 return tagInfo;
1486 }
1487
1488 public TagFileInfo getTagFileInfo() {
1489 return tagFileInfo;
1490 }
1491
1492
1493
1494
1495
1496 public boolean isTagFile() {
1497 return tagFileInfo != null;
1498 }
1499
1500 public Class getTagHandlerClass() {
1501 return tagHandlerClass;
1502 }
1503
1504 public void setTagHandlerClass(Class hc) {
1505 tagHandlerClass = hc;
1506 }
1507
1508 public boolean implementsIterationTag() {
1509 return implementsIterationTag;
1510 }
1511
1512 public boolean implementsBodyTag() {
1513 return implementsBodyTag;
1514 }
1515
1516 public boolean implementsTryCatchFinally() {
1517 return implementsTryCatchFinally;
1518 }
1519
1520 public boolean implementsSimpleTag() {
1521 return implementsSimpleTag;
1522 }
1523
1524 public boolean implementsDynamicAttributes() {
1525 return implementsDynamicAttributes;
1526 }
1527
1528 public TagVariableInfo[] getTagVariableInfos() {
1529 return tagInfo.getTagVariableInfos();
1530 }
1531
1532 public VariableInfo[] getVariableInfos() {
1533 return varInfos;
1534 }
1535
1536 public void setCustomTagParent(Node.CustomTag n) {
1537 this.customTagParent = n;
1538 }
1539
1540 public Node.CustomTag getCustomTagParent() {
1541 return this.customTagParent;
1542 }
1543
1544 public void setNumCount(Integer count) {
1545 this.numCount = count;
1546 }
1547
1548 public Integer getNumCount() {
1549 return this.numCount;
1550 }
1551
1552 public void setScriptingVars(Vector vec, int scope) {
1553 switch (scope) {
1554 case VariableInfo.AT_BEGIN:
1555 this.atBeginScriptingVars = vec;
1556 break;
1557 case VariableInfo.AT_END:
1558 this.atEndScriptingVars = vec;
1559 break;
1560 case VariableInfo.NESTED:
1561 this.nestedScriptingVars = vec;
1562 break;
1563 }
1564 }
1565
1566
1567
1568
1569
1570 public Vector getScriptingVars(int scope) {
1571 Vector vec = null;
1572
1573 switch (scope) {
1574 case VariableInfo.AT_BEGIN:
1575 vec = this.atBeginScriptingVars;
1576 break;
1577 case VariableInfo.AT_END:
1578 vec = this.atEndScriptingVars;
1579 break;
1580 case VariableInfo.NESTED:
1581 vec = this.nestedScriptingVars;
1582 break;
1583 }
1584
1585 return vec;
1586 }
1587
1588
1589
1590
1591
1592 public int getCustomNestingLevel() {
1593 return customNestingLevel;
1594 }
1595
1596 /***
1597 * Checks to see if the attribute of the given name is of type
1598 * JspFragment.
1599 */
1600 public boolean checkIfAttributeIsJspFragment(String name) {
1601 boolean result = false;
1602
1603 TagAttributeInfo[] attributes = tagInfo.getAttributes();
1604 for (int i = 0; i < attributes.length; i++) {
1605 if (attributes[i].getName().equals(name) &&
1606 attributes[i].isFragment()) {
1607 result = true;
1608 break;
1609 }
1610 }
1611
1612 return result;
1613 }
1614
1615 public void setUseTagPlugin(boolean use) {
1616 useTagPlugin = use;
1617 }
1618
1619 public boolean useTagPlugin() {
1620 return useTagPlugin;
1621 }
1622
1623 public void setTagPluginContext(TagPluginContext tagPluginContext) {
1624 this.tagPluginContext = tagPluginContext;
1625 }
1626
1627 public TagPluginContext getTagPluginContext() {
1628 return tagPluginContext;
1629 }
1630
1631 public void setAtSTag(Nodes sTag) {
1632 atSTag = sTag;
1633 }
1634
1635 public Nodes getAtSTag() {
1636 return atSTag;
1637 }
1638
1639 public void setAtETag(Nodes eTag) {
1640 atETag = eTag;
1641 }
1642
1643 public Nodes getAtETag() {
1644 return atETag;
1645 }
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670 private int makeCustomNestingLevel() {
1671 int n = 0;
1672 Node p = parent;
1673 while (p != null) {
1674 if ((p instanceof Node.CustomTag)
1675 && qName.equals(((Node.CustomTag) p).qName)) {
1676 n++;
1677 }
1678 p = p.parent;
1679 }
1680 return n;
1681 }
1682
1683 /***
1684 * Returns true if this custom action has an empty body, and false
1685 * otherwise.
1686 * <p/>
1687 * A custom action is considered to have an empty body if the
1688 * following holds true:
1689 * - getBody() returns null, or
1690 * - all immediate children are jsp:attribute actions, or
1691 * - the action's jsp:body is empty.
1692 */
1693 public boolean hasEmptyBody() {
1694 boolean hasEmptyBody = true;
1695 Nodes nodes = getBody();
1696 if (nodes != null) {
1697 int numChildNodes = nodes.size();
1698 for (int i = 0; i < numChildNodes; i++) {
1699 Node n = nodes.getNode(i);
1700 if (!(n instanceof NamedAttribute)) {
1701 if (n instanceof JspBody) {
1702 hasEmptyBody = (n.getBody() == null);
1703 } else {
1704 hasEmptyBody = false;
1705 }
1706 break;
1707 }
1708 }
1709 }
1710
1711 return hasEmptyBody;
1712 }
1713 }
1714
1715 /***
1716 * Used as a placeholder for the evaluation code of a custom action
1717 * attribute (used by the tag plugin machinery only).
1718 */
1719 public static class AttributeGenerator extends Node {
1720 String name;
1721 CustomTag tag;
1722
1723 public AttributeGenerator(Mark start, String name, CustomTag tag) {
1724 super(start, null);
1725 this.name = name;
1726 this.tag = tag;
1727 }
1728
1729 public void accept(Visitor v) throws JasperException {
1730 v.visit(this);
1731 }
1732
1733 public String getName() {
1734 return name;
1735 }
1736
1737 public CustomTag getTag() {
1738 return tag;
1739 }
1740 }
1741
1742 /***
1743 * Represents the body of a <jsp:text> element
1744 */
1745 public static class JspText extends Node {
1746
1747 public JspText(String qName, Attributes nonTaglibXmlnsAttrs,
1748 Attributes taglibAttrs, Mark start, Node parent) {
1749 super(qName, TEXT_ACTION, null, nonTaglibXmlnsAttrs, taglibAttrs,
1750 start, parent);
1751 }
1752
1753 public void accept(Visitor v) throws JasperException {
1754 v.visit(this);
1755 }
1756 }
1757
1758 /***
1759 * Represents a Named Attribute (<jsp:attribute>)
1760 */
1761 public static class NamedAttribute extends Node {
1762
1763
1764 private String temporaryVariableName;
1765
1766
1767 private boolean trim = true;
1768
1769 private ChildInfo childInfo;
1770 private String name;
1771 private String localName;
1772 private String prefix;
1773
1774 public NamedAttribute(Attributes attrs, Mark start, Node parent) {
1775 this(JSP_ATTRIBUTE_ACTION, attrs, null, null, start, parent);
1776 }
1777
1778 public NamedAttribute(String qName, Attributes attrs,
1779 Attributes nonTaglibXmlnsAttrs,
1780 Attributes taglibAttrs,
1781 Mark start, Node parent) {
1782
1783 super(qName, ATTRIBUTE_ACTION, attrs, nonTaglibXmlnsAttrs,
1784 taglibAttrs, start, parent);
1785 if ("false".equals(this.getAttributeValue("trim"))) {
1786
1787 trim = false;
1788 }
1789 childInfo = new ChildInfo();
1790 name = this.getAttributeValue("name");
1791 if (name != null) {
1792
1793 localName = name;
1794 int index = name.indexOf(':');
1795 if (index != -1) {
1796 prefix = name.substring(0, index);
1797 localName = name.substring(index + 1);
1798 }
1799 }
1800 }
1801
1802 public void accept(Visitor v) throws JasperException {
1803 v.visit(this);
1804 }
1805
1806 public String getName() {
1807 return this.name;
1808 }
1809
1810 public String getLocalName() {
1811 return this.localName;
1812 }
1813
1814 public String getPrefix() {
1815 return this.prefix;
1816 }
1817
1818 public ChildInfo getChildInfo() {
1819 return this.childInfo;
1820 }
1821
1822 public boolean isTrim() {
1823 return trim;
1824 }
1825
1826 /***
1827 * @return A unique temporary variable name to store the result in.
1828 * (this probably could go elsewhere, but it's convenient here)
1829 */
1830 public String getTemporaryVariableName() {
1831 if (temporaryVariableName == null) {
1832 temporaryVariableName = JspUtil.nextTemporaryVariableName();
1833 }
1834 return temporaryVariableName;
1835 }
1836
1837
1838
1839
1840
1841
1842 public String getText() {
1843
1844 class AttributeVisitor extends Visitor {
1845 String attrValue = null;
1846
1847 public void visit(TemplateText txt) {
1848 attrValue = new String(txt.getText());
1849 }
1850
1851 public String getAttrValue() {
1852 return attrValue;
1853 }
1854 }
1855
1856
1857
1858
1859 String text = "";
1860 if (getBody() != null) {
1861 AttributeVisitor attributeVisitor = new AttributeVisitor();
1862 try {
1863 getBody().visit(attributeVisitor);
1864 } catch (JasperException e) {
1865 }
1866 text = attributeVisitor.getAttrValue();
1867 }
1868
1869 return text;
1870 }
1871 }
1872
1873 /***
1874 * Represents a JspBody node (<jsp:body>)
1875 */
1876 public static class JspBody extends Node {
1877
1878 private ChildInfo childInfo;
1879
1880 public JspBody(Mark start, Node parent) {
1881 this(JSP_BODY_ACTION, null, null, start, parent);
1882 }
1883
1884 public JspBody(String qName, Attributes nonTaglibXmlnsAttrs,
1885 Attributes taglibAttrs, Mark start, Node parent) {
1886 super(qName, BODY_ACTION, null, nonTaglibXmlnsAttrs, taglibAttrs,
1887 start, parent);
1888 this.childInfo = new ChildInfo();
1889 }
1890
1891 public void accept(Visitor v) throws JasperException {
1892 v.visit(this);
1893 }
1894
1895 public ChildInfo getChildInfo() {
1896 return childInfo;
1897 }
1898 }
1899
1900 /***
1901 * Represents a template text string
1902 */
1903 public static class TemplateText extends Node {
1904
1905 private ArrayList extraSmap = null;
1906
1907 public TemplateText(String text, Mark start, Node parent) {
1908 super(null, null, text, start, parent);
1909 }
1910
1911 public void accept(Visitor v) throws JasperException {
1912 v.visit(this);
1913 }
1914
1915 /***
1916 * Trim all whitespace from the left of the template text
1917 */
1918 public void ltrim() {
1919 int index = 0;
1920 while ((index < text.length()) && (text.charAt(index) <= ' ')) {
1921 index++;
1922 }
1923 text = text.substring(index);
1924 }
1925
1926 public void setText(String text) {
1927 this.text = text;
1928 }
1929
1930 /***
1931 * Trim all whitespace from the right of the template text
1932 */
1933 public void rtrim() {
1934 int index = text.length();
1935 while ((index > 0) && (text.charAt(index - 1) <= ' ')) {
1936 index--;
1937 }
1938 text = text.substring(0, index);
1939 }
1940
1941 /***
1942 * Returns true if this template text contains whitespace only.
1943 */
1944 public boolean isAllSpace() {
1945 boolean isAllSpace = true;
1946 for (int i = 0; i < text.length(); i++) {
1947 if (!Character.isWhitespace(text.charAt(i))) {
1948 isAllSpace = false;
1949 break;
1950 }
1951 }
1952 return isAllSpace;
1953 }
1954
1955 /***
1956 * Add a source to Java line mapping
1957 *
1958 * @param srcLine The postion of the source line, relative to the line
1959 * at the start of this node. The corresponding java line is
1960 * assumed to be consecutive, i.e. one more than the last.
1961 */
1962 public void addSmap(int srcLine) {
1963 if (extraSmap == null) {
1964 extraSmap = new ArrayList();
1965 }
1966 extraSmap.add(new Integer(srcLine));
1967 }
1968
1969 public ArrayList getExtraSmap() {
1970 return extraSmap;
1971 }
1972 }
1973
1974 /**********************************************************************
1975 * Auxillary classes used in Node
1976 */
1977
1978 /***
1979 * Represents attributes that can be request time expressions.
1980 * <p/>
1981 * Can either be a plain attribute, an attribute that represents a
1982 * request time expression value, or a named attribute (specified using
1983 * the jsp:attribute standard action).
1984 */
1985
1986 public static class JspAttribute {
1987
1988 private String qName;
1989 private String uri;
1990 private String localName;
1991 private String value;
1992 private boolean expression;
1993 private boolean dynamic;
1994 private ELNode.Nodes el;
1995
1996
1997 private boolean namedAttribute;
1998
1999 private NamedAttribute namedAttributeNode;
2000
2001 JspAttribute(String qName, String uri, String localName, String value,
2002 boolean expr, ELNode.Nodes el, boolean dyn) {
2003 this.qName = qName;
2004 this.uri = uri;
2005 this.localName = localName;
2006 this.value = value;
2007 this.namedAttributeNode = null;
2008 this.expression = expr;
2009 this.el = el;
2010 this.dynamic = dyn;
2011 this.namedAttribute = false;
2012 }
2013
2014 /***
2015 * Use this constructor if the JspAttribute represents a
2016 * named attribute. In this case, we have to store the nodes of
2017 * the body of the attribute.
2018 */
2019 JspAttribute(NamedAttribute na, boolean dyn) {
2020 this.qName = na.getName();
2021 this.localName = na.getLocalName();
2022 this.value = null;
2023 this.namedAttributeNode = na;
2024 this.expression = false;
2025 this.el = null;
2026 this.dynamic = dyn;
2027 this.namedAttribute = true;
2028 }
2029
2030 /***
2031 * @return The name of the attribute
2032 */
2033 public String getName() {
2034 return qName;
2035 }
2036
2037 /***
2038 * @return The local name of the attribute
2039 */
2040 public String getLocalName() {
2041 return localName;
2042 }
2043
2044 /***
2045 * @return The namespace of the attribute, or null if in the default
2046 * namespace
2047 */
2048 public String getURI() {
2049 return uri;
2050 }
2051
2052 /***
2053 * Only makes sense if namedAttribute is false.
2054 *
2055 * @return the value for the attribute, or the expression string
2056 * (stripped of "<%=", "%>", "%=", or "%"
2057 * but containing "${" and "}" for EL expressions)
2058 */
2059 public String getValue() {
2060 return value;
2061 }
2062
2063 /***
2064 * Only makes sense if namedAttribute is true.
2065 *
2066 * @return the nodes that evaluate to the body of this attribute.
2067 */
2068 public NamedAttribute getNamedAttributeNode() {
2069 return namedAttributeNode;
2070 }
2071
2072 /***
2073 * @return true if the value represents a traditional rtexprvalue
2074 */
2075 public boolean isExpression() {
2076 return expression;
2077 }
2078
2079 /***
2080 * @return true if the value represents a NamedAttribute value.
2081 */
2082 public boolean isNamedAttribute() {
2083 return namedAttribute;
2084 }
2085
2086 /***
2087 * @return false for string literals or rtexprvalues that should
2088 * not be interpreted or reevaluated
2089 */
2090 public boolean isELInterpreterInput() {
2091 return el != null;
2092 }
2093
2094 /***
2095 * @return true if the value is a string literal known at translation
2096 * time.
2097 */
2098 public boolean isLiteral() {
2099 return !expression && (el != null) && !namedAttribute;
2100 }
2101
2102 /***
2103 * XXX
2104 */
2105 public boolean isDynamic() {
2106 return dynamic;
2107 }
2108
2109 public ELNode.Nodes getEL() {
2110 return el;
2111 }
2112 }
2113
2114 /***
2115 * An ordered list of Node, used to represent the body of an element, or
2116 * a jsp page of jsp document.
2117 */
2118 public static class Nodes {
2119
2120 private List list;
2121 private Node.Root root;
2122 private boolean generatedInBuffer;
2123
2124 public Nodes() {
2125 list = new Vector();
2126 }
2127
2128 public Nodes(Node.Root root) {
2129 this.root = root;
2130 list = new Vector();
2131 list.add(root);
2132 }
2133
2134 /***
2135 * Appends a node to the list
2136 *
2137 * @param n The node to add
2138 */
2139 public void add(Node n) {
2140 list.add(n);
2141 root = null;
2142 }
2143
2144 /***
2145 * Removes the given node from the list.
2146 *
2147 * @param n The node to be removed
2148 */
2149 public void remove(Node n) {
2150 list.remove(n);
2151 }
2152
2153 /***
2154 * Visit the nodes in the list with the supplied visitor
2155 *
2156 * @param v The visitor used
2157 */
2158 public void visit(Visitor v) throws JasperException {
2159 Iterator iter = list.iterator();
2160 while (iter.hasNext()) {
2161 Node n = (Node) iter.next();
2162 n.accept(v);
2163 }
2164 }
2165
2166 public int size() {
2167 return list.size();
2168 }
2169
2170 public Node getNode(int index) {
2171 Node n = null;
2172 try {
2173 n = (Node) list.get(index);
2174 } catch (ArrayIndexOutOfBoundsException e) {
2175 }
2176 return n;
2177 }
2178
2179 public Node.Root getRoot() {
2180 return root;
2181 }
2182
2183 public boolean isGeneratedInBuffer() {
2184 return generatedInBuffer;
2185 }
2186
2187 public void setGeneratedInBuffer(boolean g) {
2188 generatedInBuffer = g;
2189 }
2190 }
2191
2192 /***
2193 * A visitor class for visiting the node. This class also provides the
2194 * default action (i.e. nop) for each of the child class of the Node.
2195 * An actual visitor should extend this class and supply the visit
2196 * method for the nodes that it cares.
2197 */
2198 public static class Visitor {
2199
2200 /***
2201 * This method provides a place to put actions that are common to
2202 * all nodes. Override this in the child visitor class if need to.
2203 */
2204 protected void doVisit(Node n) throws JasperException {
2205 }
2206
2207 /***
2208 * Visit the body of a node, using the current visitor
2209 */
2210 protected void visitBody(Node n) throws JasperException {
2211 if (n.getBody() != null) {
2212 n.getBody().visit(this);
2213 }
2214 }
2215
2216 public void visit(Root n) throws JasperException {
2217 doVisit(n);
2218 visitBody(n);
2219 }
2220
2221 public void visit(JspRoot n) throws JasperException {
2222 doVisit(n);
2223 visitBody(n);
2224 }
2225
2226 public void visit(PageDirective n) throws JasperException {
2227 doVisit(n);
2228 }
2229
2230 public void visit(TagDirective n) throws JasperException {
2231 doVisit(n);
2232 }
2233
2234 public void visit(IncludeDirective n) throws JasperException {
2235 doVisit(n);
2236 visitBody(n);
2237 }
2238
2239 public void visit(TaglibDirective n) throws JasperException {
2240 doVisit(n);
2241 }
2242
2243 public void visit(AttributeDirective n) throws JasperException {
2244 doVisit(n);
2245 }
2246
2247 public void visit(VariableDirective n) throws JasperException {
2248 doVisit(n);
2249 }
2250
2251 public void visit(Comment n) throws JasperException {
2252 doVisit(n);
2253 }
2254
2255 public void visit(Declaration n) throws JasperException {
2256 doVisit(n);
2257 }
2258
2259 public void visit(Expression n) throws JasperException {
2260 doVisit(n);
2261 }
2262
2263 public void visit(Scriptlet n) throws JasperException {
2264 doVisit(n);
2265 }
2266
2267 public void visit(ELExpression n) throws JasperException {
2268 doVisit(n);
2269 }
2270
2271 public void visit(IncludeAction n) throws JasperException {
2272 doVisit(n);
2273 visitBody(n);
2274 }
2275
2276 public void visit(ForwardAction n) throws JasperException {
2277 doVisit(n);
2278 visitBody(n);
2279 }
2280
2281 public void visit(GetProperty n) throws JasperException {
2282 doVisit(n);
2283 visitBody(n);
2284 }
2285
2286 public void visit(SetProperty n) throws JasperException {
2287 doVisit(n);
2288 visitBody(n);
2289 }
2290
2291 public void visit(ParamAction n) throws JasperException {
2292 doVisit(n);
2293 visitBody(n);
2294 }
2295
2296 public void visit(ParamsAction n) throws JasperException {
2297 doVisit(n);
2298 visitBody(n);
2299 }
2300
2301 public void visit(FallBackAction n) throws JasperException {
2302 doVisit(n);
2303 visitBody(n);
2304 }
2305
2306 public void visit(UseBean n) throws JasperException {
2307 doVisit(n);
2308 visitBody(n);
2309 }
2310
2311 public void visit(PlugIn n) throws JasperException {
2312 doVisit(n);
2313 visitBody(n);
2314 }
2315
2316 public void visit(CustomTag n) throws JasperException {
2317 doVisit(n);
2318 visitBody(n);
2319 }
2320
2321 public void visit(UninterpretedTag n) throws JasperException {
2322 doVisit(n);
2323 visitBody(n);
2324 }
2325
2326 public void visit(JspElement n) throws JasperException {
2327 doVisit(n);
2328 visitBody(n);
2329 }
2330
2331 public void visit(JspText n) throws JasperException {
2332 doVisit(n);
2333 visitBody(n);
2334 }
2335
2336 public void visit(NamedAttribute n) throws JasperException {
2337 doVisit(n);
2338 visitBody(n);
2339 }
2340
2341 public void visit(JspBody n) throws JasperException {
2342 doVisit(n);
2343 visitBody(n);
2344 }
2345
2346 public void visit(InvokeAction n) throws JasperException {
2347 doVisit(n);
2348 visitBody(n);
2349 }
2350
2351 public void visit(DoBodyAction n) throws JasperException {
2352 doVisit(n);
2353 visitBody(n);
2354 }
2355
2356 public void visit(TemplateText n) throws JasperException {
2357 doVisit(n);
2358 }
2359
2360 public void visit(JspOutput n) throws JasperException {
2361 doVisit(n);
2362 }
2363
2364 public void visit(AttributeGenerator n) throws JasperException {
2365 doVisit(n);
2366 }
2367 }
2368 }