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 */ 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 */ 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 } 1517