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
22 import javax.servlet.jsp.tagext.TagVariableInfo;
23 import javax.servlet.jsp.tagext.VariableInfo;
24 import java.util.Hashtable;
25 import java.util.Vector;
26
27 /***
28 * Class responsible for determining the scripting variables that every
29 * custom action needs to declare.
30 *
31 * @author Jan Luehe
32 */
33 class ScriptingVariabler {
34
35 private static final Integer MAX_SCOPE = new Integer(Integer.MAX_VALUE);
36
37
38
39
40
41
42 static class CustomTagCounter extends Node.Visitor {
43
44 private int count;
45 private Node.CustomTag parent;
46
47 public void visit(Node.CustomTag n) throws JasperException {
48 n.setCustomTagParent(parent);
49 Node.CustomTag tmpParent = parent;
50 parent = n;
51 visitBody(n);
52 parent = tmpParent;
53 n.setNumCount(new Integer(count++));
54 }
55 }
56
57
58
59
60
61 static class ScriptingVariableVisitor extends Node.Visitor {
62
63 private ErrorDispatcher err;
64 private Hashtable scriptVars;
65
66 public ScriptingVariableVisitor(ErrorDispatcher err) {
67 this.err = err;
68 scriptVars = new Hashtable();
69 }
70
71 public void visit(Node.CustomTag n) throws JasperException {
72 setScriptingVars(n, VariableInfo.AT_BEGIN);
73 setScriptingVars(n, VariableInfo.NESTED);
74 visitBody(n);
75 setScriptingVars(n, VariableInfo.AT_END);
76 }
77
78 private void setScriptingVars(Node.CustomTag n, int scope)
79 throws JasperException {
80
81 TagVariableInfo[] tagVarInfos = n.getTagVariableInfos();
82 VariableInfo[] varInfos = n.getVariableInfos();
83 if (tagVarInfos.length == 0 && varInfos.length == 0) {
84 return;
85 }
86
87 Vector vec = new Vector();
88
89 Integer ownRange = null;
90 if (scope == VariableInfo.AT_BEGIN
91 || scope == VariableInfo.AT_END) {
92 Node.CustomTag parent = n.getCustomTagParent();
93 if (parent == null)
94 ownRange = MAX_SCOPE;
95 else
96 ownRange = parent.getNumCount();
97 } else {
98
99 ownRange = n.getNumCount();
100 }
101
102 if (varInfos.length > 0) {
103 for (int i = 0; i < varInfos.length; i++) {
104 if (varInfos[i].getScope() != scope
105 || !varInfos[i].getDeclare()) {
106 continue;
107 }
108 String varName = varInfos[i].getVarName();
109
110 Integer currentRange = (Integer) scriptVars.get(varName);
111 if (currentRange == null
112 || ownRange.compareTo(currentRange) > 0) {
113 scriptVars.put(varName, ownRange);
114 vec.add(varInfos[i]);
115 }
116 }
117 } else {
118 for (int i = 0; i < tagVarInfos.length; i++) {
119 if (tagVarInfos[i].getScope() != scope
120 || !tagVarInfos[i].getDeclare()) {
121 continue;
122 }
123 String varName = tagVarInfos[i].getNameGiven();
124 if (varName == null) {
125 varName = n.getTagData().getAttributeString(
126 tagVarInfos[i].getNameFromAttribute());
127 if (varName == null) {
128 err.jspError(n, "jsp.error.scripting.variable.missing_name",
129 tagVarInfos[i].getNameFromAttribute());
130 }
131 }
132
133 Integer currentRange = (Integer) scriptVars.get(varName);
134 if (currentRange == null
135 || ownRange.compareTo(currentRange) > 0) {
136 scriptVars.put(varName, ownRange);
137 vec.add(tagVarInfos[i]);
138 }
139 }
140 }
141
142 n.setScriptingVars(vec, scope);
143 }
144 }
145
146 public static void set(Node.Nodes page, ErrorDispatcher err)
147 throws JasperException {
148 page.visit(new CustomTagCounter());
149 page.visit(new ScriptingVariableVisitor(err));
150 }
151 }