View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.struts2.jasper.compiler;
19  
20  import org.apache.struts2.jasper.JasperException;
21  
22  /***
23   * Collect info about the page and nodes, and make them availabe through
24   * the PageInfo object.
25   *
26   * @author Kin-man Chung
27   * @author Mark Roth
28   */
29  
30  class Collector {
31  
32      /***
33       * A visitor for collecting information on the page and the body of
34       * the custom tags.
35       */
36      static class CollectVisitor extends Node.Visitor {
37  
38          private boolean scriptingElementSeen = false;
39          private boolean usebeanSeen = false;
40          private boolean includeActionSeen = false;
41          private boolean paramActionSeen = false;
42          private boolean setPropertySeen = false;
43          private boolean hasScriptingVars = false;
44  
45          public void visit(Node.ParamAction n) throws JasperException {
46              if (n.getValue().isExpression()) {
47                  scriptingElementSeen = true;
48              }
49              paramActionSeen = true;
50          }
51  
52          public void visit(Node.IncludeAction n) throws JasperException {
53              if (n.getPage().isExpression()) {
54                  scriptingElementSeen = true;
55              }
56              includeActionSeen = true;
57              visitBody(n);
58          }
59  
60          public void visit(Node.ForwardAction n) throws JasperException {
61              if (n.getPage().isExpression()) {
62                  scriptingElementSeen = true;
63              }
64              visitBody(n);
65          }
66  
67          public void visit(Node.SetProperty n) throws JasperException {
68              if (n.getValue() != null && n.getValue().isExpression()) {
69                  scriptingElementSeen = true;
70              }
71              setPropertySeen = true;
72          }
73  
74          public void visit(Node.UseBean n) throws JasperException {
75              if (n.getBeanName() != null && n.getBeanName().isExpression()) {
76                  scriptingElementSeen = true;
77              }
78              usebeanSeen = true;
79              visitBody(n);
80          }
81  
82          public void visit(Node.PlugIn n) throws JasperException {
83              if (n.getHeight() != null && n.getHeight().isExpression()) {
84                  scriptingElementSeen = true;
85              }
86              if (n.getWidth() != null && n.getWidth().isExpression()) {
87                  scriptingElementSeen = true;
88              }
89              visitBody(n);
90          }
91  
92          public void visit(Node.CustomTag n) throws JasperException {
93              // Check to see what kinds of element we see as child elements
94              checkSeen(n.getChildInfo(), n);
95          }
96  
97          /***
98           * Check all child nodes for various elements and update the given
99           * ChildInfo object accordingly.  Visits body in the process.
100          */
101         private void checkSeen(Node.ChildInfo ci, Node n)
102                 throws JasperException {
103             // save values collected so far
104             boolean scriptingElementSeenSave = scriptingElementSeen;
105             scriptingElementSeen = false;
106             boolean usebeanSeenSave = usebeanSeen;
107             usebeanSeen = false;
108             boolean includeActionSeenSave = includeActionSeen;
109             includeActionSeen = false;
110             boolean paramActionSeenSave = paramActionSeen;
111             paramActionSeen = false;
112             boolean setPropertySeenSave = setPropertySeen;
113             setPropertySeen = false;
114             boolean hasScriptingVarsSave = hasScriptingVars;
115             hasScriptingVars = false;
116 
117             // Scan attribute list for expressions
118             if (n instanceof Node.CustomTag) {
119                 Node.CustomTag ct = (Node.CustomTag) n;
120                 Node.JspAttribute[] attrs = ct.getJspAttributes();
121                 for (int i = 0; attrs != null && i < attrs.length; i++) {
122                     if (attrs[i].isExpression()) {
123                         scriptingElementSeen = true;
124                         break;
125                     }
126                 }
127             }
128 
129             visitBody(n);
130 
131             if ((n instanceof Node.CustomTag) && !hasScriptingVars) {
132                 Node.CustomTag ct = (Node.CustomTag) n;
133                 hasScriptingVars = ct.getVariableInfos().length > 0 ||
134                         ct.getTagVariableInfos().length > 0;
135             }
136 
137             // Record if the tag element and its body contains any scriptlet.
138             ci.setScriptless(!scriptingElementSeen);
139             ci.setHasUseBean(usebeanSeen);
140             ci.setHasIncludeAction(includeActionSeen);
141             ci.setHasParamAction(paramActionSeen);
142             ci.setHasSetProperty(setPropertySeen);
143             ci.setHasScriptingVars(hasScriptingVars);
144 
145             // Propagate value of scriptingElementSeen up.
146             scriptingElementSeen = scriptingElementSeen || scriptingElementSeenSave;
147             usebeanSeen = usebeanSeen || usebeanSeenSave;
148             setPropertySeen = setPropertySeen || setPropertySeenSave;
149             includeActionSeen = includeActionSeen || includeActionSeenSave;
150             paramActionSeen = paramActionSeen || paramActionSeenSave;
151             hasScriptingVars = hasScriptingVars || hasScriptingVarsSave;
152         }
153 
154         public void visit(Node.JspElement n) throws JasperException {
155             if (n.getNameAttribute().isExpression())
156                 scriptingElementSeen = true;
157 
158             Node.JspAttribute[] attrs = n.getJspAttributes();
159             for (int i = 0; i < attrs.length; i++) {
160                 if (attrs[i].isExpression()) {
161                     scriptingElementSeen = true;
162                     break;
163                 }
164             }
165             visitBody(n);
166         }
167 
168         public void visit(Node.JspBody n) throws JasperException {
169             checkSeen(n.getChildInfo(), n);
170         }
171 
172         public void visit(Node.NamedAttribute n) throws JasperException {
173             checkSeen(n.getChildInfo(), n);
174         }
175 
176         public void visit(Node.Declaration n) throws JasperException {
177             scriptingElementSeen = true;
178         }
179 
180         public void visit(Node.Expression n) throws JasperException {
181             scriptingElementSeen = true;
182         }
183 
184         public void visit(Node.Scriptlet n) throws JasperException {
185             scriptingElementSeen = true;
186         }
187 
188         public void updatePageInfo(PageInfo pageInfo) {
189             pageInfo.setScriptless(!scriptingElementSeen);
190         }
191     }
192 
193 
194     public static void collect(Compiler compiler, Node.Nodes page)
195             throws JasperException {
196 
197         CollectVisitor collectVisitor = new CollectVisitor();
198         page.visit(collectVisitor);
199         collectVisitor.updatePageInfo(compiler.getPageInfo());
200 
201     }
202 }
203