KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > xsl > java > XslNode


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.java;
30
31 import com.caucho.java.JavaWriter;
32 import com.caucho.log.Log;
33 import com.caucho.util.CharBuffer;
34 import com.caucho.util.CompileException;
35 import com.caucho.util.L10N;
36 import com.caucho.util.LineCompileException;
37 import com.caucho.xml.QName;
38 import com.caucho.xml.XmlChar;
39 import com.caucho.xpath.Expr;
40 import com.caucho.xpath.NamespaceContext;
41 import com.caucho.xpath.XPath;
42 import com.caucho.xpath.expr.NumericExpr;
43 import com.caucho.xpath.pattern.*;
44 import com.caucho.xsl.JavaGenerator;
45 import com.caucho.xsl.XslParseException;
46
47 import java.io.IOException JavaDoc;
48 import java.util.ArrayList JavaDoc;
49 import java.util.logging.Logger JavaDoc;
50
51 /**
52  * Represents any XSL node from the stylesheet.
53  */

54 public abstract class XslNode {
55   static final L10N L = new L10N(XslNode.class);
56   static final Logger JavaDoc log = Log.open(XslNode.class);
57
58   protected String JavaDoc _systemId;
59   protected String JavaDoc _filename;
60   protected int _startLine;
61   protected int _endLine;
62   
63   protected JavaGenerator _gen;
64
65   protected QName _name;
66   protected XslNode _parent;
67
68   protected ArrayList JavaDoc<XslNode> _children;
69   protected NamespaceContext _matchNamespace;
70   protected NamespaceContext _outputNamespace;
71
72   private int _varCount;
73
74   protected XslNode()
75   {
76   }
77
78   /**
79    * Sets the Java generator.
80    */

81   public void setGenerator(JavaGenerator gen)
82   {
83     _gen = gen;
84   }
85
86   /**
87    * Returns the qname of the node.
88    */

89   public QName getQName()
90   {
91     return _name;
92   }
93
94   /**
95    * Sets the node's qname
96    */

97   public void setQName(QName name)
98   {
99     _name = name;
100   }
101
102   /**
103    * Returns the qname of the node.
104    */

105   public String JavaDoc getTagName()
106   {
107     if (_name != null)
108       return _name.getName();
109     else
110       return getClass().getName();
111   }
112   
113   /**
114    * Returns the parent node.
115    */

116   public XslNode getParent()
117   {
118     return _parent;
119   }
120
121   /**
122    * Sets the parent node
123    */

124   public void setParent(XslNode parent)
125   {
126     _parent = parent;
127
128     if (parent != null) {
129       _matchNamespace = parent.getMatchNamespace();
130       _outputNamespace = parent.getOutputNamespace();
131     }
132   }
133
134   /**
135    * Add variable.
136    */

137   public void addVariableCount()
138   {
139     if (_parent != null)
140       _parent._varCount++;
141   }
142
143   /**
144    * Sets the start location of the node.
145    */

146   public void setStartLocation(String JavaDoc systemId, String JavaDoc filename, int line)
147   {
148     _systemId = systemId;
149     _filename = filename;
150     _startLine = line;
151   }
152
153   /**
154    * Sets the end location of the node.
155    */

156   public void setEndLocation(String JavaDoc filename, int line)
157   {
158     if (_filename != null && _filename.equals(filename))
159       _endLine = line;
160   }
161
162   /**
163    * Gets the system id of the node
164    */

165   public String JavaDoc getSystemId()
166   {
167     return _systemId;
168   }
169
170   /**
171    * Gets the filename of the node
172    */

173   public String JavaDoc getFilename()
174   {
175     return _filename;
176   }
177
178   /**
179    * Gets the starting line number
180    */

181   public int getStartLine()
182   {
183     return _startLine;
184   }
185
186   /**
187    * Gets the ending line number
188    */

189   public int getEndLine()
190   {
191     return _endLine;
192   }
193
194   /**
195    * Returns the base URI.
196    */

197   public String JavaDoc getBaseURI()
198   {
199     return _filename;
200   }
201
202   /**
203    * Returns the namespaces.
204    */

205   public NamespaceContext getMatchNamespace()
206   {
207     return _matchNamespace;
208   }
209
210   /**
211    * Returns the namespaces.
212    */

213   public NamespaceContext getOutputNamespace()
214   {
215     return _outputNamespace;
216   }
217
218   /**
219    * Returns the matching node in the namespace.
220    */

221   public String JavaDoc getNamespace(String JavaDoc prefix)
222   {
223     return NamespaceContext.find(getOutputNamespace(), prefix);
224   }
225
226   /**
227    * Adds an attribute.
228    */

229   public void addAttribute(QName name, String JavaDoc value)
230     throws XslParseException
231   {
232     if (name.getName().startsWith("xmlns")) {
233       addNamespaceAttribute(name, value);
234       return;
235     }
236     
237     if (name.getName().startsWith("xml"))
238       return;
239     
240     throw error(L.l("attribute `{0}' is not allowed in <{1}>.",
241                     name.getName(), getTagName()));
242   }
243
244   /**
245    * Adds an attribute.
246    */

247   protected void addNamespaceAttribute(QName name, String JavaDoc url)
248     throws XslParseException
249   {
250     // Note: according to the spec, the default namespace is not used
251

252     /*
253     if (url.equals(JavaGenerator.XSLNS) || url.equals(JavaGenerator.XTPNS))
254       return;
255
256     if (url.startsWith("quote:"))
257       url = url.substring(6);
258     */

259     
260     String JavaDoc localName = name.getLocalName();
261
262
263     _outputNamespace = new NamespaceContext(_outputNamespace, localName, url);
264
265     if (! localName.equals("xmlns")) {
266       // xsl/04w3
267
_matchNamespace = new NamespaceContext(_matchNamespace, localName, url);
268     }
269   }
270
271   /**
272    * Called after all the attributes from the tag.
273    */

274   public void endAttributes()
275     throws XslParseException
276   {
277   }
278
279   /**
280    * Adds text.
281    */

282   public void addText(String JavaDoc text)
283     throws XslParseException
284   {
285     for (int i = 0; i < text.length(); i++) {
286       char ch = text.charAt(i);
287
288       if (! XmlChar.isWhitespace(ch))
289         throw error(L.l("Text is not allowed in <{0}> at `{1}'.",
290                         _name.getName(), text));
291     }
292   }
293
294   /**
295    * Adds a child node.
296    */

297   public void addChild(XslNode node)
298     throws XslParseException
299   {
300     if (node == null)
301       return;
302     
303     if (_children == null)
304       _children = new ArrayList JavaDoc<XslNode>();
305
306     _children.add(node);
307   }
308
309   /**
310    * Called when the tag closes.
311    */

312   public void endElement()
313     throws Exception JavaDoc
314   {
315   }
316
317   /**
318    * Returns the children.
319    */

320   public ArrayList JavaDoc<XslNode> getChildren()
321   {
322     return _children;
323   }
324
325   /**
326    * Returns true if there are any children.
327    */

328   public boolean hasChildren()
329   {
330     return _children != null && _children.size() > 0;
331   }
332
333   /**
334    * Generates the code for the tag
335    *
336    * @param out the output writer for the generated java.
337    */

338   abstract public void generate(JavaWriter out)
339     throws Exception JavaDoc;
340
341   /**
342    * Generates the code for the children.
343    *
344    * @param out the output writer for the generated java.
345    */

346   public void generateChildren(JavaWriter out)
347     throws Exception JavaDoc
348   {
349     if (_children == null)
350       return;
351
352     for (int i = 0; i < _children.size(); i++) {
353       XslNode child = _children.get(i);
354
355       out.setLocation(child.getFilename(), child.getStartLine());
356       
357       child.generate(out);
358     }
359
360     popScope(out);
361   }
362
363   /**
364    * Generates the prelude code for the tag
365    *
366    * @param out the output writer for the generated java.
367    */

368   public void generateDeclaration(JavaWriter out)
369     throws Exception JavaDoc
370   {
371     generateDeclarationChildren(out);
372   }
373
374   /**
375    * Generates the declaration code for the children.
376    *
377    * @param out the output writer for the generated java.
378    */

379   public void generateDeclarationChildren(JavaWriter out)
380     throws Exception JavaDoc
381   {
382     if (_children == null)
383       return;
384
385     for (int i = 0; i < _children.size(); i++) {
386       XslNode child = _children.get(i);
387
388       child.generateDeclaration(out);
389     }
390   }
391
392   /**
393    * Prints an attribute value.
394    */

395   protected void printAttributeValue(JavaWriter out, String JavaDoc name, String JavaDoc value)
396     throws Exception JavaDoc
397   {
398     out.print("out.attribute(");
399     out.print(name == null ? "null" : ("\"" + name + "\""));
400     out.print(", ");
401     if (value == null)
402       out.print("null");
403     else {
404       out.print("\"");
405       out.printJavaString(value);
406       out.print("\"");
407     }
408     out.println(");");
409   }
410
411   /**
412    * Prints an attribute value.
413    */

414   protected void printAttributeValue(JavaWriter out, String JavaDoc value)
415     throws Exception JavaDoc
416   {
417     if (value == null) {
418       out.print("null");
419       return;
420     }
421
422     if (value.indexOf("{") < 0) {
423       out.print("\"");
424       out.printJavaString(value);
425       out.print("\"");
426     }
427     else {
428       generateString(out, value);
429     }
430   }
431
432   /**
433    * Produces code to generate an attribute value template. The same
434    * code is used to produce a string ('a{b}c' -> "a" + b + "c") or a series of
435    * print statements (',').
436    *
437    * @param string the source template
438    * @param mode separator: either '+' or ','
439    * @param elt the containing element. Needed for namespaces.
440    */

441   void generateString(JavaWriter out, String JavaDoc string)
442     throws Exception JavaDoc
443   {
444     int i = 0;
445     boolean first = true;
446     int length = string.length();
447     CharBuffer cb = CharBuffer.allocate();
448
449     for (; i < length; i++) {
450       char ch = string.charAt(i);
451
452       if (ch == '\n') {
453     cb.append("\\n");
454       }
455       else if (ch == '"') {
456     cb.append("\\\"");
457       }
458       else if (ch == '{' && i + 1 < length) {
459     // {{ is treated as a single {
460
if (string.charAt(i + 1) == '{') {
461       cb.append('{');
462       i++;
463     }
464     // the value is computed from an XPath expr
465
else {
466       // print the gathered text if any
467
if (cb.length() > 0) {
468         out.print("out.print(\"");
469         out.printJavaString(cb.toString());
470         out.println("\");");
471       }
472
473       // scan the contents of '{' ... '}'
474
cb.clear();
475       for (i++; i < length && string.charAt(i) != '}'; i++)
476         cb.append(string.charAt(i));
477
478       printStringExpr(out, cb.toString());
479
480       cb.clear();
481       first = false;
482     }
483       }
484       // }} is treated as a single }
485
else if (ch == '}' && i + 1 < length) {
486     if (string.charAt(i + 1) == '}') {
487       cb.append('}');
488       i++;
489     }
490     else
491       cb.append('}');
492       }
493       // <#= interpolates
494
else if (i + 2 < length && ch == '<' &&
495            string.charAt(i + 1) == '#' &&
496            string.charAt(i + 2) == '=') {
497     // print the gathered text if any
498
if (cb.length() > 0) {
499       out.print("out.print(\"");
500       out.printJavaString(cb.toString());
501       out.println("\");");
502     }
503
504     // scan the contents of '{' ... '}'
505
cb.clear();
506     for (i += 3;
507          i + 1 < length && string.charAt(i) != '#' &&
508            string.charAt(i + 1) != '>';
509          i++)
510       cb.append(string.charAt(i));
511
512     i++;
513     
514     // and add the results
515
out.println("out.print(" + cb + ");");
516     
517     cb.clear();
518     first = false;
519       }
520       else
521     cb.append((char) ch);
522     }
523
524     // add any trailing text
525
if (cb.length() > 0)
526       out.println("out.print(\"" + cb + "\");");
527   }
528
529   /**
530    * Produces code to generate an attribute value template. The same
531    * code is used to produce a string ('a{b}c' -> "a" + b + "c") or a series of
532    * print statements (',').
533    *
534    * @param string the source template
535    * @param mode separator: either '+' or ','
536    * @param elt the containing element. Needed for namespaces.
537    */

538   void generateString(JavaWriter out, String JavaDoc string, int mode)
539     throws Exception JavaDoc
540   {
541     CharBuffer cb = new CharBuffer();
542     int i = 0;
543     boolean first = true;
544     int length = string.length();
545
546     for (; i < length; i++) {
547       char ch = string.charAt(i);
548
549       if (ch == '\n') {
550     cb.append("\\n");
551       }
552       else if (ch == '"') {
553     cb.append("\\\"");
554       }
555       else if (ch == '{' && i + 1 < length) {
556     // {{ is treated as a single {
557
if (string.charAt(i + 1) == '{') {
558       cb.append('{');
559       i++;
560     }
561     // the value is computed from an XPath expr
562
else {
563       // print the gathered text if any
564
if (mode == ',') {
565         if (cb.length() > 0)
566           out.println("out.print(\"" + cb.toString() + "\");");
567       }
568       else {
569         if (! first)
570           out.print((char) mode);
571
572         if (cb.length() > 0) {
573           out.print("\"");
574           out.print(cb.toString());
575           out.print("\"");
576           out.print((char) mode);
577         }
578       }
579
580       // scan the contents of '{' ... '}'
581
cb.clear();
582       for (i++; i < length && string.charAt(i) != '}'; i++)
583         cb.append(string.charAt(i));
584
585       // and add the results
586
if (mode == ',')
587         printStringExpr(out, cb.toString());
588       else
589         stringExpr(out, cb.toString());
590       cb.clear();
591       first = false;
592     }
593       }
594       // }} is treated as a single }
595
else if (ch == '}' && i + 1 < length) {
596     if (string.charAt(i + 1) == '}') {
597       cb.append('}');
598       i++;
599     }
600     else
601       cb.append('}');
602       }
603       // <#= interpolates
604
else if (i + 2 < length && ch == '<' &&
605            string.charAt(i + 1) == '#' &&
606            string.charAt(i + 2) == '=') {
607     // print the gathered text if any
608
if (mode == ',') {
609       if (cb.length() > 0)
610         out.println("out.print(\"" + cb.toString() + "\");");
611     }
612     else {
613       if (! first)
614         out.print((char) mode);
615
616       if (cb.length() > 0) {
617         out.print("\"");
618         out.print(cb.toString());
619         out.print("\"");
620         out.print((char) mode);
621       }
622     }
623
624     // scan the contents of '{' ... '}'
625
cb.clear();
626     for (i += 3;
627          i + 1 < length && string.charAt(i) != '#' &&
628            string.charAt(i + 1) != '>';
629          i++)
630       cb.append(string.charAt(i));
631
632     i++;
633     
634     // and add the results
635
if (mode == ',')
636       out.println("out.print(" + cb + ");");
637     else {
638       out.print("(" + cb + ")");
639     }
640     cb.clear();
641     first = false;
642       }
643       else
644     cb.append((char) ch);
645     }
646
647     // add any trailing text
648
if (cb.length() > 0) {
649       if (mode == ',')
650     out.println("out.print(\"" + cb + "\");");
651       else {
652     if (! first)
653       out.print((char) mode);
654
655     out.print("\"" + cb + "\"");
656       }
657     } else if (first && mode == '+')
658       out.print("\"\"");
659   }
660
661   /**
662    * Prints a value-of expression
663    */

664   protected void printStringExpr(JavaWriter out, String JavaDoc exprString)
665     throws Exception JavaDoc
666   {
667     if (exprString == null)
668       return;
669     
670     int length = exprString.length();
671     
672     if (length == 0)
673       return;
674
675     AbstractPattern select = null;
676     try {
677       select = parseSelect(exprString);
678     } catch (Exception JavaDoc e) {
679       // this is expected in case where the expr is not a select expression
680
}
681     
682     if (exprString.equals(".")) {
683       out.println("out.valueOf(node);");
684       return;
685     }
686     else if (exprString.charAt(0) == '@') {
687       boolean isSimple = true;
688       
689       for (int i = 1; i < length; i++) {
690         char ch = exprString.charAt(i);
691         if (! XmlChar.isNameChar(ch) || ch == ':')
692           isSimple = false;
693       }
694
695       if (isSimple) {
696         out.println("if (node instanceof Element)");
697         out.print(" out.print(((Element) node).getAttribute(\"");
698         out.print(exprString.substring(1));
699         out.println("\"));");
700         return;
701       }
702     }
703     else if (allowJavaSelect(select)) {
704       int oldSelectDepth = _gen.getSelectDepth();
705
706       String JavaDoc loop = "_xsl_loop" + _gen.generateId();
707       _gen.setSelectLoopDepth(0);
708       
709       String JavaDoc ptr = printSelectBegin(out, select, true, loop);
710
711       out.println("out.valueOf(" + ptr + ");");
712       out.println("break " + loop + ";");
713
714       int selectDepth = _gen.getSelectDepth();
715       for (; oldSelectDepth < selectDepth; selectDepth--) {
716         out.popDepth();
717         out.println("}");
718       }
719       _gen.setSelectDepth(oldSelectDepth);
720
721       return;
722     }
723
724     out.println("out.valueOf(_exprs[" + addExpr(exprString) +
725         "].evalObject(node, " + _gen.getEnv() + "));");
726   }
727
728   protected void stringExpr(JavaWriter out, String JavaDoc exprString)
729     throws Exception JavaDoc, XslParseException
730   {
731     out.print("_exprs[" + _gen.addExpr(parseExpr(exprString)) +
732           "].evalString(node, " + getEnv() + ")");
733   }
734
735   protected void pushCall(JavaWriter out)
736     throws IOException JavaDoc
737   {
738     out.println("{");
739     out.pushDepth();
740
741     int callDepth = _gen.pushCallDepth();
742     
743     out.println("Env _xsl_arg" + callDepth + " = XPath.createCall(env);");
744   }
745
746   protected void popCall(JavaWriter out)
747     throws IOException JavaDoc
748   {
749     int callDepth = _gen.popCallDepth();
750     out.println("_xsl_arg" + callDepth + ".free();");
751     
752     out.popDepth();
753     out.println("}");
754   }
755
756   /**
757    * Prints iterator code to start a select.
758    */

759   protected String JavaDoc printSelectBegin(JavaWriter out,
760                     AbstractPattern select,
761                     boolean isForEach, String JavaDoc loopVar)
762     throws IOException JavaDoc, XslParseException
763   {
764     if (select == null)
765       throw new NullPointerException JavaDoc();
766     
767     if (select instanceof FromContext &&
768         ((FromContext) select).getCount() == 0)
769       return "node";
770
771     else if (select instanceof FromRoot)
772       return "ownerDocument(node)";
773
774     boolean useXPath = allowJavaSelect(select);
775     
776     String JavaDoc name = "node";
777
778     if (! useXPath) {
779       // punt and let XPath handle it.
780
String JavaDoc iterName = "_xsl_iter" + _gen.generateId();
781       
782       String JavaDoc ptrName = "_xsl_ptr" + _gen.generateId();
783
784       if (isForEach)
785         out.println("env.setCurrentNode(node);");
786       
787       out.println("Iterator " + iterName + " = _select_patterns[" +
788           _gen.addSelect(select) + "].select(" + name + ", env);");
789       
790       if (loopVar != null && _gen.getSelectLoopDepth() == 0)
791         out.println(loopVar + ":");
792       
793       out.println("while (" + iterName + ".hasNext()) {");
794       out.pushDepth();
795       _gen.pushSelectDepth();
796       _gen.pushSelectLoopDepth();
797       out.println("Node " + ptrName + " = (Node) " + iterName + ".next();");
798
799       return ptrName;
800     }
801
802     if (select instanceof FromChildren) {
803       name = printSelectBegin(out, select.getParent(), isForEach, loopVar);
804       
805       String JavaDoc ptrName = "_xsl_ptr" + _gen.generateId();
806
807       if (loopVar != null && _gen.getSelectLoopDepth() == 0)
808         out.println(loopVar + ":");
809       
810       out.println("for (Node " + ptrName + " = " + name + ".getFirstChild();");
811       out.println(" " + ptrName + " != null;");
812       out.println(" " + ptrName + " = " + ptrName + ".getNextSibling()) {");
813       out.pushDepth();
814       _gen.pushSelectDepth();
815       _gen.pushSelectLoopDepth();
816
817       return ptrName;
818     }
819     else if (select instanceof FromNextSibling) {
820       name = printSelectBegin(out, select.getParent(), isForEach, loopVar);
821       
822       String JavaDoc ptrName = "_xsl_ptr" + _gen.generateId();
823       
824       if (loopVar != null && _gen.getSelectLoopDepth() == 0)
825         out.println(loopVar + ":");
826       
827       out.println("for (Node " + ptrName + " = " + name + ".getNextSibling();");
828       out.println(" " + ptrName + " != null;");
829       out.println(" " + ptrName + " = " + ptrName + ".getNextSibling()) {");
830       out.pushDepth();
831       _gen.pushSelectDepth();
832       _gen.pushSelectLoopDepth();
833
834       return ptrName;
835     }
836     else if (select instanceof NodePattern) {
837       name = printSelectBegin(out, select.getParent(), isForEach, loopVar);
838       
839       NodePattern pat = (NodePattern) select;
840       
841       out.println("if (" + name + ".getNodeName() == \"" + pat.getNodeName() + "\" &&");
842       out.println(" " + name + " instanceof Element) {");
843       out.pushDepth();
844       _gen.pushSelectDepth();
845
846       return name;
847     }
848     else if (select instanceof NodeTypePattern) {
849       name = printSelectBegin(out, select.getParent(), isForEach, loopVar);
850       
851       NodeTypePattern pat = (NodeTypePattern) select;
852
853       if (pat.getNodeType() >= 0) {
854         out.println("if (" + name + ".getNodeType() == " + pat.getNodeType() + ") {");
855         out.pushDepth();
856         _gen.pushSelectDepth();
857       }
858
859       return name;
860     }
861     else if (select instanceof FilterPattern) {
862       String JavaDoc posId = "_xsl_pos" + _gen.generateId();
863
864       out.println("int " + posId + " = 0;");
865       
866       name = printSelectBegin(out, select.getParent(), isForEach, loopVar);
867
868       out.println(posId + "++;");
869       
870       FilterPattern pat = (FilterPattern) select;
871       Expr expr = pat.getExpr();
872
873       if (expr instanceof NumericExpr) {
874         NumericExpr num = (NumericExpr) expr;
875         if (num.isConstant()) {
876           out.println("if (" + posId + " > " + (int) num.getValue() + ")");
877           out.println(" break;");
878           out.println("else if (" + posId + " == " + (int) num.getValue() + ") {");
879           out.pushDepth();
880           _gen.pushSelectDepth();
881
882           return name;
883         }
884       }
885
886       throw new RuntimeException JavaDoc();
887     }
888
889     throw new RuntimeException JavaDoc(String.valueOf(select));
890   }
891
892   /**
893    * Returns true if we can compile in the java select.
894    */

895   protected boolean allowJavaSelect(AbstractPattern select)
896   {
897     if (select == null)
898       return false;
899
900     else if (! select.isStrictlyAscending())
901       return false;
902     
903     else if (select instanceof FromContext)
904       return ((FromContext) select).getCount() == 0;
905
906     else if (select instanceof FromRoot)
907       return true;
908
909     else if (select instanceof NodePattern)
910       return allowJavaSelect(select.getParent());
911
912     else if (select instanceof NodeTypePattern)
913       return allowJavaSelect(select.getParent());
914
915     else if (select instanceof FromChildren)
916       return allowJavaSelect(select.getParent());
917
918     else if (select instanceof FromNextSibling)
919       return allowJavaSelect(select.getParent());
920
921     else if (select instanceof FilterPattern) {
922       if (! allowJavaSelect(select.getParent()))
923         return false;
924
925       Expr expr = ((FilterPattern) select).getExpr();
926
927       return ((expr instanceof NumericExpr) &&
928               ((NumericExpr) expr).isConstant());
929     }
930
931     else
932       return false;
933   }
934
935   protected void printNamespace(JavaWriter out, NamespaceContext namespace)
936     throws Exception JavaDoc
937   {
938     int index = _gen.addNamespace(namespace);
939
940     out.print("_namespaces[" + index + "]");
941   }
942
943   /**
944    * Prints the children as a fragment stored in a variable.
945    */

946   protected void printFragmentString(JavaWriter out, String JavaDoc id)
947     throws Exception JavaDoc
948   {
949     String JavaDoc fragId = "_frag_" + _gen.generateId();
950     
951     out.println("XMLWriter " + fragId + " = out.pushFragment();");
952
953     generateChildren(out);
954
955     out.println(id + " = com.caucho.xml.XmlUtil.textValue(out.popFragment(" + fragId + "));");
956   }
957
958   /**
959    * Prints the children as a fragment stored in a variable.
960    */

961   protected void printFragmentValue(JavaWriter out, String JavaDoc id)
962     throws Exception JavaDoc
963   {
964     String JavaDoc fragId = "_frag_" + _gen.generateId();
965     
966     out.println("XMLWriter " + fragId + " = out.pushFragment();");
967
968     generateChildren(out);
969
970     out.println(id + " = out.popFragment(" + fragId + ");");
971   }
972
973   protected void popScope(JavaWriter out)
974     throws Exception JavaDoc
975   {
976     printPopScope(out);
977   }
978
979   protected void printPopScope(JavaWriter out)
980     throws Exception JavaDoc
981   {
982     if (_varCount > 0)
983       out.println("env.popVars(" + _varCount + ");");
984   }
985
986   /**
987    * Prints a test expr.
988    */

989   protected void printExprTest(JavaWriter out, int id, String JavaDoc node)
990     throws IOException JavaDoc
991   {
992     out.print("_exprs[" + id + "].evalBoolean(" + node +
993           ", " + getEnv() + ")");
994   }
995
996   public AbstractPattern parseMatch(String JavaDoc pattern)
997     throws XslParseException, IOException JavaDoc
998   {
999     try {
1000      return XPath.parseMatch(pattern, getMatchNamespace()).getPattern();
1001    } catch (Exception JavaDoc e) {
1002      throw error(L.l("{0} in pattern `{1}'",
1003                      e.toString(), pattern));
1004    }
1005  }
1006
1007  protected AbstractPattern parseSelect(String JavaDoc pattern)
1008    throws XslParseException
1009  {
1010    try {
1011      return XPath.parseSelect(pattern, getMatchNamespace()).getPattern();
1012    } catch (Exception JavaDoc e) {
1013      throw error(e);
1014    }
1015  }
1016
1017  protected int addExpr(String JavaDoc pattern)
1018    throws XslParseException
1019  {
1020    return _gen.addExpr(parseExpr(pattern));
1021  }
1022
1023  /**
1024   * Parses an XPath expression in the current context.
1025   */

1026  protected Expr parseExpr(String JavaDoc pattern)
1027    throws XslParseException
1028  {
1029    try {
1030      return XPath.parseExpr(pattern,
1031                 getMatchNamespace(),
1032                 _gen.getNodeListContext());
1033    } catch (Exception JavaDoc e) {
1034      throw error(e);
1035    }
1036  }
1037
1038  protected int generateId()
1039  {
1040    return _gen.generateId();
1041  }
1042
1043  protected String JavaDoc getEnv()
1044  {
1045    return _gen.getEnv();
1046  }
1047
1048  public String JavaDoc escapeJavaString(String JavaDoc s)
1049  {
1050    if (s == null)
1051      return "";
1052
1053    CharBuffer cb = CharBuffer.allocate();
1054    for (int i = 0; i < s.length(); i++) {
1055      if (s.charAt(i) == '\\')
1056        cb.append("\\\\");
1057      else if (s.charAt(i) == '"')
1058        cb.append("\\\"");
1059      else if (s.charAt(i) == '\n')
1060        cb.append("\\n");
1061      else if (s.charAt(i) == '\r')
1062        cb.append("\\r");
1063      else
1064        cb.append(s.charAt(i));
1065    }
1066
1067    return cb.close();
1068  }
1069
1070  /**
1071   * Creates a parse exception with the proper line information.
1072   */

1073  protected XslParseException error(String JavaDoc msg)
1074  {
1075    String JavaDoc filename = _filename;
1076    if (filename == null)
1077      filename = _systemId;
1078    
1079    if (filename != null)
1080      return new XslParseException(filename + ":" + _startLine + ": " + msg);
1081    else
1082      return new XslParseException(msg);
1083  }
1084
1085  /**
1086   * Creates a parse exception with the proper line information.
1087   */

1088  protected XslParseException error(Throwable JavaDoc e)
1089  {
1090    String JavaDoc filename = _filename;
1091    if (filename == null)
1092      filename = _systemId;
1093    
1094    if (filename == null || e instanceof LineCompileException)
1095      return new XslParseException(e);
1096    else if (e instanceof CompileException)
1097      return new XslParseException(filename + ":" + _startLine + ": " +
1098                                   e.getMessage(), e);
1099    else
1100      return new XslParseException(_filename + ":" + _startLine + ": " +
1101                                   String.valueOf(e), e);
1102  }
1103
1104  /**
1105   * Returns a printable version of the node.
1106   */

1107  public String JavaDoc toString()
1108  {
1109    if (_name == null)
1110      return "<" + getClass().getName() + ">";
1111    else
1112      return "<" + _name.getName() + ">";
1113  }
1114}
1115
Popular Tags