1 /*
2 * The Apache Software License, Version 1.1
3 *
4 * Copyright (c) 1999 The Apache Software Foundation. All rights
5 * reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. The end-user documentation included with the redistribution, if
20 * any, must include the following acknowlegement:
21 * "This product includes software developed by the
22 * Apache Software Foundation (http://www.apache.org/)."
23 * Alternately, this acknowlegement may appear in the software itself,
24 * if and wherever such third-party acknowlegements normally appear.
25 *
26 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
27 * Foundation" must not be used to endorse or promote products derived
28 * from this software without prior written permission. For written
29 * permission, please contact apache@apache.org.
30 *
31 * 5. Products derived from this software may not be called "Apache"
32 * nor may "Apache" appear in their names without prior written
33 * permission of the Apache Group.
34 *
35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46 * SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This software consists of voluntary contributions made by many
50 * individuals on behalf of the Apache Software Foundation. For more
51 * information on the Apache Software Foundation, please see
52 * <http://www.apache.org/>.
53 *
54 */
55
56 package org.apache.jasper.compiler;
57
58 import java.util.Hashtable;
59 import java.util.Vector;
60 import java.util.Enumeration;
61 import java.util.StringTokenizer;
62 import java.io.IOException;
63 import java.io.FileNotFoundException;
64 import java.io.File;
65 import java.io.ObjectOutputStream;
66 import java.io.FileOutputStream;
67 import java.net.URL;
68 import java.net.MalformedURLException;
69
70 import javax.servlet.ServletContext;
71
72 import javax.servlet.jsp.tagext.TagInfo;
73 import javax.servlet.jsp.tagext.TagLibraryInfo;
74
75 import org.apache.jasper.JasperException;
76 import org.apache.jasper.Constants;
77 import org.apache.jasper.JspEngineContext;
78
79 /**
80 * JSP code generator "backend".
81 *
82 * @author Anil K. Vijendran
83 */
84 public class JspParseEventListener extends BaseJspListener {
85
86 JspEngineContext ctxt;
87
88 String jspServletBase = Constants.JSP_SERVLET_BASE;
89 String serviceMethodName = Constants.SERVICE_METHOD_NAME;
90 String servletContentType = Constants.SERVLET_CONTENT_TYPE;
91
92 String extendsClass = "";
93 Vector interfaces = new Vector();
94 Vector imports = new Vector();
95
96 String error = "";
97
98 boolean genSessionVariable = true;
99 boolean singleThreaded = false;
100 boolean autoFlush = true;
101
102 Vector generators = new Vector();
103
104 BeanRepository beanInfo;
105
106 int bufferSize = Constants.DEFAULT_BUFFER_SIZE;
107
108 // a set of boolean variables to check if there are multiple attr-val
109 // pairs for jsp directive.
110 boolean languageDir = false, extendsDir = false, sessionDir = false;
111 boolean bufferDir = false, threadsafeDir = false, errorpageDir = false;
112 boolean iserrorpageDir = false, infoDir = false, autoFlushDir = false;
113 boolean contentTypeDir = false;
114
115
116 /* support for large files */
117 int stringId = 0;
118 Vector vector = new Vector();
119 String dataFile;
120
121 TagLibraries libraries;
122
123 final void addGenerator(Generator gen) throws JasperException {
124 gen.init(ctxt);
125 generators.addElement(gen);
126 }
127
128 /*
129 * Package private since I want everyone to come in through
130 * org.apache.jasper.compiler.Main.
131 */
132 JspParseEventListener(JspEngineContext ctxt) {
133 super(ctxt.getReader(), ctxt.getWriter());
134 this.ctxt = ctxt;
135 this.beanInfo = new BeanRepository(ctxt.getClassLoader());
136 this.libraries = new TagLibraries(ctxt.getClassLoader());
137
138 // FIXME: Is this good enough? (I'm just taking the easy way out - akv)
139 if (ctxt.getOptions().largeFile())
140 dataFile = ctxt.getOutputDir() + File.separatorChar +
141 ctxt.getServletPackageName() + "_" +
142 ctxt.getServletClassName() + ".dat";
143 }
144
145 public void beginPageProcessing() throws JasperException {
146 for(int i = 0; i < Constants.STANDARD_IMPORTS.length; i++)
147 imports.addElement(Constants.STANDARD_IMPORTS[i]);
148 }
149
150 public void endPageProcessing() throws JasperException {
151 generateHeader();
152 writer.println();
153 generateAll(ServiceMethodPhase.class);
154 writer.println();
155 generateFooter();
156 if (ctxt.getOptions().largeFile())
157 try {
158 ObjectOutputStream o
159 = new ObjectOutputStream(new FileOutputStream(dataFile));
160
161 /*
162 * Serialize an array of char[]'s instead of an
163 * array of String's because there is a limitation
164 * on the size of Strings that can be serialized.
165 */
166
167 char[][] tempCharArray = new char[vector.size()][];
168 vector.copyInto(tempCharArray);
169 o.writeObject(tempCharArray);
170 o.close();
171 writer.close();
172 } catch (IOException ex) {
173 throw new JasperException(Constants.getString(
174 "jsp.error.data.file.write"), ex);
175 }
176 ctxt.setContentType(servletContentType);
177 }
178
179 private void generateAll(Class phase) throws JasperException {
180
181 for(int i = 0; i < generators.size(); i++) {
182 Generator gen = (Generator) generators.elementAt(i);
183 if (phase.isInstance(gen)) {
184 gen.generate(writer, phase);
185 }
186 }
187
188 }
189
190 private void generateHeader() throws JasperException {
191 String servletPackageName = ctxt.getServletPackageName();
192 String servletClassName = ctxt.getServletClassName();
193 // First the package name:
194 if (! "".equals(servletPackageName) && servletPackageName != null) {
195 writer.println("package "+servletPackageName+";");
196 writer.println();
197 }
198
199 Enumeration e = imports.elements();
200 while (e.hasMoreElements())
201 writer.println("import "+(String) e.nextElement()+";");
202
203 writer.println();
204 generateAll(FileDeclarationPhase.class);
205 writer.println();
206
207 writer.print("public class "+servletClassName+ " extends ");
208 writer.print(extendsClass.equals("") ? jspServletBase : extendsClass);
209
210 if (singleThreaded)
211 interfaces.addElement("SingleThreadModel");
212
213 if (interfaces.size() != 0) {
214 writer.println();
215 writer.println(" implements ");
216
217 for(int i = 0; i < interfaces.size() - 1; i++)
218 writer.println(" "+interfaces.elementAt(i)+",");
219 writer.println(" "+interfaces.elementAt(interfaces.size()-1));
220 }
221
222 writer.println(" {");
223
224 writer.pushIndent();
225 writer.println();
226 generateAll(ClassDeclarationPhase.class);
227 writer.println();
228
229 writer.println("static {");
230 writer.pushIndent();
231 generateAll(StaticInitializerPhase.class);
232 writer.popIndent();
233 writer.println("}");
234
235 writer.println("public "+servletClassName+"( ) {");
236 writer.println("}");
237 writer.println();
238
239 writer.println("private static boolean _jspx_inited = false;");
240 writer.println();
241
242 writer.println("public final void _jspx_init() throws JasperException {");
243 writer.pushIndent();
244 generateAll(InitMethodPhase.class);
245 writer.popIndent();
246 writer.println("}");
247 writer.println();
248
249
250 writer.println("public void "+serviceMethodName+"("+
251 "HttpServletRequest request, "+
252 "HttpServletResponse response)");
253
254 writer.println(" throws IOException, ServletException {");
255 writer.pushIndent();
256 writer.println();
257 writer.println("JspFactory _jspxFactory = null;");
258 writer.println("PageContext pageContext = null;");
259
260 if (genSessionVariable)
261 writer.println("HttpSession session = null;");
262
263 if (ctxt.isErrorPage())
264 writer.println("Throwable exception = (Throwable) request.getAttribute(\"javax.servlet.jsp.jspException\");");
265
266
267 writer.println("ServletContext application = null;");
268 writer.println("ServletConfig config = null;");
269 writer.println("JspWriter out = null;");
270 writer.println("Object page = this;");
271 writer.println("String _value = null;");
272 writer.println("try {");
273 writer.pushIndent();
274
275 writer.println();
276 writer.println("if (_jspx_inited == false) {");
277 writer.pushIndent();
278 writer.println("_jspx_init();");
279 writer.println("_jspx_inited = true;");
280 writer.popIndent();
281 writer.println("}");
282
283 writer.println("_jspxFactory = JspFactory.getDefaultFactory();");
284 writer.println("response.setContentType("
285 + writer.quoteString(servletContentType)
286 + ");");
287 writer.println("pageContext = _jspxFactory.getPageContext(this, request, response,\n"
288 + "\t\t\t"
289 + writer.quoteString(error) + ", "
290 + genSessionVariable + ", "
291 + bufferSize + ", "
292 + autoFlush
293 + ");");
294 writer.println();
295
296 writer.println("application = pageContext.getServletContext();");
297 writer.println("config = pageContext.getServletConfig();");
298
299 if (genSessionVariable)
300 writer.println("session = pageContext.getSession();");
301
302 writer.println("out = pageContext.getOut();");
303 }
304
305 private void generateFooter() throws JasperException {
306 writer.popIndent();
307 //writer.println("} catch (Throwable t) {");
308 writer.println("} catch (Exception ex) {");
309 writer.pushIndent();
310 writer.println("if (out.getBufferSize() != 0)");
311 writer.pushIndent(); writer.println("out.clear();"); writer.popIndent();
312 writer.println("pageContext.handlePageException(ex);");
313 writer.popIndent();
314 writer.println("} finally {");
315 writer.pushIndent();
316 /* Do stuff here for finally actions... */
317 //writer.println("out.close();");
318 writer.println("out.flush();");
319 writer.println("_jspxFactory.releasePageContext(pageContext);");
320 writer.popIndent();
321 writer.println("}");
322 // Close the service method:
323 writer.popIndent();
324 writer.println("}");
325
326 // Close the class definition:
327 writer.popIndent();
328 writer.println("}");
329 }
330
331
332 public void handleComment(Mark start, Mark stop) throws JasperException {
333 Constants.message("jsp.message.htmlcomment",
334 new Object[] { reader.getChars(start, stop) },
335 Constants.HIGH_VERBOSITY);
336 }
337
338 interface PageDirectiveHandler {
339 void handlePageDirectiveAttribute(JspParseEventListener listener,
340 String value,
341 Mark start, Mark stop)
342 throws JasperException;
343 }
344
345 static final class PageDirectiveHandlerInfo {
346 String attribute;
347 PageDirectiveHandler handler;
348 PageDirectiveHandlerInfo(String attribute, PageDirectiveHandler handler) {
349 this.attribute = attribute;
350 this.handler = handler;
351 }
352 }
353
354 static final String languageStr = "language";
355 static final String extendsStr = "extends";
356 static final String importStr = "import";
357 static final String sessionStr = "session";
358 static final String bufferStr = "buffer";
359 static final String autoFlushStr = "autoFlush";
360 static final String isThreadSafeStr = "isThreadSafe";
361 static final String infoStr = "info";
362 static final String errorPageStr = "errorPage";
363 static final String isErrorPageStr = "isErrorPage";
364 static final String contentTypeStr = "contentType";
365
366
367 PageDirectiveHandlerInfo[] pdhis = new PageDirectiveHandlerInfo[] {
368 new PageDirectiveHandlerInfo(languageStr, new LanguageHandler()),
369 new PageDirectiveHandlerInfo(extendsStr, new ExtendsHandler()),
370 new PageDirectiveHandlerInfo(importStr, new ImportsHandler()),
371 new PageDirectiveHandlerInfo(sessionStr, new SessionHandler()),
372 new PageDirectiveHandlerInfo(bufferStr, new BufferHandler()),
373 new PageDirectiveHandlerInfo(autoFlushStr, new AutoFlushHandler()),
374 new PageDirectiveHandlerInfo(isThreadSafeStr, new IsThreadSafeHandler()),
375 new PageDirectiveHandlerInfo(infoStr, new InfoHandler()),
376 new PageDirectiveHandlerInfo(isErrorPageStr, new IsErrorPageHandler()),
377 new PageDirectiveHandlerInfo(contentTypeStr, new ContentTypeHandler()),
378 new PageDirectiveHandlerInfo(errorPageStr, new ErrorPageHandler())
379 };
380
381 // FIXME: Need to further refine these abstractions by moving the code
382 // to handle duplicate directive instance checks to outside.
383
384 static final class ContentTypeHandler implements PageDirectiveHandler {
385 public void handlePageDirectiveAttribute(JspParseEventListener listener,
386 String contentType,
387 Mark start, Mark stop)
388 throws JasperException
389 {
390 if (listener.contentTypeDir == true)
391 throw new JasperException(Constants.getString("jsp.error.page.multiple.contenttypes"));
392 listener.contentTypeDir = true;
393 if (contentType == null)
394 throw new JasperException(Constants.getString("jsp.error.page.invalid.contenttype"));
395 listener.servletContentType = contentType;
396 }
397 }
398
399 static final class SessionHandler implements PageDirectiveHandler {
400 public void handlePageDirectiveAttribute(JspParseEventListener listener,
401 String session,
402 Mark start, Mark stop)
403 throws JasperException
404 {
405 if (listener.sessionDir == true)
406 throw new JasperException (Constants.getString("jsp.error.page.multiple.session"));
407 listener.sessionDir = true;
408 if (session == null)
409 throw new JasperException (Constants.getString("jsp.error.page.invalid.session"));
410 if (session.equalsIgnoreCase("true"))
411 listener.genSessionVariable = true;
412 else if (session.equalsIgnoreCase("false"))
413 listener.genSessionVariable = false;
414 else
415 throw new JasperException("Invalid value for session");
416 }
417 }
418
419 static final class BufferHandler implements PageDirectiveHandler {
420 public void handlePageDirectiveAttribute(JspParseEventListener listener,
421 String buffer,
422 Mark start, Mark stop)
423 throws JasperException
424 {
425 if (listener.bufferDir == true)
426 throw new JasperException(Constants.getString("jsp.error.page.multiple.buffer"));
427 listener.bufferDir = true;
428 if (buffer != null) {
429 if (buffer.equalsIgnoreCase("none"))
430 listener.bufferSize = 0;
431 else {
432 Integer i = null;
433 try {
434 int ind = buffer.indexOf("k");
435 String num;
436 if (ind == -1)
437 num = buffer;
438 else
439 num = buffer.substring(0, ind);
440 i = new Integer(num);
441 } catch (NumberFormatException n) {
442 throw new JasperException(Constants.getString(
443 "jsp.error.page.invalid.buffer"), n);
444 }
445 listener.bufferSize = i.intValue()*1024;
446 }
447 }
448 else
449 throw new JasperException(Constants.getString("jsp.error.page.invalid.buffer"));
450 }
451 }
452
453 static final class AutoFlushHandler implements PageDirectiveHandler {
454 public void handlePageDirectiveAttribute(JspParseEventListener listener,
455 String autoflush,
456 Mark start, Mark stop)
457 throws JasperException
458 {
459 if (listener.autoFlushDir == true)
460 throw new JasperException(Constants.getString("jsp.error.page.multiple.autoflush"));
461
462 listener.autoFlushDir = true;
463 if (autoflush == null)
464 throw new JasperException(Constants.getString("jsp.error.page.invalid.autoflush"));
465
466 if (autoflush.equalsIgnoreCase("true"))
467 listener.autoFlush = true;
468 else if (autoflush.equalsIgnoreCase("false"))
469 listener.autoFlush = false;
470 else
471 throw new JasperException(Constants.getString("jsp.error.page.invalid.autoflush"));
472 }
473 }
474
475 static final class IsThreadSafeHandler implements PageDirectiveHandler {
476 public void handlePageDirectiveAttribute(JspParseEventListener listener,
477 String threadsafe,
478 Mark start, Mark stop)
479 throws JasperException
480 {
481 if (listener.threadsafeDir == true)
482 throw new JasperException(Constants.getString("jsp.error.page.multiple.threadsafe"));
483
484 listener.threadsafeDir = true;
485 if (threadsafe == null)
486 throw new JasperException (Constants.getString("jsp.error.page.invalid.threadsafe"));
487
488 if (threadsafe.equalsIgnoreCase("true"))
489 listener.singleThreaded = false;
490 else if (threadsafe.equalsIgnoreCase("false"))
491 listener.singleThreaded = true;
492 else
493 throw new JasperException (Constants.getString("jsp.error.page.invalid.threadsafe"));
494 }
495 }
496
497 static final class InfoHandler implements PageDirectiveHandler {
498 public void handlePageDirectiveAttribute(JspParseEventListener listener,
499 String info,
500 Mark start, Mark stop)
501 throws JasperException
502 {
503 if (listener.infoDir == true)
504 throw new JasperException (Constants.getString("jsp.error.page.multiple.info"));
505
506 listener.infoDir = true;
507 if (info == null)
508 throw new JasperException(Constants.getString("jsp.error.page.invalid.info"));
509
510 GeneratorWrapper gen = listener. new GeneratorWrapper(new InfoGenerator(info),
511 start, stop);
512 listener.addGenerator(gen);
513 }
514 }
515
516 static final class IsErrorPageHandler implements PageDirectiveHandler {
517 public void handlePageDirectiveAttribute(JspParseEventListener listener,
518 String iserrorpage,
519 Mark start, Mark stop)
520 throws JasperException
521 {
522 if (listener.iserrorpageDir == true)
523 throw new JasperException (Constants.getString("jsp.error.page.multiple.iserrorpage"));
524
525 listener.iserrorpageDir = true;
526 if (iserrorpage == null)
527 throw new JasperException(Constants.getString("jsp.error.page.invalid.iserrorpage"));
528
529 if (iserrorpage.equalsIgnoreCase("true"))
530 listener.ctxt.setErrorPage(true);
531 else if (iserrorpage.equalsIgnoreCase("false"))
532 listener.ctxt.setErrorPage(false);
533 else
534 throw new JasperException(Constants.getString("jsp.error.page.invalid.iserrorpage"));
535 }
536 }
537
538 static final class ErrorPageHandler implements PageDirectiveHandler {
539 public void handlePageDirectiveAttribute(JspParseEventListener listener,
540 String errorpage,
541 Mark start, Mark stop)
542 throws JasperException
543 {
544 if (listener.errorpageDir == true)
545 throw new JasperException(Constants.getString("jsp.error.page.multiple.errorpage"));
546
547 listener.errorpageDir = true;
548 if (errorpage != null)
549 listener.error = errorpage;
550 }
551 }
552
553 static final class LanguageHandler implements PageDirectiveHandler {
554 public void handlePageDirectiveAttribute(JspParseEventListener listener,
555 String language,
556 Mark start, Mark stop)
557 throws JasperException
558 {
559 if (listener.languageDir == true)
560 throw new JasperException(Constants.getString("jsp.error.page.multiple.language"));
561
562 listener.languageDir = true;
563 if (language != null)
564 if (!language.equalsIgnoreCase("java"))
565 throw new JasperException(Constants.getString("jsp.error.page.nomapping.language")+language);
566 }
567 }
568
569 static final class ImportsHandler implements PageDirectiveHandler {
570 public void handlePageDirectiveAttribute(JspParseEventListener listener,
571 String importPkgs,
572 Mark start, Mark stop)
573 throws JasperException
574 {
575 if (importPkgs != null) {
576 StringTokenizer tokenizer = new StringTokenizer(importPkgs, ",");
577 while (tokenizer.hasMoreTokens())
578 listener.imports.addElement(tokenizer.nextToken());
579 }
580 }
581 }
582
583 static final class ExtendsHandler implements PageDirectiveHandler {
584 public void handlePageDirectiveAttribute(JspParseEventListener listener,
585 String extendsClzz,
586 Mark start, Mark stop)
587 throws JasperException
588 {
589 if (listener.extendsDir == true)
590 throw new JasperException(Constants.getString("jsp.error.page.multiple.extends"));
591
592 listener.extendsDir = true;
593 if (extendsClzz != null) {
594 listener.extendsClass = extendsClzz;
595
596 /*
597 * If page superclass is top level class (i.e. not in a pkg)
598 * explicitly import it. If this is not done, the compiler
599 * will assume the extended class is in the same pkg as
600 * the generated servlet.
601 */
602 if (extendsClzz.indexOf(".") == -1) {
603 listener.imports.addElement(extendsClzz);
604 }
605 }
606 }
607 }
608
609 public void handleDirective(String directive, Mark start,
610 Mark stop, Hashtable attrs)
611 throws JasperException
612 {
613 Constants.message("jsp.message.handling_directive",
614 new Object[] { directive, attrs },
615 Constants.HIGH_VERBOSITY);
616
617 if (directive.equals("page")) {
618 Enumeration e = attrs.keys();
619 String attr;
620 while (e.hasMoreElements()) {
621 attr = (String) e.nextElement();
622 for(int i = 0; i < pdhis.length; i++) {
623 PageDirectiveHandlerInfo pdhi = pdhis[i];
624 if (attr.equals(pdhi.attribute)) {
625 String value = (String) attrs.get(pdhi.attribute);
626 pdhi.handler.handlePageDirectiveAttribute(this, value,
627 start, stop);
628 }
629 }
630 }
631 }
632
633 // Do some validations...
634 if (bufferSize == 0 && autoFlush == false)
635 throw new JasperException(Constants.getString(
636 "jsp.error.page.bad_b_and_a_combo"));
637
638 if (directive.equals("taglib")) {
639 String uri = (String) attrs.get("uri");
640 String prefix = (String) attrs.get("prefix");
641 try {
642 TagLibraryInfoImpl tl = new TagLibraryInfoImpl(ctxt,
643 prefix,
644 uri);
645 libraries.addTagLibrary(prefix, tl);
646 } catch (Exception ex) {
647 ex.printStackTrace();
648 Object[] args = new Object[] { uri, ex.getMessage() };
649 throw new JasperException(Constants.getString("jsp.error.badtaglib",
650 args));
651 }
652 }
653
654 if (directive.equals("include")) {
655 String file = (String) attrs.get("file");
656 String encoding = (String) attrs.get("encoding");
657
658 if (file == null)
659 throw new JasperException(Constants.getString("jsp.error.include.missing.file"));
660
661 // jsp.error.include.bad.file needs taking care of here??
662 try {
663 reader.pushFile(file, encoding);
664 } catch (FileNotFoundException fnfe) {
665 throw new JasperException(Constants.getString("jsp.error.include.bad.file"));
666 }
667 }
668 }
669
670
671 class GeneratorWrapper
672 implements Generator, ClassDeclarationPhase,
673 FileDeclarationPhase, ServiceMethodPhase,
674 InitMethodPhase, StaticInitializerPhase
675 {
676 Generator generator;
677 Mark start, stop;
678
679 GeneratorWrapper(Generator generator, Mark start, Mark stop) {
680 this.generator = generator;
681 this.start = start;
682 this.stop = stop;
683 }
684
685 /*
686 * This is really a no-op.
687 */
688 public boolean generateCoordinates(Class phase) {
689 return generator.generateCoordinates(phase);
690 }
691
692 public void init(JspEngineContext ctxt)
693 throws JasperException
694 {
695 generator.init(ctxt);
696 }
697
698 public void generate(ServletWriter out, Class phase)
699 throws JasperException
700 {
701 if (phase.isInstance(generator)) {
702 boolean genCoords = generator.generateCoordinates(phase);
703 if (genCoords) {
704 if (start != null && stop != null) {
705 if (start.fileid == stop.fileid) {
706 String fileName = out.quoteString(
707 start.getFile ());
708 out.println("// begin [file="+fileName+";from="+
709 start.toShortString()+";to="+stop.toShortString()+"]");
710 }
711 else
712 out.println("// begin [from="+start+";to="+stop+"]");
713 } else
714 out.println("// begin");
715 out.pushIndent();
716 }
717 generator.generate(out, phase);
718 if (genCoords) {
719 out.popIndent();
720 out.println("// end");
721 }
722 }
723 }
724 }
725
726 public void handleDeclaration(Mark start, Mark stop)
727 throws JasperException
728 {
729 Generator gen
730 = new GeneratorWrapper(new DeclarationGenerator(reader.getChars(
731 start, stop)), start, stop);
732 addGenerator(gen);
733 }
734
735 public void handleScriptlet(Mark start, Mark stop)
736 throws JasperException
737 {
738 Generator gen
739 = new GeneratorWrapper(new ScriptletGenerator(reader.getChars(
740 start, stop)), start, stop);
741 addGenerator(gen);
742 }
743
744 public void handleExpression(Mark start, Mark stop)
745 throws JasperException
746 {
747 Generator gen
748 = new GeneratorWrapper(new ExpressionGenerator(reader.getChars(
749 start, stop)), start, stop);
750 addGenerator(gen);
751 }
752
753 public void handleBean(Mark start, Mark stop, Hashtable attrs)
754 throws JasperException
755 {
756 Generator gen
757 = new GeneratorWrapper(new BeanGenerator(start, attrs, beanInfo,
758 genSessionVariable),
759 start, stop);
760
761 addGenerator(gen);
762 }
763
764 public void handleBeanEnd(Mark start, Mark stop, Hashtable attrs)
765 throws JasperException
766 {
767 Generator gen
768 = new GeneratorWrapper(new BeanEndGenerator(),
769 start, stop);
770 // End the block started by useBean body.
771 addGenerator(gen);
772 }
773
774 public void handleGetProperty(Mark start, Mark stop, Hashtable attrs)
775 throws JasperException
776 {
777 Generator gen
778 = new GeneratorWrapper(new GetPropertyGenerator(start, stop, attrs,
779 beanInfo), start, stop);
780
781 addGenerator(gen);
782 }
783
784 public void handleSetProperty(Mark start, Mark stop, Hashtable attrs)
785 throws JasperException
786 {
787 Generator gen
788 = new GeneratorWrapper(new SetPropertyGenerator(start, stop, attrs,
789 beanInfo), start, stop);
790
791 addGenerator(gen);
792 }
793
794 public void handlePlugin(Mark start, Mark stop, Hashtable attrs,
795 Hashtable param, String fallback)
796 throws JasperException
797 {
798 Constants.message("jsp.message.handling_plugin",
799 new Object[] { attrs },
800 Constants.HIGH_VERBOSITY);
801
802 Generator gen = new GeneratorWrapper (new PluginGenerator (attrs,
803 param, fallback), start, stop);
804 addGenerator (gen);
805 }
806
807 public void handleForward(Mark start, Mark stop, Hashtable attrs, Hashtable param)
808 throws JasperException
809 {
810 Generator gen
811 = new GeneratorWrapper(new ForwardGenerator(attrs, param),
812 start, stop);
813
814 addGenerator(gen);
815 }
816
817 public void handleInclude(Mark start, Mark stop, Hashtable attrs, Hashtable param)
818 throws JasperException
819 {
820 Generator gen
821 = new GeneratorWrapper(new IncludeGenerator(attrs, param),
822 start, stop);
823
824 addGenerator(gen);
825 }
826
827
828 public void handleCharData(char[] chars) throws JasperException {
829 GeneratorBase cdg;
830 if (ctxt.getOptions().largeFile())
831 cdg = new StoredCharDataGenerator(vector, dataFile, stringId++, chars);
832 else
833 cdg = new CharDataGenerator(chars);
834
835 // FIXME: change null
836 Generator gen
837 = new GeneratorWrapper(cdg,
838 null, null);
839
840 addGenerator(gen);
841 }
842
843 public void handleTagBegin(Mark start, Hashtable attrs, String prefix,
844 String shortTagName, TagLibraryInfoImpl tli,
845 TagInfo ti)
846 throws JasperException
847 {
848 // FIXME: null's
849 Generator gen
850 = new GeneratorWrapper(new TagBeginGenerator(prefix, shortTagName, attrs,
851 tli, ti),
852 null, null);
853
854 addGenerator(gen);
855
856 }
857
858 public void handleTagEnd(Mark start, Mark stop, String prefix,
859 String shortTagName, Hashtable attrs,
860 TagLibraryInfoImpl tli, TagInfo ti)
861 throws JasperException
862 {
863 // FIXME: null's
864 Generator gen
865 = new GeneratorWrapper(new TagEndGenerator(prefix, shortTagName, attrs, tli, ti),
866 null, null);
867
868 addGenerator(gen);
869 }
870
871 public TagLibraries getTagLibraries() {
872 return libraries;
873 }
874 }