001: /*
002: * The Apache Software License, Version 1.1
003: *
004: * Copyright (c) 1999 The Apache Software Foundation. All rights
005: * reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The end-user documentation included with the redistribution, if
020: * any, must include the following acknowlegement:
021: * "This product includes software developed by the
022: * Apache Software Foundation (http://www.apache.org/)."
023: * Alternately, this acknowlegement may appear in the software itself,
024: * if and wherever such third-party acknowlegements normally appear.
025: *
026: * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
027: * Foundation" must not be used to endorse or promote products derived
028: * from this software without prior written permission. For written
029: * permission, please contact apache@apache.org.
030: *
031: * 5. Products derived from this software may not be called "Apache"
032: * nor may "Apache" appear in their names without prior written
033: * permission of the Apache Group.
034: *
035: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: *
049: * This software consists of voluntary contributions made by many
050: * individuals on behalf of the Apache Software Foundation. For more
051: * information on the Apache Software Foundation, please see
052: * <http://www.apache.org/>.
053: *
054: */
055:
056: package com.sun.portal.providers.jsp.jasper3.jasper.compiler;
057:
058: import java.util.Hashtable;
059: import java.util.Vector;
060: import java.util.Enumeration;
061: import java.lang.reflect.Method;
062:
063: import com.sun.portal.providers.jsp.jasper3.jasper.JasperException;
064: import com.sun.portal.providers.jsp.jasper3.jasper.Constants;
065:
066: /**
067: * Generate code for useBean.
068: *
069: * @author Mandar Raje
070: */
071: public class BeanGenerator extends GeneratorBase implements
072: ServiceMethodPhase, ClassDeclarationPhase {
073:
074: Hashtable attrs;
075: BeanRepository beanInfo;
076: boolean genSession;
077: boolean beanRT = false;
078: Mark start;
079: //As per 2.13.1.1 in Jsp 1.1 spec
080: // (to avoid generating an unnecessary if block)
081: boolean bodyEmpty = true;
082:
083: //As per 2.13.1.1 in Jsp 1.1 spec
084: // (to avoid generating an unnecessary if block)
085: public BeanGenerator(Mark start, Hashtable attrs,
086: BeanRepository beanInfo, boolean genSession,
087: boolean bodyEmpty) {
088: this .attrs = attrs;
089: this .beanInfo = beanInfo;
090: this .genSession = genSession;
091: this .start = start;
092:
093: //As per 2.13.1.1 in Jsp 1.1 spec
094: // (to avoid generating an unnecessary if block)
095: this .bodyEmpty = bodyEmpty;
096: }
097:
098: public void generate(ServletWriter writer, Class phase)
099: throws JasperException {
100:
101: if (ClassDeclarationPhase.class.equals(phase))
102: checkSyntax(writer, phase);
103: else if (ServiceMethodPhase.class.equals(phase))
104: generateMethod(writer, phase);
105: }
106:
107: public void checkSyntax(ServletWriter writer, Class phase)
108: throws JasperException {
109: String name = getAttribute("id");
110: String varname = name;
111: String serfile = name;
112: String scope = getAttribute("scope");
113: String clsname = getAttribute("class");
114: String type = getAttribute("type");
115: String beanName = getAttribute("beanName");
116:
117: // Check for mandatory attributes:
118: if (name == null) {
119: String m = Constants
120: .getString("jsp.error.usebean.missing.attribute");
121: throw new CompileException(start, m);
122: }
123:
124: if (clsname == null && type == null) {
125: String m = Constants.getString(
126: "jsp.error.usebean.missing.type",
127: new Object[] { name });
128: throw new CompileException(start, m);
129: }
130:
131: if (beanInfo.checkVariable(name) == true) {
132: String m = Constants.getString(
133: "jsp.error.usebean.duplicate",
134: new Object[] { name });
135: throw new CompileException(start, m);
136: }
137:
138: if (scope != null && scope.equalsIgnoreCase("session")) {
139: if (genSession != true) {
140: String m = Constants.getString(
141: "jsp.error.usebean.prohibited.as.session",
142: new Object[] { name });
143: throw new CompileException(start, m);
144: }
145: }
146:
147: if (clsname != null && beanName != null) {
148: String m = Constants
149: .getString("jsp.error.usebean.not.both",
150: new Object[] { name });
151: throw new CompileException(start, m);
152: }
153:
154: if (clsname == null)
155: clsname = type;
156: if (scope == null || scope.equals("page")) {
157: beanInfo.addPageBean(name, clsname);
158: } else if (scope.equals("request")) {
159: beanInfo.addRequestBean(name, clsname);
160: } else if (scope.equals("session")) {
161: beanInfo.addSessionBean(name, clsname);
162: } else if (scope.equals("application")) {
163: beanInfo.addApplicationBean(name, clsname);
164: } else {
165: String m = Constants.getString(
166: "jsp.error.usebean.invalid.scope", new Object[] {
167: name, scope });
168: throw new CompileException(start, m);
169: }
170: }
171:
172: public void generateMethod(ServletWriter writer, Class phase)
173: throws JasperException {
174: String name = getAttribute("id");
175: String varname = name;
176: String serfile = name;
177: String scope = getAttribute("scope");
178: String clsname = getAttribute("class");
179: String type = getAttribute("type");
180: String beanName = getAttribute("beanName");
181:
182: if (type == null)
183: type = clsname;
184:
185: // See if beanName is a request-time expression.
186: if (beanName != null && JspUtil.isExpression(beanName)) {
187: beanName = JspUtil.getExpr(beanName);
188: beanRT = true;
189: }
190:
191: if (scope == null || scope.equals("page")) {
192:
193: // declare the variable.
194: declareBean(writer, type, varname);
195:
196: // synchronized inspection.
197: lock(writer, "pageContext");
198:
199: // Generate code to locate the bean.
200: locateBean(writer, type, varname, name,
201: "PageContext.PAGE_SCOPE");
202:
203: // create the bean if it doesn't exists.
204: createBean(writer, varname, clsname, beanName, name, type,
205: "PageContext.PAGE_SCOPE");
206:
207: // unlock
208: unlock(writer);
209:
210: // Initialize the bean if the body is present.
211: generateInit(writer, varname);
212:
213: } else if (scope.equals("request")) {
214:
215: // declare the variable.
216: declareBean(writer, type, varname);
217:
218: // synchronized inspection.
219: lock(writer, "request");
220:
221: // Generate code to locate the bean.
222: locateBean(writer, type, varname, name,
223: "PageContext.REQUEST_SCOPE");
224:
225: // create the bean if it doesn't exists.
226: createBean(writer, varname, clsname, beanName, name, type,
227: "PageContext.REQUEST_SCOPE");
228:
229: // unlock.
230: unlock(writer);
231:
232: // Initialize the bean if the body is present.
233: generateInit(writer, varname);
234:
235: } else if (scope.equals("session")) {
236:
237: // declare the variable.
238: declareBean(writer, type, varname);
239:
240: // synchronized inspection.
241: lock(writer, "session");
242:
243: // Generate code to locate the bean.
244: locateBean(writer, type, varname, name,
245: "PageContext.SESSION_SCOPE");
246:
247: // create the bean if it doesn't exists.
248: createBean(writer, varname, clsname, beanName, name, type,
249: "PageContext.SESSION_SCOPE");
250:
251: // unlock.
252: unlock(writer);
253:
254: // Initialize the bean.
255: generateInit(writer, varname);
256:
257: } else if (scope.equals("application")) {
258:
259: // declare the variable.
260: declareBean(writer, type, varname);
261:
262: // synchronized inspection
263: lock(writer, "application");
264:
265: // Generate code to locate the bean.
266: locateBean(writer, type, varname, name,
267: "PageContext.APPLICATION_SCOPE");
268:
269: // create the bean if it doesn't exist.
270: createBean(writer, varname, clsname, beanName, name, type,
271: "PageContext.APPLICATION_SCOPE");
272:
273: // unlock.
274: unlock(writer);
275:
276: // Initialize the bean.
277: generateInit(writer, varname);
278: }
279: }
280:
281: private void lock(ServletWriter writer, String scope) {
282:
283: writer.println(" synchronized (" + scope + ") {");
284: writer.pushIndent();
285: }
286:
287: private void unlock(ServletWriter writer) {
288:
289: writer.popIndent();
290: writer.println(" } ");
291: }
292:
293: private void generateInit(ServletWriter writer, String name) {
294: // As per section 2.13.1.1 in the Jsp 1.1 spec
295: // Initialize the bean if non-empty body
296: if (!bodyEmpty)
297: writer.println("if(_jspx_special" + name + " == true) {");
298: }
299:
300: private void declareBean(ServletWriter writer, String type,
301: String varname) {
302:
303: writer.println(type + " " + varname + " = null;");
304:
305: // Variable _jspx_special used for initialization.
306: // As per section 2.13.1.1 in the Jsp 1.1 spec
307: // we declare this variable only if jsp:useBean has a body
308: if (!bodyEmpty)
309: writer.println("boolean _jspx_special" + varname
310: + " = false;");
311:
312: }
313:
314: private void locateBean(ServletWriter writer, String type,
315: String varname, String name, String scope) {
316:
317: writer.println(varname + "= (" + type + ")");
318: writer.println("pageContext.getAttribute("
319: + writer.quoteString(name) + "," + scope + ");");
320: }
321:
322: private void createBean(ServletWriter writer, String varname,
323: String clsname, String beanName, String name, String type,
324: String scope) {
325:
326: // Create the bean only if classname is specified.
327: // Otherwise bean must be located in the scope.
328: if (clsname != null || beanName != null) {
329: writer.println("if ( " + varname + " == null ) {");
330:
331: // Code to create the bean:
332: writer.pushIndent();
333:
334: // Set the boolean var. so that bean can be initialized.
335: // As per section 2.13.1.1 in the Jsp 1.1 spec
336: // we initialize this variable only if jsp:useBean has a body
337: if (!bodyEmpty)
338: writer.println("_jspx_special" + name + " = true;");
339:
340: generateBeanCreate(writer, varname, clsname, beanName, type);
341:
342: writer.println("pageContext.setAttribute("
343: + writer.quoteString(name) + ", " + varname + ", "
344: + scope + ");");
345:
346: writer.popIndent();
347: writer.println("}");
348: } else {
349:
350: // clsname not specified -- object must be found inside the scope.
351: writer.println("if (" + varname + " == null) ");
352: writer
353: .println(" throw new java.lang.InstantiationException (\"bean "
354: + varname
355: + " not found within scope \"); ");
356: }
357: }
358:
359: protected void generateBeanCreate(ServletWriter writer,
360: String varname, String clsname, String beanName, String type) {
361:
362: String convert = (clsname == null) ? type : clsname;
363: if (beanName != null)
364: clsname = beanName;
365: writer.println("try {");
366: writer.pushIndent();
367: if (beanRT == false)
368: writer
369: .println(varname
370: + " = ("
371: + convert
372: + ") Beans.instantiate(this.getClass().getClassLoader(), "
373: + writer.quoteString(clsname) + ");");
374: else
375: writer
376: .println(varname
377: + " = ("
378: + convert
379: + ") Beans.instantiate(this.getClass().getClassLoader(), "
380: + clsname + ");");
381: writer.popIndent();
382: writer.println("} catch (Exception exc) {");
383: writer.pushIndent();
384: writer
385: .println(" throw new ServletException (\" Cannot create bean of class \""
386: + "+\"" + clsname + "\");");
387: writer.popIndent();
388: writer.println("}");
389:
390: }
391:
392: public String getAttribute(String name) {
393: return (attrs != null) ? (String) attrs.get(name) : null;
394: }
395:
396: }
|