001: /*
002: * Copyright 1999,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.jasper.compiler;
018:
019: import java.util.*;
020: import javax.servlet.jsp.tagext.*;
021: import org.apache.jasper.JasperException;
022:
023: /**
024: * Class responsible for determining the scripting variables that every
025: * custom action needs to declare.
026: *
027: * @author Jan Luehe
028: */
029: class ScriptingVariabler {
030:
031: private static final Integer MAX_SCOPE = new Integer(
032: Integer.MAX_VALUE);
033:
034: /*
035: * Assigns an identifier (of type integer) to every custom tag, in order
036: * to help identify, for every custom tag, the scripting variables that it
037: * needs to declare.
038: */
039: static class CustomTagCounter extends Node.Visitor {
040:
041: private int count;
042: private Node.CustomTag parent;
043:
044: public void visit(Node.CustomTag n) throws JasperException {
045: n.setCustomTagParent(parent);
046: Node.CustomTag tmpParent = parent;
047: parent = n;
048: visitBody(n);
049: parent = tmpParent;
050: n.setNumCount(new Integer(count++));
051: }
052: }
053:
054: /*
055: * For every custom tag, determines the scripting variables it needs to
056: * declare.
057: */
058: static class ScriptingVariableVisitor extends Node.Visitor {
059:
060: private ErrorDispatcher err;
061: private Hashtable scriptVars;
062:
063: public ScriptingVariableVisitor(ErrorDispatcher err) {
064: this .err = err;
065: scriptVars = new Hashtable();
066: }
067:
068: public void visit(Node.CustomTag n) throws JasperException {
069: setScriptingVars(n, VariableInfo.AT_BEGIN);
070: setScriptingVars(n, VariableInfo.NESTED);
071: visitBody(n);
072: setScriptingVars(n, VariableInfo.AT_END);
073: }
074:
075: private void setScriptingVars(Node.CustomTag n, int scope)
076: throws JasperException {
077:
078: TagVariableInfo[] tagVarInfos = n.getTagVariableInfos();
079: VariableInfo[] varInfos = n.getVariableInfos();
080: if (tagVarInfos.length == 0 && varInfos.length == 0) {
081: return;
082: }
083:
084: Vector vec = new Vector();
085:
086: Integer ownRange = null;
087: if (scope == VariableInfo.AT_BEGIN
088: || scope == VariableInfo.AT_END) {
089: Node.CustomTag parent = n.getCustomTagParent();
090: if (parent == null)
091: ownRange = MAX_SCOPE;
092: else
093: ownRange = parent.getNumCount();
094: } else {
095: // NESTED
096: ownRange = n.getNumCount();
097: }
098:
099: if (varInfos.length > 0) {
100: for (int i = 0; i < varInfos.length; i++) {
101: if (varInfos[i].getScope() != scope
102: || !varInfos[i].getDeclare()) {
103: continue;
104: }
105: String varName = varInfos[i].getVarName();
106:
107: Integer currentRange = (Integer) scriptVars
108: .get(varName);
109: if (currentRange == null
110: || ownRange.compareTo(currentRange) > 0) {
111: scriptVars.put(varName, ownRange);
112: vec.add(varInfos[i]);
113: }
114: }
115: } else {
116: for (int i = 0; i < tagVarInfos.length; i++) {
117: if (tagVarInfos[i].getScope() != scope
118: || !tagVarInfos[i].getDeclare()) {
119: continue;
120: }
121: String varName = tagVarInfos[i].getNameGiven();
122: if (varName == null) {
123: varName = n.getTagData().getAttributeString(
124: tagVarInfos[i].getNameFromAttribute());
125: if (varName == null) {
126: err
127: .jspError(
128: n,
129: "jsp.error.scripting.variable.missing_name",
130: tagVarInfos[i]
131: .getNameFromAttribute());
132: }
133: }
134:
135: Integer currentRange = (Integer) scriptVars
136: .get(varName);
137: if (currentRange == null
138: || ownRange.compareTo(currentRange) > 0) {
139: scriptVars.put(varName, ownRange);
140: vec.add(tagVarInfos[i]);
141: }
142: }
143: }
144:
145: n.setScriptingVars(vec, scope);
146: }
147: }
148:
149: public static void set(Node.Nodes page, ErrorDispatcher err)
150: throws JasperException {
151: page.visit(new CustomTagCounter());
152: page.visit(new ScriptingVariableVisitor(err));
153: }
154: }
|