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 org.apache.jasper.JasperException;
020:
021: /**
022: * Collect info about the page and nodes, and make them availabe through
023: * the PageInfo object.
024: *
025: * @author Kin-man Chung
026: * @author Mark Roth
027: */
028:
029: class Collector {
030:
031: /**
032: * A visitor for collecting information on the page and the body of
033: * the custom tags.
034: */
035: static class CollectVisitor extends Node.Visitor {
036:
037: private int maxTagNesting = 0;
038: private int curTagNesting = 0;
039: private boolean scriptingElementSeen = false;
040: private boolean usebeanSeen = false;
041: private boolean includeActionSeen = false;
042: private boolean paramActionSeen = false;
043: private boolean setPropertySeen = false;
044: private boolean hasScriptingVars = false;
045:
046: public void visit(Node.ParamAction n) throws JasperException {
047: if (n.getValue().isExpression()) {
048: scriptingElementSeen = true;
049: }
050: paramActionSeen = true;
051: }
052:
053: public void visit(Node.IncludeAction n) throws JasperException {
054: if (n.getPage().isExpression()) {
055: scriptingElementSeen = true;
056: }
057: includeActionSeen = true;
058: visitBody(n);
059: }
060:
061: public void visit(Node.ForwardAction n) throws JasperException {
062: if (n.getPage().isExpression()) {
063: scriptingElementSeen = true;
064: }
065: visitBody(n);
066: }
067:
068: public void visit(Node.SetProperty n) throws JasperException {
069: if (n.getValue() != null && n.getValue().isExpression()) {
070: scriptingElementSeen = true;
071: }
072: setPropertySeen = true;
073: }
074:
075: public void visit(Node.UseBean n) throws JasperException {
076: if (n.getBeanName() != null
077: && n.getBeanName().isExpression()) {
078: scriptingElementSeen = true;
079: }
080: usebeanSeen = true;
081: visitBody(n);
082: }
083:
084: public void visit(Node.PlugIn n) throws JasperException {
085: if (n.getHeight() != null && n.getHeight().isExpression()) {
086: scriptingElementSeen = true;
087: }
088: if (n.getWidth() != null && n.getWidth().isExpression()) {
089: scriptingElementSeen = true;
090: }
091: visitBody(n);
092: }
093:
094: public void visit(Node.CustomTag n) throws JasperException {
095:
096: curTagNesting++;
097: if (curTagNesting > maxTagNesting) {
098: maxTagNesting = curTagNesting;
099: }
100:
101: // Check to see what kinds of element we see as child elements
102: checkSeen(n.getChildInfo(), n);
103:
104: curTagNesting--;
105: }
106:
107: /**
108: * Check all child nodes for various elements and update the given
109: * ChildInfo object accordingly. Visits body in the process.
110: */
111: private void checkSeen(Node.ChildInfo ci, Node n)
112: throws JasperException {
113: // save values collected so far
114: boolean scriptingElementSeenSave = scriptingElementSeen;
115: scriptingElementSeen = false;
116: boolean usebeanSeenSave = usebeanSeen;
117: usebeanSeen = false;
118: boolean includeActionSeenSave = includeActionSeen;
119: includeActionSeen = false;
120: boolean paramActionSeenSave = paramActionSeen;
121: paramActionSeen = false;
122: boolean setPropertySeenSave = setPropertySeen;
123: setPropertySeen = false;
124: boolean hasScriptingVarsSave = hasScriptingVars;
125: hasScriptingVars = false;
126:
127: // Scan attribute list for expressions
128: if (n instanceof Node.CustomTag) {
129: Node.CustomTag ct = (Node.CustomTag) n;
130: Node.JspAttribute[] attrs = ct.getJspAttributes();
131: for (int i = 0; attrs != null && i < attrs.length; i++) {
132: if (attrs[i].isExpression()) {
133: scriptingElementSeen = true;
134: break;
135: }
136: }
137: }
138:
139: visitBody(n);
140:
141: if ((n instanceof Node.CustomTag) && !hasScriptingVars) {
142: Node.CustomTag ct = (Node.CustomTag) n;
143: hasScriptingVars = ct.getVariableInfos().length > 0
144: || ct.getTagVariableInfos().length > 0;
145: }
146:
147: // Record if the tag element and its body contains any scriptlet.
148: ci.setScriptless(!scriptingElementSeen);
149: ci.setHasUseBean(usebeanSeen);
150: ci.setHasIncludeAction(includeActionSeen);
151: ci.setHasParamAction(paramActionSeen);
152: ci.setHasSetProperty(setPropertySeen);
153: ci.setHasScriptingVars(hasScriptingVars);
154:
155: // Propagate value of scriptingElementSeen up.
156: scriptingElementSeen = scriptingElementSeen
157: || scriptingElementSeenSave;
158: usebeanSeen = usebeanSeen || usebeanSeenSave;
159: setPropertySeen = setPropertySeen || setPropertySeenSave;
160: includeActionSeen = includeActionSeen
161: || includeActionSeenSave;
162: paramActionSeen = paramActionSeen || paramActionSeenSave;
163: hasScriptingVars = hasScriptingVars || hasScriptingVarsSave;
164: }
165:
166: public void visit(Node.JspElement n) throws JasperException {
167: if (n.getNameAttribute().isExpression())
168: scriptingElementSeen = true;
169:
170: Node.JspAttribute[] attrs = n.getJspAttributes();
171: for (int i = 0; i < attrs.length; i++) {
172: if (attrs[i].isExpression()) {
173: scriptingElementSeen = true;
174: break;
175: }
176: }
177: visitBody(n);
178: }
179:
180: public void visit(Node.JspBody n) throws JasperException {
181: checkSeen(n.getChildInfo(), n);
182: }
183:
184: public void visit(Node.NamedAttribute n) throws JasperException {
185: checkSeen(n.getChildInfo(), n);
186: }
187:
188: public void visit(Node.Declaration n) throws JasperException {
189: scriptingElementSeen = true;
190: }
191:
192: public void visit(Node.Expression n) throws JasperException {
193: scriptingElementSeen = true;
194: }
195:
196: public void visit(Node.Scriptlet n) throws JasperException {
197: scriptingElementSeen = true;
198: }
199:
200: public void updatePageInfo(PageInfo pageInfo) {
201: pageInfo.setMaxTagNesting(maxTagNesting);
202: pageInfo.setScriptless(!scriptingElementSeen);
203: }
204: }
205:
206: public static void collect(Compiler compiler, Node.Nodes page)
207: throws JasperException {
208:
209: CollectVisitor collectVisitor = new CollectVisitor();
210: page.visit(collectVisitor);
211: collectVisitor.updatePageInfo(compiler.getPageInfo());
212:
213: }
214: }
|