KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > jsp > java > JavaJspGenerator


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.jsp.java;
31
32 import com.caucho.config.types.Signature;
33 import com.caucho.java.CompileClassNotFound;
34 import com.caucho.java.LineMap;
35 import com.caucho.java.LineMapWriter;
36 import com.caucho.jsp.*;
37 import com.caucho.jsp.cfg.TldFunction;
38 import com.caucho.jsp.el.JspELParser;
39 import com.caucho.loader.DynamicClassLoader;
40 import com.caucho.log.Log;
41 import com.caucho.make.ClassDependency;
42 import com.caucho.server.util.CauchoSystem;
43 import com.caucho.util.IntMap;
44 import com.caucho.util.L10N;
45 import com.caucho.vfs.*;
46 import com.caucho.xml.QName;
47 import com.caucho.xpath.NamespaceContext;
48 import com.caucho.xpath.XPath;
49 import com.caucho.xpath.XPathParseException;
50
51 import javax.el.ELContext;
52 import javax.servlet.jsp.el.ELException JavaDoc;
53 import javax.servlet.jsp.tagext.PageData JavaDoc;
54 import javax.servlet.jsp.tagext.Tag JavaDoc;
55 import javax.servlet.jsp.tagext.TagInfo JavaDoc;
56 import javax.servlet.jsp.tagext.TagLibraryValidator JavaDoc;
57 import javax.servlet.jsp.tagext.ValidationMessage JavaDoc;
58 import java.io.IOException JavaDoc;
59 import java.lang.reflect.Array JavaDoc;
60 import java.lang.reflect.Method JavaDoc;
61 import java.math.BigDecimal JavaDoc;
62 import java.math.BigInteger JavaDoc;
63 import java.util.ArrayList JavaDoc;
64 import java.util.HashMap JavaDoc;
65 import java.util.HashSet JavaDoc;
66 import java.util.Iterator JavaDoc;
67 import java.util.logging.Level JavaDoc;
68 import java.util.logging.Logger JavaDoc;
69
70 /**
71  * Generates JSP code. JavaGenerator, JavaScriptGenerator, and
72  * StaticGenerator specialize the JspGenerator for language-specific
73  * requirements.
74  *
75  * <p>JspParser parses the JSP file into an XML-DOM tree. JspGenerator
76  * generates code from that tree.
77  */

78 public class JavaJspGenerator extends JspGenerator {
79   static final L10N L = new L10N(JavaJspGenerator.class);
80   static final Logger JavaDoc log = Log.open(JavaJspGenerator.class);
81   
82   static final String JavaDoc IE_CLSID = "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93";
83   static final String JavaDoc IE_URL = "http://java.sun.com/products/plugin/1.2.2/jinstall-1_2_2-win.cab#Version=1,2,2,0";
84   static final String JavaDoc NS_URL = "http://java.sun.com/products/plugin/";
85
86   static HashMap JavaDoc<String JavaDoc,Class JavaDoc> _primitiveClasses;
87   static HashMap JavaDoc<String JavaDoc,String JavaDoc> _primitives;
88
89   protected JspNode _rootNode;
90
91   protected ParseState _parseState;
92
93   /*
94    * Variables storing the JSP directives.
95    */

96   protected boolean _ideHack = false;
97
98   /*
99    * Variables controlling caching
100    * isUncacheable overrides isCacheable.
101    */

102   protected boolean _isCacheable;
103   protected boolean _isUncacheable;
104   protected ArrayList JavaDoc<Depend> _cacheDepends = new ArrayList JavaDoc<Depend>();
105   
106   // dependencies for the source file itself
107
protected ArrayList JavaDoc<PersistentDependency> _depends =
108   new ArrayList JavaDoc<PersistentDependency>();
109
110   long _lastModified; // XXX: obsolete?
111

112   protected TagInstance _topTag;
113   protected int _tagId;
114
115   // XXX: needed in combination with XTP
116
boolean _alwaysModified;
117   
118   protected ParseTagManager _tagManager;
119
120   protected JspPageConfig _config = new JspPageConfig();
121
122   protected String JavaDoc _fullClassName;
123   protected String JavaDoc _className;
124   private HashMap JavaDoc<String JavaDoc,Class JavaDoc> _classes;
125   private ClassLoader JavaDoc _parentLoader;
126
127   private HashSet JavaDoc<String JavaDoc> _declaredVariables = new HashSet JavaDoc<String JavaDoc>();
128
129   private String JavaDoc _filename;
130
131   private final JspGenELContext _elContext;
132
133   private HashMap JavaDoc<String JavaDoc,Method JavaDoc> _elFunctionMap = new HashMap JavaDoc<String JavaDoc,Method JavaDoc>();
134   private ArrayList JavaDoc<Taglib> _tagLibraryList
135     = new ArrayList JavaDoc<Taglib>();
136   
137   private PageData JavaDoc _pageData;
138   
139   protected IntMap _strings = new IntMap();
140   
141   private ArrayList JavaDoc<com.caucho.el.Expr> _exprList
142     = new ArrayList JavaDoc<com.caucho.el.Expr>();
143   
144   private ArrayList JavaDoc<ValueExpr> _valueExprList
145     = new ArrayList JavaDoc<ValueExpr>();
146   
147   private ArrayList JavaDoc<MethodExpr> _methodExprList
148     = new ArrayList JavaDoc<MethodExpr>();
149   
150   private ArrayList JavaDoc<com.caucho.xpath.Expr> _xpathExprList
151     = new ArrayList JavaDoc<com.caucho.xpath.Expr>();
152   
153   private ArrayList JavaDoc<JspFragmentNode> _fragmentList
154     = new ArrayList JavaDoc<JspFragmentNode>();
155
156   private String JavaDoc _workPath;
157   private String JavaDoc _sourceName;
158   protected String JavaDoc _pkg;
159   private int _uniqueId = 0;
160   private int _jspId = 1;
161
162   private boolean _hasReleaseTag;
163   private boolean _hasBundle = false;
164   private boolean _hasBundlePrefix = false;
165   private boolean _requireSource = false;
166   
167   private boolean _isOmitXmlDeclaration = false;
168   
169   private String JavaDoc _doctypeSystem;
170   private String JavaDoc _doctypePublic;
171   private String JavaDoc _doctypeRootElement;
172
173   private boolean _isStatic = false;
174
175   protected ArrayList JavaDoc<JspDeclaration> _declarations =
176   new ArrayList JavaDoc<JspDeclaration>();
177
178   public JavaJspGenerator(ParseTagManager tagManager)
179   {
180     _elContext = new JspGenELContext(this);
181     
182     _tagManager = tagManager;
183     
184     _topTag = new TagInstance(tagManager);
185   }
186
187   public TagInstance getRootTag()
188   {
189     return _topTag;
190   }
191   
192   protected void setParseState(ParseState parseState)
193   {
194     _parseState = parseState;
195   }
196   
197   public ParseState getParseState()
198   {
199     return _parseState;
200   }
201
202   public void setPageConfig(JspPageConfig pageConfig)
203   {
204     _config = pageConfig;
205   }
206
207   void setStaticEncoding(boolean staticEncoding)
208   {
209     _config.setStaticEncoding(staticEncoding);
210   }
211
212   void setRequireSource(boolean requireSource)
213   {
214     _requireSource = requireSource;
215   }
216
217   void setIdeHack(boolean ideHack)
218   {
219     _ideHack = ideHack;
220   }
221
222   String JavaDoc getPackagePrefix()
223   {
224     return "";
225   }
226
227   Path getAppDir()
228   {
229     return _jspCompiler.getAppDir();
230   }
231
232   /**
233    * Returns true for XML.
234    */

235   boolean isXml()
236   {
237     // jsp/0362
238
return _parseState.isXml();
239   }
240
241   /**
242    * Returns true if the XML declaration should be set.
243    */

244   boolean isOmitXmlDeclaration()
245   {
246     return _isOmitXmlDeclaration;
247   }
248
249   /**
250    * Returns true if the XML declaration should be set.
251    */

252   void setOmitXmlDeclaration(boolean omitXml)
253   {
254     _isOmitXmlDeclaration = omitXml;
255   }
256
257   /**
258    * Sets the dtd system name
259    */

260   void setDoctypeSystem(String JavaDoc doctypeSystem)
261   {
262     _doctypeSystem = doctypeSystem;
263   }
264
265   /**
266    * Gets the dtd system name
267    */

268   String JavaDoc getDoctypeSystem()
269   {
270     return _doctypeSystem;
271   }
272
273   /**
274    * Sets the dtd public name
275    */

276   void setDoctypePublic(String JavaDoc doctypePublic)
277   {
278     _doctypePublic = doctypePublic;
279   }
280
281   /**
282    * Gets the dtd public name
283    */

284   String JavaDoc getDoctypePublic()
285   {
286     return _doctypePublic;
287   }
288
289   /**
290    * Gets the dtd root element name
291    */

292   void setDoctypeRootElement(String JavaDoc doctypeRootElement)
293   {
294     _doctypeRootElement = doctypeRootElement;
295   }
296
297   /**
298    * Gets the dtd root element name
299    */

300   String JavaDoc getDoctypeRootElement()
301   {
302     return _doctypeRootElement;
303   }
304
305   /**
306    * Returns the character encoding.
307    */

308   String JavaDoc getCharacterEncoding()
309   {
310     return _parseState.getCharEncoding();
311   }
312
313   Path getClassDir()
314   {
315     return _jspCompiler.getClassDir();
316   }
317
318   /**
319    * Sets the root JSP node.
320    */

321   public void setRootNode(JspNode node)
322   {
323     _rootNode = node;
324   }
325
326   public JspPageConfig getConfig()
327   {
328     return _config;
329   }
330
331   public boolean isTag()
332   {
333     return false;
334   }
335
336   public void init()
337   {
338     _isOmitXmlDeclaration = ! isXml();
339   }
340
341   public boolean hasScripting()
342   {
343     return _rootNode.hasScripting();
344   }
345
346   /**
347    * Adds a taglib.
348    */

349   public void addTaglib(String JavaDoc prefix, String JavaDoc uri)
350     throws JspParseException
351   {
352     addTaglib(prefix, uri, false);
353   }
354
355   /**
356    * Adds a taglib.
357    */

358   public void addOptionalTaglib(String JavaDoc prefix, String JavaDoc uri)
359     throws JspParseException
360   {
361     addTaglib(prefix, uri, true);
362   }
363   
364   /**
365    * Adds a taglib.
366    */

367   public Taglib addTaglib(String JavaDoc prefix, String JavaDoc uri, boolean isOptional)
368     throws JspParseException
369   {
370     if (log.isLoggable(Level.FINEST))
371       log.finest("taglib prefix=" + prefix + " uri:" + uri);
372
373     Taglib taglib;
374
375     try {
376       taglib = _tagManager.addTaglib(prefix, uri);
377     } catch (JspParseException e) {
378       if (isOptional) {
379     log.log(Level.FINE, e.toString(), e);
380     return null;
381       }
382
383       throw e;
384     }
385
386     if (taglib == null && isOptional &&
387     ! uri.startsWith("urn:jsptld:") && ! uri.startsWith("urn:jsptagdir:"))
388       return null;
389
390     if (taglib == null)
391       throw error(L.l("`{0}' has no matching taglib-uri. The taglib uri must match a taglib-uri for a taglib specified in the web.xml or implicitly in a taglib.tld in the tag jar.", uri));
392
393     taglib = addLibrary(taglib);
394     ArrayList JavaDoc<TldFunction> functions = taglib.getFunctionList();
395
396     for (int i = 0; i < functions.size(); i++) {
397       TldFunction function = functions.get(i);
398
399       String JavaDoc name = taglib.getPrefixString() + ":" + function.getName();
400
401       _elFunctionMap.put(name, function.getMethod());
402     }
403
404     return taglib;
405   }
406
407   private Taglib addLibrary(Taglib taglib)
408     throws JspParseException
409   {
410     for (int i = 0; i < _tagLibraryList.size(); i++) {
411       Taglib oldTaglib = _tagLibraryList.get(i);
412
413       if (oldTaglib.getURI().equals(taglib.getURI()))
414     return oldTaglib;
415     }
416
417     /*
418     // taglib = taglib.copy();
419     
420     for (int i = 0; i < _tagLibraryList.size(); i++) {
421       Taglib oldTaglib = _tagLibraryList.get(i);
422
423       oldTaglib.addTaglib(taglib);
424       taglib.addTaglib(oldTaglib);
425     }
426     */

427
428     _tagLibraryList.add(taglib);
429
430     return taglib;
431   }
432              
433
434   Method JavaDoc resolveFunction(String JavaDoc prefix, String JavaDoc localName)
435   {
436     if (prefix.equals(""))
437       return _elFunctionMap.get(localName);
438     else
439       return _elFunctionMap.get(prefix + ':' + localName);
440   }
441
442   /**
443    * Adds a taglib.
444    */

445   public void addTaglibDir(String JavaDoc prefix, String JavaDoc tagdir)
446     throws JspParseException
447   {
448     Taglib taglib = _tagManager.addTaglibDir(prefix, tagdir);
449
450     ArrayList JavaDoc<TldFunction> functions = taglib.getFunctionList();
451
452     for (int i = 0; i < functions.size(); i++) {
453       TldFunction function = functions.get(i);
454
455       String JavaDoc name = taglib.getPrefixString() + ":" + function.getName();
456
457       _elFunctionMap.put(name, function.getMethod());
458     }
459   }
460
461   /**
462    * Returns true if the JSP compilation has produced a static file.
463    */

464   public boolean isStatic()
465   {
466     return _isStatic;
467   }
468
469   /**
470    * Returns the page's XML view.
471    */

472   public PageData JavaDoc getPageData()
473     throws IOException JavaDoc
474   {
475     if (_pageData != null)
476       return _pageData;
477     
478     TempStream ts = new TempStream(null);
479
480     ts.openWrite();
481     WriteStream ws = new WriteStream(ts);
482     ws.setEncoding("UTF-8");
483
484     _rootNode.printXml(ws);
485     
486     ws.close();
487     
488     _pageData = new QPageData(ts);
489
490     return _pageData;
491   }
492
493   public ELContext getELContext()
494   {
495     return _elContext;
496   }
497   
498   /**
499    * Validates the JSP page.
500    */

501   public void validate()
502     throws Exception JavaDoc
503   {
504     for (int i = 0; i < _tagLibraryList.size(); i++) {
505       Taglib taglib = _tagLibraryList.get(i);
506       TagLibraryValidator JavaDoc validator = taglib.getValidator();
507     
508       if (validator != null) {
509     ValidationMessage JavaDoc []messages;
510
511     messages = validator.validate(taglib.getPrefixString(),
512                       taglib.getURI(),
513                       getPageData());
514
515     if (messages != null && messages.length > 0) {
516           StringBuilder JavaDoc message = new StringBuilder JavaDoc();
517           for (int j = 0; j < messages.length; j++) {
518             if (j != 0)
519               message.append("\n");
520             message.append(messages[j].getMessage());
521           }
522           
523           throw _rootNode.error(message.toString());
524     }
525       }
526     }
527   }
528
529   /**
530    * Generates the JSP page.
531    */

532   protected void generate(Path path, String JavaDoc className)
533     throws Exception JavaDoc
534   {
535     init(className);
536
537     if (_jspCompilerInstance == null ||
538     ! _jspCompilerInstance.isGeneratedSource())
539       addDepend(path);
540
541     _cacheDepends = new ArrayList JavaDoc<Depend>();
542
543     _tagId = 1;
544
545     if (_ideHack)
546       _config.setStaticEncoding(false);
547
548     // disable static pages. No longer needed and complicates
549
// precompilation
550
if (isGenerateStatic() &&
551     ! _parseState.getJspPropertyGroup().getStaticPageGeneratesClass()) {
552       generateStatic();
553     }
554     else {
555       WriteStream os = openWriteStream();
556       JspJavaWriter out = new JspJavaWriter(os, this);
557
558       try {
559         generate(out);
560       } finally {
561         if (os != null)
562           os.close();
563       }
564     }
565
566     if (_lineMap != null) {
567       Path javaPath = getGeneratedPath();
568       String JavaDoc tail = javaPath.getTail();
569       tail = tail + ".smap";
570       WriteStream os = javaPath.getParent().lookup(tail).openWrite();
571
572       LineMapWriter writer = new LineMapWriter(os);
573       writer.write(_lineMap);
574       os.close();
575     }
576   }
577
578   public void addDepend(Path path)
579   {
580     addDepend(new Depend(path));
581   }
582
583   /**
584    * Adds a dependency based on a class.
585    */

586   public void addDepend(Class JavaDoc cl)
587   {
588     addDepend(new ClassDependency(cl));
589   }
590
591   public void addDepend(PersistentDependency depend)
592   {
593     if (! _depends.contains(depend))
594       _depends.add(depend);
595   }
596
597   public ArrayList JavaDoc<PersistentDependency> getDependList()
598   {
599     return _depends;
600   }
601
602   public boolean isStaticEncoding()
603   {
604     return _config.isStaticEncoding();
605   }
606
607   public boolean getRecycleTags()
608   {
609     return _parseState.isRecycleTags();
610   }
611
612   /**
613    * Adds a new Java declaration to the list.
614    */

615   public void addDeclaration(JspDeclaration decl)
616   {
617     _declarations.add(decl);
618   }
619
620   /**
621    * Sets the taglib manager.
622    */

623   public void setTagManager(ParseTagManager tagManager)
624   {
625     _tagManager = tagManager;
626   }
627
628   /**
629    * Returns the taglib manager.
630    */

631   public ParseTagManager getTagManager()
632   {
633     return _tagManager;
634   }
635
636   protected void init(String JavaDoc className)
637   {
638     _fullClassName = className;
639     _className = className;
640
641     String JavaDoc prefix = getPackagePrefix();
642     if (prefix.endsWith("."))
643       prefix = prefix.substring(0, prefix.length() - 1);
644
645     int p = className.lastIndexOf('.');
646     if (p > 0) {
647       _pkg = className.substring(0, p);
648       _className = className.substring(p + 1);
649     }
650     else
651       _pkg = "";
652
653     if (prefix.length() > 0 && _pkg.length() > 0)
654       _pkg = prefix + "." + _pkg;
655     else if (prefix.length() > 0)
656       _pkg = prefix;
657
658     _workPath = _pkg.replace('.', '/');
659
660     _lineMap = new LineMap(className.replace('.', '/') + ".java");
661   }
662
663   /**
664    * True if it's a declared variable.
665    */

666   public boolean isDeclared(String JavaDoc var)
667   {
668     return _declaredVariables.contains(var);
669   }
670
671   /**
672    * Adds a declared variable.
673    */

674   public void addDeclared(String JavaDoc var)
675   {
676     _declaredVariables.add(var);
677   }
678
679   /**
680    * Generates the Java code.
681    */

682   protected void generate(JspJavaWriter out)
683     throws Exception JavaDoc
684   {
685     out.setLineMap(_lineMap);
686     
687     generateClassHeader(out);
688
689     generatePageHeader(out);
690     printTry(out);
691
692     _rootNode.generate(out);
693       
694     generatePageFooter(out);
695
696     // _rootNode.generateDeclaration(out);
697

698     generateClassFooter(out);
699   }
700
701   /**
702    * Generates a static file.
703    */

704   protected void generateStatic()
705     throws Exception JavaDoc
706   {
707     _isStatic = true;
708     
709     Path javaPath = getGeneratedPath();
710     String JavaDoc tail = javaPath.getTail();
711     int p = tail.indexOf('.');
712     tail = tail.substring(0, p);
713
714     Path staticPath = javaPath.getParent().lookup(tail + ".static");
715
716     WriteStream os = staticPath.openWrite();
717     //os.setEncoding(_parseState.getCharEncoding());
718
os.setEncoding("UTF-8");
719
720     try {
721       JspJavaWriter out = new JspJavaWriter(os, this);
722
723       _rootNode.generateStatic(out);
724     } finally {
725       os.close();
726     }
727     
728     Path dependPath = javaPath.getParent().lookup(tail + ".depend");
729     StaticPage.writeDepend(dependPath, getDependList());
730   }
731
732   /**
733    * Generates the class header.
734    *
735    * @param doc the XML document representing the JSP page.
736    */

737   protected void generateClassHeader(JspJavaWriter out)
738     throws IOException JavaDoc, JspParseException
739   {
740     out.println("/*");
741     out.println(" * JSP generated by " + com.caucho.Version.FULL_VERSION);
742     out.println(" */" );
743     out.println();
744
745     if (_pkg != null && ! _pkg.equals(""))
746       out.println("package " + _pkg + ";");
747
748     out.println("import javax.servlet.*;");
749     out.println("import javax.servlet.jsp.*;");
750     out.println("import javax.servlet.http.*;");
751
752     fillSingleTaglibImports();
753
754     ArrayList JavaDoc<String JavaDoc> imports = _parseState.getImportList();
755     for (int i = 0; i < imports.size(); i++) {
756       String JavaDoc name = imports.get(i);
757       out.print("import ");
758       out.print(name);
759       out.println(";");
760     }
761     _parseState.addImport("javax.servlet.*");
762     _parseState.addImport("javax.servlet.jsp.*");
763     _parseState.addImport("javax.servlet.http.*");
764     _parseState.addImport("java.lang.*");
765     out.println();
766
767     if (_parseState.getExtends() != null) {
768       //if (extendsLocation != null)
769
//setLocation(extendsLocation.srcFilename, extendsLocation.srcLine, 0);
770

771       out.print("public class ");
772       out.print(_className);
773       out.print(" extends ");
774       out.print(_parseState.getExtends().getName());
775       out.print(" implements com.caucho.jsp.CauchoPage");
776       if (! _parseState.isThreadSafe())
777         out.print(", javax.servlet.SingleThreadModel");
778     } else {
779       out.print("public class ");
780       out.print(_className);
781       out.print(" extends com.caucho.jsp.JavaPage");
782       if (! _parseState.isThreadSafe())
783         out.print(" implements javax.servlet.SingleThreadModel");
784     }
785
786     out.println();
787     out.println("{");
788     out.pushDepth();
789
790     out.println("private final java.util.HashMap<String,java.lang.reflect.Method> _jsp_functionMap = new java.util.HashMap<String,java.lang.reflect.Method>();");
791
792     out.println("private boolean _caucho_isDead;");
793
794     String JavaDoc info = _parseState.getInfo();
795     if (info != null) {
796       out.println();
797       out.print("public String getServletInfo() { return \"");
798       for (int i = 0; i < info.length(); i++) {
799     char ch = info.charAt(i);
800     if (ch == '\\')
801       out.print("\\\\");
802     else if (ch == '\n')
803       out.print("\\n");
804     else if (ch == '\r')
805       out.print("\\r");
806     else if (ch == '"')
807       out.print("\\\"");
808     else
809       out.print(ch);
810       }
811       out.println("\"; }");
812     }
813     
814     for (int i = 0; i < _declarations.size(); i++) {
815       JspDeclaration decl = _declarations.get(i);
816
817       out.println();
818       decl.generateDeclaration(out);
819     }
820   }
821
822   /**
823    * As a convenience, when the Tag isn't in a package, import
824    * it automatically.
825    */

826   protected void fillSingleTaglibImports()
827     throws JspParseException
828   {
829     /*
830     Iterator<Taglib> iter = _taglibMap.values().iterator();
831     
832     while (iter.hasNext()) {
833       Taglib taglib = iter.next();
834
835       if (taglib == null)
836         continue;
837       
838       ArrayList<String> singleTags = taglib.getSingleTagClassNames();
839
840       for (int i = 0; i < singleTags.size(); i++) {
841         String className = singleTags.get(i);
842
843         _parseState.addImport(className);
844       }
845     }
846     */

847   }
848
849   /**
850    * Prints the _jspService header
851    */

852   protected void generatePageHeader(JspJavaWriter out) throws Exception JavaDoc
853   {
854     out.println("");
855     out.println("public void");
856     out.println("_jspService(javax.servlet.http.HttpServletRequest request,");
857     out.println(" javax.servlet.http.HttpServletResponse response)");
858     out.println(" throws java.io.IOException, javax.servlet.ServletException");
859     out.println("{");
860     out.pushDepth();
861
862     // static shouldn't start up a session
863
boolean isSession = _parseState.isSession() && ! _rootNode.isStatic();
864     
865     if (isSession) {
866       out.println("javax.servlet.http.HttpSession session = request.getSession(true);");
867     }
868     out.println("com.caucho.server.webapp.WebApp _jsp_application = _caucho_getApplication();");
869     out.println("javax.servlet.ServletContext application = _jsp_application;");
870
871     out.print("com.caucho.jsp.PageContextImpl pageContext = com.caucho.jsp.QJspFactory.allocatePageContext(");
872     out.print("this, _jsp_application, request, response, ");
873     if (_parseState.getErrorPage() == null)
874       out.print("null");
875     else
876       out.print("\"" + _parseState.getErrorPage() + "\"");
877     out.print(", ");
878     if (isSession) {
879       out.print("session");
880     }
881     else
882       out.print("null");
883     out.print(", ");
884     out.print(_parseState.getBuffer());
885     out.print(", ");
886     out.print(_parseState.isAutoFlush());
887     out.print(", ");
888     out.print(_parseState.isPrintNullAsBlank());
889     out.println(");");
890     out.println("javax.servlet.jsp.JspWriter out = pageContext.getOut();");
891     out.println("final javax.el.ELContext _jsp_env = pageContext.getELContext();");
892     out.println("javax.servlet.ServletConfig config = getServletConfig();");
893     out.println("javax.servlet.Servlet page = this;");
894     if (_parseState.isErrorPage()) {
895       out.println("java.lang.Throwable exception = ((com.caucho.jsp.PageContextImpl) pageContext).getThrowable();");
896     }
897
898     generateContentType(out);
899
900     /*
901     for (int i = 0; i < _fragmentList.size(); i++) {
902       JspNode node = _fragmentList.get(i);
903
904       if (node.isStatic())
905     out.println("com.caucho.jsp.StaticJspFragmentSupport _jsp_frag_" + i + " = null;");
906       else
907     out.println("_CauchoFragment _jsp_frag_" + i + " = null;");
908     }
909     */

910     
911     _rootNode.generatePrologue(out);
912   }
913
914   /**
915    * Generates the content type of the page.
916    */

917   private void generateContentType(JspJavaWriter out)
918     throws IOException JavaDoc
919   {
920     String JavaDoc encoding = Encoding.getMimeName(_parseState.getCharEncoding());
921     
922     if (encoding != null && encoding.equals("ISO-8859-1"))
923       encoding = null;
924
925     String JavaDoc contentType = _parseState.getContentType();
926     if (contentType != null && contentType.equals("text/html"))
927       contentType = null;
928
929     out.print("response.setContentType(\"");
930     if (contentType == null)
931       out.print("text/html");
932     else {
933       out.printJavaString(contentType);
934     }
935     out.println("\");");
936
937     if (encoding == null) {
938       // server/1204
939
}
940     else if (contentType == null || contentType.indexOf("charset") < 0) {
941       out.print("response.setCharacterEncoding(\"");
942       if (encoding != null)
943     out.printJavaString(encoding);
944       else
945     out.printJavaString("iso-8859-1");
946       out.println("\");");
947     }
948     
949     if (encoding != null)
950       out.println("request.setCharacterEncoding(\"" + encoding + "\");");
951   }
952
953   private void printTry(JspJavaWriter out) throws IOException JavaDoc
954   {
955     out.println("try {");
956     out.pushDepth();
957     // out.println("_caucho_init_tags(pageContext, _jsp_tags);");
958
}
959
960   public int addString(String JavaDoc string)
961   {
962     int index = _strings.get(string);
963     if (index < 0) {
964       index = _strings.size();
965       _strings.put(string, index);
966     }
967     return index;
968   }
969
970   /**
971    * Saves a bean's class for later introspection.
972    *
973    * @param id the bean id
974    * @param typeName the bean's type
975    */

976   public void addBeanClass(String JavaDoc id, String JavaDoc typeName)
977     throws Exception JavaDoc
978   {
979     if (_classes == null)
980       _classes = new HashMap JavaDoc<String JavaDoc,Class JavaDoc>();
981
982     try {
983       if (_primitives.get(typeName) != null)
984         return;
985
986       Class JavaDoc cl = getBeanClass(typeName);
987
988       if (cl == null)
989         throw error(L.l("Can't find class '{0}'",
990                         typeName));
991
992       _classes.put(id, cl);
993     } catch (CompileClassNotFound e) {
994       log.log(Level.WARNING, e.toString(), e);
995
996       throw error(L.l("Can't find class '{0}'\n{1}",
997               typeName, e.getMessage()));
998     } catch (ClassNotFoundException JavaDoc e) {
999       log.log(Level.FINE, e.toString(), e);
1000
1001      throw error(L.l("Can't find class '{0}'", typeName));
1002    }
1003  }
1004
1005  /**
1006   * Loads a bean based on the class name.
1007   */

1008  public Class JavaDoc getBeanClass(String JavaDoc typeName)
1009    throws ClassNotFoundException JavaDoc
1010  {
1011    
1012    // Arrays need to use Array.newInstance(cl, new int[]);
1013
int p = typeName.indexOf('[');
1014    if (p > 0) {
1015      Class JavaDoc cl = getBeanClass(typeName.substring(0, p));
1016      int count = 0;
1017      for (int i = 0; i < typeName.length(); i++)
1018        if (typeName.charAt(i) == '[')
1019          count++;
1020      int []dims = new int[count];
1021      for (int i = 0; i < count; i++)
1022        dims[i] = 1;
1023
1024      Object JavaDoc obj = Array.newInstance(cl, dims);
1025      
1026      return obj.getClass();
1027    }
1028
1029    Class JavaDoc cl = loadBeanClass(typeName);
1030    if (cl != null)
1031      return cl;
1032
1033    // Inner classes need rewriting Foo.Bar -> Foo$Bar
1034
int i = typeName.lastIndexOf('.');
1035    for (; i >= 0; i = typeName.lastIndexOf('.', i - 1)) {
1036      String JavaDoc mainClassName = typeName.substring(0, i);
1037      Class JavaDoc mainClass = loadBeanClass(mainClassName);
1038      
1039      typeName = mainClassName + '$' + typeName.substring(i + 1);
1040      
1041      if (mainClass != null)
1042        return getBeanClass(typeName);
1043    }
1044
1045    return null;
1046  }
1047  
1048  Class JavaDoc loadBeanClass(String JavaDoc typeName)
1049  {
1050    Class JavaDoc cl = _primitiveClasses.get(typeName);
1051
1052    if (cl != null)
1053      return cl;
1054
1055    try {
1056      return CauchoSystem.loadClass(typeName);
1057    } catch (CompileClassNotFound e) {
1058      log.log(Level.FINE, e.toString(), e);
1059    } catch (ClassNotFoundException JavaDoc e) {
1060    }
1061
1062    // qualified names don't use the imports
1063
if (typeName.indexOf('.') >= 0)
1064      return null;
1065
1066    ArrayList JavaDoc<String JavaDoc> imports = _parseState.getImportList();
1067    for (int i = 0; i < imports.size(); i++) {
1068      String JavaDoc pkg = imports.get(i);
1069      String JavaDoc fullName = null;
1070
1071      if (pkg.endsWith("." + typeName))
1072        fullName = pkg;
1073      else if (pkg.endsWith(".*"))
1074        fullName = pkg.substring(0, pkg.length() - 1) + typeName;
1075      else
1076        continue;
1077    
1078      try {
1079        return CauchoSystem.loadClass(fullName);
1080      } catch (CompileClassNotFound e) {
1081        log.log(Level.WARNING, e.toString(), e);
1082      } catch (ClassNotFoundException JavaDoc e) {
1083      }
1084    }
1085
1086    return null;
1087  }
1088
1089  public Class JavaDoc getClass(String JavaDoc id)
1090  {
1091    if (_classes == null)
1092      return null;
1093
1094    return _classes.get(id);
1095  }
1096
1097  protected void generatePageFooter(JspJavaWriter out) throws IOException JavaDoc
1098  {
1099    out.popDepth();
1100    out.println("} catch (java.lang.Throwable _jsp_e) {");
1101    out.println(" pageContext.handlePageException(_jsp_e);");
1102    out.println("} finally {");
1103    out.pushDepth();
1104
1105    for (int i = 0; i < _topTag.size(); i++) {
1106      TagInstance tag = _topTag.get(i);
1107
1108      if (tag.getTagClass() == null) {
1109      }
1110      else if (Tag JavaDoc.class.isAssignableFrom(tag.getTagClass())) {
1111        out.println("if (" + tag.getId() + " != null)");
1112        out.println(" " + tag.getId() + ".release();");
1113      }
1114    }
1115    
1116    if (_hasReleaseTag) {
1117      out.popDepth();
1118      out.println("} finally {");
1119      out.pushDepth();
1120    }
1121    
1122    out.println("com.caucho.jsp.QJspFactory.freePageContext(pageContext);");
1123
1124    if (_hasReleaseTag) {
1125      out.popDepth();
1126      out.println("}");
1127    }
1128    
1129    // close finally
1130
out.popDepth();
1131    out.println("}");
1132    out.popDepth();
1133    out.println("}");
1134  }
1135
1136  /**
1137   * Completes the generated class: closing the main method, generating
1138   * the dependencies and generating the constant strings.
1139   *
1140   * @param doc the XML document representing the JSP page.
1141   */

1142  protected void generateClassFooter(JspJavaWriter out) throws Exception JavaDoc
1143  {
1144    // fragments must be first because they may create others.
1145
generateFragments(out);
1146    
1147    generateDepends(out);
1148
1149    generateExprs(out);
1150    generateXPath(out);
1151    generateConstantStrings(out);
1152
1153    out.popDepth();
1154    out.println("}");
1155  }
1156
1157  public int addFragment(JspFragmentNode node)
1158  {
1159    int index = _fragmentList.indexOf(node);
1160
1161    if (index >= 0)
1162      return index;
1163    
1164    _fragmentList.add(node);
1165    
1166    return _fragmentList.size() - 1;
1167  }
1168
1169  public JspFragmentNode getFragment(int index)
1170  {
1171    return _fragmentList.get(index);
1172  }
1173  
1174  /**
1175   * Adds an expression to the expression list.
1176   */

1177  public int addExpr(String JavaDoc value)
1178    throws JspParseException, ELException JavaDoc
1179  {
1180    return addExpr(genExpr(value));
1181  }
1182  
1183  public com.caucho.el.Expr genExpr(String JavaDoc value)
1184    throws JspParseException, ELException JavaDoc
1185  {
1186    JspELParser parser = new JspELParser(_elContext, value);
1187
1188    return parser.parse();
1189  }
1190
1191  /**
1192   * Adds an expression to the expression list.
1193   */

1194  public int addExpr(com.caucho.el.Expr expr)
1195    throws JspParseException
1196  {
1197    int index = _exprList.indexOf(expr);
1198    if (index >= 0)
1199      return index;
1200
1201    index = _exprList.size();
1202    _exprList.add(expr);
1203
1204    return index;
1205  }
1206  
1207  /**
1208   * Adds an expression to the expression list.
1209   */

1210  public int addValueExpr(String JavaDoc value, String JavaDoc type)
1211    throws JspParseException, ELException JavaDoc
1212  {
1213    JspELParser parser = new JspELParser(_elContext, value);
1214
1215    com.caucho.el.Expr expr = parser.parse();
1216
1217    int index = _valueExprList.indexOf(expr);
1218    if (index >= 0)
1219      return index;
1220
1221    index = _valueExprList.size();
1222
1223    try {
1224      if (type == null || type.equals(""))
1225    _valueExprList.add(new ValueExpr(expr, null));
1226      else
1227    _valueExprList.add(new ValueExpr(expr, getBeanClass(type)));
1228    } catch (ClassNotFoundException JavaDoc e) {
1229      throw new ELException JavaDoc(e);
1230    }
1231
1232    return index;
1233  }
1234  
1235  /**
1236   * Adds an expression to the expression list.
1237   */

1238  public int addMethodExpr(String JavaDoc value, String JavaDoc sigString)
1239    throws JspParseException, ELException JavaDoc
1240  {
1241    JspELParser parser = new JspELParser(_elContext, value);
1242
1243    com.caucho.el.Expr expr = parser.parse();
1244
1245    Class JavaDoc retType = void.class;
1246    Class JavaDoc []args = new Class JavaDoc[0];
1247
1248    try {
1249      if (sigString != null && ! sigString.equals("")) {
1250    Signature sig = new Signature(sigString);
1251
1252    String JavaDoc []types = sig.getParameterTypes();
1253
1254    args = new Class JavaDoc[types.length];
1255
1256    for (int i = 0; i < types.length; i++) {
1257      args[i] = getBeanClass(types[i]);
1258    }
1259
1260    retType = getBeanClass(sig.getReturnType());
1261      }
1262    } catch (ClassNotFoundException JavaDoc e) {
1263      throw new ELException JavaDoc(e);
1264    }
1265
1266    MethodExpr methodExpr = new MethodExpr(expr, args, retType);
1267
1268    int index = _methodExprList.indexOf(methodExpr);
1269    if (index >= 0)
1270      return index;
1271
1272    index = _methodExprList.size();
1273    _methodExprList.add(methodExpr);
1274
1275    return index;
1276  }
1277
1278  /**
1279   * out.Prints the expressions
1280   */

1281  private void generateExprs(JspJavaWriter out) throws IOException JavaDoc
1282  {
1283    for (int i = 0; i < _exprList.size(); i++) {
1284      com.caucho.el.Expr expr = _exprList.get(i);
1285      
1286      out.println("private final static com.caucho.el.Expr _caucho_expr_" + i + " =");
1287      out.print(" ");
1288      expr.printCreate(out.getWriteStream());
1289      out.println(";");
1290    }
1291    
1292    for (int i = 0; i < _valueExprList.size(); i++) {
1293      ValueExpr expr = _valueExprList.get(i);
1294
1295      String JavaDoc exprType = "ObjectValueExpression";
1296
1297      Class JavaDoc retType = expr.getReturnType();
1298
1299      if (String JavaDoc.class.equals(retType))
1300    exprType = "StringValueExpression";
1301      else if (Byte JavaDoc.class.equals(retType)
1302           || byte.class.equals(retType))
1303    exprType = "ByteValueExpression";
1304      else if (Short JavaDoc.class.equals(retType)
1305           || short.class.equals(retType))
1306    exprType = "ShortValueExpression";
1307      else if (Integer JavaDoc.class.equals(retType)
1308           || int.class.equals(retType))
1309    exprType = "IntegerValueExpression";
1310      else if (Long JavaDoc.class.equals(retType)
1311           || long.class.equals(retType))
1312    exprType = "LongValueExpression";
1313      else if (Float JavaDoc.class.equals(retType)
1314           || long.class.equals(retType))
1315    exprType = "FloatValueExpression";
1316      else if (Double JavaDoc.class.equals(retType)
1317           || double.class.equals(retType))
1318    exprType = "DoubleValueExpression";
1319      else if (Boolean JavaDoc.class.equals(retType)
1320           || boolean.class.equals(retType))
1321    exprType = "BooleanValueExpression";
1322      else if (Character JavaDoc.class.equals(retType)
1323           || char.class.equals(retType))
1324    exprType = "CharacterValueExpression";
1325      else if (BigInteger JavaDoc.class.equals(retType))
1326    exprType = "BigIntegerValueExpression";
1327      else if (BigDecimal JavaDoc.class.equals(retType))
1328    exprType = "BigDecimalValueExpression";
1329      
1330      out.println("private final static javax.el.ValueExpression _caucho_value_expr_" + i + " = new com.caucho.el." + exprType + "(");
1331      out.print(" ");
1332      expr.getExpr().printCreate(out.getWriteStream());
1333      out.print(", \"");
1334      out.printJavaString(expr.getExpr().getExpressionString());
1335      out.print("\"");
1336      if (expr.getReturnType() != null) {
1337    out.print(", ");
1338    out.printClass(expr.getReturnType());
1339    out.print(".class");
1340      }
1341      out.println(");");
1342    }
1343    
1344    for (int i = 0; i < _methodExprList.size(); i++) {
1345      MethodExpr expr = _methodExprList.get(i);
1346      
1347      out.println("private final static javax.el.MethodExpression _caucho_method_expr_" + i);
1348      out.print(" = ");
1349
1350      out.print("new com.caucho.el.MethodExpressionImpl");
1351      
1352      out.print("( ");
1353      expr.getExpr().printCreate(out.getWriteStream());
1354      out.print(", \"");
1355      out.printJavaString(expr.getExpr().toString());
1356      out.print("\", ");
1357      if (expr.getReturnType() != null) {
1358    out.printClass(expr.getReturnType());
1359    out.print(".class");
1360      }
1361      else
1362    out.print("String.class");
1363      out.print(", new Class[] {");
1364
1365      Class JavaDoc []args = expr.getArgs();
1366      if (args != null) {
1367    for (int j = 0; j < args.length; j++) {
1368      if (j != 0)
1369        out.print(", ");
1370
1371      out.printClass(args[j]);
1372      out.print(".class");
1373    }
1374      }
1375      
1376      out.println("});");
1377    }
1378  }
1379
1380  /**
1381   * Adds an expression to the expression list.
1382   */

1383  public String JavaDoc addXPathExpr(String JavaDoc value, NamespaceContext ns)
1384    throws JspParseException, XPathParseException
1385  {
1386    return addXPathExpr(XPath.parseExpr(value, ns));
1387  }
1388
1389  /**
1390   * Adds an expression to the expression list.
1391   */

1392  public String JavaDoc addXPathExpr(com.caucho.xpath.Expr expr)
1393    throws JspParseException
1394  {
1395    int index = _xpathExprList.indexOf(expr);
1396    if (index >= 0)
1397      return "_caucho_xpath_" + index;
1398
1399    index = _xpathExprList.size();
1400    _xpathExprList.add(expr);
1401
1402    return "_caucho_xpath_" + index;
1403  }
1404
1405  /**
1406   * out.Prints the expressions
1407   */

1408  private void generateXPath(JspJavaWriter out) throws IOException JavaDoc
1409  {
1410    if (_xpathExprList.size() == 0)
1411      return;
1412    
1413    for (int i = 0; i < _xpathExprList.size(); i++) {
1414      com.caucho.xpath.Expr expr = _xpathExprList.get(i);
1415      
1416      out.println("private static com.caucho.xpath.Expr _caucho_xpath_" + i + ";");
1417    }
1418
1419    out.println("static {");
1420    out.pushDepth();
1421    out.println("try {");
1422    out.pushDepth();
1423    
1424    for (int i = 0; i < _xpathExprList.size(); i++) {
1425      com.caucho.xpath.Expr expr = _xpathExprList.get(i);
1426      
1427      out.print("_caucho_xpath_" + i + " =");
1428      out.println(" com.caucho.xpath.XPath.parseExpr(\"" + expr + "\");");
1429    }
1430
1431    out.popDepth();
1432    out.println("} catch (Exception e) {");
1433    out.println(" e.printStackTrace();");
1434    out.println("}");
1435    out.popDepth();
1436    out.println("}");
1437  }
1438
1439  /**
1440   * out.Prints the fragments
1441   */

1442  private void generateFragments(JspJavaWriter out) throws Exception JavaDoc
1443  {
1444    boolean hasFragment = false;
1445
1446    for (int i = 0; i < _fragmentList.size(); i++) {
1447      JspFragmentNode node = _fragmentList.get(i);
1448
1449      if (node.isStatic()) {
1450      }
1451      /*
1452      else if (node.isValueFragment()) {
1453    node.generateValueMethod(out);
1454      }
1455      */

1456      else
1457    hasFragment = true;
1458    }
1459    
1460    if (! hasFragment)
1461      return;
1462
1463    out.println("public static class _CauchoFragment extends com.caucho.jsp.JspFragmentSupport {");
1464    out.pushDepth();
1465    out.println("private int _frag_code;");
1466
1467    out.println();
1468    out.println("static _CauchoFragment create(_CauchoFragment frag, int code,");
1469    out.println(" com.caucho.jsp.PageContextImpl pageContext,");
1470    out.println(" javax.servlet.jsp.tagext.JspTag parent,");
1471    out.println(" javax.servlet.jsp.tagext.JspFragment jspBody)");
1472    out.println("{");
1473    out.pushDepth();
1474    out.println("if (frag == null)");
1475    out.println(" frag = new _CauchoFragment();");
1476    out.println();
1477    out.println("frag._frag_code = code;");
1478    out.println("frag.pageContext = pageContext;");
1479    out.println("frag._jsp_env = pageContext.getELContext();");
1480    out.println("frag._jsp_parent_tag = parent;");
1481    out.println("frag._jspBody = jspBody;");
1482    out.println();
1483    out.println("return frag;");
1484    out.popDepth();
1485    out.println("}");
1486    
1487      
1488    for (int i = 0; i < _fragmentList.size(); i++) {
1489      JspFragmentNode frag = _fragmentList.get(i);
1490
1491      if (frag.isStatic())
1492    continue;
1493
1494      if (frag.isValueFragment())
1495    frag.generateValueMethod(out);
1496      else {
1497    out.println();
1498    out.println("private void " + frag.getFragmentName() + "(JspWriter out)");
1499    out.println(" throws Throwable");
1500    out.println("{");
1501    out.pushDepth();
1502
1503    HashSet JavaDoc<String JavaDoc> oldDeclaredVariables = _declaredVariables;
1504    _declaredVariables = new HashSet JavaDoc<String JavaDoc>();
1505    try {
1506      frag.generatePrologueChildren(out);
1507      frag.generate(out);
1508    } finally {
1509      _declaredVariables = oldDeclaredVariables;
1510    }
1511    
1512    out.popDepth();
1513    out.println("}");
1514      }
1515    }
1516
1517    out.println();
1518    out.println("protected void _jsp_invoke(JspWriter out)");
1519    out.println(" throws Throwable");
1520    out.println("{");
1521    out.pushDepth();
1522    out.println("switch (_frag_code) {");
1523    
1524    for (int i = 0; i < _fragmentList.size(); i++) {
1525      JspFragmentNode frag = _fragmentList.get(i);
1526      
1527      if (frag.isStatic() || frag.isValueFragment())
1528    continue;
1529      
1530      out.println("case " + i + ":");
1531      out.println(" " + frag.getFragmentName() + "(out);");
1532      out.println(" break;");
1533    }
1534
1535    out.println("}");
1536    
1537    out.popDepth();
1538    out.println("}");
1539    
1540    out.popDepth();
1541    out.println("}");
1542  }
1543
1544  /**
1545   * Generates the dependency methods. Since we can't assume the
1546   * underlying class is Page when the JSP page uses "extends"
1547   * each JSP page needs to generate this code.
1548   */

1549  private void generateDepends(JspJavaWriter out) throws IOException JavaDoc
1550  {
1551    out.println();
1552    // out.println("private com.caucho.java.LineMap _caucho_line_map;");
1553
out.println("private java.util.ArrayList _caucho_depends = new java.util.ArrayList();");
1554    if (_isCacheable && ! _isUncacheable)
1555      out.println("private java.util.ArrayList _caucho_cacheDepends = new java.util.ArrayList();");
1556    
1557    out.println();
1558    out.println("public java.util.ArrayList _caucho_getDependList()");
1559    out.println("{");
1560    out.println(" return _caucho_depends;");
1561    out.println("}");
1562    
1563    out.println();
1564    out.println("public void _caucho_addDepend(com.caucho.vfs.PersistentDependency depend)");
1565    out.println("{");
1566    if (_parseState.getExtends() == null)
1567      out.println(" super._caucho_addDepend(depend);");
1568    out.println(" com.caucho.jsp.JavaPage.addDepend(_caucho_depends, depend);");
1569    out.println("}");
1570
1571    out.println();
1572    out.println("public boolean _caucho_isModified()");
1573    out.println("{");
1574    out.pushDepth();
1575    out.println("if (_caucho_isDead)");
1576    out.println(" return true;");
1577    out.println("if (com.caucho.server.util.CauchoSystem.getVersionId() != " +
1578        CauchoSystem.getVersionId() + "L)");
1579    out.println(" return true;");
1580    
1581    ArrayList JavaDoc<PersistentDependency> depends;
1582    depends = new ArrayList JavaDoc<PersistentDependency>();
1583    depends.addAll(_parseState.getDependList());
1584
1585    for (int i = 0; i < _depends.size(); i++) {
1586      PersistentDependency depend = _depends.get(i);
1587
1588      if (! depends.contains(depend))
1589    depends.add(depend);
1590    }
1591
1592    if (_alwaysModified)
1593      out.println("return true;");
1594
1595    else if (depends.size() == 0)
1596      out.println("return false;");
1597
1598    else {
1599      out.println("for (int i = _caucho_depends.size() - 1; i >= 0; i--) {");
1600      out.pushDepth();
1601      out.println("com.caucho.vfs.Dependency depend;");
1602      out.println("depend = (com.caucho.vfs.Dependency) _caucho_depends.get(i);");
1603      out.println("if (depend.isModified())");
1604      out.println(" return true;");
1605      out.popDepth();
1606      out.println("}");
1607      out.println("return false;");
1608    }
1609    
1610    out.popDepth();
1611    out.println("}");
1612
1613    if (_rootNode.isStatic() && CauchoSystem.isTest())
1614      out.println("private static long _caucho_lastModified = com.caucho.util.Alarm.getCurrentTime();");
1615    
1616    out.println();
1617    out.println("public long _caucho_lastModified()");
1618    out.println("{");
1619    out.pushDepth();
1620    /*
1621    if (! _isCacheable || _isUncacheable)
1622      out.println("return 0;");
1623    else {
1624      out.println("return com.caucho.jsp.Page.calculateLastModified(_caucho_depends, _caucho_cacheDepends);");
1625    }
1626    */

1627
1628    if (! isGenerateStatic()) {
1629      out.println("return 0;");
1630    }
1631    else if (CauchoSystem.isTest()) {
1632      out.println("return _caucho_lastModified;");
1633    }
1634    else {
1635      out.println("long lastModified = 0;");
1636      
1637      out.println("for (int i = _caucho_depends.size() - 1; i >= 0; i--) {");
1638      out.pushDepth();
1639      out.println("Object oDepend = _caucho_depends.get(i);");
1640      out.println("if (oDepend instanceof com.caucho.vfs.Depend) {");
1641      out.println(" com.caucho.vfs.Depend depend = (com.caucho.vfs.Depend) oDepend;");
1642      out.println(" if (lastModified < depend.getLastModified())");
1643      out.println(" lastModified = depend.getLastModified();");
1644      out.println("}");
1645      out.popDepth();
1646      out.println("}");
1647
1648      out.println();
1649      out.println("return lastModified;");
1650    }
1651    
1652    out.popDepth();
1653    out.println("}");
1654
1655    /*
1656    out.println();
1657    out.println("public com.caucho.java.LineMap _caucho_getLineMap()");
1658    out.println("{");
1659    out.pushDepth();
1660    out.println("return _caucho_line_map;");
1661    out.popDepth();
1662    out.println("}");
1663    */

1664
1665    generateInit(out);
1666
1667    if (_parseState.getExtends() == null && ! _parseState.isTag()) {
1668      out.println();
1669      out.println("public void destroy()");
1670      out.println("{");
1671      out.pushDepth();
1672      out.println(" _caucho_isDead = true;");
1673      out.println(" super.destroy();");
1674      out.popDepth();
1675      out.println("}");
1676    }
1677
1678    if (_parseState.getExtends() != null && ! _parseState.isTag()) {
1679      out.println();
1680      out.println("public com.caucho.server.webapp.WebApp _caucho_getApplication()");
1681      out.println("{");
1682      out.pushDepth();
1683      out.println(" return (com.caucho.server.webapp.WebApp) getServletConfig().getServletContext();");
1684      out.popDepth();
1685      out.println("}");
1686    }
1687
1688    printDependInit(out, depends);
1689    generateInject(out);
1690  }
1691
1692  private boolean isGenerateStatic()
1693  {
1694    return (_rootNode.isStatic() &&
1695        ! _parseState.isTag() &&
1696        _parseState.getExtends() == null);
1697  }
1698  /**
1699   * Generates the normal init.
1700   */

1701  private void generateInit(JspJavaWriter out)
1702    throws IOException JavaDoc
1703  {
1704    out.println();
1705    out.println("public java.util.HashMap<String,java.lang.reflect.Method> _caucho_getFunctionMap()");
1706    out.println("{");
1707    out.pushDepth();
1708
1709    out.println("return _jsp_functionMap;");
1710    
1711    out.popDepth();
1712    out.println("}");
1713
1714    if (! isTag() && _parseState.getExtends() == null) {
1715      out.println();
1716      out.println("public void init(ServletConfig config)");
1717      out.println(" throws ServletException");
1718      out.println("{");
1719      out.pushDepth();
1720    
1721      out.println("super.init(config);");
1722
1723      out.println("com.caucho.server.webapp.WebApp webApp");
1724      out.println(" = (com.caucho.server.webapp.WebApp) config.getServletContext();");
1725      out.println("com.caucho.jsp.TaglibManager manager = webApp.getJspApplicationContext().getTaglibManager();");
1726
1727      for (Taglib taglib : _tagLibraryList) {
1728    out.print("manager.addTaglibFunctions(_jsp_functionMap, \"");
1729    out.printJavaString(taglib.getPrefixString());
1730    out.print("\", \"");
1731    out.printJavaString(taglib.getURI());
1732    out.print("\");");
1733      }
1734
1735      out.popDepth();
1736      out.println("}");
1737    }
1738  }
1739
1740  /**
1741   * Prints the initialization methods to track dependencies.
1742   */

1743  private void printDependInit(JspJavaWriter out,
1744                   ArrayList JavaDoc<PersistentDependency> depends)
1745    throws IOException JavaDoc
1746  {
1747    out.println();
1748    out.println("public void init(com.caucho.vfs.Path appDir)");
1749    out.println(" throws javax.servlet.ServletException");
1750    out.println("{");
1751    out.pushDepth();
1752
1753    if (_ideHack) {
1754      out.println("_jsp_init_strings();");
1755    }
1756
1757    out.println("com.caucho.vfs.Path resinHome = com.caucho.server.util.CauchoSystem.getResinHome();");
1758    out.println("com.caucho.vfs.MergePath mergePath = new com.caucho.vfs.MergePath();");
1759    out.println("mergePath.addMergePath(appDir);");
1760    out.println("mergePath.addMergePath(resinHome);");
1761    out.println("com.caucho.loader.DynamicClassLoader loader;");
1762    out.println("loader = (com.caucho.loader.DynamicClassLoader) getClass().getClassLoader();");
1763    out.println("String resourcePath = loader.getResourcePathSpecificFirst();");
1764    out.println("mergePath.addClassPath(resourcePath);");
1765
1766    MergePath classPath = new MergePath();
1767    ClassLoader JavaDoc classLoader = Thread.currentThread().getContextClassLoader();
1768    if (classLoader instanceof DynamicClassLoader) {
1769      DynamicClassLoader loader = (DynamicClassLoader) classLoader;
1770    
1771      String JavaDoc resourcePath = loader.getResourcePathSpecificFirst();
1772      classPath.addClassPath(resourcePath);
1773    }
1774    
1775    String JavaDoc srcName = _filename;
1776    if (srcName == null)
1777      srcName = "foo";
1778
1779    /*
1780    out.print("_caucho_line_map = new com.caucho.java.LineMap(\"");
1781    out.printJavaString(_lineMap.getDestFilename());
1782    out.print("\", \"");
1783    out.printJavaString(srcName);
1784    out.println("\");");
1785
1786    Iterator<LineMap.Line> iter = _lineMap.iterator();
1787    String lastSrcFilename = srcName;
1788    while (iter.hasNext()) {
1789      LineMap.Line line = iter.next();
1790
1791      if (lastSrcFilename != null &&
1792          lastSrcFilename.equals(line.getSourceFilename())) {
1793        out.println("_caucho_line_map.add(" + line.getSourceLine() + ", " +
1794                line.getDestLine() + ");");
1795      } else {
1796        out.print("_caucho_line_map.add(\"");
1797        out.printJavaString(line.getSourceFilename());
1798        out.println("\", " + line.getSourceLine() + ", " +
1799                line.getDestLine() + ");");
1800        lastSrcFilename = line.getSourceFilename();
1801      }
1802    }
1803    */

1804
1805    out.println("com.caucho.vfs.Depend depend;");
1806    
1807    Path appDir = getAppDir();
1808    for (int i = 0; i < depends.size(); i++) {
1809      PersistentDependency dependency = depends.get(i);
1810
1811      if (dependency instanceof Depend) {
1812        Depend depend = (Depend) dependency;
1813    
1814    if (depend.getPath().isDirectory())
1815      continue;
1816    
1817        out.print("depend = new com.caucho.vfs.Depend(");
1818        printPathDir(out, depend.getPath().getFullPath(), appDir, classPath);
1819        out.println(", " + depend.getDigest() + "L, " +
1820                    _requireSource + ");");
1821        out.println("com.caucho.jsp.JavaPage.addDepend(_caucho_depends, depend);");
1822      }
1823      else {
1824        out.print("com.caucho.jsp.JavaPage.addDepend(_caucho_depends, ");
1825        out.print(dependency.getJavaCreateString());
1826        out.println(");");
1827      }
1828    }
1829
1830    if (_isCacheable && ! _isUncacheable) {
1831      for (int i = 0; i < _cacheDepends.size(); i++) {
1832        Depend depend = _cacheDepends.get(i);
1833
1834    if (depend.getPath().isDirectory())
1835      continue;
1836
1837        out.print("depend = new com.caucho.vfs.Depend(");
1838        printPathDir(out, depend.getPath().getFullPath(), appDir, classPath);
1839        out.println(", \"" + depend.getDigest() + "\", " +
1840                    _requireSource + ");");
1841        out.println("_caucho_cacheDepends.add((Object) depend);");
1842      }
1843    }
1844    out.popDepth();
1845    out.println("}");
1846  }
1847
1848  /**
1849   * Prints an expression to lookup the path directory
1850   */

1851  private void printPathDir(JspJavaWriter out, String JavaDoc path,
1852                            Path appDir, MergePath classPath)
1853    throws IOException JavaDoc
1854  {
1855    String JavaDoc resinHome = CauchoSystem.getResinHome().getFullPath();
1856
1857    String JavaDoc prefix = getAppDir().getFullPath();
1858    
1859    if (prefix.length() > 1 && ! prefix.endsWith("/"))
1860      prefix = prefix + "/";
1861
1862    if (path.startsWith(prefix)) {
1863      path = path.substring(prefix.length());
1864      out.print("appDir.lookup(\"");
1865      out.printJavaString(path);
1866      out.print("\")");
1867      return;
1868    }
1869
1870    ArrayList JavaDoc<Path> classPathList = classPath.getMergePaths();
1871    
1872    for (int i = 0; i < classPathList.size(); i++) {
1873      Path dir = classPathList.get(i);
1874      prefix = dir.getFullPath();
1875
1876      if (! prefix.endsWith("/"))
1877    prefix = prefix + "/";
1878
1879      if (path.startsWith(prefix)) {
1880        String JavaDoc tail = path.substring(prefix.length());
1881
1882    if (dir.lookup(tail).canRead() &&
1883        classPath.lookup(tail).equals(dir.lookup(tail))) {
1884      out.print("mergePath.lookup(\"");
1885      out.printJavaString(tail);
1886      out.print("\")");
1887      return;
1888    }
1889      }
1890    }
1891      
1892    if (path.startsWith(resinHome + "/")) {
1893      path = path.substring(resinHome.length() + 1);
1894      out.print("mergePath.lookup(\"");
1895      out.printJavaString(path);
1896      out.print("\")");
1897    }
1898    /* XXX: why? This messes up tests like server/0526
1899    else if (path.startsWith("/")) {
1900      out.print("mergePath.lookup(\"file:");
1901      out.printJavaString(path);
1902      out.print("\")");
1903    }
1904    */

1905    /*
1906    else if (classPath.lookup("./" + path).canRead()) {
1907      out.print("mergePath.lookup(\"./");
1908      out.printJavaString(path);
1909      out.print("\")");
1910    }
1911    */

1912    else {
1913      out.print("mergePath.lookup(\"");
1914      out.printJavaString(path);
1915      out.print("\")");
1916    }
1917  }
1918
1919  /**
1920   * Prints the tag injection.
1921   */

1922  private void generateInject(JspJavaWriter out) throws IOException JavaDoc
1923  {
1924    if (_topTag == null || ! _topTag.hasChildren())
1925      return;
1926
1927    Iterator JavaDoc<TagInstance> iter = _topTag.iterator();
1928    while (iter.hasNext()) {
1929      TagInstance tag = iter.next();
1930
1931      if (tag != null)
1932      generateTagInjectDecl(out, tag);
1933    }
1934    
1935    out.println();
1936    out.println("static {");
1937    out.pushDepth();
1938    out.println("try {");
1939    out.pushDepth();
1940
1941    iter = _topTag.iterator();
1942    while (iter.hasNext()) {
1943      TagInstance tag = iter.next();
1944
1945      if (tag != null)
1946    generateTagInject(out, tag);
1947    }
1948    
1949    out.popDepth();
1950    out.println("} catch (Exception e) {");
1951    out.println(" e.printStackTrace();");
1952    out.println(" throw new RuntimeException(e);");
1953    out.println("}");
1954
1955    out.popDepth();
1956    out.println("}");
1957  }
1958
1959  /**
1960   * Prints the tag injection.
1961   */

1962  private void generateTagInjectDecl(JspJavaWriter out, TagInstance tag)
1963    throws IOException JavaDoc
1964  {
1965    if (tag.getAnalyzedTag() != null
1966    && tag.getAnalyzedTag().getHasInjection()) {
1967      out.println("private static com.caucho.config.j2ee.InjectProgram _jsp_inject_" + tag.getId() + ";");
1968    }
1969
1970    Iterator JavaDoc<TagInstance> iter = tag.iterator();
1971    while (iter.hasNext()) {
1972      TagInstance child = iter.next();
1973
1974      generateTagInjectDecl(out, child);
1975    }
1976  }
1977
1978  /**
1979   * Prints the tag injection.
1980   */

1981  private void generateTagInject(JspJavaWriter out, TagInstance tag)
1982    throws IOException JavaDoc
1983  {
1984    if (tag.getAnalyzedTag() != null
1985    && tag.getAnalyzedTag().getHasInjection()) {
1986      out.print("_jsp_inject_" + tag.getId() + " = ");
1987      out.println("com.caucho.config.j2ee.InjectIntrospector.introspectProgram("
1988          + tag.getTagClass().getName() + ".class);");
1989    }
1990
1991    Iterator JavaDoc<TagInstance> iter = tag.iterator();
1992    while (iter.hasNext()) {
1993      TagInstance child = iter.next();
1994
1995      generateTagInject(out, child);
1996    }
1997  }
1998
1999  private void generateConstantStrings(JspJavaWriter out)
2000    throws IOException JavaDoc
2001  {
2002    if (_strings.size() == 0)
2003      return;
2004
2005    out.println();
2006    Iterator JavaDoc iter = _strings.iterator();
2007    while (iter.hasNext()) {
2008      Object JavaDoc key = iter.next();
2009      int j = _strings.get(key);
2010
2011      if (_ideHack)
2012        out.println("private final char []_jsp_string" + j + ";");
2013      else
2014        out.println("private final static char []_jsp_string" + j + ";");
2015    }
2016
2017    if (_ideHack) {
2018      out.println("private void _jsp_init_strings() {");
2019      out.pushDepth();
2020    }
2021    else {
2022      out.println("static {");
2023      out.pushDepth();
2024    }
2025    
2026    String JavaDoc enc = out.getWriteStream().getJavaEncoding();
2027    if (enc == null || enc.equals("ISO8859_1"))
2028      enc = null;
2029
2030    if (_config.isStaticEncoding() && enc != null) {
2031      out.println("try {");
2032      out.pushDepth();
2033    }
2034
2035    iter = _strings.iterator();
2036    while (iter.hasNext()) {
2037      String JavaDoc text = (String JavaDoc) iter.next();
2038      int j = _strings.get(text);
2039
2040      out.print("_jsp_string" + j + " = \"");
2041      
2042      for (int i = 0; i < text.length(); i++) {
2043    char ch = text.charAt(i);
2044    switch (ch) {
2045    case '\n':
2046      out.print("\\n");
2047      break;
2048    case '\r':
2049      out.print("\\r");
2050      break;
2051    case '"':
2052      out.print("\\\"");
2053      break;
2054    case '\\':
2055      out.print("\\\\");
2056      break;
2057    default:
2058      out.print(ch);
2059    }
2060      }
2061
2062      out.println("\".toCharArray();");
2063    }
2064    if (_config.isStaticEncoding() && enc != null) {
2065      out.popDepth();
2066      out.println("} catch (java.io.UnsupportedEncodingException e) {");
2067      out.println(" e.printStackTrace();");
2068      out.println("}");
2069    }
2070    out.popDepth();
2071    out.println("}");
2072  }
2073
2074  /**
2075   * Opens a write stream to the *.java file we're generating.
2076   *
2077   * @param path work directory path
2078   *
2079   * @return the write stream
2080   */

2081  WriteStream openWriteStream()
2082    throws IOException JavaDoc
2083  {
2084    Path javaPath = getGeneratedPath();
2085    
2086    WriteStream os = javaPath.openWrite();
2087
2088    os.setEncoding("JAVA");
2089    
2090    return os;
2091  }
2092
2093  Path getGeneratedPath()
2094    throws IOException JavaDoc
2095  {
2096    String JavaDoc name = _pkg + "." + _className;
2097
2098    Path dir = getJspCompiler().getClassDir().lookup(_workPath);
2099    Path javaPath = dir.lookup(_className + ".java");
2100    
2101    try {
2102      javaPath.getParent().mkdirs();
2103    } catch (Exception JavaDoc e) {
2104      log.log(Level.WARNING, e.toString(), e);
2105    }
2106
2107    return javaPath;
2108  }
2109  
2110  public int uniqueId()
2111  {
2112    return _uniqueId++;
2113  }
2114  
2115  public int generateJspId()
2116  {
2117    return _jspId++;
2118  }
2119
2120  protected void addImport(String JavaDoc name)
2121  {
2122  }
2123
2124  boolean hasTags()
2125  {
2126    // size() == 1 is the jsp: tags.
2127
return _tagManager.hasTags();
2128  }
2129
2130  /**
2131   * Returns the tag with the given qname.
2132   */

2133  public TagInfo JavaDoc getTag(QName qname)
2134    throws JspParseException
2135  {
2136    return _tagManager.getTag(qname);
2137  }
2138
2139  /**
2140   * Returns the tag with the given qname.
2141   */

2142  public Class JavaDoc getTagClass(QName qname)
2143    throws Exception JavaDoc
2144  {
2145    return _tagManager.getTagClass(qname);
2146  }
2147
2148  public Taglib addTaglib(QName qname)
2149    throws JspParseException
2150  {
2151    return _tagManager.addTaglib(qname);
2152  }
2153
2154  public String JavaDoc getSourceLines(Path source, int errorLine)
2155  {
2156    if (source == null || errorLine < 1)
2157      return "";
2158
2159    boolean hasLine = false;
2160    StringBuilder JavaDoc sb = new StringBuilder JavaDoc("\n\n");
2161
2162    ReadStream is = null;
2163    try {
2164      is = source.openRead();
2165      is.setEncoding(_parseState.getPageEncoding());
2166
2167      int line = 0;
2168      String JavaDoc text;
2169      while ((text = is.readLine()) != null) {
2170    line++;
2171
2172    if (errorLine - 2 <= line && line <= errorLine + 2) {
2173      sb.append(line);
2174      sb.append(": ");
2175      sb.append(text);
2176      sb.append("\n");
2177      hasLine = true;
2178    }
2179      }
2180    } catch (IOException JavaDoc e) {
2181      log.log(Level.FINER, e.toString(), e);
2182    } finally {
2183      is.close();
2184    }
2185
2186    if (hasLine)
2187      return sb.toString();
2188    else
2189      return "";
2190  }
2191  public JspParseException error(String JavaDoc message)
2192  {
2193    JspParseException e = new JspParseException(message);
2194    e.setErrorPage(_parseState.getErrorPage());
2195
2196    return e;
2197  }
2198
2199  public JspParseException error(Exception JavaDoc e)
2200  {
2201    JspParseException exn = new JspParseException(e);
2202    
2203    exn.setErrorPage(_parseState.getErrorPage());
2204
2205    return exn;
2206  }
2207
2208  static class MethodExpr {
2209    com.caucho.el.Expr _expr;
2210    Class JavaDoc []_args;
2211    Class JavaDoc _retType;
2212
2213    MethodExpr(com.caucho.el.Expr expr, Class JavaDoc []args, Class JavaDoc retType)
2214    {
2215      _expr = expr;
2216      _args = args;
2217      _retType = retType;
2218    }
2219
2220    com.caucho.el.Expr getExpr()
2221    {
2222      return _expr;
2223    }
2224
2225    Class JavaDoc []getArgs()
2226    {
2227      return _args;
2228    }
2229
2230    Class JavaDoc getReturnType()
2231    {
2232      return _retType;
2233    }
2234  }
2235
2236  static class ValueExpr {
2237    com.caucho.el.Expr _expr;
2238    Class JavaDoc _retType;
2239
2240    ValueExpr(com.caucho.el.Expr expr, Class JavaDoc retType)
2241    {
2242      _expr = expr;
2243      _retType = retType;
2244    }
2245
2246    com.caucho.el.Expr getExpr()
2247    {
2248      return _expr;
2249    }
2250
2251    Class JavaDoc getReturnType()
2252    {
2253      return _retType;
2254    }
2255  }
2256
2257  static {
2258    _primitives = new HashMap JavaDoc<String JavaDoc,String JavaDoc>();
2259    _primitives.put("boolean", "boolean");
2260    _primitives.put("byte", "byte");
2261    _primitives.put("short", "short");
2262    _primitives.put("char", "char");
2263    _primitives.put("int", "int");
2264    _primitives.put("long", "long");
2265    _primitives.put("float", "float");
2266    _primitives.put("double", "double");
2267    
2268    _primitiveClasses = new HashMap JavaDoc<String JavaDoc,Class JavaDoc>();
2269    _primitiveClasses.put("boolean", boolean.class);
2270    _primitiveClasses.put("byte", byte.class);
2271    _primitiveClasses.put("short", short.class);
2272    _primitiveClasses.put("char", char.class);
2273    _primitiveClasses.put("int", int.class);
2274    _primitiveClasses.put("long", long.class);
2275    _primitiveClasses.put("float", float.class);
2276    _primitiveClasses.put("double", double.class);
2277  }
2278}
2279
Popular Tags