KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > xsl > JavaGenerator


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  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.xsl;
30
31 import com.caucho.java.JavaCompiler;
32 import com.caucho.java.JavaWriter;
33 import com.caucho.loader.DynamicClassLoader;
34 import com.caucho.log.Log;
35 import com.caucho.server.util.CauchoSystem;
36 import com.caucho.util.CharBuffer;
37 import com.caucho.util.IntArray;
38 import com.caucho.util.IntMap;
39 import com.caucho.vfs.Depend;
40 import com.caucho.vfs.Path;
41 import com.caucho.vfs.WriteStream;
42 import com.caucho.xml.QAbstractNode;
43 import com.caucho.xml.QAttr;
44 import com.caucho.xml.QElement;
45 import com.caucho.xml.QName;
46 import com.caucho.xml.XmlChar;
47 import com.caucho.xpath.Expr;
48 import com.caucho.xpath.NamespaceContext;
49 import com.caucho.xpath.expr.NumericExpr;
50 import com.caucho.xpath.pattern.*;
51 import com.caucho.xsl.fun.KeyFun;
52 import com.caucho.xsl.java.*;
53
54 import org.w3c.dom.*;
55
56 import java.io.IOException JavaDoc;
57 import java.text.DecimalFormatSymbols JavaDoc;
58 import java.util.ArrayList JavaDoc;
59 import java.util.HashMap JavaDoc;
60 import java.util.Iterator JavaDoc;
61 import java.util.Locale JavaDoc;
62 import java.util.logging.Logger JavaDoc;
63
64 /**
65  * Generates code for a Java based stylesheet.
66  *
67  * <pre>
68  * package work.xsl;
69  * public class foo extends JavaStylesheet {
70  * }
71  * </pre>
72  */

73 public class JavaGenerator extends Generator {
74   private static final Logger JavaDoc log = Log.open(JavaGenerator.class);
75
76   private static HashMap JavaDoc<QName,Class JavaDoc> _tagMap;
77   private static HashMap JavaDoc<QName,Class JavaDoc> _topTagMap;
78   
79   private static int _count;
80
81   Path _path;
82   WriteStream _s;
83   JavaWriter _out;
84
85   ArrayList JavaDoc<AbstractPattern> _matchPatterns = new ArrayList JavaDoc<AbstractPattern>();
86   IntMap _matchMap = new IntMap();
87   ArrayList JavaDoc<AbstractPattern> _selectPatterns = new ArrayList JavaDoc<AbstractPattern>();
88   IntMap _selectMap = new IntMap();
89   
90   ArrayList JavaDoc<Expr> _exprs = new ArrayList JavaDoc<Expr>();
91   IntMap _exprMap = new IntMap();
92   
93   ArrayList JavaDoc<Sort[]> _sorts = new ArrayList JavaDoc<Sort[]>();
94   ArrayList JavaDoc<NamespaceContext> _namespaces = new ArrayList JavaDoc<NamespaceContext>();
95   ArrayList JavaDoc<XslNumberFormat> _formats = new ArrayList JavaDoc<XslNumberFormat>();
96   ArrayList JavaDoc<String JavaDoc> _functions = new ArrayList JavaDoc<String JavaDoc>();
97   ArrayList JavaDoc<Template> _templateList = new ArrayList JavaDoc<Template>();
98   ArrayList JavaDoc<String JavaDoc> _stylesheets = new ArrayList JavaDoc<String JavaDoc>();
99   int _templateCount = 0;
100   // integer counting unique identifier
101
int _unique;
102   HashMap JavaDoc<String JavaDoc,String JavaDoc> _macros = new HashMap JavaDoc<String JavaDoc,String JavaDoc>();
103   ArrayList JavaDoc<Object JavaDoc> _fragments = new ArrayList JavaDoc<Object JavaDoc>();
104   
105   ArrayList JavaDoc<String JavaDoc> _strings = new ArrayList JavaDoc<String JavaDoc>();
106   IntMap _stringMap = new IntMap();
107   
108   IntArray _envDepth = new IntArray();
109
110   ArrayList JavaDoc<String JavaDoc> _modes = new ArrayList JavaDoc<String JavaDoc>();
111
112   private XslNode _xslNode;
113
114   private boolean _isLineBegin;
115   private int _depth;
116   private int _callDepth;
117
118   // integer counting the depth of nested selects
119
private int _selectDepth;
120   private int _selectLoopDepth;
121   
122   private int _flagCount;
123   private String JavaDoc _className;
124   private String JavaDoc _pkg;
125
126   private String JavaDoc _currentPos;
127   
128   private ClassLoader JavaDoc _parentLoader;
129   private JavaCompiler _compiler;
130   private boolean _disableEscaping;
131   private boolean _printLocation = true;
132
133   private String JavaDoc _oldFilename = null;
134   private int _oldLine = -1;
135
136   private boolean _hasHeader;
137
138   /**
139    * Creates a new XSL generator for Java.
140    *
141    * @param xslGenerator the owning factory.
142    * @param className the name of the generated class
143    * @param encoding the generated output encoding.
144    */

145   JavaGenerator(AbstractStylesheetFactory xslGenerator,
146                 String JavaDoc className, String JavaDoc encoding)
147     throws IOException JavaDoc
148   {
149     super(xslGenerator);
150
151     _parentLoader = xslGenerator.getClassLoader();
152
153     ArrayList JavaDoc pathDepends = new ArrayList JavaDoc();
154
155     _compiler = JavaCompiler.create(_parentLoader);
156     _compiler.setClassDir(_workPath);
157
158     if (encoding == null) {
159     }
160     else if (encoding.equalsIgnoreCase("UTF-16")) {
161       // utf-16 isn't supported by some javac
162
encoding = "UTF-8";
163       _compiler.setEncoding(encoding);
164     } else {
165       _compiler.setEncoding(encoding);
166     }
167
168     int p = className.lastIndexOf('.');
169     if (p >= 0) {
170       _pkg = className.substring(0, p);
171       className = className.substring(p + 1);
172     }
173     else {
174       _pkg = "_xsl";
175       className = className;
176     }
177       
178     _className = className;
179     init((_pkg + "." + className).replace('.', '/') + ".java");
180
181     String JavaDoc fileName = (_pkg + "." + className).replace('.', '/') + ".java";
182     _path = _workPath.lookup(fileName);
183     _path.getParent().mkdirs();
184
185     _s = _path.openWrite();
186     if (encoding != null)
187       _s.setEncoding(encoding);
188     if (_s.getEncoding() == null || _s.getEncoding().equals("ISO-8859-1"))
189       _s.setEncoding("JAVA");
190     _out = new JavaWriter(_s);
191     _out.setLineMap(_lineMap);
192     
193     _matchPatterns = new ArrayList JavaDoc<AbstractPattern>();
194     _selectPatterns = new ArrayList JavaDoc<AbstractPattern>();
195
196     _modes = new ArrayList JavaDoc<String JavaDoc>();
197     _modes.add("");
198   }
199
200   protected JavaWriter getOut()
201   {
202     return _out;
203   }
204
205   public int getSelectDepth()
206   {
207     return _selectDepth;
208   }
209
210   public void setSelectDepth(int depth)
211   {
212     _selectDepth = depth;
213   }
214
215   public int pushSelectDepth()
216   {
217     return ++_selectDepth;
218   }
219
220   public int popSelectDepth()
221   {
222     return _selectDepth--;
223   }
224
225   public int getSelectLoopDepth()
226   {
227     return _selectLoopDepth;
228   }
229
230   public int pushSelectLoopDepth()
231   {
232     return ++_selectLoopDepth;
233   }
234
235   public int popSelectLoopDepth()
236   {
237     return _selectLoopDepth--;
238   }
239
240   public void setSelectLoopDepth(int depth)
241   {
242     _selectLoopDepth = depth;
243   }
244
245   public int generateId()
246   {
247     return _unique++;
248   }
249
250   public void clearUnique()
251   {
252     _unique = 0;
253   }
254     
255
256   /**
257    * Prints the generated header.
258    */

259   protected void printHeader()
260     throws IOException JavaDoc
261   {
262     if (_hasHeader)
263       return;
264     _hasHeader = true;
265     
266     println("/*");
267     println(" * Generated by " + com.caucho.Version.FULL_VERSION);
268     println(" */");
269     println();
270     println("package " + _pkg + ";");
271     println();
272     println("import java.io.*;");
273     println("import java.util.*;");
274     println("import org.w3c.dom.*;");
275     println("import org.xml.sax.*;");
276     println("import com.caucho.util.*;");
277     println("import com.caucho.xml.*;");
278     println("import com.caucho.xpath.*;");
279     println("import com.caucho.xpath.expr.*;");
280     println("import com.caucho.xpath.pattern.*;");
281     println("import com.caucho.xsl.*;");
282
283     try {
284       Class.forName("javax.servlet.Servlet");
285       println("import javax.servlet.*;");
286       println("import javax.servlet.jsp.*;");
287       println("import javax.servlet.http.*;");
288     } catch (Throwable JavaDoc e) {
289     }
290     
291     for (int i = 0; i < _imports.size(); i++)
292       println("import " + _imports.get(i) + ";");
293     println();
294
295     println("public class " + _className + " extends JavaStylesheet {");
296     pushDepth();
297
298     println("private StylesheetEnv stylesheets[];");
299   }
300   
301   protected void generateChild(Node child)
302     throws Exception JavaDoc
303   {
304     XslNode node = createChild(child);
305
306     if (node != null)
307       node.generate(_out);
308   }
309
310   protected XslNode createChild(XslNode parent, Node childNode)
311     throws Exception JavaDoc
312   {
313     XslNode xslNode = _xslNode;
314
315     _xslNode = parent;
316
317     XslNode child = createChild(childNode);
318
319     _xslNode = xslNode;
320
321     return child;
322   }
323   
324   protected XslNode createChild(Node child)
325     throws Exception JavaDoc
326   {
327     XslNode xslNode = null;
328
329     if (child instanceof QElement) {
330       QElement elt = (QElement) child;
331
332       Class JavaDoc cl = _tagMap.get(elt.getQName());
333
334       if (cl != null) {
335     xslNode = (XslNode) cl.newInstance();
336     xslNode.setGenerator(this);
337     xslNode.setParent(_xslNode);
338     
339     xslNode.setStartLocation(((QAbstractNode) child).getBaseURI(),
340                  ((QAbstractNode) child).getFilename(),
341                  ((QAbstractNode) child).getLine());
342
343     QAttr attr = (QAttr) elt.getFirstAttribute();
344     for (; attr != null; attr = (QAttr) attr.getNextSibling()) {
345       xslNode.addAttribute(attr.getQName(), attr.getNodeValue());
346     }
347
348     xslNode.endAttributes();
349
350     XslNode oldNode = _xslNode;
351     _xslNode = xslNode;
352     
353     Node node = elt.getFirstChild();
354     for (; node != null; node = node.getNextSibling()) {
355       XslNode xslChild = createChild(node);
356
357       if (xslChild != null)
358         xslNode.addChild(xslChild);
359     }
360
361     xslNode.endElement();
362
363     _xslNode = oldNode;
364       }
365       /*
366       else if (elt.getNodeName().equals("jsp:decl") ||
367            elt.getNodeName().equals("jsp:declaration") ||
368            elt.getNodeName().startsWith("jsp:directive")) {
369       }
370       */

371       else if (child.getNodeName().startsWith("xsl:") &&
372            ! XSLNS.equals(child.getNamespaceURI())) {
373     throw error(child, L.l("<{0}> has an xsl: prefix, but is not in the {1} namespace. XSL requires an xmlns:xsl=\"{1}\" namespace attribute.",
374                    child.getNodeName(),
375                    XSLNS));
376       }
377       else if (! XSLNS.equals(child.getNamespaceURI()) &&
378            ! XTPNS.equals(child.getNamespaceURI())) {
379     xslNode = new XslElementNode(elt.getQName());
380     xslNode.setGenerator(this);
381     xslNode.setParent(_xslNode);
382     
383     xslNode.setStartLocation(((QAbstractNode) child).getBaseURI(),
384                  ((QAbstractNode) child).getFilename(),
385                  ((QAbstractNode) child).getLine());
386
387     QAttr attr = (QAttr) elt.getFirstAttribute();
388     for (; attr != null; attr = (QAttr) attr.getNextSibling())
389       xslNode.addAttribute(attr.getQName(), attr.getNodeValue());
390
391     xslNode.endAttributes();
392
393     XslNode oldNode = _xslNode;
394     _xslNode = xslNode;
395     
396     Node node = elt.getFirstChild();
397     for (; node != null; node = node.getNextSibling()) {
398       XslNode xslChild = createChild(node);
399       
400       xslNode.addChild(xslChild);
401     }
402
403     xslNode.endElement();
404
405     _xslNode = oldNode;
406       }
407       else {
408     throw error(child, L.l("<{0}> is an unknown XSL tag.",
409             child.getNodeName()));
410     /*
411       XslWrapperNode wrapNode = new XslWrapperNode();
412       wrapNode.setNode(child);
413       xslNode = wrapNode;
414       xslNode.setGenerator(this);
415     */

416       }
417     }
418     else if (child instanceof Text) {
419       xslNode = new TextNode(((Text) child).getData());
420       xslNode.setGenerator(this);
421       xslNode.setParent(_xslNode);
422     }
423     else if (child instanceof Comment) {
424     }
425     else if (child instanceof ProcessingInstruction) {
426     }
427     else
428       throw new UnsupportedOperationException JavaDoc(String.valueOf(child));
429
430     if (xslNode != null) {
431       xslNode.setStartLocation(((QAbstractNode) child).getBaseURI(),
432                    ((QAbstractNode) child).getFilename(),
433                    ((QAbstractNode) child).getLine());
434     }
435
436     return xslNode;
437   }
438   
439   /**
440    * Generates code for a template
441    *
442    * @param absNode the XSL node for the emplace
443    * @param name the template name
444    * @param pattern the pattern string
445    * @param mode the template's mode
446    * @param priority the template's priority
447    */

448   protected void printTemplate(Element absNode, String JavaDoc name,
449                    String JavaDoc pattern, String JavaDoc mode, double priority)
450     throws Exception JavaDoc
451   {
452     throw new RuntimeException JavaDoc();
453     /*
454     QElement node = (QElement) absNode;
455     
456     if (name != null && ! name.equals(""))
457       addMacro(name, node);
458     
459     if (! pattern.equals("")) {
460       String fun = createTemplatePattern(name, pattern,
461                      mode, priority);
462       
463       print("// '" + pattern.replace('\n', ' ') + "'");
464       
465       if (mode != null && mode != "") {
466         if (! _modes.contains(mode))
467           _modes.add(mode);
468         println(" mode '" + mode + "'");
469       }
470       else
471         println();
472       
473       printString("// " + node.getFilename() + ":" + node.getLine());
474       println();
475       
476       println("private void " + fun +
477           "(XslWriter out, Node inputNode, Env env)");
478       println(" throws Exception");
479       println("{");
480       pushDepth();
481
482       println("Object _xsl_tmp;");
483       println("Node node = inputNode;");
484       println("int _xsl_top = env.getTop();");
485
486       if (_isRawText)
487     println("boolean oldEscaping = out.disableEscaping(true);");
488       else
489     println("boolean oldEscaping = out.disableEscaping(false);");
490
491       String filename = node.getBaseURI();
492       if (filename != null) {
493         int pos = _stylesheets.indexOf(filename);
494         if (pos < 0) {
495           pos = _stylesheets.size();
496           _stylesheets.add(filename);
497         }
498         
499         println("env.setStylesheetEnv(stylesheets[" + pos + "]);");
500       }
501
502       _selectDepth = 0;
503       _unique = 0;
504       
505       if (node.getLocalName().equals("template") ||
506       node.getLocalName().equals("xsl:template"))
507         generateChildren(node);
508       else
509         generateChild((QAbstractNode) node);
510       
511       if (! _isCacheable)
512     println("out.setNotCacheable();");
513
514       println("out.disableEscaping(oldEscaping);");
515       println("env.popToTop(_xsl_top);");
516       popDepth();
517       println("}");
518       println();
519     }
520     */

521   }
522
523   public void addMacro(String JavaDoc name, String JavaDoc functionName)
524   {
525     _macros.put(name, functionName);
526   }
527
528   /*
529   public void addMacro(String name)
530   {
531     addMacro(name, "_xsl_macro_" + toJavaIdentifier(name);
532   }
533   */

534
535   public boolean hasMacro(String JavaDoc name)
536   {
537     return _macros.keySet().contains(name);
538   }
539
540   /**
541    * Generates the pattern for a matching pattern
542    *
543    * @param name the mangled name of the function
544    * @param match the XPath match pattern
545    * @param mode the template mode
546    * @param priority the template priority
547    * @param node the source XML node from the XSL file
548    *
549    * @return the name of the function
550    */

551   public String JavaDoc createTemplatePattern(String JavaDoc name, AbstractPattern match,
552                       String JavaDoc mode, double priority)
553     throws Exception JavaDoc
554   {
555     String JavaDoc tagName;
556
557     if (name != null)
558       tagName = getName(name);
559     else
560       tagName = getName(match.toString());
561
562     String JavaDoc function = "_xsl_template_" + tagName;
563     _functions.add(function);
564
565     if (match != null) {
566       Template template = addPattern(match,
567                                      mode, priority, function,
568                                      _functions.size());
569       _templateList.add(template);
570     }
571     else
572       _templateList.add(null);
573
574     return function;
575   }
576   
577   protected void startDisableEscaping()
578     throws IOException JavaDoc
579   {
580     if (! _isRawText)
581       println("out.disableEscaping(true);");
582   }
583  
584   protected void endDisableEscaping()
585     throws IOException JavaDoc
586   {
587     if (! _isRawText)
588       println("out.disableEscaping(false);");
589   }
590
591   /**
592    * Creates Java code to print plain text.
593    */

594   protected void writeText(String JavaDoc text)
595     throws Exception JavaDoc
596   {
597     if (text == null || text.length() == 0)
598       return;
599
600     int index = _stringMap.get(text);
601     if (index < 0) {
602       index = _strings.size();
603       _stringMap.put(text, index);
604       _strings.add(text);
605     }
606
607     printLocation(_systemId, _filename, _line);
608     println("out.write(_xsl_string" + index + ", 0, " + text.length() + ");");
609   }
610
611   protected void printElement(Node node)
612     throws Exception JavaDoc
613   {
614     QElement elt = (QElement) node;
615     String JavaDoc name = node.getNodeName();
616
617     if (name.equals("jsp:decl") || name.equals("jsp:declaration")) {
618       println("if (out.isFlagFirst(" + _flagCount++ + ")) {");
619       pushDepth();
620     }
621     
622     String JavaDoc prefix = elt.getPrefix();
623     String JavaDoc local = elt.getLocalName();
624     String JavaDoc namespace = elt.getNamespaceURI();
625
626     String JavaDoc []postPrefix = (String JavaDoc []) _namespaceAliases.get(namespace);
627     if (postPrefix != null) {
628       prefix = postPrefix[0];
629       namespace = postPrefix[1];
630       if (prefix == null || prefix.equals(""))
631         name = local;
632       else
633         name = prefix + ":" + local;
634     }
635     if (_excludedNamespaces.get(namespace) != null)
636       namespace = null;
637
638     printLocation(_systemId, _filename, _line);
639     if (namespace == null || namespace.equals("")) {
640       print("out.pushElement(");
641       print(name == null ? "null" : ("\"" + name + "\""));
642       println(");");
643     } else {
644       print("out.pushElement(");
645       print(namespace == null ? "null" : ("\"" + namespace + "\""));
646       print(prefix == null ? ", null" : (", \"" + prefix + "\""));
647       print(local == null ? ", null" : (", \"" + local + "\""));
648       print(name == null ? ", null" : (", \"" + name + "\""));
649       println(");");
650     }
651     
652     printUseAttributeSet((QElement) node, false);
653     
654     NamedNodeMap list = node.getAttributes();
655     for (int i = 0; i < list.getLength(); i++) {
656       QAbstractNode attr = (QAbstractNode) list.item(i);
657
658       printAttribute(attr, elt);
659     }
660     
661     generateChildren(node);
662     
663     println("out.popElement();");
664
665     if (node.getNodeName().equals("jsp:decl") ||
666         node.getNodeName().equals("jsp:declaration")) {
667       popDepth();
668       println("}");
669     }
670   }
671
672   /**
673    * Prints a command to set the current file and line into the
674    * generated document.
675    *
676    * @param filename the source filename
677    * @param line the source line number.
678    */

679   public void printLocation(String JavaDoc systemId, String JavaDoc filename, int line)
680     throws Exception JavaDoc
681   {
682     if (_printLocation && filename != null && ! _isSpecial) {
683       print("out.setLocation(");
684       if (systemId != null) {
685     print("\"");
686     printString(systemId);
687     print("\"");
688       }
689       else
690     print("null");
691       print(", \"");
692       printString(filename);
693       println("\", " + line + ");");
694       _oldFilename = filename;
695       _oldLine = line;
696     }
697   }
698
699   /**
700    * Prints code for an element's attributes.
701    */

702   private void printAttribute(QAbstractNode attr, QElement elt)
703     throws Exception JavaDoc
704   {
705     if (attr.getNodeName().equals("xsl:use-attribute-sets")) {
706     }
707     else if (XSLNS.equals(elt.getNamespace(attr.getPrefix()))) {
708     }
709     else if (XTPNS.equals(elt.getNamespace(attr.getPrefix()))) {
710     }
711     else {
712       QAbstractNode qnode = (QAbstractNode) attr;
713       String JavaDoc prefix = qnode.getPrefix();
714       String JavaDoc local = qnode.getLocalName();
715       String JavaDoc namespace = qnode.getNamespaceURI();
716       String JavaDoc value = attr.getNodeValue();
717
718       String JavaDoc []postSuffix = (String JavaDoc []) _namespaceAliases.get(namespace);
719       if (postSuffix != null) {
720     prefix = postSuffix[0];
721     namespace = postSuffix[1];
722       }
723
724       else if (value.equals(XSLNS) && prefix.equals("xmlns"))
725         return;
726       else if (value.equals(XTPNS) && prefix.equals("xmlns"))
727         return;
728
729       if (_excludedNamespaces.get(namespace) != null)
730     namespace = null;
731       
732       if ("".equals(prefix) && ("".equals(namespace) || namespace == null)) {
733         String JavaDoc var = generateStringVar(value, elt);
734         println("out.setAttribute(\"" + local + "\", " + var + ");");
735       }
736       else {
737         print("out.pushAttribute(");
738         print(prefix == null ? "null" : ("\"" + prefix + "\""));
739         print(local == null ? ", null" : (", \"" + local + "\""));
740         print(namespace == null ? ", null" : (", \"" + namespace + "\""));
741         println(");");
742         generateString(value, ',', elt);
743         println("out.popAttribute();");
744       }
745     }
746   }
747
748   protected void pushCall()
749     throws IOException JavaDoc
750   {
751     println("{");
752     pushDepth();
753     _callDepth++;
754     println("Env _xsl_arg" + _callDepth + " = XPath.createCall(env);");
755   }
756
757   public int pushCallDepth()
758   {
759     return ++_callDepth;
760   }
761
762   public int popCallDepth()
763   {
764     return _callDepth--;
765   }
766
767   public int getCallDepth()
768   {
769     return _callDepth;
770   }
771
772   protected void popCall()
773     throws IOException JavaDoc
774   {
775     //println("_xsl_arg" + callDepth + ".free();");
776
_callDepth--;
777     popDepth();
778     println("}");
779   }
780
781   /**
782    * Prints code for xsl:apply-templates
783    *
784    * @param select the select pattern
785    * @param mode the template mode
786    * @param sort the sort expressions
787    */

788   protected void printApplyTemplates(AbstractPattern select,
789                                      String JavaDoc mode,
790                                      Sort []sort)
791     throws Exception JavaDoc
792   {
793     int min = 0;
794     int max = Integer.MAX_VALUE;
795
796     String JavaDoc applyName = "applyNode" + getModeName(mode);
797     String JavaDoc env = "_xsl_arg" + _callDepth;
798
799     if (select == null && sort == null) {
800       println("for (Node _xsl_node = node.getFirstChild();");
801       println(" _xsl_node != null;");
802       println(" _xsl_node = _xsl_node.getNextSibling()) {");
803       println(" " + env + ".setSelect(node, null);");
804       println(" " + env + ".setCurrentNode(_xsl_node);");
805       println(" " + applyName + "(out, _xsl_node, " + env + ", " +
806               min + ", " + max + ");");
807       println("}");
808     }
809     else if (sort == null) {
810       int oldSelectDepth = _selectDepth;
811       println(env + ".setSelect(node, _select_patterns[" +
812               addSelect(select) + "]);");
813
814       String JavaDoc name = printSelectBegin(select, false, null);
815
816       println(env + ".setCurrentNode(" + name + ");");
817
818       println(applyName + "(out, " + name + ", " + env + ", " +
819               min + ", " + max + ");");
820
821       for (; _selectDepth > oldSelectDepth; _selectDepth--) {
822         popDepth();
823         println("}");
824       }
825     }
826     else {
827       println("{");
828       pushDepth();
829       println("ArrayList _xsl_list = xslSort(node, env" +
830           ", _select_patterns[" + addSelect(select) + "]" +
831           ", _xsl_sorts[" + _sorts.size() + "]);");
832       println(env + ".setContextSize(_xsl_list.size());");
833       println("for (int _xsl_i = 0; _xsl_i < _xsl_list.size(); _xsl_i++) {");
834       println(" " + env + ".setContextPosition(_xsl_i + 1);");
835       println(" " + applyName + "(out, (Node) _xsl_list.get(_xsl_i)" +
836           ", " + env + ", " + min + ", " + max + ");");
837       println("}");
838       popDepth();
839       println("}");
840
841       _sorts.add(sort);
842     }
843   }
844
845   public int addSort(Sort []sort)
846   {
847     int index = _sorts.size();
848     
849     _sorts.add(sort);
850
851     return index;
852   }
853
854   /**
855    * Prints code to implement xsl:apply-imports
856    *
857    * @param mode the mode of the imported files
858    * @param min the min importance
859    * @param max the max importance
860    */

861   protected void printApplyImports(String JavaDoc mode, int min, int max)
862     throws Exception JavaDoc
863   {
864   }
865
866   protected void printCallTemplate(String JavaDoc name, String JavaDoc mode)
867     throws Exception JavaDoc
868   {
869     println(getMacroName(name) + "(out, node, _xsl_arg" +
870             _callDepth + ");");
871   }
872
873   public String JavaDoc getMacroName(String JavaDoc name)
874   {
875     return _macros.get(name);
876     //return "_xsl_macro_" + toJavaIdentifier(name);
877
}
878
879   /**
880    * Prints the value for a parameter.
881    */

882   protected void printParam(String JavaDoc name, String JavaDoc value, Element elt)
883     throws Exception JavaDoc
884   {
885     print("_xsl_arg" + _callDepth + ".addVar(\"" + name + "\", ");
886     generateString(value, '+', elt);
887     println(");");
888   }
889   
890   protected void printParam(String JavaDoc name, Object JavaDoc value)
891     throws Exception JavaDoc
892   {
893     if (value instanceof Expr) {
894       print("_exprs[" + addExpr((Expr) value) + "]");
895       println(".addVar(_xsl_arg" + _callDepth + ", \"" + name + "\", " +
896               "node, env);");
897     }
898     else {
899       print("_xsl_arg" + _callDepth + ".addVar(\"");
900       print(name);
901       print("\", ");
902       printVariableValue(value);
903       println(");");
904     }
905   }
906
907   /**
908    * Prints code to add the value of an expression as a parameter.
909    */

910   protected void printParamVariable(String JavaDoc name, Expr value)
911     throws Exception JavaDoc
912   {
913     print("_exprs[" + addExpr(value) + "]");
914     println(".addParam(env, \"" + name + "\", " +
915             "node, env);");
916   }
917
918   protected void printParamVariable(String JavaDoc name, Element value)
919     throws Exception JavaDoc
920   {
921     if (value.getFirstChild() != null) {
922       println("_xsl_tmp = env.getVar(\"" + name + "\");");
923       println("if (_xsl_tmp == null)");
924       print(" _xsl_tmp = ");
925       printVariableValue(value);
926       println(";");
927       println("env.addVar(\"" + name + "\", _xsl_tmp);");
928     }
929   }
930
931   protected void printVariable(String JavaDoc name, Object JavaDoc value)
932     throws Exception JavaDoc
933   {
934     if (value instanceof Expr) {
935       print("_exprs[" + addExpr((Expr) value) + "]");
936       println(".addVar(env, \"" + name + "\", node, env);");
937     }
938     else {
939       print("env.addVar(\"");
940       print(name);
941       print("\", ");
942       printVariableValue(value);
943       println(");");
944     }
945   }
946
947   protected void printAssign(String JavaDoc name, Object JavaDoc value)
948     throws Exception JavaDoc
949   {
950     if (value instanceof Expr) {
951       print("_exprs[" + addExpr((Expr) value) + "]");
952       println(".setVar(\"" + name + "\", node, env, node);");
953     }
954     else {
955       print("env.setVar(\"");
956       print(name);
957       print("\", ");
958       printVariableValue(value);
959       println(");");
960     }
961   }
962
963   private void printVariableValue(Object JavaDoc value)
964     throws Exception JavaDoc
965   {
966     if (value instanceof Expr) {
967       print("_exprs[" + addExpr((Expr) value) + "].evalObject(node, env)");
968     }
969     else if (value instanceof Node) {
970       print("_xsl_fragment" + _fragments.size() + "(out, node, env)");
971       _fragments.add(value);
972     }
973     else
974       throw new RuntimeException JavaDoc();
975   }
976
977   protected void printPopScope(int count)
978     throws Exception JavaDoc
979   {
980     if (count > 0)
981       println("env.popVars(" + count + ");");
982   }
983
984   protected void printCopyOf(String JavaDoc select, Element elt)
985     throws Exception JavaDoc
986   {
987     println("out.copyOf(_exprs[ " + addExpr(select) +
988             "].evalObject(node, env));");
989   }
990
991   protected void printSelectValue(String JavaDoc select, Element elt)
992     throws Exception JavaDoc
993   {
994     printStringExpr(select, elt);
995   }
996
997   protected void printForEach(Element element, String JavaDoc select)
998     throws Exception JavaDoc
999   {
1000    println("{");
1001    pushDepth();
1002
1003    AbstractPattern selectPattern = null;
1004    try {
1005      selectPattern = parseSelect(select);
1006    } catch (Exception JavaDoc e) {
1007    }
1008    
1009    boolean hasExprEnv = ! allowJavaSelect(selectPattern);
1010
1011    int id = _unique++;
1012    
1013    String JavaDoc sel = "_xsl_sel" + id;
1014    String JavaDoc oldCxt = "_xsl_cxt" + id;
1015    String JavaDoc oldCur = "_xsl_cur" + id;
1016    String JavaDoc oldSel = "_xsl_old_sel" + id;
1017    String JavaDoc oldEnv = "_xsl_env" + id;
1018
1019    println("com.caucho.xpath.pattern.AbstractPattern " + sel + ";");
1020    print(sel + " = _select_patterns[");
1021    print(createNodeSet(select, element));
1022    println("];");
1023    println("Node " + oldCxt + " = env.getContextNode();");
1024    println("Node " + oldCur + " = env.getCurrentNode();");
1025    
1026    if (! hasExprEnv) {
1027      println("AbstractPattern " + oldSel + " = env.setSelect(node, " + sel + ");");
1028    }
1029    
1030    
1031    // String pos = "_xsl_pos" + unique++;
1032
String JavaDoc iter = "_xsl_iter" + _unique++;
1033
1034    int oldSelectDepth = _selectDepth;
1035    
1036    // println("int " + pos + " = 0;");
1037

1038    boolean hasEnv = false;
1039    
1040    if (allowJavaSelect(selectPattern)) {
1041      println("ExprEnvironment " + oldEnv + " = env.setExprEnv(null);");
1042      
1043      String JavaDoc ptr = printSelectBegin(selectPattern, true, null);
1044
1045      pushLoop();
1046      println("Node " + getElement() + " = node;");
1047      println("node = " + ptr + ";");
1048    }
1049    else {
1050      print("NodeIterator " + iter + " = " + sel);
1051      println(".select(node, " + getEnv() + ");");
1052      println("ExprEnvironment " + oldEnv + " = env.setExprEnv(" + iter + ");");
1053      println("while (" + iter + ".hasNext()) {");
1054      pushDepth();
1055      _selectDepth++;
1056      
1057      pushLoop();
1058      
1059      println("Node " + getElement() + " = node;");
1060      println("node = " + iter + ".nextNode();");
1061      
1062    }
1063    println("env.setCurrentNode(node);");
1064    
1065    // println(pos + "++;");
1066

1067    // String oldPos = currentPos;
1068
// currentPos = pos;
1069

1070    AbstractPattern oldNodeListContext = _nodeListContext;
1071    _nodeListContext = parseMatch(select);
1072
1073    generateChildren(element);
1074
1075    _nodeListContext = oldNodeListContext;
1076    
1077    // currentPos = oldPos;
1078

1079    println("node = " + getElement() + ";");
1080    println("env.setCurrentNode(" + oldCur + ");");
1081    
1082    for (; _selectDepth > oldSelectDepth; _selectDepth--) {
1083      popDepth();
1084      println("}");
1085    }
1086    
1087    println("env.setExprEnv(" + oldEnv + ");");
1088    
1089    if (! hasExprEnv) {
1090      println("env.setSelect(" + oldCxt + ", " + oldSel + ");");
1091    //println("env.setCurrentNode(node);");
1092
}
1093    
1094    popDepth();
1095    println("}");
1096    popLoop();
1097  }
1098
1099  /**
1100   * Prints code for xsl:for-each when the for-each has any xsl:sort.
1101   */

1102  protected void printForEach(Element element, String JavaDoc select, Sort []sort)
1103    throws Exception JavaDoc
1104  {
1105    println("{");
1106    pushDepth();
1107    println("env.setCurrentNode(node);");
1108    String JavaDoc pos = "_xsl_pos" + _unique++;
1109    String JavaDoc list = "_xsl_list" + _unique++;
1110    
1111    println("ArrayList " + list +
1112        " = xslSort(node, env" +
1113        ", _select_patterns[" + addSelect(select) + "]" +
1114        ", _xsl_sorts[" + _sorts.size() + "]);");
1115    println("env.setContextSize(" + list + ".size());");
1116    println("for (int " + pos + " = 1; " + pos +
1117        " <= " + list + ".size(); " + pos + "++) {");
1118    pushLoop();
1119    pushDepth();
1120    println("Node " + getElement() + " = node;");
1121    println("node = (Node) " + list + ".get(" + pos + " - 1);");
1122
1123    String JavaDoc oldPos = _currentPos;
1124    _currentPos = pos;
1125    
1126    println("env.setPosition(" + _currentPos + ");");
1127    
1128    _sorts.add(sort);
1129    
1130    AbstractPattern oldNodeListContext = _nodeListContext;
1131    _nodeListContext = parseMatch(select);
1132
1133    generateChildren(element);
1134
1135    _currentPos = oldPos;
1136
1137    _nodeListContext = oldNodeListContext;
1138    
1139    println("node = " + getElement() + ";");
1140    
1141    popDepth();
1142    println("}");
1143    popLoop();
1144    popDepth();
1145    println("}");
1146  }
1147
1148  public String JavaDoc getCurrentPosition()
1149  {
1150    return _currentPos;
1151  }
1152
1153  public void setCurrentPosition(String JavaDoc pos)
1154  {
1155    _currentPos = pos;
1156  }
1157
1158  public AbstractPattern getNodeListContext()
1159  {
1160    return _nodeListContext;
1161  }
1162
1163  public void setNodeListContext(AbstractPattern context)
1164  {
1165    _nodeListContext = context;
1166  }
1167
1168  protected void printIf(Element element, Expr test)
1169    throws Exception JavaDoc
1170  {
1171    print("if (");
1172    printExprTest(test, "node");
1173    println(") {");
1174    pushDepth();
1175    generateChildren(element);
1176    popDepth();
1177    println("}");
1178  }
1179
1180  protected void printChoose(Element element, Expr expr, boolean first)
1181    throws Exception JavaDoc
1182  {
1183    if (! first)
1184      print("else if (");
1185    else
1186      print("if (");
1187    printExprTest(expr, "node");
1188    println(") {");
1189    pushDepth();
1190    generateChildren(element);
1191    popDepth();
1192    println("}");
1193  }
1194
1195  protected void printOtherwise(Element element, boolean first)
1196    throws Exception JavaDoc
1197  {
1198    if (! first)
1199      print("else ");
1200    println("{");
1201    pushDepth();
1202    generateChildren(element);
1203    popDepth();
1204    println("}");
1205  }
1206
1207  void printNumber(Expr expr, XslNumberFormat format)
1208    throws Exception JavaDoc
1209  {
1210    print("exprNumber(out, node, env, _exprs[" + addExpr(expr) + "]");
1211    print(", _xsl_formats[" + _formats.size() + "]");
1212    println(");");
1213
1214    _formats.add(format);
1215  }
1216
1217  void printNumber(String JavaDoc level,
1218                   AbstractPattern countPattern,
1219                   AbstractPattern fromPattern,
1220           XslNumberFormat format)
1221    throws Exception JavaDoc
1222  {
1223    if (level.equals("single"))
1224      print("singleNumber(out, ");
1225    else if (level.equals("multiple"))
1226      print("multiNumber(out, ");
1227    else if (level.equals("any"))
1228      print("anyNumber(out, ");
1229    else
1230      throw error("xsl:number cannot understand level=`" + level + "'");
1231
1232    print("node, env, ");
1233    printPattern(countPattern);
1234    print(", ");
1235    printPattern(fromPattern);
1236    print(", _xsl_formats[" + _formats.size() + "]");
1237    println(");");
1238
1239    _formats.add(format);
1240  }
1241
1242  public int addFormat(XslNumberFormat format)
1243  {
1244    int index = _formats.size();
1245
1246    _formats.add(format);
1247
1248    return index;
1249  }
1250
1251  protected void printCopy(Element element)
1252    throws Exception JavaDoc
1253  {
1254    println("out.pushCopy(node);");
1255    printUseAttributeSet(element, true);
1256    generateChildren(element);
1257    println("out.popCopy(node);");
1258  }
1259
1260  protected void printResultDocument(Element element, String JavaDoc href, String JavaDoc format)
1261    throws Exception JavaDoc
1262  {
1263    println("XslWriter oldOut = out;");
1264    println("OutputStream os = null;");
1265    println("try {");
1266    pushDepth();
1267    print("os = out.openWrite(env, ");
1268    generateString(href, '+', element);
1269    println(");");
1270
1271    println("out = out.openResultDocument(os);");
1272    generateChildren(element);
1273    println("out.close();");
1274    popDepth();
1275    println("} finally {");
1276    println(" if (os != null)");
1277    println(" os.close();");
1278    println(" out = oldOut;");
1279    println("}");
1280  }
1281
1282  protected void printElement(Element element, String JavaDoc name)
1283    throws Exception JavaDoc
1284  {
1285    print("out.pushElement(");
1286    generateString(name, '+', element);
1287    if (_namespace != null) {
1288      print(", ");
1289      printNamespace(_namespace);
1290    }
1291    println(");");
1292    printUseAttributeSet(element, true);
1293    generateChildren(element);
1294    println("out.popElement();");
1295  }
1296
1297  protected void printElement(Element element, String JavaDoc name, String JavaDoc namespace)
1298    throws Exception JavaDoc
1299  {
1300    print("out.pushElementNs(");
1301    generateString(name, '+', element);
1302    print(", ");
1303    generateString(namespace, '+', element);
1304    println(");");
1305    printUseAttributeSet(element, true);
1306    generateChildren(element);
1307    print("out.popElement();");
1308  }
1309
1310  /**
1311   * Prints the attributes in a use-attribute-set.
1312   */

1313  private void printUseAttributeSet(Element element, boolean isXSL)
1314    throws Exception JavaDoc
1315  {
1316    Attr attr = (Attr) ((QElement) element).getFirstAttribute();
1317    for (; attr != null; attr = (Attr) attr.getNextSibling()) {
1318      if (isXSL && attr.getNodeName().equals("use-attribute-sets") ||
1319          ! isXSL && attr.getNodeName().equals("xsl:use-attribute-sets")) {
1320    HashMap JavaDoc set = getAttributeSet(attr.getNodeValue());
1321    if (set == null)
1322      continue;
1323    Iterator JavaDoc iter = set.keySet().iterator();
1324    while (iter.hasNext()) {
1325      String JavaDoc key = (String JavaDoc) iter.next();
1326      String JavaDoc value = (String JavaDoc) set.get(key);
1327          
1328          printAttributeValue(key, value, element);
1329    }
1330      }
1331    }
1332  }
1333
1334  /**
1335   * Returns the named attribute set.
1336   */

1337  public HashMap JavaDoc<String JavaDoc,String JavaDoc> getAttributeSet(String JavaDoc name)
1338  {
1339    CharBuffer cb = CharBuffer.allocate();
1340    int i = 0;
1341    int len = name.length();
1342
1343    HashMap JavaDoc<String JavaDoc,String JavaDoc> map = new HashMap JavaDoc<String JavaDoc,String JavaDoc>();
1344    
1345    while (i < len) {
1346      for (; i < len && name.charAt(i) == ' '; i++) {
1347      }
1348
1349      cb.clear();
1350      for (; i < len && name.charAt(i) != ' '; i++)
1351        cb.append(name.charAt(i));
1352
1353      if (cb.length() > 0) {
1354        XslAttributeSet newSet = _attributeSets.get(cb.toString());
1355
1356        if (newSet != null) {
1357      ArrayList JavaDoc<XslAttribute> attrList = newSet.getAttributes();
1358
1359      for (int j = 0; j < attrList.size(); j++) {
1360        XslAttribute attr = attrList.get(j);
1361
1362        map.put(attr.getName(), attr.getValue());
1363          }
1364        }
1365      }
1366    }
1367
1368    return map;
1369  }
1370
1371  /**
1372   * Returns the named attribute set.
1373   */

1374  public ArrayList JavaDoc<XslAttribute> getAttributeSetList(String JavaDoc name)
1375  {
1376    CharBuffer cb = CharBuffer.allocate();
1377    int i = 0;
1378    int len = name.length();
1379
1380    ArrayList JavaDoc<XslAttribute> set = new ArrayList JavaDoc<XslAttribute>();
1381    
1382    while (i < len) {
1383      for (; i < len && name.charAt(i) == ' '; i++) {
1384      }
1385
1386      cb.clear();
1387      for (; i < len && name.charAt(i) != ' '; i++)
1388        cb.append(name.charAt(i));
1389
1390      if (cb.length() > 0) {
1391        XslAttributeSet newSet = _attributeSets.get(cb.toString());
1392
1393        if (newSet != null) {
1394      set.addAll(newSet.getAttributes());
1395        }
1396      }
1397    }
1398
1399    return set;
1400  }
1401
1402  /**
1403   * Prints an xsl:attribute
1404   */

1405  protected void printAttribute(Element element, String JavaDoc name)
1406    throws Exception JavaDoc
1407  {
1408    print("out.pushAttribute(");
1409    generateString(name, '+', element);
1410    
1411    if (_namespace != null) {
1412      print(", ");
1413      printNamespace(_namespace);
1414    }
1415    
1416    println(");");
1417      
1418    generateChildren(element);
1419    println("out.popAttribute();");
1420  }
1421
1422  /**
1423   * Prints a single attribute value.
1424   */

1425  private void printAttributeValue(String JavaDoc key, String JavaDoc value, Element elt)
1426    throws Exception JavaDoc
1427  {
1428    if (_namespace == null && ! attributeHasSpecial(key) &&
1429        ! attributeHasSpecial(value)) {
1430      print("out.setAttribute(");
1431      generateString(key, '+', elt);
1432      print(", ");
1433      generateString(value, '+', elt);
1434      println(");");
1435    }
1436    else {
1437      print("out.pushAttribute(");
1438      generateString(key, '+', elt);
1439      if (_namespace != null) {
1440        print(", ");
1441        printNamespace(_namespace);
1442      }
1443      println(");");
1444      generateString(value, ',', elt);
1445      println("out.popAttribute();");
1446    }
1447  }
1448
1449  public void printNamespace(NamespaceContext namespace)
1450    throws Exception JavaDoc
1451  {
1452    for (int i = 0; i < _namespaces.size(); i++) {
1453      if (_namespaces.get(i).equals(namespace)) {
1454        print("_namespaces[" + i + "]");
1455        return;
1456      }
1457    }
1458    
1459    print("_namespaces[" + _namespaces.size() + "]");
1460    _namespaces.add(namespace);
1461  }
1462
1463  public int addNamespace(NamespaceContext namespace)
1464    throws Exception JavaDoc
1465  {
1466    for (int i = 0; i < _namespaces.size(); i++) {
1467      if (_namespaces.get(i).equals(namespace)) {
1468    return i;
1469      }
1470    }
1471    
1472    _namespaces.add(namespace);
1473
1474    return _namespaces.size() - 1;
1475  }
1476
1477  protected void printAttribute(Element element, String JavaDoc name, String JavaDoc namespace)
1478    throws Exception JavaDoc
1479  {
1480    print("out.pushAttributeNs(");
1481    generateString(name, '+', element);
1482    print(", ");
1483    generateString(namespace, '+', element);
1484    println(");");
1485    generateChildren(element);
1486    println("out.popAttribute();");
1487  }
1488
1489  protected void printPi(Element element)
1490    throws Exception JavaDoc
1491  {
1492    String JavaDoc name = element.getAttribute("name");
1493    if (name.equals(""))
1494      throw error("xsl:pi expected `name' attribute.");
1495
1496    print("out.pushPi();");
1497    
1498    generateChildren(element);
1499    println("out.popPi(");
1500    generateString(name, '+', element);
1501    println(");");
1502  }
1503
1504  protected void printComment(Element element)
1505    throws Exception JavaDoc
1506  {
1507    println("out.pushComment();");
1508    generateChildren(element);
1509    println("out.popComment();");
1510  }
1511
1512  protected void printError(String JavaDoc msg)
1513    throws Exception JavaDoc
1514  {
1515    println("if (true) throw new javax.xml.transform.TransformerException(\"" + msg + "\");");
1516  }
1517
1518  protected void printMessage(Element msg)
1519    throws Exception JavaDoc
1520  {
1521    int unique = _unique++;
1522    
1523    println("XMLWriter frag" + unique + " = out.pushFragment();");
1524    generateChildren(msg);
1525
1526    String JavaDoc terminate = msg.getAttribute("terminate");
1527    if (terminate.equals("yes"))
1528      println("if (true) throw new javax.xml.transform.TransformerException(((QAbstractNode) out.popFragment(frag" + unique + ")).getTextValue());");
1529    else
1530      println("System.err.println(((QAbstractNode) out.popFragment(frag" + unique + ")).getTextValue());");
1531  }
1532
1533  /**
1534   * Prints code to implement the xtp:expression tag, i.e. print
1535   * the value of the Java expression.
1536   */

1537  protected void printExpression(Element element)
1538    throws Exception JavaDoc
1539  {
1540    String JavaDoc expr = element.getAttribute("expr");
1541
1542    if (! expr.equals("")) {
1543      print("out.print(");
1544      print(expr);
1545      println(");");
1546    }
1547    else {
1548      print("out.print(");
1549      print(((QAbstractNode) element).getTextValue());
1550      println(");");
1551    }
1552  }
1553
1554  protected void printScriptlet(Element element)
1555    throws Exception JavaDoc
1556  {
1557    println(((QAbstractNode) element).getTextValue());
1558  }
1559
1560  protected void printWhile(Element element, Expr test)
1561    throws Exception JavaDoc
1562  {
1563    print("while (");
1564    printExprTest(test, "node");
1565    println(") {");
1566    pushDepth();
1567    generateChildren(element);
1568    popDepth();
1569    println("}");
1570  }
1571
1572  protected void printDeclaration(Element element)
1573    throws Exception JavaDoc
1574  {
1575    println(((QAbstractNode) element).getTextValue());
1576  }
1577
1578  protected void printCacheDepends(String JavaDoc name)
1579    throws Exception JavaDoc
1580  {
1581    print("out.addCacheDepend(((com.caucho.vfs.Path) out.getProperty(\"caucho.pwd\")).lookup(\"");
1582    printString(name);
1583    println("\"));");
1584  }
1585
1586  public String JavaDoc getElement()
1587  {
1588    return "node" + _loopDepth;
1589  }
1590
1591  public void pushLoop()
1592  {
1593    _loopDepth++;
1594  }
1595
1596  public void popLoop()
1597  {
1598    _loopDepth--;
1599  }
1600
1601  public String JavaDoc getEnv()
1602  {
1603    return "env";
1604  }
1605
1606  void pushEnv()
1607  {
1608    _envDepth.add(0);
1609  }
1610
1611  void popEnv()
1612  {
1613    _envDepth.pop();
1614  }
1615
1616  void printPattern(AbstractPattern pattern)
1617    throws Exception JavaDoc
1618  {
1619    if (pattern == null)
1620      print("null");
1621    else {
1622      print("_match_patterns[" + _matchPatterns.size() + "]");
1623      _matchPatterns.add(pattern);
1624    }
1625  }
1626
1627  private int createNodeSet(String JavaDoc select, Element element)
1628    throws Exception JavaDoc
1629  {
1630    return addSelect(select);
1631  }
1632  
1633  int createSelectPattern(AbstractPattern pattern)
1634    throws Exception JavaDoc
1635  {
1636    return addSelect(pattern);
1637  }
1638
1639  int createMatchPattern(String JavaDoc select, Element element)
1640    throws Exception JavaDoc
1641  {
1642    AbstractPattern pattern = parseMatch(select);
1643
1644    _matchPatterns.add(pattern);
1645
1646    return _matchPatterns.size() - 1;
1647  }
1648
1649  String JavaDoc getName(String JavaDoc tag)
1650  {
1651    CharBuffer newTag = new CharBuffer();
1652
1653    for (int i = 0; i < tag.length(); i++) {
1654      int ch = tag.charAt(i);
1655      switch (ch) {
1656      case ' ':
1657      case '\t':
1658      case '\r':
1659      case '\n':
1660      case '(':
1661      case ')':
1662    break;
1663
1664      case ':':
1665      case '.':
1666      case '|':
1667    newTag.append('_');
1668    break;
1669
1670      default:
1671    if (ch >= 'a' && ch <= 'z' ||
1672        ch >= 'A' && ch <= 'Z' ||
1673        ch >= '0' && ch <= '9')
1674      newTag.append((char) ch);
1675      }
1676    }
1677    tag = newTag.toString();
1678
1679    if (_names.get(tag) == null) {
1680      _names.put(tag, tag);
1681      return tag;
1682    }
1683
1684    int i = 0;
1685    while (true) {
1686      String JavaDoc subname = tag + i;
1687      if (_names.get(subname) == null) {
1688    _names.put(subname, subname);
1689    return subname;
1690      }
1691
1692      i++;
1693    }
1694  }
1695
1696  void printExprTest(Expr expr, String JavaDoc element)
1697    throws Exception JavaDoc
1698  {
1699    print("_exprs[" + addExpr(expr) + "].evalBoolean(" + element +
1700      ", " + getEnv() + ")");
1701  }
1702
1703  public void printExprTest(int exprId, String JavaDoc element)
1704    throws Exception JavaDoc
1705  {
1706    print("_exprs[" + exprId + "].evalBoolean(" + element +
1707      ", " + getEnv() + ")");
1708  }
1709
1710  private boolean attributeHasSpecial(String JavaDoc string)
1711  {
1712    int length = string.length();
1713    
1714    for (int i = 0; i < length; i++) {
1715      char ch = string.charAt(i);
1716
1717      if (ch == '{' && i + 1 < length) {
1718    // {{ is treated as a single {
1719
if (string.charAt(i + 1) == '{') {
1720      i++;
1721          continue;
1722    }
1723
1724        return true;
1725      }
1726      // <#= interpolates
1727
else if (i + 2 < length && ch == '<' &&
1728           string.charAt(i + 1) == '#' &&
1729           string.charAt(i + 2) == '=')
1730        return true;
1731    }
1732
1733    return false;
1734  }
1735
1736  /**
1737   * Produces code to generate an attribute value template. The same
1738   * code is used to produce a string ('a{b}c' -> "a" + b + "c") or a series of
1739   * print statements (',').
1740   *
1741   * @param string the source template
1742   * @param mode separator: either '+' or ','
1743   * @param elt the containing element. Needed for namespaces.
1744   */

1745  void generateString(String JavaDoc string, int mode, Element elt)
1746    throws Exception JavaDoc
1747  {
1748    CharBuffer cb = new CharBuffer();
1749    int i = 0;
1750    boolean first = true;
1751    int length = string.length();
1752
1753    for (; i < length; i++) {
1754      char ch = string.charAt(i);
1755
1756      if (ch == '\n') {
1757    cb.append("\\n");
1758      }
1759      else if (ch == '"') {
1760    cb.append("\\\"");
1761      }
1762      else if (ch == '{' && i + 1 < length) {
1763    // {{ is treated as a single {
1764
if (string.charAt(i + 1) == '{') {
1765      cb.append('{');
1766      i++;
1767    }
1768    // the value is computed from an XPath expr
1769
else {
1770      // print the gathered text if any
1771
if (mode == ',') {
1772        if (cb.length() > 0)
1773          println("out.print(\"" + cb.toString() + "\");");
1774      }
1775      else {
1776        if (! first)
1777          print((char) mode);
1778
1779        if (cb.length() > 0) {
1780          print("\"");
1781          print(cb.toString());
1782          print("\"");
1783          print((char) mode);
1784        }
1785      }
1786
1787      // scan the contents of '{' ... '}'
1788
cb.clear();
1789      for (i++; i < length && string.charAt(i) != '}'; i++)
1790        cb.append(string.charAt(i));
1791
1792      // and add the results
1793
if (mode == ',')
1794        printStringExpr(cb.toString(), elt);
1795      else
1796        stringExpr(cb.toString(), elt);
1797      cb.clear();
1798      first = false;
1799    }
1800      }
1801      // }} is treated as a single }
1802
else if (ch == '}' && i + 1 < length) {
1803    if (string.charAt(i + 1) == '}') {
1804      cb.append('}');
1805      i++;
1806    }
1807    else
1808      cb.append('}');
1809      }
1810      // <#= interpolates
1811
else if (i + 2 < length && ch == '<' &&
1812           string.charAt(i + 1) == '#' &&
1813           string.charAt(i + 2) == '=') {
1814    // print the gathered text if any
1815
if (mode == ',') {
1816      if (cb.length() > 0)
1817        println("out.print(\"" + cb.toString() + "\");");
1818    }
1819    else {
1820      if (! first)
1821        print((char) mode);
1822
1823      if (cb.length() > 0) {
1824        print("\"");
1825        print(cb.toString());
1826        print("\"");
1827        print((char) mode);
1828      }
1829    }
1830
1831    // scan the contents of '{' ... '}'
1832
cb.clear();
1833    for (i += 3;
1834         i + 1 < length && string.charAt(i) != '#' &&
1835           string.charAt(i + 1) != '>';
1836         i++)
1837      cb.append(string.charAt(i));
1838
1839    i++;
1840    
1841    // and add the results
1842
if (mode == ',')
1843      println("out.print(" + cb + ");");
1844    else {
1845      print("(" + cb + ")");
1846    }
1847    cb.clear();
1848    first = false;
1849      }
1850      else
1851    cb.append((char) ch);
1852    }
1853
1854    // add any trailing text
1855
if (cb.length() > 0) {
1856      if (mode == ',')
1857    println("out.print(\"" + cb + "\");");
1858      else {
1859    if (! first)
1860      print((char) mode);
1861
1862    print("\"" + cb + "\"");
1863      }
1864    } else if (first && mode == '+')
1865      print("\"\"");
1866  }
1867
1868  /**
1869   * Produces code to generate an attribute value template. The same
1870   * code is used to produce a string ('a{b}c' -> "a" + b + "c") or a series of
1871   * print statements (',').
1872   *
1873   * @param string the source template
1874   * @param elt the containing element. Needed for namespaces.
1875   *
1876   * @return the variable storing the generated string.
1877   */

1878  String JavaDoc generateStringVar(String JavaDoc string, Element elt)
1879    throws Exception JavaDoc
1880  {
1881    CharBuffer cb = new CharBuffer();
1882    int i = 0;
1883    boolean first = true;
1884    int length = string.length();
1885
1886    String JavaDoc strVar = "_xsl_str" + _unique++;
1887
1888    if (string.indexOf('{') < 0 &&
1889        string.indexOf('}') < 0) {
1890      print("String " + strVar + " = \"");
1891      printString(string);
1892      println("\";");
1893      
1894      return strVar;
1895    }
1896    else if (string.lastIndexOf('{') == 0 &&
1897        string.indexOf('}') == string.length() - 1) {
1898      println("String " + strVar + " = \"\";");
1899      string = string.substring(1, string.length() - 1);
1900      
1901      addStringExpr(strVar, string, elt, true);
1902      return strVar;
1903    }
1904
1905    
1906    String JavaDoc cbVar = "_xsl_cb" + _unique++;
1907
1908    println("com.caucho.util.CharBuffer " + cbVar +
1909            " = com.caucho.util.CharBuffer.allocate();");
1910
1911    for (; i < length; i++) {
1912      char ch = string.charAt(i);
1913
1914      if (ch == '\n') {
1915    cb.append("\\n");
1916      }
1917      else if (ch == '"') {
1918    cb.append("\\\"");
1919      }
1920      else if (ch == '{' && i + 1 < length) {
1921    // {{ is treated as a single {
1922
if (string.charAt(i + 1) == '{') {
1923      cb.append('{');
1924      i++;
1925    }
1926    // the value is computed from an XPath expr
1927
else {
1928      // print the gathered text if any
1929
if (cb.length() > 0)
1930            println(cbVar + ".append(\"" + cb.toString() + "\");");
1931
1932      // scan the contents of '{' ... '}'
1933
cb.clear();
1934      for (i++; i < length && string.charAt(i) != '}'; i++)
1935        cb.append(string.charAt(i));
1936
1937      // and add the results
1938
addStringExpr(cbVar, cb.toString(), elt, false);
1939          
1940      cb.clear();
1941      first = false;
1942    }
1943      }
1944      // }} is treated as a single }
1945
else if (ch == '}' && i + 1 < length) {
1946    if (string.charAt(i + 1) == '}') {
1947      cb.append('}');
1948      i++;
1949    }
1950    else
1951      cb.append('}');
1952      }
1953      // <#= interpolates
1954
else if (i + 2 < length && ch == '<' &&
1955           string.charAt(i + 1) == '#' &&
1956           string.charAt(i + 2) == '=') {
1957    // print the gathered text if any
1958
if (cb.length() > 0)
1959          println(cbVar + ".append(\"" + cb.toString() + "\");");
1960
1961    // scan the contents of '<#=' ... '#>'
1962
cb.clear();
1963    for (i += 3;
1964         i + 1 < length && string.charAt(i) != '#' &&
1965           string.charAt(i + 1) != '>';
1966         i++)
1967      cb.append(string.charAt(i));
1968
1969    i++;
1970    
1971    // and add the results
1972
println(cbVar + ".append(" + cb + ");");
1973    cb.clear();
1974    first = false;
1975      }
1976      else
1977    cb.append((char) ch);
1978    }
1979
1980    // add any trailing text
1981
if (cb.length() > 0)
1982      println(cbVar + ".append(\"" + cb + "\");");
1983
1984    println("String " + strVar + " = " + cbVar + ".close();");
1985
1986    return strVar;
1987    
1988  }
1989
1990  /**
1991   * Prints a value-of expression
1992   */

1993  private void printStringExpr(String JavaDoc exprString, Element elt)
1994    throws Exception JavaDoc
1995  {
1996    int length = exprString.length();
1997    
1998    if (length == 0)
1999      return;
2000
2001    AbstractPattern select = null;
2002    try {
2003      select = parseSelect(exprString);
2004    } catch (Exception JavaDoc e) {
2005    }
2006    
2007    if (exprString.equals(".")) {
2008      println("out.valueOf(node);");
2009      return;
2010    }
2011    else if (exprString.charAt(0) == '@') {
2012      boolean isSimple = true;
2013      
2014      for (int i = 1; i < length; i++) {
2015        char ch = exprString.charAt(i);
2016        if (! XmlChar.isNameChar(ch) || ch == ':')
2017          isSimple = false;
2018      }
2019
2020      if (isSimple) {
2021        println("if (node instanceof Element)");
2022        print(" out.print(((Element) node).getAttribute(\"");
2023        print(exprString.substring(1));
2024        println("\"));");
2025        return;
2026      }
2027    }
2028    else if (allowJavaSelect(select)) {
2029      int oldSelectDepth = _selectDepth;
2030
2031      String JavaDoc loop = "_xsl_loop" + _unique++;
2032      _selectLoopDepth = 0;
2033      
2034      String JavaDoc ptr = printSelectBegin(select, true, loop);
2035
2036      println("out.valueOf(" + ptr + ");");
2037      println("break " + loop + ";");
2038
2039      for (; _selectDepth > oldSelectDepth; _selectDepth--) {
2040        popDepth();
2041        println("}");
2042      }
2043
2044      return;
2045    }
2046
2047    println("out.valueOf(_exprs[" + addExpr(exprString) +
2048            "].evalObject(node, " + getEnv() + "));");
2049  }
2050
2051  /**
2052   * Prints a value-of expression
2053   */

2054  private void addStringExpr(String JavaDoc var, String JavaDoc exprString,
2055                             Element elt, boolean isSingleString)
2056    throws Exception JavaDoc
2057  {
2058    int length = exprString.length();
2059    
2060    if (length == 0)
2061      return;
2062
2063    AbstractPattern select = null;
2064    try {
2065      select = parseSelect(exprString);
2066    } catch (Exception JavaDoc e) {
2067    }
2068    
2069    if (exprString.equals(".")) {
2070      if (isSingleString)
2071        println(var + " = XmlUtil.textValue(node);");
2072      else
2073        println("XmlUtil.textValue(" + var + ", node);");
2074      return;
2075    }
2076    else if (exprString.charAt(0) == '@') {
2077      boolean isSimple = true;
2078      
2079      for (int i = 1; i < length; i++) {
2080        char ch = exprString.charAt(i);
2081        if (! XmlChar.isNameChar(ch) || ch == ':')
2082          isSimple = false;
2083      }
2084
2085      if (isSimple) {
2086        println("if (node instanceof Element)");
2087        if (isSingleString) {
2088          print(" " + var + " = ((Element) node).getAttribute(\"");
2089          print(exprString.substring(1));
2090          println("\");");
2091        }
2092        else {
2093          print(" " + var + ".append(((Element) node).getAttribute(\"");
2094          print(exprString.substring(1));
2095          println("\"));");
2096        }
2097        return;
2098      }
2099    }
2100    else if (allowJavaSelect(select)) {
2101      int oldSelectDepth = _selectDepth;
2102
2103      String JavaDoc loopVar = "_xsl_loop" + _unique++;
2104      _selectLoopDepth = 0;
2105      
2106      String JavaDoc ptr = printSelectBegin(select, true, loopVar);
2107
2108      if (isSingleString)
2109        println(var + " = XmlUtil.textValue(" + ptr + ");");
2110      else
2111        println("XmlUtil.textValue(" + var + ", " + ptr + ");");
2112      println("break " + loopVar + ";");
2113
2114      for (; _selectDepth > oldSelectDepth; _selectDepth--) {
2115        popDepth();
2116        println("}");
2117      }
2118
2119      return;
2120    }
2121
2122    if (isSingleString) {
2123      println(var + " = _exprs[" + addExpr(exprString) +
2124              "].evalString(node, " + getEnv() + ");");
2125    }
2126    else {
2127      println("_exprs[" + addExpr(exprString) + "].evalString(" +
2128              var + ", node, " + getEnv() + ");");
2129    }
2130  }
2131
2132  /**
2133   * Prints iterator code to start a select.
2134   */

2135  private String JavaDoc printSelectBegin(AbstractPattern select,
2136                                  boolean isForEach, String JavaDoc loopVar)
2137    throws IOException JavaDoc, XslParseException
2138  {
2139    if (select == null)
2140      throw new NullPointerException JavaDoc();
2141    
2142    if (select instanceof FromContext &&
2143        ((FromContext) select).getCount() == 0)
2144      return "node";
2145
2146    else if (select instanceof FromRoot)
2147      return "ownerDocument(node)";
2148
2149    boolean useXPath = allowJavaSelect(select);
2150    
2151    String JavaDoc name = "node";
2152
2153    if (! useXPath) {
2154      // punt and let XPath handle it.
2155
String JavaDoc iterName = "_xsl_iter" + _unique++;
2156      
2157      String JavaDoc ptrName = "_xsl_ptr" + _unique++;
2158
2159      if (isForEach)
2160        println("env.setCurrentNode(node);");
2161      println("Iterator " + iterName + " = _select_patterns[" +
2162              addSelect(select) + "].select(" + name + ", env);");
2163      
2164      if (loopVar != null && _selectLoopDepth == 0)
2165        println(loopVar + ":");
2166      
2167      println("while (" + iterName + ".hasNext()) {");
2168      pushDepth();
2169      _selectDepth++;
2170      _selectLoopDepth++;
2171      println("Node " + ptrName + " = (Node) " + iterName + ".next();");
2172
2173      return ptrName;
2174    }
2175
2176    if (select instanceof FromChildren) {
2177      name = printSelectBegin(select.getParent(), isForEach, loopVar);
2178      
2179      String JavaDoc ptrName = "_xsl_ptr" + _unique++;
2180
2181      if (loopVar != null && _selectLoopDepth == 0)
2182        println(loopVar + ":");
2183      
2184      println("for (Node " + ptrName + " = " + name + ".getFirstChild();");
2185      println(" " + ptrName + " != null;");
2186      println(" " + ptrName + " = " + ptrName + ".getNextSibling()) {");
2187      pushDepth();
2188      _selectDepth++;
2189      _selectLoopDepth++;
2190
2191      return ptrName;
2192    }
2193    else if (select instanceof FromNextSibling) {
2194      name = printSelectBegin(select.getParent(), isForEach, loopVar);
2195      
2196      String JavaDoc ptrName = "_xsl_ptr" + _unique++;
2197      
2198      if (loopVar != null && _selectLoopDepth == 0)
2199        println(loopVar + ":");
2200      
2201      println("for (Node " + ptrName + " = " + name + ".getNextSibling();");
2202      println(" " + ptrName + " != null;");
2203      println(" " + ptrName + " = " + ptrName + ".getNextSibling()) {");
2204      pushDepth();
2205      _selectDepth++;
2206      _selectLoopDepth++;
2207
2208      return ptrName;
2209    }
2210    else if (select instanceof NodePattern) {
2211      name = printSelectBegin(select.getParent(), isForEach, loopVar);
2212      
2213      NodePattern pat = (NodePattern) select;
2214      
2215      println("if (" + name + ".getNodeName() == \"" + pat.getNodeName() + "\" &&");
2216      println(" " + name + " instanceof Element) {");
2217      pushDepth();
2218      _selectDepth++;
2219
2220      return name;
2221    }
2222    else if (select instanceof NodeTypePattern) {
2223      name = printSelectBegin(select.getParent(), isForEach, loopVar);
2224      
2225      NodeTypePattern pat = (NodeTypePattern) select;
2226
2227      if (pat.getNodeType() >= 0) {
2228        println("if (" + name + ".getNodeType() == " + pat.getNodeType() + ") {");
2229        pushDepth();
2230        _selectDepth++;
2231      }
2232
2233      return name;
2234    }
2235    else if (select instanceof FilterPattern) {
2236      String JavaDoc posId = "_xsl_pos" + _unique++;
2237
2238      println("int " + posId + " = 0;");
2239      
2240      name = printSelectBegin(select.getParent(), isForEach, loopVar);
2241
2242      println(posId + "++;");
2243      
2244      FilterPattern pat = (FilterPattern) select;
2245      Expr expr = pat.getExpr();
2246
2247      if (expr instanceof NumericExpr) {
2248        NumericExpr num = (NumericExpr) expr;
2249        if (num.isConstant()) {
2250          println("if (" + posId + " > " + (int) num.getValue() + ")");
2251          println(" break;");
2252          println("else if (" + posId + " == " + (int) num.getValue() + ") {");
2253          pushDepth();
2254          _selectDepth++;
2255
2256          return name;
2257        }
2258      }
2259
2260      throw new RuntimeException JavaDoc();
2261    }
2262
2263    throw new RuntimeException JavaDoc(String.valueOf(select));
2264  }
2265
2266  /**
2267   * Returns true if we can compile in the java select.
2268   */

2269  private boolean allowJavaSelect(AbstractPattern select)
2270  {
2271    if (select == null)
2272      return false;
2273
2274    else if (! select.isStrictlyAscending())
2275      return false;
2276    
2277    else if (select instanceof FromContext)
2278      return ((FromContext) select).getCount() == 0;
2279
2280    else if (select instanceof FromRoot)
2281      return true;
2282
2283    else if (select instanceof NodePattern)
2284      return allowJavaSelect(select.getParent());
2285
2286    else if (select instanceof NodeTypePattern)
2287      return allowJavaSelect(select.getParent());
2288
2289    else if (select instanceof FromChildren)
2290      return allowJavaSelect(select.getParent());
2291
2292    else if (select instanceof FromNextSibling)
2293      return allowJavaSelect(select.getParent());
2294
2295    else if (select instanceof FilterPattern) {
2296      if (! allowJavaSelect(select.getParent()))
2297        return false;
2298
2299      Expr expr = ((FilterPattern) select).getExpr();
2300
2301      return ((expr instanceof NumericExpr) &&
2302              ((NumericExpr) expr).isConstant());
2303    }
2304
2305    else
2306      return false;
2307  }
2308
2309  private void stringExpr(String JavaDoc exprString, Element element)
2310    throws Exception JavaDoc, XslParseException
2311  {
2312    print("_exprs[" + addExpr(exprString) +
2313          "].evalString(node, " + getEnv() + ")");
2314  }
2315
2316  /**
2317   * Adds an expression constant returning its index.
2318   *
2319   * @param expr the expression to add.
2320   *
2321   * @return the index into the runtime expression array
2322   */

2323  public int addExpr(Expr expr)
2324    throws XslParseException
2325  {
2326    String JavaDoc exprStr = expr.toString();
2327
2328    int i = _exprMap.get(exprStr);
2329    if (i >= 0)
2330      return i;
2331
2332    i = _exprs.size();
2333    _exprMap.put(exprStr, i);
2334    _exprs.add(expr);
2335    
2336    return i;
2337  }
2338
2339  /**
2340   * Adds an expression constant returning its index.
2341   *
2342   * @param exprString the expression to add.
2343   *
2344   * @return the index into the runtime expression array
2345   */

2346  public int addExpr(String JavaDoc exprString)
2347    throws XslParseException
2348  {
2349    int i = _exprMap.get(exprString);
2350
2351    if (i >= 0)
2352      return i;
2353    
2354    Expr expr = parseExpr(exprString);
2355    i = _exprs.size();
2356    _exprs.add(expr);
2357
2358    _exprMap.put(exprString, i);
2359
2360    return i;
2361  }
2362
2363  /**
2364   * Adds a select pattern returning its index.
2365   *
2366   * @param select the select pattern to add.
2367   *
2368   * @return the index into the runtime expression array
2369   */

2370  public int addSelect(AbstractPattern select)
2371    throws IOException JavaDoc, XslParseException
2372  {
2373    String JavaDoc selectStr = select.toString();
2374
2375    int i = _selectMap.get(selectStr);
2376    if (i >= 0)
2377      return i;
2378
2379    i = _selectPatterns.size();
2380    _selectMap.put(selectStr, i);
2381    _selectPatterns.add(select);
2382    
2383    return i;
2384  }
2385
2386  /**
2387   * Adds a select pattern, returning its index.
2388   *
2389   * @param selectString the expression to add.
2390   *
2391   * @return the index into the runtime select pattern array
2392   */

2393  public int addSelect(String JavaDoc selectString)
2394    throws IOException JavaDoc, XslParseException
2395  {
2396    int i = _selectMap.get(selectString);
2397
2398    if (i >= 0)
2399      return i;
2400    
2401    AbstractPattern select = parseSelect(selectString);
2402    i = _selectPatterns.size();
2403    _selectPatterns.add(select);
2404
2405    _selectMap.put(selectString, i);
2406
2407    return i;
2408  }
2409
2410  /**
2411   * Adds a match pattern, returning its index.
2412   *
2413   * @param pattern the expression to add.
2414   *
2415   * @return the index into the runtime expression array
2416   */

2417  public int addMatch(AbstractPattern pattern)
2418    throws XslParseException
2419  {
2420    int index = _matchPatterns.size();
2421
2422    _matchPatterns.add(pattern);
2423
2424    return index;
2425  }
2426
2427  protected StylesheetImpl completeGenerate(ArrayList JavaDoc<XslNode> inits,
2428                                            ArrayList JavaDoc globals)
2429    throws Exception JavaDoc
2430  {
2431    printTemplates();
2432    printMacros();
2433
2434    printInitVars(inits);
2435    printFragments();
2436
2437    printInit();
2438    
2439    printStrings();
2440    printExpressions();
2441    printPatterns();
2442
2443    popDepth();
2444    println("}");
2445    _s.close();
2446    _s = null;
2447
2448    /*
2449    if (dbg.canWrite()) {
2450      ReadStream is = path.openRead();
2451      dbg.writeStream(is);
2452      is.close();
2453    }
2454    */

2455    
2456    if (_parentLoader instanceof DynamicClassLoader)
2457      ((DynamicClassLoader) _parentLoader).make();
2458    
2459    _compiler.compile(_path.getPath(), _lineMap);
2460
2461    StylesheetImpl stylesheet;
2462
2463    stylesheet = (StylesheetImpl) _xslGenerator.loadStylesheet(_path.getFullPath(),
2464                                                               _pkg + "." + _className);
2465    //if (stylesheet != null)
2466
// stylesheet.init(context);
2467

2468    return stylesheet;
2469  }
2470
2471  private long getLastModified()
2472  {
2473    long lastModified = 0;
2474    for (int i = 0; i < _depends.size(); i++) {
2475      Path path = _depends.get(i);
2476      if (path.getLastModified() > lastModified)
2477    lastModified = path.getLastModified();
2478    }
2479
2480    return lastModified;
2481  }
2482
2483  /**
2484   * Generate code executed for all transformations.
2485   * <ul>
2486   * <li>Add the stylesheet namespaces to the generated document.
2487   * <li>Assign the global variables.
2488   * <li>Initialize the cache dependencies.
2489   */

2490  protected void printInitVars(ArrayList JavaDoc<XslNode> inits)
2491    throws Exception JavaDoc
2492  {
2493    println("private void _xsl_init_vars(XslWriter out, Node node, Env env)");
2494    println(" throws Exception");
2495    println("{");
2496    pushDepth();
2497
2498    // Add the stylesheet namespaces to the generated document.
2499
HashMap JavaDoc namespaces = _qDoc.getNamespaces();
2500    if (namespaces != null) {
2501      Iterator JavaDoc prefixes = namespaces.keySet().iterator();
2502      while (prefixes.hasNext()) {
2503        String JavaDoc prefix = (String JavaDoc) prefixes.next();
2504        String JavaDoc url = (String JavaDoc) namespaces.get(prefix);
2505
2506        if (url.startsWith("http://www.w3.org/XSL/Transform/") ||
2507            url.startsWith("http://www.w3.org/1999/XSL/Transform") ||
2508            url.startsWith("http://www.w3.org/XML/2000/xmlns") ||
2509            url.startsWith("http://www.w3.org/2000/xmlns") ||
2510        url.equals(XTPNS))
2511          continue;
2512        else if (_excludedNamespaces.get(url) != null)
2513          continue;
2514        else if (_namespaceAliases.get(url) != null)
2515          continue;
2516
2517    if (prefix == null)
2518      println("out.addNamespace(\"\", \"" + url + "\");");
2519    else
2520      println("out.addNamespace(\"" + prefix + "\", \"" + url + "\");");
2521      }
2522    }
2523
2524    // Initialize the global stylesheet variables
2525
println("Object _xsl_tmp;");
2526    for (int i = 0; i < inits.size(); i++) {
2527      XslNode node = inits.get(i);
2528      // NamespaceContext oldNamespace = addNamespace(elt);
2529

2530      node.generate(getOut());
2531
2532      /*
2533      if ("variable".equals(getXslLocal(elt)) ||
2534          "assign".equals(getXslLocal(elt))) {
2535    String name = elt.getAttribute("name");
2536    String expr = elt.getAttribute("select");
2537    print("env.setGlobal(\"" + name + "\", ");
2538    if (! expr.equals(""))
2539      printVariableValue(parseExpr(expr));
2540    else
2541      printVariableValue(elt);
2542    println(");");
2543      }
2544      else if ("param".equals(getXslLocal(elt))) {
2545        String name = elt.getAttribute("name");
2546        String expr = elt.getAttribute("select");
2547        print("env.setGlobal(\"" + name + "\", ");
2548        if (! expr.equals(""))
2549          printVariableValue(parseExpr(expr));
2550        else
2551          printVariableValue(elt);
2552        println(");");
2553         
2554        println("_xsl_tmp = out.getParameter(\"" + name + "\");");
2555        println("if (_xsl_tmp != null)");
2556        println(" env.setGlobal(\"" + name + "\", _xsl_tmp);");
2557      }
2558      */

2559      
2560      // oldNamespace = _namespace;
2561
}
2562
2563    // Initialize the cache dependencies.
2564
println("com.caucho.vfs.Path pwd;");
2565    println("pwd = (com.caucho.vfs.Path) out.getProperty(\"caucho.pwd\");");
2566    for (int i = 0; i < _cacheDepends.size(); i++) {
2567      String JavaDoc depend = (String JavaDoc) _cacheDepends.get(i);
2568
2569      print("out.addCacheDepend(pwd.lookup(\"");
2570      printString(depend);
2571      println("\"));");
2572    }
2573    
2574    popDepth();
2575    println("}");
2576  }
2577
2578  protected void printInit()
2579    throws Exception JavaDoc
2580  {
2581    println("protected void _xsl_init(XslWriter out, Node node, Env env)");
2582    println(" throws Exception");
2583    println("{");
2584    pushDepth();
2585    println("Object _xsl_tmp;");
2586    println("_xsl_init_vars(out, node, env);");
2587
2588    // Generic init vars
2589
// println("templates = _staticTemplates;");
2590

2591    for (int i = 0; _globalActions != null && i < _globalActions.size(); i++) {
2592      QAbstractNode node = (QAbstractNode) _globalActions.get(i);
2593      generateChild(node);
2594    }
2595
2596    popDepth();
2597    println("}");
2598
2599    // depends
2600
println("public boolean isModified()");
2601    println("{");
2602    pushDepth();
2603    println("return com.caucho.server.util.CauchoSystem.getVersionId() != " +
2604            CauchoSystem.getVersionId() + "L ||");
2605    println(" super.isModified();");
2606    popDepth();
2607    println("}");
2608
2609    println("public void init(com.caucho.vfs.Path path)");
2610    println(" throws Exception");
2611    println("{");
2612    pushDepth();
2613    println("super.init(path);");
2614    println("com.caucho.vfs.Path pwd = path.getParent();");
2615
2616    for (int i = 0; i < _depends.size(); i++) {
2617      Path path = _depends.get(i);
2618      
2619      if (path.canRead() && ! path.isDirectory()) {
2620    Depend depend = new Depend(path);
2621 
2622    print("addDepend(new com.caucho.vfs.Depend(pwd.lookup(\"");
2623    printString(path.getRelativePath());
2624    println("\"), " + depend.getDigest() + "L));");
2625      }
2626    }
2627
2628    println("stylesheets = new StylesheetEnv[" + _stylesheets.size() + "];");
2629    println("StylesheetEnv env;");
2630    
2631    for (int i = 0; i < _stylesheets.size(); i++) {
2632      String JavaDoc ss = _stylesheets.get(i);
2633
2634      println("env = new StylesheetEnv();");
2635      println("stylesheets[" + i + "] = env;");
2636      print("env.setPath(pwd.lookup(\"");
2637      printString(ss);
2638      println("\"));");
2639    }
2640
2641    if (! _strip.isEmpty()) {
2642      println("HashMap preserve = new HashMap();");
2643      println("HashMap preservePrefix = new HashMap();");
2644      Iterator JavaDoc iter = _preserve.keySet().iterator();
2645      while (iter.hasNext()) {
2646        String JavaDoc key = (String JavaDoc) iter.next();
2647        if (key.endsWith(":*")) {
2648          String JavaDoc prefix = key.substring(0, key.length() - 2);
2649          println("preservePrefix.put(\"" + prefix + "\", \"true\");");
2650        }
2651        else
2652          println("preserve.put(\"" + key + "\", \"true\");");
2653      }
2654      println("HashMap strip = new HashMap();");
2655      println("HashMap stripPrefix = new HashMap();");
2656      iter = _strip.keySet().iterator();
2657      while (iter.hasNext()) {
2658        String JavaDoc key = (String JavaDoc) iter.next();
2659        if (key.endsWith(":*")) {
2660          String JavaDoc prefix = key.substring(0, key.length() - 2);
2661          println("stripPrefix.put(\"" + prefix + "\", \"true\");");
2662        }
2663        else
2664          println("strip.put(\"" + key + "\", \"true\");");
2665      }
2666      println("setSpaces(preserve, preservePrefix, strip, stripPrefix);");
2667    }
2668
2669    printOutput();
2670
2671    if (_errorPage != null) {
2672      print("setProperty(\"caucho.error.page\", \"");
2673      printString(_errorPage);
2674      println("\");");
2675    }
2676
2677    if (_globalParameters != null && _globalParameters.size() > 0) {
2678      println("ArrayList params = new ArrayList();");
2679      for (int i = 0; i < _globalParameters.size(); i++) {
2680        String JavaDoc param = _globalParameters.get(i);
2681
2682        println("params.add(\"" + param + "\");");
2683      }
2684      print("setProperty(\"caucho.global.param\", params);");
2685    }
2686    
2687    String JavaDoc disable = null;
2688    /*
2689    if (_outputAttributes != null)
2690      disable = (String) _outputAttributes.get("disable-output-escaping");
2691    if (disable != null && ! disable.equals("no") && ! disable.equals("false"))
2692      println("defaultDisableEscaping = true;");
2693    */

2694    
2695    if (_isRawText)
2696      println("_defaultDisableEscaping = true;");
2697
2698    printNamespaces();
2699    printFunctions();
2700    printSorts();
2701    printFormats();
2702    
2703    popDepth();
2704    println("}");
2705  }
2706
2707  /**
2708   * Sets the property for the xsl:output keys.
2709   */

2710  private void printOutput() throws Exception JavaDoc
2711  {
2712    Iterator JavaDoc iter = _outputAttributes.keySet().iterator();
2713
2714    if (_outputAttributes.get("encoding") == null)
2715      println("_output.put(\"encoding\", \"utf-8\");");
2716    
2717    while (iter.hasNext()) {
2718      String JavaDoc key = (String JavaDoc) iter.next();
2719      String JavaDoc value = (String JavaDoc) _outputAttributes.get(key);
2720
2721      println("_output.put(\"" + key + "\", \"" + value + "\");");
2722    }
2723  }
2724
2725  private void printSorts() throws Exception JavaDoc
2726  {
2727    if (_sorts.size() == 0)
2728      return;
2729
2730    println();
2731    println("_xsl_sorts = new com.caucho.xsl.Sort[][] { ");
2732    pushDepth();
2733
2734    for (int i = 0; i < _sorts.size(); i++) {
2735      Sort []sorts = _sorts.get(i);
2736
2737      print("new com.caucho.xsl.Sort[] {");
2738      
2739      for (int j = 0; j < sorts.length; j++) {
2740        Sort sort = sorts[j];
2741
2742    Expr lang = sort.getLang();
2743    Expr caseOrder = sort.getCaseOrder();
2744    
2745        if (lang != null || caseOrder != null) {
2746          print("new com.caucho.xsl.Sort(\"" + sort.getExpr() + "\", " +
2747                "\"" + sort.getAscending() + "\", " +
2748                (lang == null ? "null, " : "\"" + lang + "\", ") +
2749                (caseOrder == null ? "null), " : "\"" + caseOrder + "\"), "));
2750        }
2751        else
2752          print("new com.caucho.xsl.Sort(\"" + sort.getExpr() + "\", " +
2753                "\"" + sort.getAscending() + "\", " +
2754                sort.isText() + "), ");
2755      }
2756      
2757      println("},");
2758    }
2759    popDepth();
2760    println("};");
2761  }
2762
2763  private void printLocale(Locale JavaDoc locale) throws Exception JavaDoc
2764  {
2765    String JavaDoc language = locale.getLanguage();
2766    String JavaDoc country = locale.getCountry();
2767    String JavaDoc variant = locale.getVariant();
2768
2769    if (variant != null && country != null) {
2770      print("new java.util.Locale(\"" + language + "\", " +
2771            "\"" + country + "\", \"" + variant + "\")");
2772    }
2773    else if (country != null) {
2774      print("new java.util.Locale(\"" + language + "\", " +
2775            "\"" + country + "\")");
2776    }
2777    else {
2778      print("new java.util.Locale(\"" + language + "\")");
2779    }
2780  }
2781
2782  private void printFormats() throws Exception JavaDoc
2783  {
2784    if (_formats.size() == 0)
2785      return;
2786
2787    println();
2788    println("_xsl_formats = new XslNumberFormat[] { ");
2789    pushDepth();
2790
2791    for (int i = 0; i < _formats.size(); i++) {
2792      XslNumberFormat format = (XslNumberFormat) _formats.get(i);
2793
2794      println("new XslNumberFormat(\"" + format.getFormat() + "\", \"" +
2795              format.getLang() + "\", " + format.isAlphabetic() + ", \"" +
2796              format.getGroupSeparator() + "\", " +
2797              format.getGroupSize() + "),");
2798    }
2799    popDepth();
2800    println("};");
2801  }
2802
2803  private void printNamespaces() throws Exception JavaDoc
2804  {
2805    if (_namespaces.size() == 0)
2806      return;
2807
2808    println();
2809    println("_namespaces = new NamespaceContext[] { ");
2810    pushDepth();
2811
2812    for (int i = 0; i < _namespaces.size(); i++) {
2813      NamespaceContext ns = _namespaces.get(i);
2814
2815      printNamespaceDef(ns);
2816      println(",");
2817    }
2818    popDepth();
2819    println("};");
2820  }
2821
2822  private void printNamespaceDef(NamespaceContext ns) throws Exception JavaDoc
2823  {
2824    if (ns == null) {
2825      print("null");
2826      return;
2827    }
2828
2829    print("new NamespaceContext(");
2830    printNamespaceDef(ns.getPrev());
2831    print(", \"" + ns.getPrefix() + "\", \"" + ns.getUrl() + "\")");
2832  }
2833
2834  private void printFunctions() throws Exception JavaDoc
2835  {
2836    println();
2837    println("com.caucho.xsl.fun.KeyFun keyFun = new com.caucho.xsl.fun.KeyFun();");
2838    HashMap JavaDoc keys = _keyFun.getKeys();
2839    Iterator JavaDoc iter = keys.keySet().iterator();
2840    while (iter.hasNext()) {
2841      String JavaDoc name = (String JavaDoc) iter.next();
2842      KeyFun.Key key = (KeyFun.Key) keys.get(name);
2843
2844      println("keyFun.add(\"" + name + "\", XPath.parseMatch(\"" +
2845              key.getMatch() + "\").getPattern(), XPath.parseExpr(\"" +
2846              key.getUse() + "\"));");
2847    }
2848    println("addFunction(\"key\", keyFun);");
2849    
2850    println();
2851    println("com.caucho.xsl.fun.FormatNumberFun formatFun = new com.caucho.xsl.fun.FormatNumberFun();");
2852    println("java.text.DecimalFormatSymbols symbols;");
2853    JavaWriter out = _out;
2854
2855    HashMap JavaDoc locales = _formatNumberFun.getLocales();
2856    iter = locales.keySet().iterator();
2857    while (iter.hasNext()) {
2858      String JavaDoc name = (String JavaDoc) iter.next();
2859      DecimalFormatSymbols JavaDoc symbols = (DecimalFormatSymbols JavaDoc) locales.get(name);
2860
2861      out.println("symbols = new java.text.DecimalFormatSymbols();");
2862      
2863      out.print("symbols.setDecimalSeparator(\'");
2864      out.printJavaChar(symbols.getDecimalSeparator());
2865      out.println("\');");
2866      
2867      out.print("symbols.setGroupingSeparator(\'");
2868      out.printJavaChar(symbols.getGroupingSeparator());
2869      out.println("\');");
2870      
2871      out.print("symbols.setInfinity(\"");
2872      out.printJavaString(symbols.getInfinity());
2873      out.println("\");");
2874      
2875      out.print("symbols.setMinusSign(\'");
2876      out.printJavaChar(symbols.getMinusSign());
2877      out.println("\');");
2878      
2879      out.print("symbols.setNaN(\"");
2880      out.printJavaString(symbols.getNaN());
2881      out.println("\");");
2882      
2883      out.print("symbols.setPercent(\'");
2884      out.printJavaChar(symbols.getPercent());
2885      out.println("\');");
2886      
2887      out.print("symbols.setPerMill(\'");
2888      out.printJavaChar(symbols.getPerMill());
2889      out.println("\');");
2890      
2891      out.print("symbols.setZeroDigit(\'");
2892      out.printJavaChar(symbols.getZeroDigit());
2893      out.println("\');");
2894      
2895      out.print("symbols.setDigit(\'");
2896      out.printJavaChar(symbols.getDigit());
2897      out.println("\');");
2898      
2899      out.print("symbols.setPatternSeparator(\'");
2900      out.printJavaChar(symbols.getPatternSeparator());
2901      out.println("\');");
2902
2903      println("formatFun.addLocale(\"" + name + "\", symbols);");
2904    }
2905    
2906    println("addFunction(\"format-number\", formatFun);");
2907  }
2908
2909  private void printMacros() throws Exception JavaDoc
2910  {
2911    /*
2912    for (int i = 0; i < _macros.size(); i++) {
2913      Macro macro = _macros.get(i);
2914
2915      println("void " + getMacroName(macro.getName()) +
2916          "(XslWriter out, Node inputNode, Env env)");
2917      println(" throws Exception");
2918      println("{");
2919      pushDepth();
2920      println("Object _xsl_tmp;");
2921      println("Node node = inputNode;");
2922      generateChildren(macro.getElement());
2923      popDepth();
2924      println("}");
2925    }
2926    */

2927  }
2928
2929  private void printFragments() throws Exception JavaDoc
2930  {
2931    for (int i = 0; i < _fragments.size(); i++) {
2932      Element elt = (Element) _fragments.get(i);
2933
2934      println("Object _xsl_fragment" + i +
2935              "(XslWriter out, Node inputNode, Env env )");
2936      println(" throws Exception");
2937      println("{");
2938      pushDepth();
2939      println("Object _xsl_tmp;");
2940      println("Node node = inputNode;");
2941      println("XMLWriter _xsl_frag = out.pushFragment();");
2942      generateChildren(elt);
2943      println("return out.popFragment(_xsl_frag);");
2944      popDepth();
2945      println("}");
2946    }
2947  }
2948
2949  /**
2950   * Prints the template definitions, i.e. the set of XPath
2951   * match patterns to test a node.
2952   */

2953  private void printTemplates() throws Exception JavaDoc
2954  {
2955    for (int j = 0; j < _modes.size(); j++) {
2956      String JavaDoc mode = _modes.get(j);
2957      String JavaDoc modeName = getModeName(mode);
2958
2959      printApplyNode(mode);
2960
2961      println();
2962      println("static HashMap _static_templates" + modeName + ";");
2963      println();
2964      println("static {");
2965      pushDepth();
2966      println("_static_templates" + modeName + " = new HashMap();");
2967      println("Template []values;");
2968
2969      println("try {");
2970      pushDepth();
2971
2972      ArrayList JavaDoc defaultTemplateList = (ArrayList JavaDoc) _templates.get("*");
2973      if (defaultTemplateList == null)
2974        defaultTemplateList = new ArrayList JavaDoc();
2975      println("Template []star = new Template[] {");
2976      pushDepth();
2977      for (int i = 0; i < defaultTemplateList.size(); i++) {
2978        Template template = (Template) defaultTemplateList.get(i);
2979        
2980        if (template.getMode().equals(mode)) {
2981          printTemplate(template);
2982          println(",");
2983        }
2984      }
2985      popDepth();
2986      println("};");
2987      println();
2988      println("_static_templates" + modeName + ".put(\"*\", star);");
2989
2990      int count = _templates.size();
2991
2992      for (int i = 0; i < count; i += 64)
2993        println("_init_templates" + modeName + "_" + i + "(star);");
2994
2995      popDepth();
2996      println("} catch (Exception e) {");
2997      println(" e.printStackTrace();");
2998      println("}");
2999    
3000      popDepth();
3001      println("}");
3002
3003      for (int i = 0; i < count; i += 64)
3004        printTemplateInitFun(mode, i, 64, defaultTemplateList);
3005    }
3006  }
3007  
3008  /**
3009   * Prints a function to initialize some of the templates.
3010   */

3011  private void printApplyNode(String JavaDoc mode)
3012    throws Exception JavaDoc
3013  {
3014    String JavaDoc modeName = getModeName(mode);
3015    
3016    print("protected void applyNode" + modeName);
3017    println("(XslWriter out, Node node, Env env, int _xsl_min, int _xsl_max)");
3018    println(" throws Exception");
3019    println("{");
3020    pushDepth();
3021    println("Object _xsl_tmp;");
3022    println();
3023    println("switch (getTemplateId(_static_templates" + modeName + ", " +
3024            "node, env, _xsl_min, _xsl_max)) {");
3025    // XXX: name issue below functions/templateList
3026
for (int i = 0; i < _functions.size(); i++) {
3027      Template template = (Template) _templateList.get(i);
3028
3029      if (template == null || ! template.getMode().equals(mode))
3030        continue;
3031      
3032      println("case " + (i + 1) + ":");
3033      println(" " + _functions.get(i) + "(out, node, env);");
3034      println(" break;");
3035    }
3036    println("default:");
3037    println(" switch (node.getNodeType()) {");
3038    println(" case Node.ELEMENT_NODE:");
3039    println(" case Node.DOCUMENT_NODE:");
3040    println(" case Node.DOCUMENT_FRAGMENT_NODE:");
3041    println(" env.setSelect(node, null);");
3042    println(" for (Node child = node.getFirstChild();");
3043    println(" child != null;");
3044    println(" child = child.getNextSibling()) {");
3045    println(" env.setCurrentNode(child);");
3046    println(" applyNode" + modeName + "(out, child, env, 0, " + Integer.MAX_VALUE + ");");
3047    println(" }");
3048
3049    println(" break;");
3050    println(" default:");
3051    println(" applyNodeDefault(out, node, env);");
3052    println(" break;");
3053    println(" }");
3054    println(" break;");
3055    println("}");
3056    popDepth();
3057    println("}");
3058  }
3059
3060  /**
3061   * Prints a function to initialize some of the templates.
3062   */

3063  private void printTemplateInitFun(String JavaDoc mode, int offset, int length,
3064                                    ArrayList JavaDoc defaultTemplateList)
3065    throws Exception JavaDoc
3066  {
3067    String JavaDoc modeName = getModeName(mode);
3068                                  
3069    println("private static void _init_templates" + modeName + "_" + offset + "(Template []star)");
3070    println(" throws Exception");
3071    println("{");
3072    pushDepth();
3073
3074    Iterator JavaDoc<String JavaDoc> iter = _templates.keySet().iterator();
3075    while (iter.hasNext() && length > 0) {
3076      String JavaDoc name = iter.next();
3077      
3078      if (name.equals("*"))
3079        continue;
3080
3081      ArrayList JavaDoc templateList = (ArrayList JavaDoc) _templates.get(name);
3082      
3083      if (modeTemplateCount(mode, templateList) == 0)
3084        continue;
3085
3086      if (offset > 0) {
3087        offset--;
3088        continue;
3089      }
3090
3091      println("_static_templates" + modeName + ".put(\"" + name + "\", ");
3092      println(" mergeTemplates(star, new Template[] {");
3093      pushDepth();
3094      pushDepth();
3095      
3096      for (int i = 0; i < templateList.size(); i++) {
3097        Template template = (Template) templateList.get(i);
3098
3099        if (template.getMode().equals(mode)) {
3100          printTemplate(template);
3101          println(",");
3102        }
3103      }
3104
3105      popDepth();
3106      popDepth();
3107      println("}));");
3108
3109      length--;
3110    }
3111
3112    popDepth();
3113    println("}");
3114  }
3115
3116  /**
3117   * Returns true if the template list contains a template with the given
3118   * mode.
3119   */

3120  private int modeTemplateCount(String JavaDoc mode, ArrayList JavaDoc templateList)
3121  {
3122    int count = 0;
3123    
3124    for (int i = 0; i < templateList.size(); i++) {
3125      Template template = (Template) templateList.get(i);
3126
3127      if (template.getMode().equals(mode))
3128        count++;
3129    }
3130
3131    return count;
3132  }
3133
3134  /**
3135   * Prints initialization code for a single template.
3136   */

3137  private void printTemplate(Template template)
3138    throws IOException JavaDoc
3139  {
3140    print("new Template(");
3141    AbstractPattern pattern = template.getPattern();
3142    print("XPath.parseMatch(\"" +
3143          template.getPattern().toPatternString() + "\").getPattern(), ");
3144    print("\"" + template.getMode() + "\", ");
3145    print(template.getMin() + ", ");
3146    print(template.getMax() + ", ");
3147    print(template.getPriority() + ", ");
3148    print(template.getCount() + ", ");
3149    print("\"" + template.getFunction() + "\", ");
3150    print("" + template.getId() + ")");
3151  }
3152
3153  /**
3154   * Prints the constant strings.
3155   */

3156  private void printStrings() throws Exception JavaDoc
3157  {
3158    for (int j = 0; j < _strings.size(); j++) {
3159      String JavaDoc text = (String JavaDoc) _strings.get(j);
3160    
3161      print("static char[] _xsl_string" + j + " = \"");
3162
3163      printString(text);
3164
3165      println("\".toCharArray();");
3166    }
3167  }
3168
3169  /**
3170   * Prints the precompiled XPath expressions as static variables.
3171   */

3172  private void printExpressions() throws Exception JavaDoc
3173  {
3174    if (_exprs.size() == 0)
3175      return;
3176    
3177    println("private static Expr []_exprs;");
3178    println("static {");
3179    pushDepth();
3180    println("try {");
3181    pushDepth();
3182    
3183    println("_exprs = new Expr[] { ");
3184    pushDepth();
3185
3186    for (int i = 0; i < _exprs.size(); i++) {
3187      Expr expr = _exprs.get(i);
3188
3189      println("XPath.parseExpr(\"" + expr + "\"),");
3190
3191      // System.out.println("EXPR: " + expr + " " + expr.getListContext());
3192
/*
3193      if (expr.getListContext() == null) // || currentPos != null)
3194        println("XPath.parseExpr(\"" + expr + "\"),");
3195      else {
3196        print("XPath.parseExpr(\"" + expr + "\", null,");
3197        println("XPath.parseMatch(\"" + expr.getListContext() +"\").getPattern()),");
3198      }
3199      */

3200
3201    }
3202    popDepth();
3203    println("};");
3204
3205    popDepth();
3206    println("} catch (Exception e) {");
3207    println(" e.printStackTrace();");
3208    println("}");
3209    
3210    popDepth();
3211    println("}");
3212  }
3213
3214  /**
3215   * Prints the precompiled XPath select and match patterns as static
3216   * variables.
3217   */

3218  private void printPatterns() throws Exception JavaDoc
3219  {
3220    if (_selectPatterns.size() == 0 && _matchPatterns.size() == 0)
3221      return;
3222    
3223    println("private static com.caucho.xpath.pattern.AbstractPattern []_select_patterns;");
3224    println("private static com.caucho.xpath.pattern.AbstractPattern []_match_patterns;");
3225    println("static {");
3226    pushDepth();
3227    println("try {");
3228    pushDepth();
3229    
3230    println("_select_patterns = new com.caucho.xpath.pattern.AbstractPattern[] { ");
3231    pushDepth();
3232
3233    for (int i = 0; i < _selectPatterns.size(); i++) {
3234      AbstractPattern pattern = _selectPatterns.get(i);
3235
3236      println("XPath.parseSelect(\"" + pattern + "\").getPattern(),");
3237    }
3238    popDepth();
3239    println("};");
3240    
3241    println("_match_patterns = new com.caucho.xpath.pattern.AbstractPattern[] { ");
3242    pushDepth();
3243
3244    for (int i = 0; i < _matchPatterns.size(); i++) {
3245      AbstractPattern pattern = _matchPatterns.get(i);
3246
3247      println("XPath.parseMatch(\"" + pattern + "\").getPattern(),");
3248    }
3249    popDepth();
3250    println("};");
3251
3252    popDepth();
3253    println("} catch (Exception e) {");
3254    println(" e.printStackTrace();");
3255    println("}");
3256    
3257    popDepth();
3258    println("}");
3259  }
3260
3261  private boolean isSingleStylesheet()
3262  {
3263    // return stylesheets.size() < 2;
3264
return false;
3265  }
3266
3267  /**
3268   * Prints a character to the generated Java.
3269   */

3270  private void print(char ch)
3271    throws IOException JavaDoc
3272  {
3273    _out.print(ch);
3274  }
3275
3276  /**
3277   * Prints a string to the generated Java.
3278   */

3279  private void print(String JavaDoc string)
3280    throws IOException JavaDoc
3281  {
3282    _out.print(string);
3283  }
3284
3285  /**
3286   * Prints an integer to the generated Java.
3287   */

3288  private void print(int i)
3289    throws IOException JavaDoc
3290  {
3291    _out.print(i);
3292  }
3293
3294  /**
3295   * Prints a new line.
3296   */

3297  private void println()
3298    throws IOException JavaDoc
3299  {
3300    _out.println();
3301  }
3302
3303  private void println(char ch)
3304    throws IOException JavaDoc
3305  {
3306    _out.println(ch);
3307  }
3308
3309  private void println(String JavaDoc s)
3310    throws IOException JavaDoc
3311  {
3312    _out.println(s);
3313  }
3314
3315  /**
3316   * Pushes the pretty-printed depth of the generated java.
3317   */

3318  private void pushDepth()
3319    throws IOException JavaDoc
3320  {
3321    _out.pushDepth();
3322  }
3323
3324  /**
3325   * Pops the pretty-printed depth of the generated java.
3326   */

3327  private void popDepth()
3328    throws IOException JavaDoc
3329  {
3330    _out.popDepth();
3331  }
3332
3333  /**
3334   * Prints the contents of a string, taking care of escapes.
3335   */

3336  protected void printString(String JavaDoc str) throws IOException JavaDoc
3337  {
3338    _out.printJavaString(str);
3339  }
3340
3341  /**
3342   * Returns the name of the applyNode method.
3343   *
3344   * @param mode the template's mode.
3345   */

3346  public String JavaDoc getModeName(String JavaDoc mode)
3347  {
3348    if (mode != null && ! _modes.contains(mode))
3349      _modes.add(mode);
3350
3351    if (mode == null || mode.equals(""))
3352      return "";
3353    else
3354      return "_" + toJavaIdentifier(mode);
3355  }
3356
3357  public void addMode(String JavaDoc mode)
3358  {
3359    if (! _modes.contains(mode))
3360      _modes.add(mode);
3361  }
3362
3363  public int addStylesheet(String JavaDoc filename)
3364  {
3365    int pos = _stylesheets.indexOf(filename);
3366    
3367    if (pos < 0) {
3368      pos = _stylesheets.size();
3369      _stylesheets.add(filename);
3370    }
3371
3372    return pos;
3373  }
3374
3375  /**
3376   * Converts a string to a Java identifier, encoding unknown characters
3377   * as "_"
3378   */

3379  public String JavaDoc toJavaIdentifier(String JavaDoc name)
3380  {
3381    CharBuffer cb = new CharBuffer();
3382
3383    char ch = name.charAt(0);
3384    if (Character.isJavaIdentifierStart(ch))
3385      cb.append(ch);
3386    else
3387      cb.append("_");
3388
3389    for (int i = 1; i < name.length(); i++) {
3390      ch = name.charAt(i);
3391      
3392      if (Character.isJavaIdentifierPart(ch))
3393    cb.append(ch);
3394      else {
3395    cb.append("_");
3396        cb.append((char) ((ch & 0xf) + 'a'));
3397        cb.append((char) ((ch / 16 & 0xf) + 'a'));
3398      }
3399    }
3400
3401    return cb.toString();
3402  }
3403
3404  /**
3405   * Close call when an error occurs.
3406   */

3407  public void close()
3408    throws IOException JavaDoc
3409  {
3410    if (_s != null)
3411      _s.close();
3412  }
3413  
3414  static class Macro {
3415    String JavaDoc _name;
3416    Element _elt;
3417
3418    Macro(String JavaDoc name, Element elt)
3419    {
3420      _name = name;
3421      _elt = elt;
3422    }
3423
3424    public Element getElement()
3425    {
3426      return _elt;
3427    }
3428    
3429    public String JavaDoc getName()
3430    {
3431      return _name;
3432    }
3433  }
3434
3435  static {
3436    _tagMap = new HashMap JavaDoc<QName,Class JavaDoc>();
3437    
3438    _tagMap.put(new QName("xsl", "attribute", XSLNS), XslAttribute.class);
3439    _tagMap.put(new QName("xsl", "attribute-set", XSLNS),
3440        XslAttributeSet.class);
3441    _tagMap.put(new QName("xsl", "apply-imports", XSLNS),
3442        XslApplyImports.class);
3443    _tagMap.put(new QName("xsl", "apply-templates", XSLNS),
3444        XslApplyTemplates.class);
3445    _tagMap.put(new QName("xsl", "call-template", XSLNS), XslCallTemplate.class);
3446    _tagMap.put(new QName("xsl", "choose", XSLNS), XslChoose.class);
3447    _tagMap.put(new QName("xsl", "comment", XSLNS), XslComment.class);
3448    _tagMap.put(new QName("xsl", "copy", XSLNS), XslCopy.class);
3449    _tagMap.put(new QName("xsl", "copy-of", XSLNS), XslCopyOf.class);
3450    _tagMap.put(new QName("xsl", "decimal-format", XSLNS),
3451        XslDecimalFormat.class);
3452    _tagMap.put(new QName("xsl", "element", XSLNS), XslElement.class);
3453    _tagMap.put(new QName("xsl", "for-each", XSLNS), XslForEach.class);
3454    _tagMap.put(new QName("xsl", "if", XSLNS), XslIf.class);
3455    _tagMap.put(new QName("xsl", "import", XSLNS), XslImport.class);
3456    _tagMap.put(new QName("xsl", "include", XSLNS), XslInclude.class);
3457    _tagMap.put(new QName("xsl", "key", XSLNS), XslKey.class);
3458    _tagMap.put(new QName("xsl", "message", XSLNS), XslMessage.class);
3459    _tagMap.put(new QName("xsl", "namespace-alias", XSLNS),
3460        XslNamespaceAlias.class);
3461    _tagMap.put(new QName("xsl", "number", XSLNS), XslNumber.class);
3462    _tagMap.put(new QName("xsl", "otherwise", XSLNS), XslOtherwise.class);
3463    _tagMap.put(new QName("xsl", "output", XSLNS), XslOutput.class);
3464    _tagMap.put(new QName("xsl", "param", XSLNS), XslParam.class);
3465    _tagMap.put(new QName("xsl", "processing-instruction", XSLNS),
3466        XslProcessingInstruction.class);
3467    _tagMap.put(new QName("xsl", "sort", XSLNS), XslSort.class);
3468    _tagMap.put(new QName("xsl", "stylesheet", XSLNS), XslStylesheet.class);
3469    _tagMap.put(new QName("xsl", "text", XSLNS), XslText.class);
3470    _tagMap.put(new QName("xsl", "transform", XSLNS), XslTransform.class);
3471    _tagMap.put(new QName("xsl", "value-of", XSLNS), XslValueOf.class);
3472    _tagMap.put(new QName("xsl", "variable", XSLNS), XslVariable.class);
3473    _tagMap.put(new QName("xsl", "when", XSLNS), XslWhen.class);
3474    _tagMap.put(new QName("xsl", "with-param", XSLNS), XslWithParam.class);
3475    
3476    _tagMap.put(new QName("xsl", "template", XSLNS),
3477        XslTemplate.class);
3478    _tagMap.put(new QName("xsl", "strip-space", XSLNS),
3479        XslStripSpace.class);
3480    _tagMap.put(new QName("xsl", "preserve-space", XSLNS),
3481        XslPreserveSpace.class);
3482    _tagMap.put(new QName("xsl", "result-document", XSLNS),
3483        XslResultDocument.class);
3484    
3485    _tagMap.put(new QName("xtp", "expression", XTPNS),
3486        XtpExpression.class);
3487    _tagMap.put(new QName("xtp:expression", null), XtpExpression.class);
3488    _tagMap.put(new QName("xtp", "eval", XTPNS), XtpExpression.class);
3489    _tagMap.put(new QName("xtp:eval", null), XtpExpression.class);
3490    _tagMap.put(new QName("xtp", "expr", XTPNS), XtpExpression.class);
3491    _tagMap.put(new QName("xtp:expr", null), XtpExpression.class);
3492    _tagMap.put(new QName("xtp", "scriptlet", XTPNS),
3493        XtpScriptlet.class);
3494    _tagMap.put(new QName("xtp:scriptlet", null), XtpScriptlet.class);
3495    _tagMap.put(new QName("xtp", "declaration", XTPNS),
3496        XtpDeclaration.class);
3497    _tagMap.put(new QName("xtp", "decl", XTPNS),
3498        XtpDeclaration.class);
3499    _tagMap.put(new QName("xtp:declaration", null), XtpDeclaration.class);
3500    _tagMap.put(new QName("xtp:decl", null), XtpDeclaration.class);
3501    _tagMap.put(new QName("xtp:directive.page", null), XtpDirectivePage.class);
3502    _tagMap.put(new QName("xtp", "directive.page", XTPNS),
3503        XtpDirectivePage.class);
3504    _tagMap.put(new QName("xtp:directive.cache", null), XtpDirectiveCache.class);
3505    _tagMap.put(new QName("xtp", "directive.cache", XTPNS),
3506        XtpDirectiveCache.class);
3507    _tagMap.put(new QName("xtp:assign", null), XslVariable.class);
3508    _tagMap.put(new QName("xtp", "assign", XTPNS),
3509        XslVariable.class);
3510  }
3511}
3512
Popular Tags