1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the  "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 /*
19  * $Id: Stylesheet.java 468643 2006-10-28 06:56:03Z minchau $
20  */
21 package org.apache.xalan.templates;
22 
23 import java.io.IOException;
24 import java.io.ObjectInputStream;
25 import java.io.ObjectOutputStream;
26 import java.util.Hashtable;
27 import java.util.Stack;
28 import java.util.Vector;
29 
30 import javax.xml.transform.SourceLocator;
31 import javax.xml.transform.TransformerException;
32 
33 import org.apache.xml.dtm.DTM;
34 import org.apache.xml.utils.QName;
35 import org.apache.xml.utils.StringVector;
36 import org.apache.xml.utils.SystemIDResolver;
37 
38 /**
39  * Represents a stylesheet element.
40  * <p>All properties in this class have a fixed form of bean-style property
41  * accessors for all properties that represent XSL attributes or elements.
42  * These properties have setter method names accessed generically by the
43  * processor, and so these names must be fixed according to the system
44  * defined in the <a href="XSLTAttributeDef#getSetterMethodName">getSetterMethodName</a>
45  * function.</p>
46  * <p><pre>
47  * <!ENTITY % top-level "
48  *  (xsl:import*,
49  *   (xsl:include
50  *   | xsl:strip-space
51  *   | xsl:preserve-space
52  *   | xsl:output
53  *   | xsl:key
54  *   | xsl:decimal-format
55  *   | xsl:attribute-set
56  *   | xsl:variable
57  *   | xsl:param
58  *   | xsl:template
59  *   | xsl:namespace-alias
60  *   %non-xsl-top-level;)*)
61  * ">
62  *
63  * <!ENTITY % top-level-atts '
64  *   extension-element-prefixes CDATA #IMPLIED
65  *   exclude-result-prefixes CDATA #IMPLIED
66  *   id ID #IMPLIED
67  *   version NMTOKEN #REQUIRED
68  *   xmlns:xsl CDATA #FIXED "http://www.w3.org/1999/XSL/Transform"
69  *   %space-att;
70  * '>
71  *
72  * <!ELEMENT xsl:stylesheet %top-level;>
73  * <!ATTLIST xsl:stylesheet %top-level-atts;>
74  *
75  * <!ELEMENT xsl:transform %top-level;>
76  * <!ATTLIST xsl:transform %top-level-atts;>
77  *
78  * </p></pre>
79  * @see <a href="http://www.w3.org/TR/xslt#section-Stylesheet-Structure">section-Stylesheet-Structure in XSLT Specification</a>
80  */
81 public class Stylesheet extends ElemTemplateElement
82         implements java.io.Serializable /* , Document */
83 {
84     static final long serialVersionUID = 2085337282743043776L;
85 
86   /**
87    * Constructor for a Stylesheet.
88    * @param parent  The including or importing stylesheet.
89    */
Stylesheet(Stylesheet parent)90   public Stylesheet(Stylesheet parent)
91   {
92 
93     if (null != parent)
94     {
95       m_stylesheetParent = parent;
96       m_stylesheetRoot = parent.getStylesheetRoot();
97     }
98   }
99 
100   /**
101    * Get the owning stylesheet.  This looks up the
102    * inheritance chain until it calls getStylesheet
103    * on a Stylesheet object, which will return itself.
104    *
105    * @return The owning stylesheet, itself.
106    */
getStylesheet()107   public Stylesheet getStylesheet()
108   {
109     return this;
110   }
111 
112   /**
113    * Tell if this can be cast to a StylesheetComposed, meaning, you
114    * can ask questions from getXXXComposed functions.
115    *
116    * @return False if this is not a StylesheetComposed
117    */
isAggregatedType()118   public boolean isAggregatedType()
119   {
120     return false;
121   }
122 
123   /**
124    * Tell if this is the root of the stylesheet tree.
125    *
126    * @return False is this is not the root of the stylesheet tree.
127    */
isRoot()128   public boolean isRoot()
129   {
130     return false;
131   }
132 
133   /**
134    * Extension to be used when serializing to disk.
135    */
136   public static final String STYLESHEET_EXT = ".lxc";
137 
138   /**
139    * Read the stylesheet from a serialization stream.
140    *
141    * @param stream Input stream to read from
142    *
143    * @throws IOException
144    * @throws TransformerException
145    */
readObject(ObjectInputStream stream)146   private void readObject(ObjectInputStream stream)
147           throws IOException, TransformerException
148   {
149 
150     // System.out.println("Reading Stylesheet");
151     try
152     {
153       stream.defaultReadObject();
154     }
155     catch (ClassNotFoundException cnfe)
156     {
157       throw new TransformerException(cnfe);
158     }
159 
160     // System.out.println("Done reading Stylesheet");
161   }
162 
163   /**
164    * Write out the given output stream
165    *
166    *
167    * @param stream The output stream to write out
168    *
169    * @throws IOException
170    */
writeObject(ObjectOutputStream stream)171   private void writeObject(ObjectOutputStream stream) throws IOException
172   {
173 
174     // System.out.println("Writing Stylesheet");
175     stream.defaultWriteObject();
176 
177     // System.out.println("Done writing Stylesheet");
178   }
179 
180   //============== XSLT Properties =================
181 
182   /**
183    * The "xmlns:xsl" property.
184    * @serial
185    */
186   private String m_XmlnsXsl;
187 
188   /**
189    * Set the "xmlns:xsl" property.
190    * @see <a href="http://www.w3.org/TR/xslt#xslt-namespace">xslt-namespace in XSLT Specification</a>
191    *
192    * @param v The value to be set for the "xmlns:xsl" property.
193    */
setXmlnsXsl(String v)194   public void setXmlnsXsl(String v)
195   {
196     m_XmlnsXsl = v;
197   }
198 
199   /**
200    * Get the "xmlns:xsl" property.
201    * @see <a href="http://www.w3.org/TR/xslt#xslt-namespace">xslt-namespace in XSLT Specification</a>
202    *
203    * @return The value of the "xmlns:xsl" property.
204    */
getXmlnsXsl()205   public String getXmlnsXsl()
206   {
207     return m_XmlnsXsl;
208   }
209 
210   /**
211    * The "extension-element-prefixes" property, actually contains URIs.
212    * @serial
213    */
214   private StringVector m_ExtensionElementURIs;
215 
216   /**
217    * Set the "extension-element-prefixes" property.
218    * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
219    *
220    * @param v The value to be set for the "extension-element-prefixes"
221    * property: a vector of extension element URIs.
222    */
setExtensionElementPrefixes(StringVector v)223   public void setExtensionElementPrefixes(StringVector v)
224   {
225     m_ExtensionElementURIs = v;
226   }
227 
228   /**
229    * Get and "extension-element-prefix" property.
230    * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
231    *
232    * @param i Index of extension element URI in list
233    *
234    * @return The extension element URI at the given index
235    *
236    * @throws ArrayIndexOutOfBoundsException
237    */
getExtensionElementPrefix(int i)238   public String getExtensionElementPrefix(int i)
239           throws ArrayIndexOutOfBoundsException
240   {
241 
242     if (null == m_ExtensionElementURIs)
243       throw new ArrayIndexOutOfBoundsException();
244 
245     return m_ExtensionElementURIs.elementAt(i);
246   }
247 
248   /**
249    * Get the number of "extension-element-prefixes" Strings.
250    * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
251    *
252    * @return Number of URIs in the list
253    */
getExtensionElementPrefixCount()254   public int getExtensionElementPrefixCount()
255   {
256     return (null != m_ExtensionElementURIs)
257            ? m_ExtensionElementURIs.size() : 0;
258   }
259 
260   /**
261    * Find out if this contains a given "extension-element-prefix" property.
262    * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
263    *
264    * @param uri URI of extension element to look for
265    *
266    * @return True if the given URI was found in the list
267    */
containsExtensionElementURI(String uri)268   public boolean containsExtensionElementURI(String uri)
269   {
270 
271     if (null == m_ExtensionElementURIs)
272       return false;
273 
274     return m_ExtensionElementURIs.contains(uri);
275   }
276 
277   /**
278    * The "exclude-result-prefixes" property.
279    * @serial
280    */
281   private StringVector m_ExcludeResultPrefixs;
282 
283   /**
284    * Set the "exclude-result-prefixes" property.
285    * The designation of a namespace as an excluded namespace is
286    * effective within the subtree of the stylesheet rooted at
287    * the element bearing the exclude-result-prefixes or
288    * xsl:exclude-result-prefixes attribute; a subtree rooted
289    * at an xsl:stylesheet element does not include any stylesheets
290    * imported or included by children of that xsl:stylesheet element.
291    * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
292    *
293    * @param v A StringVector of prefixes to exclude
294    */
setExcludeResultPrefixes(StringVector v)295   public void setExcludeResultPrefixes(StringVector v)
296   {
297     m_ExcludeResultPrefixs = v;
298   }
299 
300   /**
301    * Get an "exclude-result-prefix" property.
302    * The designation of a namespace as an excluded namespace is
303    * effective within the subtree of the stylesheet rooted at
304    * the element bearing the exclude-result-prefixes or
305    * xsl:exclude-result-prefixes attribute; a subtree rooted
306    * at an xsl:stylesheet element does not include any stylesheets
307    * imported or included by children of that xsl:stylesheet element.
308    * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
309    *
310    * @param i Index of prefix to get in list
311    *
312    * @return Prefix to be excluded at the given index
313    *
314    * @throws ArrayIndexOutOfBoundsException
315    */
getExcludeResultPrefix(int i)316   public String getExcludeResultPrefix(int i)
317           throws ArrayIndexOutOfBoundsException
318   {
319 
320     if (null == m_ExcludeResultPrefixs)
321       throw new ArrayIndexOutOfBoundsException();
322 
323     return m_ExcludeResultPrefixs.elementAt(i);
324   }
325 
326   /**
327    * Get the number of "exclude-result-prefixes" Strings.
328    * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
329    *
330    * @return The number of prefix strings to be excluded.
331    */
getExcludeResultPrefixCount()332   public int getExcludeResultPrefixCount()
333   {
334     return (null != m_ExcludeResultPrefixs)
335            ? m_ExcludeResultPrefixs.size() : 0;
336   }
337 
338   /**
339    * Get whether or not the passed prefix is contained flagged by
340    * the "exclude-result-prefixes" property.
341    * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
342    *
343    * @param prefix non-null reference to prefix that might be excluded.
344    * @param uri reference to namespace that prefix maps to
345    *
346    * @return true if the prefix should normally be excluded.>
347    */
containsExcludeResultPrefix(String prefix, String uri)348   public boolean containsExcludeResultPrefix(String prefix, String uri)
349   {
350 
351     if (null == m_ExcludeResultPrefixs || uri == null )
352       return false;
353 
354     // This loop is ok here because this code only runs during
355     // stylesheet compile time.
356     for (int i =0; i< m_ExcludeResultPrefixs.size(); i++)
357     {
358       if (uri.equals(getNamespaceForPrefix(m_ExcludeResultPrefixs.elementAt(i))))
359         return true;
360     }
361 
362     return false;
363 
364   /*  if (prefix.length() == 0)
365       prefix = Constants.ATTRVAL_DEFAULT_PREFIX;
366 
367     return m_ExcludeResultPrefixs.contains(prefix); */
368   }
369 
370   /**
371    * The "id" property.
372    * @serial
373    */
374   private String m_Id;
375 
376   /**
377    * Set the "id" property.
378    * @see <a href="http://www.w3.org/TR/xslt#section-Embedding-Stylesheets">section-Embedding-Stylesheets in XSLT Specification</a>
379    *
380    * @param v Value for the "id" property.
381    */
setId(String v)382   public void setId(String v)
383   {
384     m_Id = v;
385   }
386 
387   /**
388    * Get the "id" property.
389    * @see <a href="http://www.w3.org/TR/xslt#section-Embedding-Stylesheets">section-Embedding-Stylesheets in XSLT Specification</a>
390    *
391    * @return The value of the "id" property.
392    */
getId()393   public String getId()
394   {
395     return m_Id;
396   }
397 
398   /**
399    * The "version" property.
400    * @serial
401    */
402   private String m_Version;
403 
404   /**
405    * Whether or not the stylesheet is in "Forward Compatibility Mode"
406    * @serial
407    */
408   private boolean m_isCompatibleMode = false;
409 
410   /**
411    * Set the "version" property.
412    * @see <a href="http://www.w3.org/TR/xslt#forwards">forwards in XSLT Specification</a>
413    *
414    * @param v Value for the "version" property.
415    */
setVersion(String v)416   public void setVersion(String v)
417   {
418     m_Version = v;
419     m_isCompatibleMode = (Double.valueOf(v).doubleValue() > Constants.XSLTVERSUPPORTED);
420   }
421 
422   /**
423    * Get whether or not the stylesheet is in "Forward Compatibility Mode"
424    *
425    * @return true if in forward compatible mode, false otherwise
426    */
getCompatibleMode()427   public boolean getCompatibleMode()
428   {
429   	return m_isCompatibleMode;
430   }
431 
432   /**
433    * Get the "version" property.
434    * @see <a href="http://www.w3.org/TR/xslt#forwards">forwards in XSLT Specification</a>
435    *
436    * @return The value of the "version" property.
437    */
getVersion()438   public String getVersion()
439   {
440     return m_Version;
441   }
442 
443   /**
444    * The "xsl:import" list.
445    * @serial
446    */
447   private Vector m_imports;
448 
449   /**
450    * Add a stylesheet to the "import" list.
451    * @see <a href="http://www.w3.org/TR/xslt#import">import in XSLT Specification</a>
452    *
453    * @param v Stylesheet to add to the import list
454    */
setImport(StylesheetComposed v)455   public void setImport(StylesheetComposed v)
456   {
457 
458     if (null == m_imports)
459       m_imports = new Vector();
460 
461     // I'm going to insert the elements in backwards order,
462     // so I can walk them 0 to n.
463     m_imports.addElement(v);
464   }
465 
466   /**
467    * Get a stylesheet from the "import" list.
468    * @see <a href="http://www.w3.org/TR/xslt#import">import in XSLT Specification</a>
469    *
470    * @param i Index of the stylesheet to get
471    *
472    * @return The stylesheet at the given index
473    *
474    * @throws ArrayIndexOutOfBoundsException
475    */
getImport(int i)476   public StylesheetComposed getImport(int i)
477           throws ArrayIndexOutOfBoundsException
478   {
479 
480     if (null == m_imports)
481       throw new ArrayIndexOutOfBoundsException();
482 
483     return (StylesheetComposed) m_imports.elementAt(i);
484   }
485 
486   /**
487    * Get the number of imported stylesheets.
488    * @see <a href="http://www.w3.org/TR/xslt#import">import in XSLT Specification</a>
489    *
490    * @return the number of imported stylesheets.
491    */
getImportCount()492   public int getImportCount()
493   {
494     return (null != m_imports) ? m_imports.size() : 0;
495   }
496 
497   /**
498    * The "xsl:include" properties.
499    * @serial
500    */
501   private Vector m_includes;
502 
503   /**
504    * Add a stylesheet to the "include" list.
505    * @see <a href="http://www.w3.org/TR/xslt#include">include in XSLT Specification</a>
506    *
507    * @param v Stylesheet to add to the "include" list
508    */
setInclude(Stylesheet v)509   public void setInclude(Stylesheet v)
510   {
511 
512     if (null == m_includes)
513       m_includes = new Vector();
514 
515     m_includes.addElement(v);
516   }
517 
518   /**
519    * Get the stylesheet at the given in index in "include" list
520    * @see <a href="http://www.w3.org/TR/xslt#include">include in XSLT Specification</a>
521    *
522    * @param i Index of stylesheet to get
523    *
524    * @return Stylesheet at the given index
525    *
526    * @throws ArrayIndexOutOfBoundsException
527    */
getInclude(int i)528   public Stylesheet getInclude(int i) throws ArrayIndexOutOfBoundsException
529   {
530 
531     if (null == m_includes)
532       throw new ArrayIndexOutOfBoundsException();
533 
534     return (Stylesheet) m_includes.elementAt(i);
535   }
536 
537   /**
538    * Get the number of included stylesheets.
539    * @see <a href="http://www.w3.org/TR/xslt#import">import in XSLT Specification</a>
540    *
541    * @return the number of included stylesheets.
542    */
getIncludeCount()543   public int getIncludeCount()
544   {
545     return (null != m_includes) ? m_includes.size() : 0;
546   }
547 
548   /**
549    * Table of tables of element decimal-format.
550    * @see DecimalFormatProperties
551    * @serial
552    */
553   Stack m_DecimalFormatDeclarations;
554 
555   /**
556    * Process the xsl:decimal-format element.
557    *
558    * @param edf Decimal-format element to push into stack
559    */
setDecimalFormat(DecimalFormatProperties edf)560   public void setDecimalFormat(DecimalFormatProperties edf)
561   {
562 
563     if (null == m_DecimalFormatDeclarations)
564       m_DecimalFormatDeclarations = new Stack();
565 
566     // Elements are pushed in by order of importance
567     // so that when recomposed, they get overiden properly.
568     m_DecimalFormatDeclarations.push(edf);
569   }
570 
571   /**
572    * Get an "xsl:decimal-format" property.
573    *
574    * @see DecimalFormatProperties
575    * @see <a href="http://www.w3.org/TR/xslt#format-number">format-number in XSLT Specification</a>
576    *
577    * @param name The qualified name of the decimal format property.
578    * @return null if not found, otherwise a DecimalFormatProperties
579    * object, from which you can get a DecimalFormatSymbols object.
580    */
getDecimalFormat(QName name)581   public DecimalFormatProperties getDecimalFormat(QName name)
582   {
583 
584     if (null == m_DecimalFormatDeclarations)
585       return null;
586 
587     int n = getDecimalFormatCount();
588 
589     for (int i = (n - 1); i >= 0; i++)
590     {
591       DecimalFormatProperties dfp = getDecimalFormat(i);
592 
593       if (dfp.getName().equals(name))
594         return dfp;
595     }
596 
597     return null;
598   }
599 
600   /**
601    * Get an "xsl:decimal-format" property.
602    * @see <a href="http://www.w3.org/TR/xslt#format-number">format-number in XSLT Specification</a>
603    * @see DecimalFormatProperties
604    *
605    * @param i Index of decimal-format property in stack
606    *
607    * @return The decimal-format property at the given index
608    *
609    * @throws ArrayIndexOutOfBoundsException
610    */
getDecimalFormat(int i)611   public DecimalFormatProperties getDecimalFormat(int i)
612           throws ArrayIndexOutOfBoundsException
613   {
614 
615     if (null == m_DecimalFormatDeclarations)
616       throw new ArrayIndexOutOfBoundsException();
617 
618     return (DecimalFormatProperties) m_DecimalFormatDeclarations.elementAt(i);
619   }
620 
621   /**
622    * Get the number of xsl:decimal-format declarations.
623    * @see DecimalFormatProperties
624    *
625    * @return the number of xsl:decimal-format declarations.
626    */
getDecimalFormatCount()627   public int getDecimalFormatCount()
628   {
629     return (null != m_DecimalFormatDeclarations)
630            ? m_DecimalFormatDeclarations.size() : 0;
631   }
632 
633   /**
634    * The "xsl:strip-space" properties,
635    * A lookup table of all space stripping elements.
636    * @serial
637    */
638   private Vector m_whitespaceStrippingElements;
639 
640   /**
641    * Set the "xsl:strip-space" properties.
642    * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
643    *
644    * @param wsi WhiteSpaceInfo element to add to list
645    */
setStripSpaces(WhiteSpaceInfo wsi)646   public void setStripSpaces(WhiteSpaceInfo wsi)
647   {
648 
649     if (null == m_whitespaceStrippingElements)
650     {
651       m_whitespaceStrippingElements = new Vector();
652     }
653 
654     m_whitespaceStrippingElements.addElement(wsi);
655   }
656 
657   /**
658    * Get an "xsl:strip-space" property.
659    * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
660    *
661    * @param i Index of WhiteSpaceInfo to get
662    *
663    * @return WhiteSpaceInfo at given index
664    *
665    * @throws ArrayIndexOutOfBoundsException
666    */
getStripSpace(int i)667   public WhiteSpaceInfo getStripSpace(int i) throws ArrayIndexOutOfBoundsException
668   {
669 
670     if (null == m_whitespaceStrippingElements)
671       throw new ArrayIndexOutOfBoundsException();
672 
673     return (WhiteSpaceInfo) m_whitespaceStrippingElements.elementAt(i);
674   }
675 
676   /**
677    * Get the number of "xsl:strip-space" properties.
678    * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
679    *
680    * @return the number of "xsl:strip-space" properties.
681    */
getStripSpaceCount()682   public int getStripSpaceCount()
683   {
684     return (null != m_whitespaceStrippingElements)
685            ? m_whitespaceStrippingElements.size() : 0;
686   }
687 
688   /**
689    * The "xsl:preserve-space" property,
690    * A lookup table of all space preserving elements.
691    * @serial
692    */
693   private Vector m_whitespacePreservingElements;
694 
695   /**
696    * Set the "xsl:preserve-space" property.
697    * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
698    *
699    * @param wsi WhiteSpaceInfo element to add to list
700    */
setPreserveSpaces(WhiteSpaceInfo wsi)701   public void setPreserveSpaces(WhiteSpaceInfo wsi)
702   {
703 
704     if (null == m_whitespacePreservingElements)
705     {
706       m_whitespacePreservingElements = new Vector();
707     }
708 
709     m_whitespacePreservingElements.addElement(wsi);
710   }
711 
712   /**
713    * Get a "xsl:preserve-space" property.
714    * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
715    *
716    * @param i Index of WhiteSpaceInfo to get
717    *
718    * @return WhiteSpaceInfo at the given index
719    *
720    * @throws ArrayIndexOutOfBoundsException
721    */
getPreserveSpace(int i)722   public WhiteSpaceInfo getPreserveSpace(int i) throws ArrayIndexOutOfBoundsException
723   {
724 
725     if (null == m_whitespacePreservingElements)
726       throw new ArrayIndexOutOfBoundsException();
727 
728     return (WhiteSpaceInfo) m_whitespacePreservingElements.elementAt(i);
729   }
730 
731   /**
732    * Get the number of "xsl:preserve-space" properties.
733    * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
734    *
735    * @return the number of "xsl:preserve-space" properties.
736    */
getPreserveSpaceCount()737   public int getPreserveSpaceCount()
738   {
739     return (null != m_whitespacePreservingElements)
740            ? m_whitespacePreservingElements.size() : 0;
741   }
742 
743   /**
744    * The "xsl:output" properties.  This is a vector of OutputProperties objects.
745    * @serial
746    */
747   private Vector m_output;
748 
749   /**
750    * Set the "xsl:output" property.
751    * @see <a href="http://www.w3.org/TR/xslt#output">output in XSLT Specification</a>
752    *
753    * @param v non-null reference to the OutputProperties object to be
754    *          added to the collection.
755    */
setOutput(OutputProperties v)756   public void setOutput(OutputProperties v)
757   {
758     if (null == m_output)
759     {
760       m_output = new Vector();
761     }
762 
763     m_output.addElement(v);
764   }
765 
766   /**
767    * Get an "xsl:output" property.
768    * @see <a href="http://www.w3.org/TR/xslt#output">output in XSLT Specification</a>
769    *
770    * @param i Index of OutputFormatExtended to get
771    *
772    * @return non-null reference to an OutputProperties object.
773    *
774    * @throws ArrayIndexOutOfBoundsException
775    */
getOutput(int i)776   public OutputProperties getOutput(int i) throws ArrayIndexOutOfBoundsException
777   {
778 
779     if (null == m_output)
780       throw new ArrayIndexOutOfBoundsException();
781 
782     return (OutputProperties) m_output.elementAt(i);
783   }
784 
785   /**
786    * Get the number of "xsl:output" properties.
787    * @see <a href="http://www.w3.org/TR/xslt#output">output in XSLT Specification</a>
788    *
789    * @return The number of OutputProperties objects contained in this stylesheet.
790    */
getOutputCount()791   public int getOutputCount()
792   {
793     return (null != m_output)
794            ? m_output.size() : 0;
795   }
796 
797   /**
798    * The "xsl:key" property.
799    * @serial
800    */
801   private Vector m_keyDeclarations;
802 
803   /**
804    * Set the "xsl:key" property.
805    * @see <a href="http://www.w3.org/TR/xslt#key">key in XSLT Specification</a>
806    *
807    * @param v KeyDeclaration element to add to the list of key declarations
808    */
setKey(KeyDeclaration v)809   public void setKey(KeyDeclaration v)
810   {
811 
812     if (null == m_keyDeclarations)
813       m_keyDeclarations = new Vector();
814 
815     m_keyDeclarations.addElement(v);
816   }
817 
818   /**
819    * Get an "xsl:key" property.
820    * @see <a href="http://www.w3.org/TR/xslt#key">key in XSLT Specification</a>
821    *
822    * @param i Index of KeyDeclaration element to get
823    *
824    * @return KeyDeclaration element at given index in list
825    *
826    * @throws ArrayIndexOutOfBoundsException
827    */
getKey(int i)828   public KeyDeclaration getKey(int i) throws ArrayIndexOutOfBoundsException
829   {
830 
831     if (null == m_keyDeclarations)
832       throw new ArrayIndexOutOfBoundsException();
833 
834     return (KeyDeclaration) m_keyDeclarations.elementAt(i);
835   }
836 
837   /**
838    * Get the number of "xsl:key" properties.
839    * @see <a href="http://www.w3.org/TR/xslt#key">key in XSLT Specification</a>
840    *
841    * @return the number of "xsl:key" properties.
842    */
getKeyCount()843   public int getKeyCount()
844   {
845     return (null != m_keyDeclarations) ? m_keyDeclarations.size() : 0;
846   }
847 
848   /**
849    * The "xsl:attribute-set" property.
850    * @serial
851    */
852   private Vector m_attributeSets;
853 
854   /**
855    * Set the "xsl:attribute-set" property.
856    * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a>
857    *
858    * @param attrSet ElemAttributeSet to add to the list of attribute sets
859    */
setAttributeSet(ElemAttributeSet attrSet)860   public void setAttributeSet(ElemAttributeSet attrSet)
861   {
862 
863     if (null == m_attributeSets)
864     {
865       m_attributeSets = new Vector();
866     }
867 
868     m_attributeSets.addElement(attrSet);
869   }
870 
871   /**
872    * Get an "xsl:attribute-set" property.
873    * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a>
874    *
875    * @param i Index of ElemAttributeSet to get in list
876    *
877    * @return ElemAttributeSet at the given index
878    *
879    * @throws ArrayIndexOutOfBoundsException
880    */
getAttributeSet(int i)881   public ElemAttributeSet getAttributeSet(int i)
882           throws ArrayIndexOutOfBoundsException
883   {
884 
885     if (null == m_attributeSets)
886       throw new ArrayIndexOutOfBoundsException();
887 
888     return (ElemAttributeSet) m_attributeSets.elementAt(i);
889   }
890 
891   /**
892    * Get the number of "xsl:attribute-set" properties.
893    * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a>
894    *
895    * @return the number of "xsl:attribute-set" properties.
896    */
getAttributeSetCount()897   public int getAttributeSetCount()
898   {
899     return (null != m_attributeSets) ? m_attributeSets.size() : 0;
900   }
901 
902   /**
903    * The "xsl:variable" and "xsl:param" properties.
904    * @serial
905    */
906   private Vector m_topLevelVariables;
907 
908   /**
909    * Set the "xsl:variable" property.
910    * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
911    *
912    * @param v ElemVariable object to add to list of top level variables
913    */
setVariable(ElemVariable v)914   public void setVariable(ElemVariable v)
915   {
916 
917     if (null == m_topLevelVariables)
918       m_topLevelVariables = new Vector();
919 
920     m_topLevelVariables.addElement(v);
921   }
922 
923   /**
924    * Get an "xsl:variable" or "xsl:param" property.
925    * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
926    *
927    * @param qname non-null reference to the qualified name of the variable.
928    *
929    * @return The ElemVariable with the given name in the list or null
930    */
getVariableOrParam(QName qname)931   public ElemVariable getVariableOrParam(QName qname)
932   {
933 
934     if (null != m_topLevelVariables)
935     {
936       int n = getVariableOrParamCount();
937 
938       for (int i = 0; i < n; i++)
939       {
940         ElemVariable var = (ElemVariable) getVariableOrParam(i);
941 
942         if (var.getName().equals(qname))
943           return var;
944       }
945     }
946 
947     return null;
948   }
949 
950 
951   /**
952    * Get an "xsl:variable" property.
953    * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
954    *
955    * @param qname Qualified name of the xsl:variable to get
956    *
957    * @return reference to the variable named by qname, or null if not found.
958    */
getVariable(QName qname)959   public ElemVariable getVariable(QName qname)
960   {
961 
962     if (null != m_topLevelVariables)
963     {
964       int n = getVariableOrParamCount();
965 
966       for (int i = 0; i < n; i++)
967       {
968         ElemVariable var = getVariableOrParam(i);
969         if((var.getXSLToken() == Constants.ELEMNAME_VARIABLE) &&
970            (var.getName().equals(qname)))
971           return var;
972       }
973     }
974 
975     return null;
976   }
977 
978   /**
979    * Get an "xsl:variable" property.
980    * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
981    *
982    * @param i Index of variable to get in the list
983    *
984    * @return ElemVariable at the given index in the list
985    *
986    * @throws ArrayIndexOutOfBoundsException
987    */
getVariableOrParam(int i)988   public ElemVariable getVariableOrParam(int i) throws ArrayIndexOutOfBoundsException
989   {
990 
991     if (null == m_topLevelVariables)
992       throw new ArrayIndexOutOfBoundsException();
993 
994     return (ElemVariable) m_topLevelVariables.elementAt(i);
995   }
996 
997   /**
998    * Get the number of "xsl:variable" properties.
999    * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
1000    *
1001    * @return the number of "xsl:variable" properties.
1002    */
getVariableOrParamCount()1003   public int getVariableOrParamCount()
1004   {
1005     return (null != m_topLevelVariables) ? m_topLevelVariables.size() : 0;
1006   }
1007 
1008   /**
1009    * Set an "xsl:param" property.
1010    * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
1011    *
1012    * @param v A non-null ElemParam reference.
1013    */
setParam(ElemParam v)1014   public void setParam(ElemParam v)
1015   {
1016     setVariable(v);
1017   }
1018 
1019   /**
1020    * Get an "xsl:param" property.
1021    * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
1022    *
1023    * @param qname non-null reference to qualified name of the parameter.
1024    *
1025    * @return ElemParam with the given name in the list or null
1026    */
getParam(QName qname)1027   public ElemParam getParam(QName qname)
1028   {
1029 
1030     if (null != m_topLevelVariables)
1031     {
1032       int n = getVariableOrParamCount();
1033 
1034       for (int i = 0; i < n; i++)
1035       {
1036         ElemVariable var = getVariableOrParam(i);
1037         if((var.getXSLToken() == Constants.ELEMNAME_PARAMVARIABLE) &&
1038            (var.getName().equals(qname)))
1039           return (ElemParam)var;
1040       }
1041     }
1042 
1043     return null;
1044   }
1045 
1046   /**
1047    * The "xsl:template" properties.
1048    * @serial
1049    */
1050   private Vector m_templates;
1051 
1052   /**
1053    * Set an "xsl:template" property.
1054    * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
1055    *
1056    * @param v ElemTemplate to add to list of templates
1057    */
setTemplate(ElemTemplate v)1058   public void setTemplate(ElemTemplate v)
1059   {
1060 
1061     if (null == m_templates)
1062       m_templates = new Vector();
1063 
1064     m_templates.addElement(v);
1065     v.setStylesheet(this);
1066   }
1067 
1068   /**
1069    * Get an "xsl:template" property.
1070    * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
1071    *
1072    * @param i Index of ElemTemplate in the list to get
1073    *
1074    * @return ElemTemplate at the given index in the list
1075    *
1076    * @throws TransformerException
1077    */
getTemplate(int i)1078   public ElemTemplate getTemplate(int i) throws TransformerException
1079   {
1080 
1081     if (null == m_templates)
1082       throw new ArrayIndexOutOfBoundsException();
1083 
1084     return (ElemTemplate) m_templates.elementAt(i);
1085   }
1086 
1087   /**
1088    * Get the number of "xsl:template" properties.
1089    * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
1090    *
1091    * @return the number of "xsl:template" properties.
1092    */
getTemplateCount()1093   public int getTemplateCount()
1094   {
1095     return (null != m_templates) ? m_templates.size() : 0;
1096   }
1097 
1098   /**
1099    * The "xsl:namespace-alias" properties.
1100    * @serial
1101    */
1102   private Vector m_prefix_aliases;
1103 
1104   /**
1105    * Set the "xsl:namespace-alias" property.
1106    * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
1107    *
1108    * @param na NamespaceAlias elemeent to add to the list
1109    */
setNamespaceAlias(NamespaceAlias na)1110   public void setNamespaceAlias(NamespaceAlias na)
1111   {
1112 
1113     if (m_prefix_aliases == null)
1114       m_prefix_aliases = new Vector();
1115 
1116     m_prefix_aliases.addElement(na);
1117   }
1118 
1119   /**
1120    * Get an "xsl:namespace-alias" property.
1121    * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
1122    *
1123    * @param i Index of NamespaceAlias element to get from the list
1124    *
1125    * @return NamespaceAlias element at the given index in the list
1126    *
1127    * @throws ArrayIndexOutOfBoundsException
1128    */
getNamespaceAlias(int i)1129   public NamespaceAlias getNamespaceAlias(int i)
1130           throws ArrayIndexOutOfBoundsException
1131   {
1132 
1133     if (null == m_prefix_aliases)
1134       throw new ArrayIndexOutOfBoundsException();
1135 
1136     return (NamespaceAlias) m_prefix_aliases.elementAt(i);
1137   }
1138 
1139   /**
1140    * Get the number of "xsl:namespace-alias" properties.
1141    * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
1142    *
1143    * @return the number of "xsl:namespace-alias" properties.
1144    */
getNamespaceAliasCount()1145   public int getNamespaceAliasCount()
1146   {
1147     return (null != m_prefix_aliases) ? m_prefix_aliases.size() : 0;
1148   }
1149 
1150   /**
1151    * The "non-xsl-top-level" properties.
1152    * @serial
1153    */
1154   private Hashtable m_NonXslTopLevel;
1155 
1156   /**
1157    * Set found a non-xslt element.
1158    * @see <a href="http://www.w3.org/TR/xslt#stylesheet-element">stylesheet-element in XSLT Specification</a>
1159    *
1160    * @param name Qualified name of the element
1161    * @param obj The element object
1162    */
setNonXslTopLevel(QName name, Object obj)1163   public void setNonXslTopLevel(QName name, Object obj)
1164   {
1165 
1166     if (null == m_NonXslTopLevel)
1167       m_NonXslTopLevel = new Hashtable();
1168 
1169     m_NonXslTopLevel.put(name, obj);
1170   }
1171 
1172   /**
1173    * Get a non-xslt element.
1174    * @see <a href="http://www.w3.org/TR/xslt#stylesheet-element">stylesheet-element in XSLT Specification</a>
1175    *
1176    * @param name Qualified name of the element to get
1177    *
1178    * @return The object associate with the given name
1179    */
getNonXslTopLevel(QName name)1180   public Object getNonXslTopLevel(QName name)
1181   {
1182     return (null != m_NonXslTopLevel) ? m_NonXslTopLevel.get(name) : null;
1183   }
1184 
1185   // =========== End top-level XSLT properties ===========
1186 
1187   /**
1188    * The base URL of the XSL document.
1189    * @serial
1190    */
1191   private String m_href = null;
1192 
1193   /** The doctype-public element.
1194    *  @serial          */
1195   private String m_publicId;
1196 
1197   /** The doctype-system element.
1198    *  @serial          */
1199   private String m_systemId;
1200 
1201   /**
1202    * Get the base identifier with which this stylesheet is associated.
1203    *
1204    * @return the base identifier with which this stylesheet is associated.
1205    */
getHref()1206   public String getHref()
1207   {
1208     return m_href;
1209   }
1210 
1211   /**
1212    * Set the base identifier with which this stylesheet is associated.
1213    *
1214    * @param baseIdent the base identifier with which this stylesheet is associated.
1215    */
setHref(String baseIdent)1216   public void setHref(String baseIdent)
1217   {
1218     m_href = baseIdent;
1219   }
1220 
1221   /**
1222    * Set the location information for this element.
1223    *
1224    * @param locator SourceLocator object with location information
1225    */
setLocaterInfo(SourceLocator locator)1226   public void setLocaterInfo(SourceLocator locator)
1227   {
1228 
1229     if (null != locator)
1230     {
1231       m_publicId = locator.getPublicId();
1232       m_systemId = locator.getSystemId();
1233 
1234       if (null != m_systemId)
1235       {
1236         try
1237         {
1238           m_href = SystemIDResolver.getAbsoluteURI(m_systemId, null);
1239         }
1240         catch (TransformerException se)
1241         {
1242 
1243           // Ignore this for right now
1244         }
1245       }
1246 
1247       super.setLocaterInfo(locator);
1248     }
1249   }
1250 
1251   /**
1252    * The root of the stylesheet, where all the tables common
1253    * to all stylesheets are kept.
1254    * @serial
1255    */
1256   private StylesheetRoot m_stylesheetRoot;
1257 
1258   /**
1259    * Get the root of the stylesheet, where all the tables common
1260    * to all stylesheets are kept.
1261    *
1262    * @return the root of the stylesheet
1263    */
getStylesheetRoot()1264   public StylesheetRoot getStylesheetRoot()
1265   {
1266     return m_stylesheetRoot;
1267   }
1268 
1269   /**
1270    * Set the root of the stylesheet, where all the tables common
1271    * to all stylesheets are kept.
1272    *
1273    * @param v the root of the stylesheet
1274    */
setStylesheetRoot(StylesheetRoot v)1275   public void setStylesheetRoot(StylesheetRoot v)
1276   {
1277     m_stylesheetRoot = v;
1278   }
1279 
1280   /**
1281    * The parent of the stylesheet.  This will be null if this
1282    * is the root stylesheet.
1283    * @serial
1284    */
1285   private Stylesheet m_stylesheetParent;
1286 
1287   /**
1288    * Get the parent of the stylesheet.  This will be null if this
1289    * is the root stylesheet.
1290    *
1291    * @return the parent of the stylesheet.
1292    */
getStylesheetParent()1293   public Stylesheet getStylesheetParent()
1294   {
1295     return m_stylesheetParent;
1296   }
1297 
1298   /**
1299    * Set the parent of the stylesheet.  This should be null if this
1300    * is the root stylesheet.
1301    *
1302    * @param v the parent of the stylesheet.
1303    */
setStylesheetParent(Stylesheet v)1304   public void setStylesheetParent(Stylesheet v)
1305   {
1306     m_stylesheetParent = v;
1307   }
1308 
1309   /**
1310    * Get the owning aggregated stylesheet, or this
1311    * stylesheet if it is aggregated.
1312    *
1313    * @return the owning aggregated stylesheet or itself
1314    */
getStylesheetComposed()1315   public StylesheetComposed getStylesheetComposed()
1316   {
1317 
1318     Stylesheet sheet = this;
1319 
1320     while (!sheet.isAggregatedType())
1321     {
1322       sheet = sheet.getStylesheetParent();
1323     }
1324 
1325     return (StylesheetComposed) sheet;
1326   }
1327 
1328   /**
1329    * Get the type of the node.  We'll pretend we're a Document.
1330    *
1331    * @return the type of the node: document node.
1332    */
getNodeType()1333   public short getNodeType()
1334   {
1335     return DTM.DOCUMENT_NODE;
1336   }
1337 
1338   /**
1339    * Get an integer representation of the element type.
1340    *
1341    * @return An integer representation of the element, defined in the
1342    *     Constants class.
1343    * @see org.apache.xalan.templates.Constants
1344    */
getXSLToken()1345   public int getXSLToken()
1346   {
1347     return Constants.ELEMNAME_STYLESHEET;
1348   }
1349 
1350   /**
1351    * Return the node name.
1352    *
1353    * @return The node name
1354    */
getNodeName()1355   public String getNodeName()
1356   {
1357     return Constants.ELEMNAME_STYLESHEET_STRING;
1358   }
1359 
1360   /**
1361    * Replace an "xsl:template" property.
1362    * This is a hook for CompilingStylesheetHandler, to allow
1363    * us to access a template, compile it, instantiate it,
1364    * and replace the original with the compiled instance.
1365    * ADDED 9/5/2000 to support compilation experiment
1366    *
1367    * @param v Compiled template to replace with
1368    * @param i Index of template to be replaced
1369    *
1370    * @throws TransformerException
1371    */
replaceTemplate(ElemTemplate v, int i)1372   public void replaceTemplate(ElemTemplate v, int i) throws TransformerException
1373   {
1374 
1375     if (null == m_templates)
1376       throw new ArrayIndexOutOfBoundsException();
1377 
1378     replaceChild(v, (ElemTemplateElement)m_templates.elementAt(i));
1379     m_templates.setElementAt(v, i);
1380     v.setStylesheet(this);
1381   }
1382 
1383     /**
1384      * Call the children visitors.
1385      * @param visitor The visitor whose appropriate method will be called.
1386      */
callChildVisitors(XSLTVisitor visitor, boolean callAttrs)1387     protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
1388     {
1389       int s = getImportCount();
1390       for (int j = 0; j < s; j++)
1391       {
1392       	getImport(j).callVisitors(visitor);
1393       }
1394 
1395       s = getIncludeCount();
1396       for (int j = 0; j < s; j++)
1397       {
1398       	getInclude(j).callVisitors(visitor);
1399       }
1400 
1401       s = getOutputCount();
1402       for (int j = 0; j < s; j++)
1403       {
1404         visitor.visitTopLevelInstruction(getOutput(j));
1405       }
1406 
1407       // Next, add in the attribute-set elements
1408 
1409       s = getAttributeSetCount();
1410       for (int j = 0; j < s; j++)
1411       {
1412       	ElemAttributeSet attrSet = getAttributeSet(j);
1413         if (visitor.visitTopLevelInstruction(attrSet))
1414         {
1415           attrSet.callChildVisitors(visitor);
1416         }
1417       }
1418       // Now the decimal-formats
1419 
1420       s = getDecimalFormatCount();
1421       for (int j = 0; j < s; j++)
1422       {
1423         visitor.visitTopLevelInstruction(getDecimalFormat(j));
1424       }
1425 
1426       // Now the keys
1427 
1428       s = getKeyCount();
1429       for (int j = 0; j < s; j++)
1430       {
1431         visitor.visitTopLevelInstruction(getKey(j));
1432       }
1433 
1434       // And the namespace aliases
1435 
1436       s = getNamespaceAliasCount();
1437       for (int j = 0; j < s; j++)
1438       {
1439         visitor.visitTopLevelInstruction(getNamespaceAlias(j));
1440       }
1441 
1442       // Next comes the templates
1443 
1444       s = getTemplateCount();
1445       for (int j = 0; j < s; j++)
1446       {
1447         try
1448         {
1449           ElemTemplate template = getTemplate(j);
1450           if (visitor.visitTopLevelInstruction(template))
1451           {
1452             template.callChildVisitors(visitor);
1453           }
1454         }
1455         catch (TransformerException te)
1456         {
1457           throw new org.apache.xml.utils.WrappedRuntimeException(te);
1458         }
1459       }
1460 
1461       // Then, the variables
1462 
1463       s = getVariableOrParamCount();
1464       for (int j = 0; j < s; j++)
1465       {
1466       	ElemVariable var = getVariableOrParam(j);
1467         if (visitor.visitTopLevelVariableOrParamDecl(var))
1468         {
1469           var.callChildVisitors(visitor);
1470         }
1471       }
1472 
1473       // And lastly the whitespace preserving and stripping elements
1474 
1475       s = getStripSpaceCount();
1476       for (int j = 0; j < s; j++)
1477       {
1478         visitor.visitTopLevelInstruction(getStripSpace(j));
1479       }
1480 
1481       s = getPreserveSpaceCount();
1482       for (int j = 0; j < s; j++)
1483       {
1484         visitor.visitTopLevelInstruction(getPreserveSpace(j));
1485       }
1486 
1487       if(null != m_NonXslTopLevel)
1488       {
1489       	java.util.Enumeration elements = m_NonXslTopLevel.elements();
1490       	while(elements.hasMoreElements())
1491       	{
1492       	  ElemTemplateElement elem = (ElemTemplateElement)elements.nextElement();
1493           if (visitor.visitTopLevelInstruction(elem))
1494           {
1495             elem.callChildVisitors(visitor);
1496           }
1497 
1498       	}
1499       }
1500     }
1501 
1502 
1503   /**
1504    * Accept a visitor and call the appropriate method
1505    * for this class.
1506    *
1507    * @param visitor The visitor whose appropriate method will be called.
1508    * @return true if the children of the object should be visited.
1509    */
accept(XSLTVisitor visitor)1510   protected boolean accept(XSLTVisitor visitor)
1511   {
1512   	return visitor.visitStylesheet(this);
1513   }
1514 
1515 
1516 }
1517