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