001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 /*
019 * $Id: Stylesheet.java 468643 2006-10-28 06:56:03Z minchau $
020 */
021 package org.apache.xalan.templates;
022
023 import java.io.IOException;
024 import java.io.ObjectInputStream;
025 import java.io.ObjectOutputStream;
026 import java.util.Hashtable;
027 import java.util.Stack;
028 import java.util.Vector;
029
030 import javax.xml.transform.SourceLocator;
031 import javax.xml.transform.TransformerException;
032
033 import org.apache.xml.dtm.DTM;
034 import org.apache.xml.utils.QName;
035 import org.apache.xml.utils.StringVector;
036 import org.apache.xml.utils.SystemIDResolver;
037
038 /**
039 * Represents a stylesheet element.
040 * <p>All properties in this class have a fixed form of bean-style property
041 * accessors for all properties that represent XSL attributes or elements.
042 * These properties have setter method names accessed generically by the
043 * processor, and so these names must be fixed according to the system
044 * defined in the <a href="XSLTAttributeDef#getSetterMethodName">getSetterMethodName</a>
045 * function.</p>
046 * <p><pre>
047 * <!ENTITY % top-level "
048 * (xsl:import*,
049 * (xsl:include
050 * | xsl:strip-space
051 * | xsl:preserve-space
052 * | xsl:output
053 * | xsl:key
054 * | xsl:decimal-format
055 * | xsl:attribute-set
056 * | xsl:variable
057 * | xsl:param
058 * | xsl:template
059 * | xsl:namespace-alias
060 * %non-xsl-top-level;)*)
061 * ">
062 *
063 * <!ENTITY % top-level-atts '
064 * extension-element-prefixes CDATA #IMPLIED
065 * exclude-result-prefixes CDATA #IMPLIED
066 * id ID #IMPLIED
067 * version NMTOKEN #REQUIRED
068 * xmlns:xsl CDATA #FIXED "http://www.w3.org/1999/XSL/Transform"
069 * %space-att;
070 * '>
071 *
072 * <!ELEMENT xsl:stylesheet %top-level;>
073 * <!ATTLIST xsl:stylesheet %top-level-atts;>
074 *
075 * <!ELEMENT xsl:transform %top-level;>
076 * <!ATTLIST xsl:transform %top-level-atts;>
077 *
078 * </p></pre>
079 * @see <a href="http://www.w3.org/TR/xslt#section-Stylesheet-Structure">section-Stylesheet-Structure in XSLT Specification</a>
080 */
081 public class Stylesheet extends ElemTemplateElement
082 implements java.io.Serializable /* , Document */
083 {
084 static final long serialVersionUID = 2085337282743043776L;
085
086 /**
087 * Constructor for a Stylesheet.
088 * @param parent The including or importing stylesheet.
089 */
090 public Stylesheet(Stylesheet parent)
091 {
092
093 if (null != parent)
094 {
095 m_stylesheetParent = parent;
096 m_stylesheetRoot = parent.getStylesheetRoot();
097 }
098 }
099
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
1510 protected boolean accept(XSLTVisitor visitor)
1511 {
1512 return visitor.visitStylesheet(this);
1513 }
1514
1515
1516 }