From dadb0f612e4336a8624398cc7dc575f6258e3b4a Mon Sep 17 00:00:00 2001 From: Andreas Martens Date: Fri, 27 Sep 2024 13:59:28 +0100 Subject: [PATCH 1/2] XALANJ-2785: Add support for XSLTC translets to store their own namespace->prefix map --- .../xalan/xsltc/compiler/Constants.java | 585 ++-- .../xalan/xsltc/compiler/Stylesheet.java | 2343 +++++++-------- .../xalan/xsltc/compiler/XslElement.java | 454 +-- .../xalan/xsltc/runtime/BasisLibrary.java | 2609 +++++++++-------- 4 files changed, 3044 insertions(+), 2947 deletions(-) diff --git a/xalan/src/main/java/org/apache/xalan/xsltc/compiler/Constants.java b/xalan/src/main/java/org/apache/xalan/xsltc/compiler/Constants.java index 865d542d9..f671dc65a 100644 --- a/xalan/src/main/java/org/apache/xalan/xsltc/compiler/Constants.java +++ b/xalan/src/main/java/org/apache/xalan/xsltc/compiler/Constants.java @@ -30,508 +30,519 @@ */ public interface Constants extends InstructionConstants { - // Error categories used to report errors to Parser.reportError() - - // Unexpected internal errors, such as null-ptr exceptions, etc. - // Immediately terminates compilation, no translet produced - public final int INTERNAL = 0; - // XSLT elements that are not implemented and unsupported ext. - // Immediately terminates compilation, no translet produced - public final int UNSUPPORTED = 1; - // Fatal error in the stylesheet input (parsing or content) - // Immediately terminates compilation, no translet produced - public final int FATAL = 2; - // Other error in the stylesheet input (parsing or content) - // Does not terminate compilation, no translet produced - public final int ERROR = 3; - // Other error in the stylesheet input (content errors only) - // Does not terminate compilation, a translet is produced - public final int WARNING = 4; - - public static final String EMPTYSTRING = ""; - - public static final String NAMESPACE_FEATURE = - "http://xml.org/sax/features/namespaces"; - - public static final String TRANSLET_INTF + // Error categories used to report errors to Parser.reportError() + + // Unexpected internal errors, such as null-ptr exceptions, etc. + // Immediately terminates compilation, no translet produced + public final int INTERNAL = 0; + // XSLT elements that are not implemented and unsupported ext. + // Immediately terminates compilation, no translet produced + public final int UNSUPPORTED = 1; + // Fatal error in the stylesheet input (parsing or content) + // Immediately terminates compilation, no translet produced + public final int FATAL = 2; + // Other error in the stylesheet input (parsing or content) + // Does not terminate compilation, no translet produced + public final int ERROR = 3; + // Other error in the stylesheet input (content errors only) + // Does not terminate compilation, a translet is produced + public final int WARNING = 4; + + public static final String EMPTYSTRING = ""; + + public static final String NAMESPACE_FEATURE = + "http://xml.org/sax/features/namespaces"; + + public static final String TRANSLET_INTF = "org.apache.xalan.xsltc.Translet"; - public static final String TRANSLET_INTF_SIG + public static final String TRANSLET_INTF_SIG = "Lorg/apache/xalan/xsltc/Translet;"; - public static final String ATTRIBUTES_SIG + public static final String ATTRIBUTES_SIG = "Lorg/apache/xalan/xsltc/runtime/Attributes;"; - public static final String NODE_ITERATOR_SIG + public static final String NODE_ITERATOR_SIG = "Lorg/apache/xml/dtm/DTMAxisIterator;"; - public static final String DOM_INTF_SIG + public static final String DOM_INTF_SIG = "Lorg/apache/xalan/xsltc/DOM;"; - public static final String DOM_IMPL_CLASS + public static final String DOM_IMPL_CLASS = "org/apache/xalan/xsltc/DOM"; // xml/dtm/ref/DTMDefaultBaseIterators"; //xalan/xsltc/dom/DOMImpl"; public static final String SAX_IMPL_CLASS = "org/apache/xalan/xsltc/DOM/SAXImpl"; - public static final String DOM_IMPL_SIG + public static final String DOM_IMPL_SIG = "Lorg/apache/xalan/xsltc/dom/SAXImpl;"; //xml/dtm/ref/DTMDefaultBaseIterators"; //xalan/xsltc/dom/DOMImpl;"; public static final String SAX_IMPL_SIG = "Lorg/apache/xalan/xsltc/dom/SAXImpl;"; - public static final String DOM_ADAPTER_CLASS + public static final String DOM_ADAPTER_CLASS = "org/apache/xalan/xsltc/dom/DOMAdapter"; - public static final String DOM_ADAPTER_SIG + public static final String DOM_ADAPTER_SIG = "Lorg/apache/xalan/xsltc/dom/DOMAdapter;"; - public static final String MULTI_DOM_CLASS + public static final String MULTI_DOM_CLASS = "org.apache.xalan.xsltc.dom.MultiDOM"; - public static final String MULTI_DOM_SIG + public static final String MULTI_DOM_SIG = "Lorg/apache/xalan/xsltc/dom/MultiDOM;"; - public static final String STRING + public static final String STRING = "java.lang.String"; - public static final int ACC_PUBLIC + public static final int ACC_PUBLIC = org.apache.bcel.Constants.ACC_PUBLIC; - public static final int ACC_SUPER + public static final int ACC_SUPER = org.apache.bcel.Constants.ACC_SUPER; - public static final int ACC_FINAL + public static final int ACC_FINAL = org.apache.bcel.Constants.ACC_FINAL; - public static final int ACC_PRIVATE + public static final int ACC_PRIVATE = org.apache.bcel.Constants.ACC_PRIVATE; - public static final int ACC_PROTECTED + public static final int ACC_PROTECTED = org.apache.bcel.Constants.ACC_PROTECTED; - public static final int ACC_STATIC + public static final int ACC_STATIC = org.apache.bcel.Constants.ACC_STATIC; - public static final String STRING_SIG + public static final String STRING_SIG = "Ljava/lang/String;"; - public static final String STRING_BUFFER_SIG + public static final String STRING_BUFFER_SIG = "Ljava/lang/StringBuffer;"; - public static final String OBJECT_SIG + public static final String OBJECT_SIG = "Ljava/lang/Object;"; - public static final String DOUBLE_SIG + public static final String DOUBLE_SIG = "Ljava/lang/Double;"; - public static final String INTEGER_SIG + public static final String INTEGER_SIG = "Ljava/lang/Integer;"; - public static final String COLLATOR_CLASS - = "java/text/Collator"; - public static final String COLLATOR_SIG - = "Ljava/text/Collator;"; - - public static final String NODE + public static final String COLLATOR_CLASS + = "java/text/Collator"; + public static final String COLLATOR_SIG + = "Ljava/text/Collator;"; + + public static final String NODE = "int"; - public static final String NODE_ITERATOR + public static final String NODE_ITERATOR = "org.apache.xml.dtm.DTMAxisIterator"; - public static final String NODE_ITERATOR_BASE + public static final String NODE_ITERATOR_BASE = "org.apache.xml.dtm.ref.DTMAxisIteratorBase"; - public static final String SORT_ITERATOR + public static final String SORT_ITERATOR = "org.apache.xalan.xsltc.dom.SortingIterator"; - public static final String SORT_ITERATOR_SIG + public static final String SORT_ITERATOR_SIG = "Lorg.apache.xalan.xsltc.dom.SortingIterator;"; - public static final String NODE_SORT_RECORD + public static final String NODE_SORT_RECORD = "org.apache.xalan.xsltc.dom.NodeSortRecord"; - public static final String NODE_SORT_FACTORY + public static final String NODE_SORT_FACTORY = "org/apache/xalan/xsltc/dom/NodeSortRecordFactory"; - public static final String NODE_SORT_RECORD_SIG + public static final String NODE_SORT_RECORD_SIG = "Lorg/apache/xalan/xsltc/dom/NodeSortRecord;"; - public static final String NODE_SORT_FACTORY_SIG + public static final String NODE_SORT_FACTORY_SIG = "Lorg/apache/xalan/xsltc/dom/NodeSortRecordFactory;"; - public static final String LOCALE_CLASS - = "java.util.Locale"; - public static final String LOCALE_SIG + public static final String LOCALE_CLASS + = "java.util.Locale"; + public static final String LOCALE_SIG = "Ljava/util/Locale;"; - public static final String STRING_VALUE_HANDLER + public static final String STRING_VALUE_HANDLER = "org.apache.xalan.xsltc.runtime.StringValueHandler"; - public static final String STRING_VALUE_HANDLER_SIG + public static final String STRING_VALUE_HANDLER_SIG = "Lorg/apache/xalan/xsltc/runtime/StringValueHandler;"; - public static final String OUTPUT_HANDLER + public static final String OUTPUT_HANDLER = SerializerBase.PKG_PATH+"/SerializationHandler"; - public static final String OUTPUT_HANDLER_SIG + public static final String OUTPUT_HANDLER_SIG = "L"+SerializerBase.PKG_PATH+"/SerializationHandler;"; - public static final String FILTER_INTERFACE + public static final String FILTER_INTERFACE = "org.apache.xalan.xsltc.dom.Filter"; - public static final String FILTER_INTERFACE_SIG + public static final String FILTER_INTERFACE_SIG = "Lorg/apache/xalan/xsltc/dom/Filter;"; - public static final String UNION_ITERATOR_CLASS + public static final String UNION_ITERATOR_CLASS = "org.apache.xalan.xsltc.dom.UnionIterator"; - public static final String STEP_ITERATOR_CLASS + public static final String STEP_ITERATOR_CLASS = "org.apache.xalan.xsltc.dom.StepIterator"; - public static final String CACHED_NODE_LIST_ITERATOR_CLASS + public static final String CACHED_NODE_LIST_ITERATOR_CLASS = "org.apache.xalan.xsltc.dom.CachedNodeListIterator"; - public static final String NTH_ITERATOR_CLASS + public static final String NTH_ITERATOR_CLASS = "org.apache.xalan.xsltc.dom.NthIterator"; - public static final String ABSOLUTE_ITERATOR + public static final String ABSOLUTE_ITERATOR = "org.apache.xalan.xsltc.dom.AbsoluteIterator"; - public static final String DUP_FILTERED_ITERATOR + public static final String DUP_FILTERED_ITERATOR = "org.apache.xalan.xsltc.dom.DupFilterIterator"; - public static final String CURRENT_NODE_LIST_ITERATOR + public static final String CURRENT_NODE_LIST_ITERATOR = "org.apache.xalan.xsltc.dom.CurrentNodeListIterator"; - public static final String CURRENT_NODE_LIST_FILTER + public static final String CURRENT_NODE_LIST_FILTER = "org.apache.xalan.xsltc.dom.CurrentNodeListFilter"; - public static final String CURRENT_NODE_LIST_ITERATOR_SIG + public static final String CURRENT_NODE_LIST_ITERATOR_SIG = "Lorg/apache/xalan/xsltc/dom/CurrentNodeListIterator;"; - public static final String CURRENT_NODE_LIST_FILTER_SIG + public static final String CURRENT_NODE_LIST_FILTER_SIG = "Lorg/apache/xalan/xsltc/dom/CurrentNodeListFilter;"; - public static final String FILTER_STEP_ITERATOR + public static final String FILTER_STEP_ITERATOR = "org.apache.xalan.xsltc.dom.FilteredStepIterator"; - public static final String FILTER_ITERATOR + public static final String FILTER_ITERATOR = "org.apache.xalan.xsltc.dom.FilterIterator"; - public static final String SINGLETON_ITERATOR + public static final String SINGLETON_ITERATOR = "org.apache.xalan.xsltc.dom.SingletonIterator"; - public static final String MATCHING_ITERATOR + public static final String MATCHING_ITERATOR = "org.apache.xalan.xsltc.dom.MatchingIterator"; - public static final String NODE_SIG + public static final String HASHMAP_CLASS = "java.util.HashMap"; + public static final String HASHMAP_SIG = "Ljava/util/HashMap;"; + public static final String MAP_SIG = "Ljava/util/Map;"; + + public static final String NODE_SIG = "I"; - public static final String GET_PARENT + public static final String GET_PARENT = "getParent"; - public static final String GET_PARENT_SIG + public static final String GET_PARENT_SIG = "(" + NODE_SIG + ")" + NODE_SIG; - public static final String NEXT_SIG + public static final String NEXT_SIG = "()" + NODE_SIG; - public static final String NEXT + public static final String NEXT = "next"; public static final String NEXTID = "nextNodeID"; - public static final String MAKE_NODE + public static final String MAKE_NODE = "makeNode"; - public static final String MAKE_NODE_LIST + public static final String MAKE_NODE_LIST = "makeNodeList"; - public static final String GET_UNPARSED_ENTITY_URI - = "getUnparsedEntityURI"; - public static final String STRING_TO_REAL + public static final String GET_UNPARSED_ENTITY_URI + = "getUnparsedEntityURI"; + public static final String STRING_TO_REAL = "stringToReal"; - public static final String STRING_TO_REAL_SIG + public static final String STRING_TO_REAL_SIG = "(" + STRING_SIG + ")D"; - public static final String STRING_TO_INT + public static final String STRING_TO_INT = "stringToInt"; - public static final String STRING_TO_INT_SIG + public static final String STRING_TO_INT_SIG = "(" + STRING_SIG + ")I"; - public static final String XSLT_PACKAGE + public static final String XSLT_PACKAGE = "org.apache.xalan.xsltc"; - public static final String COMPILER_PACKAGE + public static final String COMPILER_PACKAGE = XSLT_PACKAGE + ".compiler"; - public static final String RUNTIME_PACKAGE + public static final String RUNTIME_PACKAGE = XSLT_PACKAGE + ".runtime"; - public static final String TRANSLET_CLASS + public static final String TRANSLET_CLASS = RUNTIME_PACKAGE + ".AbstractTranslet"; - public static final String TRANSLET_SIG + public static final String TRANSLET_SIG = "Lorg/apache/xalan/xsltc/runtime/AbstractTranslet;"; - public static final String UNION_ITERATOR_SIG + public static final String UNION_ITERATOR_SIG = "Lorg/apache/xalan/xsltc/dom/UnionIterator;"; - public static final String TRANSLET_OUTPUT_SIG + public static final String TRANSLET_OUTPUT_SIG = "L"+SerializerBase.PKG_PATH+"/SerializationHandler;"; - public static final String MAKE_NODE_SIG + public static final String MAKE_NODE_SIG = "(I)Lorg/w3c/dom/Node;"; - public static final String MAKE_NODE_SIG2 + public static final String MAKE_NODE_SIG2 = "(" + NODE_ITERATOR_SIG + ")Lorg/w3c/dom/Node;"; - public static final String MAKE_NODE_LIST_SIG + public static final String MAKE_NODE_LIST_SIG = "(I)Lorg/w3c/dom/NodeList;"; - public static final String MAKE_NODE_LIST_SIG2 + public static final String MAKE_NODE_LIST_SIG2 = "(" + NODE_ITERATOR_SIG + ")Lorg/w3c/dom/NodeList;"; - public static final String STREAM_XML_OUTPUT - = SerializerBase.PKG_NAME+".ToXMLStream"; + public static final String STREAM_XML_OUTPUT + = SerializerBase.PKG_NAME+".ToXMLStream"; - public static final String OUTPUT_BASE - = SerializerBase.PKG_NAME+".SerializerBase"; + public static final String OUTPUT_BASE + = SerializerBase.PKG_NAME+".SerializerBase"; - public static final String LOAD_DOCUMENT_CLASS + public static final String LOAD_DOCUMENT_CLASS = "org.apache.xalan.xsltc.dom.LoadDocument"; - public static final String KEY_INDEX_CLASS + public static final String KEY_INDEX_CLASS = "org/apache/xalan/xsltc/dom/KeyIndex"; - public static final String KEY_INDEX_SIG + public static final String KEY_INDEX_SIG = "Lorg/apache/xalan/xsltc/dom/KeyIndex;"; - public static final String KEY_INDEX_ITERATOR_SIG + public static final String KEY_INDEX_ITERATOR_SIG = "Lorg/apache/xalan/xsltc/dom/KeyIndex$KeyIndexIterator;"; - public static final String DOM_INTF + public static final String DOM_INTF = "org.apache.xalan.xsltc.DOM"; - public static final String DOM_IMPL + public static final String DOM_IMPL = "org.apache.xalan.xsltc.dom.SAXImpl"; public static final String SAX_IMPL = "org.apache.xalan.xsltc.dom.SAXImpl"; - public static final String STRING_CLASS + public static final String STRING_CLASS = "java.lang.String"; - public static final String OBJECT_CLASS + public static final String OBJECT_CLASS = "java.lang.Object"; - public static final String BOOLEAN_CLASS + public static final String BOOLEAN_CLASS = "java.lang.Boolean"; - public static final String STRING_BUFFER_CLASS + public static final String STRING_BUFFER_CLASS = "java.lang.StringBuffer"; - public static final String STRING_WRITER - = "java.io.StringWriter"; - public static final String WRITER_SIG - = "Ljava/io/Writer;"; + public static final String STRING_WRITER + = "java.io.StringWriter"; + public static final String WRITER_SIG + = "Ljava/io/Writer;"; - public static final String TRANSLET_OUTPUT_BASE + public static final String TRANSLET_OUTPUT_BASE = "org.apache.xalan.xsltc.TransletOutputBase"; - // output interface - public static final String TRANSLET_OUTPUT_INTERFACE + // output interface + public static final String TRANSLET_OUTPUT_INTERFACE = SerializerBase.PKG_NAME+".SerializationHandler"; - public static final String BASIS_LIBRARY_CLASS + public static final String BASIS_LIBRARY_CLASS = "org.apache.xalan.xsltc.runtime.BasisLibrary"; - public static final String ATTRIBUTE_LIST_IMPL_CLASS + public static final String ATTRIBUTE_LIST_IMPL_CLASS = "org.apache.xalan.xsltc.runtime.AttributeListImpl"; - public static final String DOUBLE_CLASS + public static final String DOUBLE_CLASS = "java.lang.Double"; - public static final String INTEGER_CLASS + public static final String INTEGER_CLASS = "java.lang.Integer"; - public static final String RUNTIME_NODE_CLASS + public static final String RUNTIME_NODE_CLASS = "org.apache.xalan.xsltc.runtime.Node"; - public static final String MATH_CLASS + public static final String MATH_CLASS = "java.lang.Math"; - public static final String BOOLEAN_VALUE + public static final String BOOLEAN_VALUE = "booleanValue"; - public static final String BOOLEAN_VALUE_SIG + public static final String BOOLEAN_VALUE_SIG = "()Z"; - public static final String INT_VALUE + public static final String INT_VALUE = "intValue"; - public static final String INT_VALUE_SIG + public static final String INT_VALUE_SIG = "()I"; - public static final String DOUBLE_VALUE + public static final String DOUBLE_VALUE = "doubleValue"; - public static final String DOUBLE_VALUE_SIG + public static final String DOUBLE_VALUE_SIG = "()D"; - public static final String DOM_PNAME + public static final String DOM_PNAME = "dom"; - public static final String NODE_PNAME + public static final String NODE_PNAME = "node"; - public static final String TRANSLET_OUTPUT_PNAME + public static final String TRANSLET_OUTPUT_PNAME = "handler"; - public static final String ITERATOR_PNAME + public static final String ITERATOR_PNAME = "iterator"; - public static final String DOCUMENT_PNAME + public static final String DOCUMENT_PNAME = "document"; - public static final String TRANSLET_PNAME + public static final String TRANSLET_PNAME = "translet"; - public static final String INVOKE_METHOD + public static final String INVOKE_METHOD = "invokeMethod"; - public static final String GET_NODE_NAME + public static final String GET_NODE_NAME = "getNodeNameX"; - public static final String CHARACTERSW + public static final String CHARACTERSW = "characters"; - public static final String GET_CHILDREN + public static final String GET_CHILDREN = "getChildren"; - public static final String GET_TYPED_CHILDREN + public static final String GET_TYPED_CHILDREN = "getTypedChildren"; - public static final String CHARACTERS + public static final String CHARACTERS = "characters"; - public static final String APPLY_TEMPLATES + public static final String APPLY_TEMPLATES = "applyTemplates"; - public static final String GET_NODE_TYPE + public static final String GET_NODE_TYPE = "getNodeType"; - public static final String GET_NODE_VALUE + public static final String GET_NODE_VALUE = "getStringValueX"; - public static final String GET_ELEMENT_VALUE + public static final String GET_ELEMENT_VALUE = "getElementValue"; - public static final String GET_ATTRIBUTE_VALUE + public static final String GET_ATTRIBUTE_VALUE = "getAttributeValue"; - public static final String HAS_ATTRIBUTE + public static final String HAS_ATTRIBUTE = "hasAttribute"; - public static final String ADD_ITERATOR + public static final String ADD_ITERATOR = "addIterator"; - public static final String SET_START_NODE + public static final String SET_START_NODE = "setStartNode"; - public static final String RESET + public static final String RESET = "reset"; - public static final String ATTR_SET_SIG + public static final String ATTR_SET_SIG = "(" + DOM_INTF_SIG + NODE_ITERATOR_SIG + TRANSLET_OUTPUT_SIG + ")V"; - public static final String GET_NODE_NAME_SIG + public static final String GET_NODE_NAME_SIG = "(" + NODE_SIG + ")" + STRING_SIG; - public static final String CHARACTERSW_SIG + public static final String CHARACTERSW_SIG = "(" + STRING_SIG + TRANSLET_OUTPUT_SIG + ")V"; - public static final String CHARACTERS_SIG + public static final String CHARACTERS_SIG = "(" + NODE_SIG + TRANSLET_OUTPUT_SIG + ")V"; - public static final String GET_CHILDREN_SIG + public static final String GET_CHILDREN_SIG = "(" + NODE_SIG +")" + NODE_ITERATOR_SIG; - public static final String GET_TYPED_CHILDREN_SIG + public static final String GET_TYPED_CHILDREN_SIG = "(I)" + NODE_ITERATOR_SIG; - public static final String GET_NODE_TYPE_SIG + public static final String GET_NODE_TYPE_SIG = "()S"; - public static final String GET_NODE_VALUE_SIG + public static final String GET_NODE_VALUE_SIG = "(I)" + STRING_SIG; - public static final String GET_ELEMENT_VALUE_SIG + public static final String GET_ELEMENT_VALUE_SIG = "(I)" + STRING_SIG; - public static final String GET_ATTRIBUTE_VALUE_SIG + public static final String GET_ATTRIBUTE_VALUE_SIG = "(II)" + STRING_SIG; - public static final String HAS_ATTRIBUTE_SIG + public static final String HAS_ATTRIBUTE_SIG = "(II)Z"; - public static final String GET_ITERATOR_SIG + public static final String GET_ITERATOR_SIG = "()" + NODE_ITERATOR_SIG; - public static final String NAMES_INDEX + public static final String NAMES_INDEX = "namesArray"; - public static final String NAMES_INDEX_SIG + public static final String NAMES_INDEX_SIG = "[" + STRING_SIG; - public static final String URIS_INDEX - = "urisArray"; - public static final String URIS_INDEX_SIG - = "[" + STRING_SIG; - public static final String TYPES_INDEX - = "typesArray"; - public static final String TYPES_INDEX_SIG - = "[I"; - public static final String NAMESPACE_INDEX + public static final String URIS_INDEX + = "urisArray"; + public static final String URIS_INDEX_SIG + = "[" + STRING_SIG; + public static final String TYPES_INDEX + = "typesArray"; + public static final String TYPES_INDEX_SIG + = "[I"; + public static final String NAMESPACE_INDEX = "namespaceArray"; - public static final String NAMESPACE_INDEX_SIG + public static final String NAMESPACE_INDEX_SIG = "[" + STRING_SIG; - public static final String NS_ANCESTORS_INDEX_SIG - = "[I"; - public static final String PREFIX_URIS_IDX_SIG - = "[I"; - public static final String PREFIX_URIS_ARRAY_SIG - = "[" + STRING_SIG; - public static final String HASIDCALL_INDEX - = "_hasIdCall"; - public static final String HASIDCALL_INDEX_SIG - = "Z"; - public static final String TRANSLET_VERSION_INDEX - = "transletVersion"; - public static final String TRANSLET_VERSION_INDEX_SIG - = "I"; - public static final String LOOKUP_STYLESHEET_QNAME_NS_REF - = "lookupStylesheetQNameNamespace"; - public static final String LOOKUP_STYLESHEET_QNAME_NS_SIG - = "(" + STRING_SIG - + "I" - + NS_ANCESTORS_INDEX_SIG - + PREFIX_URIS_IDX_SIG - + PREFIX_URIS_ARRAY_SIG - + "Z)" + STRING_SIG; - public static final String EXPAND_STYLESHEET_QNAME_REF - = "expandStylesheetQNameRef"; - public static final String EXPAND_STYLESHEET_QNAME_SIG - = "(" + STRING_SIG - + "I" - + NS_ANCESTORS_INDEX_SIG - + PREFIX_URIS_IDX_SIG - + PREFIX_URIS_ARRAY_SIG - + "Z)" + STRING_SIG; - - public static final String DOM_FIELD + public static final String NS_ANCESTORS_INDEX_SIG + = "[I"; + public static final String PREFIX_URIS_IDX_SIG + = "[I"; + public static final String PREFIX_URIS_ARRAY_SIG + = "[" + STRING_SIG; + public static final String HASIDCALL_INDEX + = "_hasIdCall"; + public static final String HASIDCALL_INDEX_SIG + = "Z"; + public static final String TRANSLET_VERSION_INDEX + = "transletVersion"; + public static final String TRANSLET_VERSION_INDEX_SIG + = "I"; + public static final String LOOKUP_STYLESHEET_QNAME_NS_REF + = "lookupStylesheetQNameNamespace"; + public static final String LOOKUP_STYLESHEET_QNAME_NS_SIG + = "(" + STRING_SIG + + "I" + + NS_ANCESTORS_INDEX_SIG + + PREFIX_URIS_IDX_SIG + + PREFIX_URIS_ARRAY_SIG + + "Z)" + STRING_SIG; + public static final String EXPAND_STYLESHEET_QNAME_REF + = "expandStylesheetQNameRef"; + public static final String EXPAND_STYLESHEET_QNAME_SIG + = "(" + STRING_SIG + + "I" + + NS_ANCESTORS_INDEX_SIG + + PREFIX_URIS_IDX_SIG + + PREFIX_URIS_ARRAY_SIG + + "Z)" + STRING_SIG; + public static final String ADD_NAMESPACE_PREFIX_REF + = "addPrefix"; + public static final String ADD_NAMESPACE_PREFIX_SIG + = "(" + STRING_SIG + + STRING_SIG + + "Ljava/util/Map;"+ + ")" + STRING_SIG; + public static final String DOM_FIELD = "_dom"; - public static final String STATIC_NAMES_ARRAY_FIELD - = "_sNamesArray"; - public static final String STATIC_URIS_ARRAY_FIELD - = "_sUrisArray"; - public static final String STATIC_TYPES_ARRAY_FIELD - = "_sTypesArray"; - public static final String STATIC_NAMESPACE_ARRAY_FIELD - = "_sNamespaceArray"; - public static final String STATIC_NS_ANCESTORS_ARRAY_FIELD - = "_sNamespaceAncestorsArray"; - public static final String STATIC_PREFIX_URIS_IDX_ARRAY_FIELD - = "_sPrefixURIsIdxArray"; - public static final String STATIC_PREFIX_URIS_ARRAY_FIELD - = "_sPrefixURIPairsArray"; - public static final String STATIC_CHAR_DATA_FIELD - = "_scharData"; - public static final String STATIC_CHAR_DATA_FIELD_SIG - = "[C"; - public static final String FORMAT_SYMBOLS_FIELD + public static final String STATIC_NAMES_ARRAY_FIELD + = "_sNamesArray"; + public static final String STATIC_URIS_ARRAY_FIELD + = "_sUrisArray"; + public static final String STATIC_TYPES_ARRAY_FIELD + = "_sTypesArray"; + public static final String STATIC_NAMESPACE_ARRAY_FIELD + = "_sNamespaceArray"; + public static final String STATIC_NS_ANCESTORS_ARRAY_FIELD + = "_sNamespaceAncestorsArray"; + public static final String STATIC_PREFIX_URIS_IDX_ARRAY_FIELD + = "_sPrefixURIsIdxArray"; + public static final String STATIC_PREFIX_URIS_ARRAY_FIELD + = "_sPrefixURIPairsArray"; + public static final String STATIC_CHAR_DATA_FIELD + = "_scharData"; + public static final String STATIC_CHAR_DATA_FIELD_SIG + = "[C"; + public static final String STATIC_NS_MAP_FIELD = "_sNamespaceMap"; + public static final String FORMAT_SYMBOLS_FIELD = "format_symbols"; - public static final String ITERATOR_FIELD_SIG + public static final String ITERATOR_FIELD_SIG = NODE_ITERATOR_SIG; - public static final String NODE_FIELD + public static final String NODE_FIELD = "node"; - public static final String NODE_FIELD_SIG + public static final String NODE_FIELD_SIG = "I"; - public static final String EMPTYATTR_FIELD + public static final String EMPTYATTR_FIELD = "EmptyAttributes"; - public static final String ATTRIBUTE_LIST_FIELD + public static final String ATTRIBUTE_LIST_FIELD = "attributeList"; - public static final String CLEAR_ATTRIBUTES + public static final String CLEAR_ATTRIBUTES = "clear"; - public static final String ADD_ATTRIBUTE + public static final String ADD_ATTRIBUTE = "addAttribute"; - public static final String ATTRIBUTE_LIST_IMPL_SIG + public static final String ATTRIBUTE_LIST_IMPL_SIG = "Lorg/apache/xalan/xsltc/runtime/AttributeListImpl;"; - public static final String CLEAR_ATTRIBUTES_SIG + public static final String CLEAR_ATTRIBUTES_SIG = "()" + ATTRIBUTE_LIST_IMPL_SIG; - public static final String ADD_ATTRIBUTE_SIG + public static final String ADD_ATTRIBUTE_SIG = "(" + STRING_SIG + STRING_SIG + ")" + ATTRIBUTE_LIST_IMPL_SIG; - public static final String ADD_ITERATOR_SIG + public static final String ADD_ITERATOR_SIG = "(" + NODE_ITERATOR_SIG +")" + UNION_ITERATOR_SIG; - public static final String ORDER_ITERATOR + public static final String ORDER_ITERATOR = "orderNodes"; - public static final String ORDER_ITERATOR_SIG + public static final String ORDER_ITERATOR_SIG = "("+NODE_ITERATOR_SIG+"I)"+NODE_ITERATOR_SIG; - public static final String SET_START_NODE_SIG + public static final String SET_START_NODE_SIG = "(" + NODE_SIG + ")" + NODE_ITERATOR_SIG; - public static final String NODE_COUNTER + public static final String NODE_COUNTER = "org.apache.xalan.xsltc.dom.NodeCounter"; - public static final String NODE_COUNTER_SIG + public static final String NODE_COUNTER_SIG = "Lorg/apache/xalan/xsltc/dom/NodeCounter;"; - public static final String DEFAULT_NODE_COUNTER + public static final String DEFAULT_NODE_COUNTER = "org.apache.xalan.xsltc.dom.DefaultNodeCounter"; - public static final String DEFAULT_NODE_COUNTER_SIG + public static final String DEFAULT_NODE_COUNTER_SIG = "Lorg/apache/xalan/xsltc/dom/DefaultNodeCounter;"; - public static final String TRANSLET_FIELD + public static final String TRANSLET_FIELD = "translet"; - public static final String TRANSLET_FIELD_SIG + public static final String TRANSLET_FIELD_SIG = TRANSLET_SIG; - public static final String RESET_SIG + public static final String RESET_SIG = "()" + NODE_ITERATOR_SIG; - public static final String GET_PARAMETER + public static final String GET_PARAMETER = "getParameter"; - public static final String ADD_PARAMETER + public static final String ADD_PARAMETER = "addParameter"; - public static final String PUSH_PARAM_FRAME + public static final String PUSH_PARAM_FRAME = "pushParamFrame"; - public static final String PUSH_PARAM_FRAME_SIG + public static final String PUSH_PARAM_FRAME_SIG = "()V"; - public static final String POP_PARAM_FRAME + public static final String POP_PARAM_FRAME = "popParamFrame"; - public static final String POP_PARAM_FRAME_SIG + public static final String POP_PARAM_FRAME_SIG = "()V"; - public static final String GET_PARAMETER_SIG + public static final String GET_PARAMETER_SIG = "(" + STRING_SIG + ")" + OBJECT_SIG; - public static final String ADD_PARAMETER_SIG + public static final String ADD_PARAMETER_SIG = "(" + STRING_SIG + OBJECT_SIG + "Z)" + OBJECT_SIG; - public static final String STRIP_SPACE + public static final String STRIP_SPACE = "stripSpace"; - public static final String STRIP_SPACE_INTF + public static final String STRIP_SPACE_INTF = "org/apache/xalan/xsltc/StripFilter"; - public static final String STRIP_SPACE_SIG + public static final String STRIP_SPACE_SIG = "Lorg/apache/xalan/xsltc/StripFilter;"; - public static final String STRIP_SPACE_PARAMS + public static final String STRIP_SPACE_PARAMS = "(Lorg/apache/xalan/xsltc/DOM;II)Z"; - public static final String GET_NODE_VALUE_ITERATOR + public static final String GET_NODE_VALUE_ITERATOR = "getNodeValueIterator"; - public static final String GET_NODE_VALUE_ITERATOR_SIG + public static final String GET_NODE_VALUE_ITERATOR_SIG = "("+NODE_ITERATOR_SIG+"I"+STRING_SIG+"Z)"+NODE_ITERATOR_SIG; - public static final String GET_UNPARSED_ENTITY_URI_SIG - = "("+STRING_SIG+")"+STRING_SIG; + public static final String GET_UNPARSED_ENTITY_URI_SIG + = "("+STRING_SIG+")"+STRING_SIG; - public static final int POSITION_INDEX = 2; - public static final int LAST_INDEX = 3; + public static final int POSITION_INDEX = 2; + public static final int LAST_INDEX = 3; - public static final String XMLNS_PREFIX = "xmlns"; - public static final String XMLNS_STRING = "xmlns:"; - public static final String XMLNS_URI + public static final String XMLNS_PREFIX = "xmlns"; + public static final String XMLNS_STRING = "xmlns:"; + public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/"; - public static final String XSLT_URI + public static final String XSLT_URI = "http://www.w3.org/1999/XSL/Transform"; - public static final String XHTML_URI + public static final String XHTML_URI = "http://www.w3.org/1999/xhtml"; - public static final String TRANSLET_URI + public static final String TRANSLET_URI = "http://xml.apache.org/xalan/xsltc"; - public static final String REDIRECT_URI - = "http://xml.apache.org/xalan/redirect"; - public static final String FALLBACK_CLASS + public static final String REDIRECT_URI + = "http://xml.apache.org/xalan/redirect"; + public static final String FALLBACK_CLASS = "org.apache.xalan.xsltc.compiler.Fallback"; - public static final int RTF_INITIAL_SIZE = 32; + public static final int RTF_INITIAL_SIZE = 32; } diff --git a/xalan/src/main/java/org/apache/xalan/xsltc/compiler/Stylesheet.java b/xalan/src/main/java/org/apache/xalan/xsltc/compiler/Stylesheet.java index 7c7bda102..fcc94ad53 100644 --- a/xalan/src/main/java/org/apache/xalan/xsltc/compiler/Stylesheet.java +++ b/xalan/src/main/java/org/apache/xalan/xsltc/compiler/Stylesheet.java @@ -60,774 +60,775 @@ public final class Stylesheet extends SyntaxTreeNode { - /** - * XSLT version defined in the stylesheet. - */ - private String _version; + /** + * XSLT version defined in the stylesheet. + */ + private String _version; - /** - * Internal name of this stylesheet used as a key into the symbol table. - */ - private QName _name; + /** + * Internal name of this stylesheet used as a key into the symbol table. + */ + private QName _name; - /** - * A URI that represents the system ID for this stylesheet. - */ - private String _systemId; + /** + * A URI that represents the system ID for this stylesheet. + */ + private String _systemId; - /** - * A reference to the parent stylesheet or null if topmost. - */ - private Stylesheet _parentStylesheet; + /** + * A reference to the parent stylesheet or null if topmost. + */ + private Stylesheet _parentStylesheet; - /** - * Contains global variables and parameters defined in the stylesheet. - */ - private Vector _globals = new Vector(); - - /** - * Used to cache the result returned by hasLocalParams(). - */ - private Boolean _hasLocalParams = null; - - /** - * The name of the class being generated. - */ - private String _className; + /** + * Contains global variables and parameters defined in the stylesheet. + */ + private Vector _globals = new Vector(); + + /** + * Used to cache the result returned by hasLocalParams(). + */ + private Boolean _hasLocalParams = null; + + /** + * The name of the class being generated. + */ + private String _className; - /** - * Contains all templates defined in this stylesheet - */ - private final Vector _templates = new Vector(); + /** + * Contains all templates defined in this stylesheet + */ + private final Vector _templates = new Vector(); - /** - * Used to cache result of getAllValidTemplates(). Only - * set in top-level stylesheets that include/import other stylesheets. - */ - private Vector _allValidTemplates = null; - - private Vector _elementsWithNamespacesUsedDynamically = null; - - /** - * Counter to generate unique mode suffixes. - */ - private int _nextModeSerial = 1; + /** + * Used to cache result of getAllValidTemplates(). Only + * set in top-level stylesheets that include/import other stylesheets. + */ + private Vector _allValidTemplates = null; + + private Vector _elementsWithNamespacesUsedDynamically = null; + + /** + * Counter to generate unique mode suffixes. + */ + private int _nextModeSerial = 1; - /** - * Mapping between mode names and Mode instances. - */ - private final Hashtable _modes = new Hashtable(); + /** + * Mapping between mode names and Mode instances. + */ + private final Hashtable _modes = new Hashtable(); - /** - * A reference to the default Mode object. - */ - private Mode _defaultMode; - - /** - * Mapping between extension URIs and their prefixes. - */ - private final Hashtable _extensions = new Hashtable(); - - /** - * Reference to the stylesheet from which this stylesheet was - * imported (if any). - */ - public Stylesheet _importedFrom = null; + /** + * A reference to the default Mode object. + */ + private Mode _defaultMode; + + /** + * Mapping between extension URIs and their prefixes. + */ + private final Hashtable _extensions = new Hashtable(); + + /** + * Reference to the stylesheet from which this stylesheet was + * imported (if any). + */ + public Stylesheet _importedFrom = null; - /** - * Reference to the stylesheet from which this stylesheet was - * included (if any). - */ - public Stylesheet _includedFrom = null; + /** + * Reference to the stylesheet from which this stylesheet was + * included (if any). + */ + public Stylesheet _includedFrom = null; - /** - * Array of all the stylesheets imported or included from this one. - */ - private Vector _includedStylesheets = null; + /** + * Array of all the stylesheets imported or included from this one. + */ + private Vector _includedStylesheets = null; - /** - * Import precendence for this stylesheet. - */ - private int _importPrecedence = 1; - - /** - * Minimum precendence of any descendant stylesheet by inclusion or - * importation. - */ - private int _minimumDescendantPrecedence = -1; - - /** - * Mapping between key names and Key objects (needed by Key/IdPattern). - */ - private Hashtable _keys = new Hashtable(); - - /** - * A reference to the SourceLoader set by the user (a URIResolver - * if the JAXP API is being used). - */ - private SourceLoader _loader = null; - - /** - * Flag indicating if format-number() is called. - */ - private boolean _numberFormattingUsed = false; - - /** - * Flag indicating if this is a simplified stylesheets. A template - * matching on "/" must be added in this case. - */ - private boolean _simplified = false; - - /** - * Flag indicating if multi-document support is needed. - */ - private boolean _multiDocument = false; + /** + * Import precendence for this stylesheet. + */ + private int _importPrecedence = 1; + + /** + * Minimum precendence of any descendant stylesheet by inclusion or + * importation. + */ + private int _minimumDescendantPrecedence = -1; + + /** + * Mapping between key names and Key objects (needed by Key/IdPattern). + */ + private Hashtable _keys = new Hashtable(); + + /** + * A reference to the SourceLoader set by the user (a URIResolver + * if the JAXP API is being used). + */ + private SourceLoader _loader = null; + + /** + * Flag indicating if format-number() is called. + */ + private boolean _numberFormattingUsed = false; + + /** + * Flag indicating if this is a simplified stylesheets. A template + * matching on "/" must be added in this case. + */ + private boolean _simplified = false; + + /** + * Flag indicating if multi-document support is needed. + */ + private boolean _multiDocument = false; - /** - * Flag indicating if nodset() is called. - */ - private boolean _callsNodeset = false; - - /** - * Flag indicating if id() is called. - */ - private boolean _hasIdCall = false; + /** + * Flag indicating if nodset() is called. + */ + private boolean _callsNodeset = false; + + /** + * Flag indicating if id() is called. + */ + private boolean _hasIdCall = false; - /** - * Set to true to enable template inlining optimization. - * @see XSLTC#_templateInlining - */ - private boolean _templateInlining = false; - - /** - * A reference to the last xsl:output object found in the styleshet. - */ - private Output _lastOutputElement = null; + /** + * Set to true to enable template inlining optimization. + * @see XSLTC#_templateInlining + */ + private boolean _templateInlining = false; + + /** + * A reference to the last xsl:output object found in the styleshet. + */ + private Output _lastOutputElement = null; - /** - * Output properties for this stylesheet. - */ - private Properties _outputProperties = null; + /** + * Output properties for this stylesheet. + */ + private Properties _outputProperties = null; - /** - * Output method for this stylesheet (must be set to one of - * the constants defined below). - */ - private int _outputMethod = UNKNOWN_OUTPUT; - - // Output method constants - public static final int UNKNOWN_OUTPUT = 0; - public static final int XML_OUTPUT = 1; - public static final int HTML_OUTPUT = 2; - public static final int TEXT_OUTPUT = 3; + /** + * Output method for this stylesheet (must be set to one of + * the constants defined below). + */ + private int _outputMethod = UNKNOWN_OUTPUT; + + // Output method constants + public static final int UNKNOWN_OUTPUT = 0; + public static final int XML_OUTPUT = 1; + public static final int HTML_OUTPUT = 2; + public static final int TEXT_OUTPUT = 3; - /** - * Return the output method - */ - public int getOutputMethod() { - return _outputMethod; - } + /** + * Return the output method + */ + public int getOutputMethod() { + return _outputMethod; + } - /** - * Check and set the output method - */ - private void checkOutputMethod() { - if (_lastOutputElement != null) { + /** + * Check and set the output method + */ + private void checkOutputMethod() { + if (_lastOutputElement != null) { String method = _lastOutputElement.getOutputMethod(); if (method != null) { - if (method.equals("xml")) - _outputMethod = XML_OUTPUT; - else if (method.equals("html")) - _outputMethod = HTML_OUTPUT; - else if (method.equals("text")) - _outputMethod = TEXT_OUTPUT; + if (method.equals("xml")) + _outputMethod = XML_OUTPUT; + else if (method.equals("html")) + _outputMethod = HTML_OUTPUT; + else if (method.equals("text")) + _outputMethod = TEXT_OUTPUT; } - } } + } - public boolean getTemplateInlining() { - return _templateInlining; - } + public boolean getTemplateInlining() { + return _templateInlining; + } - public void setTemplateInlining(boolean flag) { - _templateInlining = flag; - } + public void setTemplateInlining(boolean flag) { + _templateInlining = flag; + } - public boolean isSimplified() { - return(_simplified); - } + public boolean isSimplified() { + return(_simplified); + } - public void setSimplified() { - _simplified = true; - } + public void setSimplified() { + _simplified = true; + } - public void setHasIdCall(boolean flag) { - _hasIdCall = flag; - } + public void setHasIdCall(boolean flag) { + _hasIdCall = flag; + } - public void setOutputProperty(String key, String value) { - if (_outputProperties == null) { + public void setOutputProperty(String key, String value) { + if (_outputProperties == null) { _outputProperties = new Properties(); - } - _outputProperties.setProperty(key, value); } + _outputProperties.setProperty(key, value); + } - public void setOutputProperties(Properties props) { - _outputProperties = props; - } + public void setOutputProperties(Properties props) { + _outputProperties = props; + } - public Properties getOutputProperties() { - return _outputProperties; - } + public Properties getOutputProperties() { + return _outputProperties; + } - public Output getLastOutputElement() { - return _lastOutputElement; - } + public Output getLastOutputElement() { + return _lastOutputElement; + } - public void setMultiDocument(boolean flag) { - _multiDocument = flag; - } - - public boolean isMultiDocument() { - return _multiDocument; - } - - public void setCallsNodeset(boolean flag) { - if (flag) setMultiDocument(flag); - _callsNodeset = flag; - } - - public boolean callsNodeset() { - return _callsNodeset; - } - - public void numberFormattingUsed() { - _numberFormattingUsed = true; - /* - * Fix for bug 23046, if the stylesheet is included, set the - * numberFormattingUsed flag to the parent stylesheet too. - * AbstractTranslet.addDecimalFormat() will be inlined once for the - * outer most stylesheet. - */ - Stylesheet parent = getParentStylesheet(); - if (null != parent) parent.numberFormattingUsed(); - } + public void setMultiDocument(boolean flag) { + _multiDocument = flag; + } + + public boolean isMultiDocument() { + return _multiDocument; + } + + public void setCallsNodeset(boolean flag) { + if (flag) setMultiDocument(flag); + _callsNodeset = flag; + } + + public boolean callsNodeset() { + return _callsNodeset; + } + + public void numberFormattingUsed() { + _numberFormattingUsed = true; + /* + * Fix for bug 23046, if the stylesheet is included, set the + * numberFormattingUsed flag to the parent stylesheet too. + * AbstractTranslet.addDecimalFormat() will be inlined once for the + * outer most stylesheet. + */ + Stylesheet parent = getParentStylesheet(); + if (null != parent) parent.numberFormattingUsed(); + } - public void setImportPrecedence(final int precedence) { - // Set import precedence for this stylesheet - _importPrecedence = precedence; + public void setImportPrecedence(final int precedence) { + // Set import precedence for this stylesheet + _importPrecedence = precedence; - // Set import precedence for all included stylesheets - final Enumeration elements = elements(); - while (elements.hasMoreElements()) { + // Set import precedence for all included stylesheets + final Enumeration elements = elements(); + while (elements.hasMoreElements()) { SyntaxTreeNode child = (SyntaxTreeNode)elements.nextElement(); if (child instanceof Include) { - Stylesheet included = ((Include)child).getIncludedStylesheet(); - if (included != null && included._includedFrom == this) { - included.setImportPrecedence(precedence); - } + Stylesheet included = ((Include)child).getIncludedStylesheet(); + if (included != null && included._includedFrom == this) { + included.setImportPrecedence(precedence); + } } - } + } - // Set import precedence for the stylesheet that imported this one - if (_importedFrom != null) { + // Set import precedence for the stylesheet that imported this one + if (_importedFrom != null) { if (_importedFrom.getImportPrecedence() < precedence) { - final Parser parser = getParser(); - final int nextPrecedence = parser.getNextImportPrecedence(); - _importedFrom.setImportPrecedence(nextPrecedence); + final Parser parser = getParser(); + final int nextPrecedence = parser.getNextImportPrecedence(); + _importedFrom.setImportPrecedence(nextPrecedence); } - } - // Set import precedence for the stylesheet that included this one - else if (_includedFrom != null) { + } + // Set import precedence for the stylesheet that included this one + else if (_includedFrom != null) { if (_includedFrom.getImportPrecedence() != precedence) - _includedFrom.setImportPrecedence(precedence); - } + _includedFrom.setImportPrecedence(precedence); } + } - public int getImportPrecedence() { - return _importPrecedence; - } - - /** - * Get the minimum of the precedence of this stylesheet, any stylesheet - * imported by this stylesheet and any include/import descendant of this - * stylesheet. - */ - public int getMinimumDescendantPrecedence() { - if (_minimumDescendantPrecedence == -1) { - // Start with precedence of current stylesheet as a basis. - int min = getImportPrecedence(); - - // Recursively examine all imported/included stylesheets. - final int inclImpCount = (_includedStylesheets != null) - ? _includedStylesheets.size() - : 0; - - for (int i = 0; i < inclImpCount; i++) { - int prec = ((Stylesheet)_includedStylesheets.elementAt(i)) - .getMinimumDescendantPrecedence(); - - if (prec < min) { - min = prec; - } - } - - _minimumDescendantPrecedence = min; + public int getImportPrecedence() { + return _importPrecedence; + } + + /** + * Get the minimum of the precedence of this stylesheet, any stylesheet + * imported by this stylesheet and any include/import descendant of this + * stylesheet. + */ + public int getMinimumDescendantPrecedence() { + if (_minimumDescendantPrecedence == -1) { + // Start with precedence of current stylesheet as a basis. + int min = getImportPrecedence(); + + // Recursively examine all imported/included stylesheets. + final int inclImpCount = (_includedStylesheets != null) + ? _includedStylesheets.size() + : 0; + + for (int i = 0; i < inclImpCount; i++) { + int prec = ((Stylesheet)_includedStylesheets.elementAt(i)) + .getMinimumDescendantPrecedence(); + + if (prec < min) { + min = prec; } - return _minimumDescendantPrecedence; + } + + _minimumDescendantPrecedence = min; } + return _minimumDescendantPrecedence; + } - public boolean checkForLoop(String systemId) { - // Return true if this stylesheet includes/imports itself - if (_systemId != null && _systemId.equals(systemId)) { + public boolean checkForLoop(String systemId) { + // Return true if this stylesheet includes/imports itself + if (_systemId != null && _systemId.equals(systemId)) { return true; - } - // Then check with any stylesheets that included/imported this one - if (_parentStylesheet != null) - return _parentStylesheet.checkForLoop(systemId); - // Otherwise OK - return false; } + // Then check with any stylesheets that included/imported this one + if (_parentStylesheet != null) + return _parentStylesheet.checkForLoop(systemId); + // Otherwise OK + return false; + } - public void setParser(Parser parser) { - super.setParser(parser); - _name = makeStylesheetName("__stylesheet_"); - } + public void setParser(Parser parser) { + super.setParser(parser); + _name = makeStylesheetName("__stylesheet_"); + } - public void setParentStylesheet(Stylesheet parent) { - _parentStylesheet = parent; - } + public void setParentStylesheet(Stylesheet parent) { + _parentStylesheet = parent; + } - public Stylesheet getParentStylesheet() { - return _parentStylesheet; - } + public Stylesheet getParentStylesheet() { + return _parentStylesheet; + } - public void setImportingStylesheet(Stylesheet parent) { - _importedFrom = parent; - parent.addIncludedStylesheet(this); - } + public void setImportingStylesheet(Stylesheet parent) { + _importedFrom = parent; + parent.addIncludedStylesheet(this); + } - public void setIncludingStylesheet(Stylesheet parent) { - _includedFrom = parent; - parent.addIncludedStylesheet(this); - } + public void setIncludingStylesheet(Stylesheet parent) { + _includedFrom = parent; + parent.addIncludedStylesheet(this); + } - public void addIncludedStylesheet(Stylesheet child) { - if (_includedStylesheets == null) { - _includedStylesheets = new Vector(); - } - _includedStylesheets.addElement(child); + public void addIncludedStylesheet(Stylesheet child) { + if (_includedStylesheets == null) { + _includedStylesheets = new Vector(); } + _includedStylesheets.addElement(child); + } - public void setSystemId(String systemId) { - if (systemId != null) { - _systemId = SystemIDResolver.getAbsoluteURI(systemId); - } + public void setSystemId(String systemId) { + if (systemId != null) { + _systemId = SystemIDResolver.getAbsoluteURI(systemId); } + } - public String getSystemId() { - return _systemId; - } + public String getSystemId() { + return _systemId; + } - public void setSourceLoader(SourceLoader loader) { - _loader = loader; - } + public void setSourceLoader(SourceLoader loader) { + _loader = loader; + } - public SourceLoader getSourceLoader() { - return _loader; - } - - private QName makeStylesheetName(String prefix) { - return getParser().getQName(prefix+getXSLTC().nextStylesheetSerial()); - } - - /** - * Returns true if this stylesheet has global vars or params. - */ - public boolean hasGlobals() { - return _globals.size() > 0; - } - - /** - * Returns true if at least one template in the stylesheet has params - * defined. Uses the variable _hasLocalParams to cache the - * result. - */ - public boolean hasLocalParams() { - if (_hasLocalParams == null) { + public SourceLoader getSourceLoader() { + return _loader; + } + + private QName makeStylesheetName(String prefix) { + return getParser().getQName(prefix+getXSLTC().nextStylesheetSerial()); + } + + /** + * Returns true if this stylesheet has global vars or params. + */ + public boolean hasGlobals() { + return _globals.size() > 0; + } + + /** + * Returns true if at least one template in the stylesheet has params + * defined. Uses the variable _hasLocalParams to cache the + * result. + */ + public boolean hasLocalParams() { + if (_hasLocalParams == null) { Vector templates = getAllValidTemplates(); final int n = templates.size(); for (int i = 0; i < n; i++) { - final Template template = (Template)templates.elementAt(i); - if (template.hasParams()) { - _hasLocalParams = Boolean.TRUE; - return true; - } + final Template template = (Template)templates.elementAt(i); + if (template.hasParams()) { + _hasLocalParams = Boolean.TRUE; + return true; + } } _hasLocalParams = Boolean.FALSE; return false; - } - else { - return _hasLocalParams.booleanValue(); - } } - - /** - * Adds a single prefix mapping to this syntax tree node. - * @param prefix Namespace prefix. - * @param uri Namespace URI. - */ - protected void addPrefixMapping(String prefix, String uri) { - if (prefix.equals(EMPTYSTRING) && uri.equals(XHTML_URI)) return; - super.addPrefixMapping(prefix, uri); + else { + return _hasLocalParams.booleanValue(); } - - /** - * Store extension URIs - */ - private void extensionURI(String prefixes, SymbolTable stable) { - if (prefixes != null) { + } + + /** + * Adds a single prefix mapping to this syntax tree node. + * @param prefix Namespace prefix. + * @param uri Namespace URI. + */ + protected void addPrefixMapping(String prefix, String uri) { + if (prefix.equals(EMPTYSTRING) && uri.equals(XHTML_URI)) return; + super.addPrefixMapping(prefix, uri); + } + + /** + * Store extension URIs + */ + private void extensionURI(String prefixes, SymbolTable stable) { + if (prefixes != null) { StringTokenizer tokens = new StringTokenizer(prefixes); while (tokens.hasMoreTokens()) { - final String prefix = tokens.nextToken(); - final String uri = lookupNamespace(prefix); - if (uri != null) { - _extensions.put(uri, prefix); - } + final String prefix = tokens.nextToken(); + final String uri = lookupNamespace(prefix); + if (uri != null) { + _extensions.put(uri, prefix); + } } - } } + } - public boolean isExtension(String uri) { - return (_extensions.get(uri) != null); - } + public boolean isExtension(String uri) { + return (_extensions.get(uri) != null); + } + + public void declareExtensionPrefixes(Parser parser) { + final SymbolTable stable = parser.getSymbolTable(); + final String extensionPrefixes = getAttribute("extension-element-prefixes"); + extensionURI(extensionPrefixes, stable); + } + + /** + * Parse the version and uri fields of the stylesheet and add an + * entry to the symbol table mapping the name __stylesheet_ + * to an instance of this class. + */ + public void parseContents(Parser parser) { + final SymbolTable stable = parser.getSymbolTable(); - public void declareExtensionPrefixes(Parser parser) { - final SymbolTable stable = parser.getSymbolTable(); - final String extensionPrefixes = getAttribute("extension-element-prefixes"); - extensionURI(extensionPrefixes, stable); + /* + // Make sure the XSL version set in this stylesheet + if ((_version == null) || (_version.equals(EMPTYSTRING))) { + reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR,"version"); } + // Verify that the version is 1.0 and nothing else + else if (!_version.equals("1.0")) { + reportError(this, parser, ErrorMsg.XSL_VERSION_ERR, _version); + } + */ - /** - * Parse the version and uri fields of the stylesheet and add an - * entry to the symbol table mapping the name __stylesheet_ - * to an instance of this class. - */ - public void parseContents(Parser parser) { - final SymbolTable stable = parser.getSymbolTable(); - - /* - // Make sure the XSL version set in this stylesheet - if ((_version == null) || (_version.equals(EMPTYSTRING))) { - reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR,"version"); - } - // Verify that the version is 1.0 and nothing else - else if (!_version.equals("1.0")) { - reportError(this, parser, ErrorMsg.XSL_VERSION_ERR, _version); - } - */ - - // Add the implicit mapping of 'xml' to the XML namespace URI - addPrefixMapping("xml", "http://www.w3.org/XML/1998/namespace"); - - // Report and error if more than one stylesheet defined - final Stylesheet sheet = stable.addStylesheet(_name, this); - if (sheet != null) { + // Add the implicit mapping of 'xml' to the XML namespace URI + addPrefixMapping("xml", "http://www.w3.org/XML/1998/namespace"); + + // Report and error if more than one stylesheet defined + final Stylesheet sheet = stable.addStylesheet(_name, this); + if (sheet != null) { // Error: more that one stylesheet defined ErrorMsg err = new ErrorMsg(ErrorMsg.MULTIPLE_STYLESHEET_ERR,this); parser.reportError(Constants.ERROR, err); - } - - // If this is a simplified stylesheet we must create a template that - // grabs the root node of the input doc ( ). - // This template needs the current element (the one passed to this - // method) as its only child, so the Template class has a special - // method that handles this (parseSimplified()). - if (_simplified) { + } + + // If this is a simplified stylesheet we must create a template that + // grabs the root node of the input doc ( ). + // This template needs the current element (the one passed to this + // method) as its only child, so the Template class has a special + // method that handles this (parseSimplified()). + if (_simplified) { stable.excludeURI(XSLT_URI); Template template = new Template(); template.parseSimplified(this, parser); - } - // Parse the children of this node - else { + } + // Parse the children of this node + else { parseOwnChildren(parser); - } } + } - /** - * Parse all direct children of the element. - */ - public final void parseOwnChildren(Parser parser) { - final SymbolTable stable = parser.getSymbolTable(); - final String excludePrefixes = getAttribute("exclude-result-prefixes"); - final String extensionPrefixes = getAttribute("extension-element-prefixes"); + /** + * Parse all direct children of the element. + */ + public final void parseOwnChildren(Parser parser) { + final SymbolTable stable = parser.getSymbolTable(); + final String excludePrefixes = getAttribute("exclude-result-prefixes"); + final String extensionPrefixes = getAttribute("extension-element-prefixes"); - // Exclude XSLT uri - stable.pushExcludedNamespacesContext(); - stable.excludeURI(Constants.XSLT_URI); - stable.excludeNamespaces(excludePrefixes); - stable.excludeNamespaces(extensionPrefixes); - - final Vector contents = getContents(); - final int count = contents.size(); - - // We have to scan the stylesheet element's top-level elements for - // variables and/or parameters before we parse the other elements - for (int i = 0; i < count; i++) { + // Exclude XSLT uri + stable.pushExcludedNamespacesContext(); + stable.excludeURI(Constants.XSLT_URI); + stable.excludeNamespaces(excludePrefixes); + stable.excludeNamespaces(extensionPrefixes); + + final Vector contents = getContents(); + final int count = contents.size(); + + // We have to scan the stylesheet element's top-level elements for + // variables and/or parameters before we parse the other elements + for (int i = 0; i < count; i++) { SyntaxTreeNode child = (SyntaxTreeNode)contents.elementAt(i); if ((child instanceof VariableBase) || - (child instanceof NamespaceAlias)) { - parser.getSymbolTable().setCurrentNode(child); - child.parseContents(parser); + (child instanceof NamespaceAlias)) { + parser.getSymbolTable().setCurrentNode(child); + child.parseContents(parser); } - } + } - // Now go through all the other top-level elements... - for (int i = 0; i < count; i++) { + // Now go through all the other top-level elements... + for (int i = 0; i < count; i++) { SyntaxTreeNode child = (SyntaxTreeNode)contents.elementAt(i); if (!(child instanceof VariableBase) && - !(child instanceof NamespaceAlias)) { - parser.getSymbolTable().setCurrentNode(child); - child.parseContents(parser); + !(child instanceof NamespaceAlias)) { + parser.getSymbolTable().setCurrentNode(child); + child.parseContents(parser); } // All template code should be compiled as methods if the // element was ever used in this stylesheet if (!_templateInlining && (child instanceof Template)) { - Template template = (Template)child; - String name = "template$dot$" + template.getPosition(); - template.setName(parser.getQName(name)); + Template template = (Template)child; + String name = "template$dot$" + template.getPosition(); + template.setName(parser.getQName(name)); } - } - - stable.popExcludedNamespacesContext(); } - public void processModes() { - if (_defaultMode == null) + stable.popExcludedNamespacesContext(); + } + + public void processModes() { + if (_defaultMode == null) _defaultMode = new Mode(null, this, Constants.EMPTYSTRING); - _defaultMode.processPatterns(_keys); - final Enumeration modes = _modes.elements(); - while (modes.hasMoreElements()) { + _defaultMode.processPatterns(_keys); + final Enumeration modes = _modes.elements(); + while (modes.hasMoreElements()) { final Mode mode = (Mode)modes.nextElement(); mode.processPatterns(_keys); - } } + } - private void compileModes(ClassGenerator classGen) { - _defaultMode.compileApplyTemplates(classGen); - final Enumeration modes = _modes.elements(); - while (modes.hasMoreElements()) { + private void compileModes(ClassGenerator classGen) { + _defaultMode.compileApplyTemplates(classGen); + final Enumeration modes = _modes.elements(); + while (modes.hasMoreElements()) { final Mode mode = (Mode)modes.nextElement(); mode.compileApplyTemplates(classGen); - } } + } - public Mode getMode(QName modeName) { - if (modeName == null) { + public Mode getMode(QName modeName) { + if (modeName == null) { if (_defaultMode == null) { - _defaultMode = new Mode(null, this, Constants.EMPTYSTRING); + _defaultMode = new Mode(null, this, Constants.EMPTYSTRING); } return _defaultMode; - } - else { + } + else { Mode mode = (Mode)_modes.get(modeName); if (mode == null) { - final String suffix = Integer.toString(_nextModeSerial++); - _modes.put(modeName, mode = new Mode(modeName, this, suffix)); + final String suffix = Integer.toString(_nextModeSerial++); + _modes.put(modeName, mode = new Mode(modeName, this, suffix)); } return mode; - } } + } - /** - * Type check all the children of this node. - */ - public Type typeCheck(SymbolTable stable) throws TypeCheckError { - final int count = _globals.size(); - for (int i = 0; i < count; i++) { + /** + * Type check all the children of this node. + */ + public Type typeCheck(SymbolTable stable) throws TypeCheckError { + final int count = _globals.size(); + for (int i = 0; i < count; i++) { final VariableBase var = (VariableBase)_globals.elementAt(i); var.typeCheck(stable); - } - return typeCheckContents(stable); - } - - /** - * Translate the stylesheet into JVM bytecodes. - */ - public void translate(ClassGenerator classGen, MethodGenerator methodGen) { - translate(); - } - - private void addDOMField(ClassGenerator classGen) { - final FieldGen fgen = new FieldGen(ACC_PUBLIC, - Util.getJCRefType(DOM_INTF_SIG), - DOM_FIELD, - classGen.getConstantPool()); - classGen.addField(fgen.getField()); } + return typeCheckContents(stable); + } + + /** + * Translate the stylesheet into JVM bytecodes. + */ + public void translate(ClassGenerator classGen, MethodGenerator methodGen) { + translate(); + } + + private void addDOMField(ClassGenerator classGen) { + final FieldGen fgen = new FieldGen(ACC_PUBLIC, + Util.getJCRefType(DOM_INTF_SIG), + DOM_FIELD, + classGen.getConstantPool()); + classGen.addField(fgen.getField()); + } - /** - * Add a static field - */ - private void addStaticField(ClassGenerator classGen, String type, - String name) + /** + * Add a static field + */ + private void addStaticField(ClassGenerator classGen, String type, + String name) { - final FieldGen fgen = new FieldGen(ACC_PROTECTED|ACC_STATIC, - Util.getJCRefType(type), - name, - classGen.getConstantPool()); - classGen.addField(fgen.getField()); + final FieldGen fgen = new FieldGen(ACC_PROTECTED|ACC_STATIC, + Util.getJCRefType(type), + name, + classGen.getConstantPool()); + classGen.addField(fgen.getField()); } - /** - * Translate the stylesheet into JVM bytecodes. - */ - public void translate() { - _className = getXSLTC().getClassName(); + /** + * Translate the stylesheet into JVM bytecodes. + */ + public void translate() { + _className = getXSLTC().getClassName(); - // Define a new class by extending TRANSLET_CLASS - final ClassGenerator classGen = + // Define a new class by extending TRANSLET_CLASS + final ClassGenerator classGen = new ClassGenerator(_className, - TRANSLET_CLASS, - Constants.EMPTYSTRING, - ACC_PUBLIC | ACC_SUPER, - null, this); + TRANSLET_CLASS, + Constants.EMPTYSTRING, + ACC_PUBLIC | ACC_SUPER, + null, this); - addDOMField(classGen); + addDOMField(classGen); - // Compile transform() to initialize parameters, globals & output - // and run the transformation - compileTransform(classGen); + // Compile transform() to initialize parameters, globals & output + // and run the transformation + compileTransform(classGen); - // Translate all non-template elements and filter out all templates - final Enumeration elements = elements(); - while (elements.hasMoreElements()) { + // Translate all non-template elements and filter out all templates + final Enumeration elements = elements(); + while (elements.hasMoreElements()) { Object element = elements.nextElement(); // xsl:template if (element instanceof Template) { - // Separate templates by modes - final Template template = (Template)element; - //_templates.addElement(template); - getMode(template.getModeName()).addTemplate(template); + // Separate templates by modes + final Template template = (Template)element; + //_templates.addElement(template); + getMode(template.getModeName()).addTemplate(template); } // xsl:attribute-set else if (element instanceof AttributeSet) { - ((AttributeSet)element).translate(classGen, null); + ((AttributeSet)element).translate(classGen, null); } else if (element instanceof Output) { - // save the element for later to pass to compileConstructor - Output output = (Output)element; - if (output.enabled()) _lastOutputElement = output; + // save the element for later to pass to compileConstructor + Output output = (Output)element; + if (output.enabled()) _lastOutputElement = output; } else { - // Global variables and parameters are handled elsewhere. - // Other top-level non-template elements are ignored. Literal - // elements outside of templates will never be output. + // Global variables and parameters are handled elsewhere. + // Other top-level non-template elements are ignored. Literal + // elements outside of templates will never be output. } - } + } - checkOutputMethod(); - processModes(); - compileModes(classGen); - compileStaticInitializer(classGen); - compileConstructor(classGen, _lastOutputElement); + checkOutputMethod(); + processModes(); + compileModes(classGen); + compileStaticInitializer(classGen); + compileConstructor(classGen, _lastOutputElement); - if (!getParser().errorsFound()) { + if (!getParser().errorsFound()) { getXSLTC().dumpClass(classGen.getJavaClass()); - } } - - /** - *

Compile the namesArray, urisArray, typesArray, namespaceArray, - * namespaceAncestorsArray, prefixURIsIdxArray and prefixURIPairsArray into - * the static initializer. They are read-only from the - * translet. All translet instances can share a single - * copy of this informtion.

- *

The namespaceAncestorsArray, - * prefixURIsIdxArray and prefixURIPairsArray - * contain namespace information accessible from the stylesheet: - *

- *
namespaceAncestorsArray
- *
Array indexed by integer stylesheet node IDs containing node IDs of - * the nearest ancestor node in the stylesheet with namespace - * declarations or -1 if there is no such ancestor. There - * can be more than one disjoint tree of nodes - one for each stylesheet - * module
- *
prefixURIsIdxArray
- *
Array indexed by integer stylesheet node IDs containing the index - * into prefixURIPairsArray of the first namespace prefix - * declared for the node. The values are stored in ascending order, so - * the next value in this array (if any) can be used to find the last such - * prefix-URI pair
- *
prefixURIPairsArray
- *
Array of pairs of namespace prefixes and URIs. A zero-length - * string represents the default namespace if it appears as a prefix and - * a namespace undeclaration if it appears as a URI.
- *
- *

- *

For this stylesheet - *


-     * <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
-     *   <xsl:template match="/">
-     *     <xsl:for-each select="*" xmlns:foo="foouri">
-     *       <xsl:element name="{n}" xmlns:foo="baruri">
-     *     </xsl:for-each>
-     *     <out xmlns="lumpit"/>
-     *     <xsl:element name="{n}" xmlns="foouri"/>
-     *     <xsl:element name="{n}" namespace="{ns}" xmlns="limpit"/gt;
-     *   </xsl:template>
-     * </xsl:stylesheet>
-     * 
- * there will be four stylesheet nodes whose namespace information is - * needed, and - *
    - *
  • namespaceAncestorsArray will have the value - * [-1,0,1,0];
  • - *
  • prefixURIsIdxArray will have the value - * [0,4,6,8]; and
  • - *
  • prefixURIPairsArray will have the value - * ["xml","http://www.w3.org/XML/1998/namespace", - * "xsl","http://www.w3.org/1999/XSL/Transform" - * "foo","foouri","foo","baruri","","foouri"].
  • - *
- *

- */ - private void compileStaticInitializer(ClassGenerator classGen) { - final ConstantPoolGen cpg = classGen.getConstantPool(); - final InstructionList il = new InstructionList(); - - final MethodGenerator staticConst = + } + + /** + *

Compile the namesArray, urisArray, typesArray, namespaceArray, + * namespaceAncestorsArray, prefixURIsIdxArray and prefixURIPairsArray into + * the static initializer. They are read-only from the + * translet. All translet instances can share a single + * copy of this informtion.

+ *

The namespaceAncestorsArray, + * prefixURIsIdxArray and prefixURIPairsArray + * contain namespace information accessible from the stylesheet: + *

+ *
namespaceAncestorsArray
+ *
Array indexed by integer stylesheet node IDs containing node IDs of + * the nearest ancestor node in the stylesheet with namespace + * declarations or -1 if there is no such ancestor. There + * can be more than one disjoint tree of nodes - one for each stylesheet + * module
+ *
prefixURIsIdxArray
+ *
Array indexed by integer stylesheet node IDs containing the index + * into prefixURIPairsArray of the first namespace prefix + * declared for the node. The values are stored in ascending order, so + * the next value in this array (if any) can be used to find the last such + * prefix-URI pair
+ *
prefixURIPairsArray
+ *
Array of pairs of namespace prefixes and URIs. A zero-length + * string represents the default namespace if it appears as a prefix and + * a namespace undeclaration if it appears as a URI.
+ *
+ *

+ *

For this stylesheet + *


+   * <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+   *   <xsl:template match="/">
+   *     <xsl:for-each select="*" xmlns:foo="foouri">
+   *       <xsl:element name="{n}" xmlns:foo="baruri">
+   *     </xsl:for-each>
+   *     <out xmlns="lumpit"/>
+   *     <xsl:element name="{n}" xmlns="foouri"/>
+   *     <xsl:element name="{n}" namespace="{ns}" xmlns="limpit"/gt;
+   *   </xsl:template>
+   * </xsl:stylesheet>
+   * 
+ * there will be four stylesheet nodes whose namespace information is + * needed, and + *
    + *
  • namespaceAncestorsArray will have the value + * [-1,0,1,0];
  • + *
  • prefixURIsIdxArray will have the value + * [0,4,6,8]; and
  • + *
  • prefixURIPairsArray will have the value + * ["xml","http://www.w3.org/XML/1998/namespace", + * "xsl","http://www.w3.org/1999/XSL/Transform" + * "foo","foouri","foo","baruri","","foouri"].
  • + *
+ *

+ */ + private void compileStaticInitializer(ClassGenerator classGen) { + final ConstantPoolGen cpg = classGen.getConstantPool(); + final InstructionList il = new InstructionList(); + + final MethodGenerator staticConst = new MethodGenerator(ACC_PUBLIC|ACC_STATIC, - org.apache.bcel.generic.Type.VOID, - null, null, "", - _className, il, cpg); - - addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMES_ARRAY_FIELD); - addStaticField(classGen, "[" + STRING_SIG, STATIC_URIS_ARRAY_FIELD); - addStaticField(classGen, "[I", STATIC_TYPES_ARRAY_FIELD); - addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMESPACE_ARRAY_FIELD); - // Create fields of type char[] that will contain literal text from - // the stylesheet. - final int charDataFieldCount = getXSLTC().getCharacterDataCount(); - for (int i = 0; i < charDataFieldCount; i++) { - addStaticField(classGen, STATIC_CHAR_DATA_FIELD_SIG, - STATIC_CHAR_DATA_FIELD+i); - } - - // Put the names array into the translet - used for dom/translet mapping - final Vector namesIndex = getXSLTC().getNamesIndex(); - int size = namesIndex.size(); - String[] namesArray = new String[size]; - String[] urisArray = new String[size]; - int[] typesArray = new int[size]; + org.apache.bcel.generic.Type.VOID, + null, null, "", + _className, il, cpg); + + addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMES_ARRAY_FIELD); + addStaticField(classGen, "[" + STRING_SIG, STATIC_URIS_ARRAY_FIELD); + addStaticField(classGen, "[I", STATIC_TYPES_ARRAY_FIELD); + addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMESPACE_ARRAY_FIELD); + addStaticField(classGen, MAP_SIG, STATIC_NS_MAP_FIELD ); + // Create fields of type char[] that will contain literal text from + // the stylesheet. + final int charDataFieldCount = getXSLTC().getCharacterDataCount(); + for (int i = 0; i < charDataFieldCount; i++) { + addStaticField(classGen, STATIC_CHAR_DATA_FIELD_SIG, + STATIC_CHAR_DATA_FIELD+i); + } + + // Put the names array into the translet - used for dom/translet mapping + final Vector namesIndex = getXSLTC().getNamesIndex(); + int size = namesIndex.size(); + String[] namesArray = new String[size]; + String[] urisArray = new String[size]; + int[] typesArray = new int[size]; - int index; - for (int i = 0; i < size; i++) { + int index; + for (int i = 0; i < size; i++) { String encodedName = (String)namesIndex.elementAt(i); if ((index = encodedName.lastIndexOf(':')) > -1) { - urisArray[i] = encodedName.substring(0, index); + urisArray[i] = encodedName.substring(0, index); } index = index + 1; @@ -838,350 +839,364 @@ private void compileStaticInitializer(ClassGenerator classGen) { typesArray[i] = DTM.NAMESPACE_NODE; index++; } else { - typesArray[i] = DTM.ELEMENT_NODE; + typesArray[i] = DTM.ELEMENT_NODE; } if (index == 0) { - namesArray[i] = encodedName; + namesArray[i] = encodedName; } else { - namesArray[i] = encodedName.substring(index); + namesArray[i] = encodedName.substring(index); } - } + } - staticConst.markChunkStart(); - il.append(new PUSH(cpg, size)); - il.append(new ANEWARRAY(cpg.addClass(STRING))); - int namesArrayRef = cpg.addFieldref(_className, - STATIC_NAMES_ARRAY_FIELD, - NAMES_INDEX_SIG); - il.append(new PUTSTATIC(namesArrayRef)); - staticConst.markChunkEnd(); + staticConst.markChunkStart(); + il.append(new PUSH(cpg, size)); + il.append(new ANEWARRAY(cpg.addClass(STRING))); + int namesArrayRef = cpg.addFieldref(_className, + STATIC_NAMES_ARRAY_FIELD, + NAMES_INDEX_SIG); + il.append(new PUTSTATIC(namesArrayRef)); + staticConst.markChunkEnd(); - for (int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { final String name = namesArray[i]; - staticConst.markChunkStart(); + staticConst.markChunkStart(); il.append(new GETSTATIC(namesArrayRef)); il.append(new PUSH(cpg, i)); il.append(new PUSH(cpg, name)); il.append(AASTORE); - staticConst.markChunkEnd(); - } + staticConst.markChunkEnd(); + } - staticConst.markChunkStart(); - il.append(new PUSH(cpg, size)); - il.append(new ANEWARRAY(cpg.addClass(STRING))); - int urisArrayRef = cpg.addFieldref(_className, - STATIC_URIS_ARRAY_FIELD, - URIS_INDEX_SIG); - il.append(new PUTSTATIC(urisArrayRef)); - staticConst.markChunkEnd(); + staticConst.markChunkStart(); + il.append(new PUSH(cpg, size)); + il.append(new ANEWARRAY(cpg.addClass(STRING))); + int urisArrayRef = cpg.addFieldref(_className, + STATIC_URIS_ARRAY_FIELD, + URIS_INDEX_SIG); + il.append(new PUTSTATIC(urisArrayRef)); + staticConst.markChunkEnd(); - for (int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { final String uri = urisArray[i]; - staticConst.markChunkStart(); + staticConst.markChunkStart(); il.append(new GETSTATIC(urisArrayRef)); il.append(new PUSH(cpg, i)); il.append(new PUSH(cpg, uri)); il.append(AASTORE); - staticConst.markChunkEnd(); - } + staticConst.markChunkEnd(); + } - staticConst.markChunkStart(); - il.append(new PUSH(cpg, size)); - il.append(new NEWARRAY(BasicType.INT)); - int typesArrayRef = cpg.addFieldref(_className, - STATIC_TYPES_ARRAY_FIELD, - TYPES_INDEX_SIG); - il.append(new PUTSTATIC(typesArrayRef)); - staticConst.markChunkEnd(); + staticConst.markChunkStart(); + il.append(new PUSH(cpg, size)); + il.append(new NEWARRAY(BasicType.INT)); + int typesArrayRef = cpg.addFieldref(_className, + STATIC_TYPES_ARRAY_FIELD, + TYPES_INDEX_SIG); + il.append(new PUTSTATIC(typesArrayRef)); + staticConst.markChunkEnd(); - for (int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { final int nodeType = typesArray[i]; - staticConst.markChunkStart(); + staticConst.markChunkStart(); il.append(new GETSTATIC(typesArrayRef)); il.append(new PUSH(cpg, i)); il.append(new PUSH(cpg, nodeType)); il.append(IASTORE); - staticConst.markChunkEnd(); - } + staticConst.markChunkEnd(); + } - // Put the namespace names array into the translet - final Vector namespaces = getXSLTC().getNamespaceIndex(); - staticConst.markChunkStart(); - il.append(new PUSH(cpg, namespaces.size())); - il.append(new ANEWARRAY(cpg.addClass(STRING))); - int namespaceArrayRef = cpg.addFieldref(_className, - STATIC_NAMESPACE_ARRAY_FIELD, - NAMESPACE_INDEX_SIG); - il.append(new PUTSTATIC(namespaceArrayRef)); - staticConst.markChunkEnd(); + // Put the namespace names array into the translet + final Vector namespaces = getXSLTC().getNamespaceIndex(); + staticConst.markChunkStart(); + il.append(new PUSH(cpg, namespaces.size())); + il.append(new ANEWARRAY(cpg.addClass(STRING))); + int namespaceArrayRef = cpg.addFieldref(_className, + STATIC_NAMESPACE_ARRAY_FIELD, + NAMESPACE_INDEX_SIG); + il.append(new PUTSTATIC(namespaceArrayRef)); + staticConst.markChunkEnd(); - for (int i = 0; i < namespaces.size(); i++) { + for (int i = 0; i < namespaces.size(); i++) { final String ns = (String)namespaces.elementAt(i); - staticConst.markChunkStart(); + staticConst.markChunkStart(); il.append(new GETSTATIC(namespaceArrayRef)); il.append(new PUSH(cpg, i)); il.append(new PUSH(cpg, ns)); il.append(AASTORE); - staticConst.markChunkEnd(); - } - - // Put the tree of stylesheet namespace declarations into the translet - final Vector namespaceAncestors = getXSLTC().getNSAncestorPointers(); - if (namespaceAncestors != null && namespaceAncestors.size() != 0) { - addStaticField(classGen, NS_ANCESTORS_INDEX_SIG, - STATIC_NS_ANCESTORS_ARRAY_FIELD); - staticConst.markChunkStart(); - il.append(new PUSH(cpg, namespaceAncestors.size())); - il.append(new NEWARRAY(BasicType.INT)); - int namespaceAncestorsArrayRef = - cpg.addFieldref(_className, STATIC_NS_ANCESTORS_ARRAY_FIELD, - NS_ANCESTORS_INDEX_SIG); - il.append(new PUTSTATIC(namespaceAncestorsArrayRef)); - staticConst.markChunkEnd(); - for (int i = 0; i < namespaceAncestors.size(); i++) { - int ancestor = ((Integer) namespaceAncestors.get(i)).intValue(); - staticConst.markChunkStart(); - il.append(new GETSTATIC(namespaceAncestorsArrayRef)); - il.append(new PUSH(cpg, i)); - il.append(new PUSH(cpg, ancestor)); - il.append(IASTORE); - staticConst.markChunkEnd(); - } - } - // Put the array of indices into the namespace prefix/URI pairs array - // into the translet - final Vector prefixURIPairsIdx = getXSLTC().getPrefixURIPairsIdx(); - if (prefixURIPairsIdx != null && prefixURIPairsIdx.size() != 0) { - addStaticField(classGen, PREFIX_URIS_IDX_SIG, - STATIC_PREFIX_URIS_IDX_ARRAY_FIELD); - staticConst.markChunkStart(); - il.append(new PUSH(cpg, prefixURIPairsIdx.size())); - il.append(new NEWARRAY(BasicType.INT)); - int prefixURIPairsIdxArrayRef = - cpg.addFieldref(_className, - STATIC_PREFIX_URIS_IDX_ARRAY_FIELD, - PREFIX_URIS_IDX_SIG); - il.append(new PUTSTATIC(prefixURIPairsIdxArrayRef)); - staticConst.markChunkEnd(); - for (int i = 0; i < prefixURIPairsIdx.size(); i++) { - int idx = ((Integer) prefixURIPairsIdx.get(i)).intValue(); - staticConst.markChunkStart(); - il.append(new GETSTATIC(prefixURIPairsIdxArrayRef)); - il.append(new PUSH(cpg, i)); - il.append(new PUSH(cpg, idx)); - il.append(IASTORE); - staticConst.markChunkEnd(); - } - } - - // Put the array of pairs of namespace prefixes and URIs into the - // translet - final Vector prefixURIPairs = getXSLTC().getPrefixURIPairs(); - if (prefixURIPairs != null && prefixURIPairs.size() != 0) { - addStaticField(classGen, PREFIX_URIS_ARRAY_SIG, - STATIC_PREFIX_URIS_ARRAY_FIELD); - - staticConst.markChunkStart(); - il.append(new PUSH(cpg, prefixURIPairs.size())); - il.append(new ANEWARRAY(cpg.addClass(STRING))); - int prefixURIPairsRef = - cpg.addFieldref(_className, - STATIC_PREFIX_URIS_ARRAY_FIELD, - PREFIX_URIS_ARRAY_SIG); - il.append(new PUTSTATIC(prefixURIPairsRef)); - staticConst.markChunkEnd(); - for (int i = 0; i < prefixURIPairs.size(); i++) { - String prefixOrURI = (String) prefixURIPairs.get(i); - staticConst.markChunkStart(); - il.append(new GETSTATIC(prefixURIPairsRef)); - il.append(new PUSH(cpg, i)); - il.append(new PUSH(cpg, prefixOrURI)); - il.append(AASTORE); - staticConst.markChunkEnd(); - } - } + staticConst.markChunkEnd(); + } + + // Create the namespace -> prefix map + staticConst.markChunkStart(); + il.append(new NEW(cpg.addClass(HASHMAP_CLASS))); + il.append(DUP); + final int init = cpg.addMethodref(HASHMAP_CLASS, "","()V"); + il.append(new INVOKESPECIAL(init)); + + int nsMapRef = cpg.addFieldref(_className, + STATIC_NS_MAP_FIELD, + MAP_SIG); + il.append(new PUTSTATIC(nsMapRef)); + staticConst.markChunkEnd(); + + + // Put the tree of stylesheet namespace declarations into the translet + final Vector namespaceAncestors = getXSLTC().getNSAncestorPointers(); + if (namespaceAncestors != null && namespaceAncestors.size() != 0) { + addStaticField(classGen, NS_ANCESTORS_INDEX_SIG, + STATIC_NS_ANCESTORS_ARRAY_FIELD); + staticConst.markChunkStart(); + il.append(new PUSH(cpg, namespaceAncestors.size())); + il.append(new NEWARRAY(BasicType.INT)); + int namespaceAncestorsArrayRef = + cpg.addFieldref(_className, STATIC_NS_ANCESTORS_ARRAY_FIELD, + NS_ANCESTORS_INDEX_SIG); + il.append(new PUTSTATIC(namespaceAncestorsArrayRef)); + staticConst.markChunkEnd(); + for (int i = 0; i < namespaceAncestors.size(); i++) { + int ancestor = ((Integer) namespaceAncestors.get(i)).intValue(); + staticConst.markChunkStart(); + il.append(new GETSTATIC(namespaceAncestorsArrayRef)); + il.append(new PUSH(cpg, i)); + il.append(new PUSH(cpg, ancestor)); + il.append(IASTORE); + staticConst.markChunkEnd(); + } + } + // Put the array of indices into the namespace prefix/URI pairs array + // into the translet + final Vector prefixURIPairsIdx = getXSLTC().getPrefixURIPairsIdx(); + if (prefixURIPairsIdx != null && prefixURIPairsIdx.size() != 0) { + addStaticField(classGen, PREFIX_URIS_IDX_SIG, + STATIC_PREFIX_URIS_IDX_ARRAY_FIELD); + staticConst.markChunkStart(); + il.append(new PUSH(cpg, prefixURIPairsIdx.size())); + il.append(new NEWARRAY(BasicType.INT)); + int prefixURIPairsIdxArrayRef = + cpg.addFieldref(_className, + STATIC_PREFIX_URIS_IDX_ARRAY_FIELD, + PREFIX_URIS_IDX_SIG); + il.append(new PUTSTATIC(prefixURIPairsIdxArrayRef)); + staticConst.markChunkEnd(); + for (int i = 0; i < prefixURIPairsIdx.size(); i++) { + int idx = ((Integer) prefixURIPairsIdx.get(i)).intValue(); + staticConst.markChunkStart(); + il.append(new GETSTATIC(prefixURIPairsIdxArrayRef)); + il.append(new PUSH(cpg, i)); + il.append(new PUSH(cpg, idx)); + il.append(IASTORE); + staticConst.markChunkEnd(); + } + } + + // Put the array of pairs of namespace prefixes and URIs into the + // translet + final Vector prefixURIPairs = getXSLTC().getPrefixURIPairs(); + if (prefixURIPairs != null && prefixURIPairs.size() != 0) { + addStaticField(classGen, PREFIX_URIS_ARRAY_SIG, + STATIC_PREFIX_URIS_ARRAY_FIELD); + + staticConst.markChunkStart(); + il.append(new PUSH(cpg, prefixURIPairs.size())); + il.append(new ANEWARRAY(cpg.addClass(STRING))); + int prefixURIPairsRef = + cpg.addFieldref(_className, + STATIC_PREFIX_URIS_ARRAY_FIELD, + PREFIX_URIS_ARRAY_SIG); + il.append(new PUTSTATIC(prefixURIPairsRef)); + staticConst.markChunkEnd(); + for (int i = 0; i < prefixURIPairs.size(); i++) { + String prefixOrURI = (String) prefixURIPairs.get(i); + staticConst.markChunkStart(); + il.append(new GETSTATIC(prefixURIPairsRef)); + il.append(new PUSH(cpg, i)); + il.append(new PUSH(cpg, prefixOrURI)); + il.append(AASTORE); + staticConst.markChunkEnd(); + } + } - // Grab all the literal text in the stylesheet and put it in a char[] - final int charDataCount = getXSLTC().getCharacterDataCount(); - final int toCharArray = cpg.addMethodref(STRING, "toCharArray", "()[C"); - for (int i = 0; i < charDataCount; i++) { - staticConst.markChunkStart(); - il.append(new PUSH(cpg, getXSLTC().getCharacterData(i))); - il.append(new INVOKEVIRTUAL(toCharArray)); - il.append(new PUTSTATIC(cpg.addFieldref(_className, - STATIC_CHAR_DATA_FIELD+i, - STATIC_CHAR_DATA_FIELD_SIG))); - staticConst.markChunkEnd(); - } + // Grab all the literal text in the stylesheet and put it in a char[] + final int charDataCount = getXSLTC().getCharacterDataCount(); + final int toCharArray = cpg.addMethodref(STRING, "toCharArray", "()[C"); + for (int i = 0; i < charDataCount; i++) { + staticConst.markChunkStart(); + il.append(new PUSH(cpg, getXSLTC().getCharacterData(i))); + il.append(new INVOKEVIRTUAL(toCharArray)); + il.append(new PUTSTATIC(cpg.addFieldref(_className, + STATIC_CHAR_DATA_FIELD+i, + STATIC_CHAR_DATA_FIELD_SIG))); + staticConst.markChunkEnd(); + } - il.append(RETURN); + il.append(RETURN); - classGen.addMethod(staticConst); + classGen.addMethod(staticConst); - } + } - /** - * Compile the translet's constructor - */ - private void compileConstructor(ClassGenerator classGen, Output output) { + /** + * Compile the translet's constructor + */ + private void compileConstructor(ClassGenerator classGen, Output output) { - final ConstantPoolGen cpg = classGen.getConstantPool(); - final InstructionList il = new InstructionList(); + final ConstantPoolGen cpg = classGen.getConstantPool(); + final InstructionList il = new InstructionList(); - final MethodGenerator constructor = + final MethodGenerator constructor = new MethodGenerator(ACC_PUBLIC, - org.apache.bcel.generic.Type.VOID, - null, null, "", - _className, il, cpg); - - // Call the constructor in the AbstractTranslet superclass - il.append(classGen.loadTranslet()); - il.append(new INVOKESPECIAL(cpg.addMethodref(TRANSLET_CLASS, - "", "()V"))); + org.apache.bcel.generic.Type.VOID, + null, null, "", + _className, il, cpg); + + // Call the constructor in the AbstractTranslet superclass + il.append(classGen.loadTranslet()); + il.append(new INVOKESPECIAL(cpg.addMethodref(TRANSLET_CLASS, + "", "()V"))); - constructor.markChunkStart(); - il.append(classGen.loadTranslet()); - il.append(new GETSTATIC(cpg.addFieldref(_className, - STATIC_NAMES_ARRAY_FIELD, - NAMES_INDEX_SIG))); - il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, - NAMES_INDEX, - NAMES_INDEX_SIG))); - constructor.markChunkEnd(); + constructor.markChunkStart(); + il.append(classGen.loadTranslet()); + il.append(new GETSTATIC(cpg.addFieldref(_className, + STATIC_NAMES_ARRAY_FIELD, + NAMES_INDEX_SIG))); + il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, + NAMES_INDEX, + NAMES_INDEX_SIG))); + constructor.markChunkEnd(); - constructor.markChunkStart(); - il.append(classGen.loadTranslet()); - il.append(new GETSTATIC(cpg.addFieldref(_className, - STATIC_URIS_ARRAY_FIELD, - URIS_INDEX_SIG))); - il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, - URIS_INDEX, - URIS_INDEX_SIG))); - constructor.markChunkEnd(); - - constructor.markChunkStart(); - il.append(classGen.loadTranslet()); - il.append(new GETSTATIC(cpg.addFieldref(_className, - STATIC_TYPES_ARRAY_FIELD, - TYPES_INDEX_SIG))); - il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, - TYPES_INDEX, - TYPES_INDEX_SIG))); - constructor.markChunkEnd(); - - constructor.markChunkStart(); - il.append(classGen.loadTranslet()); - il.append(new GETSTATIC(cpg.addFieldref(_className, - STATIC_NAMESPACE_ARRAY_FIELD, - NAMESPACE_INDEX_SIG))); - il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, - NAMESPACE_INDEX, - NAMESPACE_INDEX_SIG))); - constructor.markChunkEnd(); - - constructor.markChunkStart(); - il.append(classGen.loadTranslet()); - il.append(new PUSH(cpg, AbstractTranslet.CURRENT_TRANSLET_VERSION)); - il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, - TRANSLET_VERSION_INDEX, - TRANSLET_VERSION_INDEX_SIG))); - constructor.markChunkEnd(); + constructor.markChunkStart(); + il.append(classGen.loadTranslet()); + il.append(new GETSTATIC(cpg.addFieldref(_className, + STATIC_URIS_ARRAY_FIELD, + URIS_INDEX_SIG))); + il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, + URIS_INDEX, + URIS_INDEX_SIG))); + constructor.markChunkEnd(); + + constructor.markChunkStart(); + il.append(classGen.loadTranslet()); + il.append(new GETSTATIC(cpg.addFieldref(_className, + STATIC_TYPES_ARRAY_FIELD, + TYPES_INDEX_SIG))); + il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, + TYPES_INDEX, + TYPES_INDEX_SIG))); + constructor.markChunkEnd(); + + constructor.markChunkStart(); + il.append(classGen.loadTranslet()); + il.append(new GETSTATIC(cpg.addFieldref(_className, + STATIC_NAMESPACE_ARRAY_FIELD, + NAMESPACE_INDEX_SIG))); + il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, + NAMESPACE_INDEX, + NAMESPACE_INDEX_SIG))); + constructor.markChunkEnd(); + + constructor.markChunkStart(); + il.append(classGen.loadTranslet()); + il.append(new PUSH(cpg, AbstractTranslet.CURRENT_TRANSLET_VERSION)); + il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, + TRANSLET_VERSION_INDEX, + TRANSLET_VERSION_INDEX_SIG))); + constructor.markChunkEnd(); - if (_hasIdCall) { - constructor.markChunkStart(); + if (_hasIdCall) { + constructor.markChunkStart(); il.append(classGen.loadTranslet()); il.append(new PUSH(cpg, Boolean.TRUE)); il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, - HASIDCALL_INDEX, - HASIDCALL_INDEX_SIG))); - constructor.markChunkEnd(); - } + HASIDCALL_INDEX, + HASIDCALL_INDEX_SIG))); + constructor.markChunkEnd(); + } - // Compile in code to set the output configuration from - if (output != null) { + // Compile in code to set the output configuration from + if (output != null) { // Set all the output settings files in the translet - constructor.markChunkStart(); + constructor.markChunkStart(); output.translate(classGen, constructor); - constructor.markChunkEnd(); - } - - // Compile default decimal formatting symbols. - // This is an implicit, nameless xsl:decimal-format top-level element. - if (_numberFormattingUsed) { - constructor.markChunkStart(); - DecimalFormatting.translateDefaultDFS(classGen, constructor); - constructor.markChunkEnd(); - } - - il.append(RETURN); - - classGen.addMethod(constructor); + constructor.markChunkEnd(); } - /** - * Compile a topLevel() method into the output class. This method is - * called from transform() to handle all non-template top-level elements. - * Returns the signature of the topLevel() method. - * - * Global variables/params and keys are first sorted to resolve - * dependencies between them. The XSLT 1.0 spec does not allow a key - * to depend on a variable. However, for compatibility with Xalan - * interpretive, that type of dependency is allowed. Note also that - * the buildKeys() method is still generated as it is used by the - * LoadDocument class, but it no longer called from transform(). - */ - private String compileTopLevel(ClassGenerator classGen) { - final ConstantPoolGen cpg = classGen.getConstantPool(); - - final org.apache.bcel.generic.Type[] argTypes = { + // Compile default decimal formatting symbols. + // This is an implicit, nameless xsl:decimal-format top-level element. + if (_numberFormattingUsed) { + constructor.markChunkStart(); + DecimalFormatting.translateDefaultDFS(classGen, constructor); + constructor.markChunkEnd(); + } + + il.append(RETURN); + + classGen.addMethod(constructor); + } + + /** + * Compile a topLevel() method into the output class. This method is + * called from transform() to handle all non-template top-level elements. + * Returns the signature of the topLevel() method. + * + * Global variables/params and keys are first sorted to resolve + * dependencies between them. The XSLT 1.0 spec does not allow a key + * to depend on a variable. However, for compatibility with Xalan + * interpretive, that type of dependency is allowed. Note also that + * the buildKeys() method is still generated as it is used by the + * LoadDocument class, but it no longer called from transform(). + */ + private String compileTopLevel(ClassGenerator classGen) { + final ConstantPoolGen cpg = classGen.getConstantPool(); + + final org.apache.bcel.generic.Type[] argTypes = { Util.getJCRefType(DOM_INTF_SIG), Util.getJCRefType(NODE_ITERATOR_SIG), Util.getJCRefType(TRANSLET_OUTPUT_SIG) - }; + }; - final String[] argNames = { + final String[] argNames = { DOCUMENT_PNAME, ITERATOR_PNAME, TRANSLET_OUTPUT_PNAME - }; + }; - final InstructionList il = new InstructionList(); + final InstructionList il = new InstructionList(); - final MethodGenerator toplevel = + final MethodGenerator toplevel = new MethodGenerator(ACC_PUBLIC, - org.apache.bcel.generic.Type.VOID, - argTypes, argNames, - "topLevel", _className, il, - classGen.getConstantPool()); + org.apache.bcel.generic.Type.VOID, + argTypes, argNames, + "topLevel", _className, il, + classGen.getConstantPool()); - toplevel.addException("org.apache.xalan.xsltc.TransletException"); + toplevel.addException("org.apache.xalan.xsltc.TransletException"); - // Define and initialize 'current' variable with the root node - final LocalVariableGen current = + // Define and initialize 'current' variable with the root node + final LocalVariableGen current = toplevel.addLocalVariable("current", org.apache.bcel.generic.Type.INT, null, null); - final int setFilter = cpg.addInterfaceMethodref(DOM_INTF, - "setFilter", - "(Lorg/apache/xalan/xsltc/StripFilter;)V"); + final int setFilter = cpg.addInterfaceMethodref(DOM_INTF, + "setFilter", + "(Lorg/apache/xalan/xsltc/StripFilter;)V"); - final int gitr = cpg.addInterfaceMethodref(DOM_INTF, - "getIterator", - "()"+NODE_ITERATOR_SIG); - il.append(toplevel.loadDOM()); - il.append(new INVOKEINTERFACE(gitr, 1)); - il.append(toplevel.nextNode()); - current.setStart(il.append(new ISTORE(current.getIndex()))); + final int gitr = cpg.addInterfaceMethodref(DOM_INTF, + "getIterator", + "()"+NODE_ITERATOR_SIG); + il.append(toplevel.loadDOM()); + il.append(new INVOKEINTERFACE(gitr, 1)); + il.append(toplevel.nextNode()); + current.setStart(il.append(new ISTORE(current.getIndex()))); // Create a new list containing variables/params + keys Vector varDepElements = new Vector(_globals); Enumeration elements = elements(); while (elements.hasMoreElements()) { - final Object element = elements.nextElement(); - if (element instanceof Key) { - varDepElements.add(element); - } + final Object element = elements.nextElement(); + if (element instanceof Key) { + varDepElements.add(element); + } } // Determine a partial order for the variables/params and keys @@ -1190,266 +1205,266 @@ private String compileTopLevel(ClassGenerator classGen) { // Translate vars/params and keys in the right order final int count = varDepElements.size(); for (int i = 0; i < count; i++) { - final TopLevelElement tle = (TopLevelElement) varDepElements.elementAt(i); - tle.translate(classGen, toplevel); - if (tle instanceof Key) { - final Key key = (Key) tle; - _keys.put(key.getName(), key); - } + final TopLevelElement tle = (TopLevelElement) varDepElements.elementAt(i); + tle.translate(classGen, toplevel); + if (tle instanceof Key) { + final Key key = (Key) tle; + _keys.put(key.getName(), key); + } } // Compile code for other top-level elements Vector whitespaceRules = new Vector(); elements = elements(); - while (elements.hasMoreElements()) { + while (elements.hasMoreElements()) { final Object element = elements.nextElement(); // xsl:decimal-format if (element instanceof DecimalFormatting) { - ((DecimalFormatting)element).translate(classGen,toplevel); + ((DecimalFormatting)element).translate(classGen,toplevel); } // xsl:strip/preserve-space else if (element instanceof Whitespace) { - whitespaceRules.addAll(((Whitespace)element).getRules()); + whitespaceRules.addAll(((Whitespace)element).getRules()); } - } + } - // Translate all whitespace strip/preserve rules - if (whitespaceRules.size() > 0) { + // Translate all whitespace strip/preserve rules + if (whitespaceRules.size() > 0) { Whitespace.translateRules(whitespaceRules,classGen); - } + } - if (classGen.containsMethod(STRIP_SPACE, STRIP_SPACE_PARAMS) != null) { + if (classGen.containsMethod(STRIP_SPACE, STRIP_SPACE_PARAMS) != null) { il.append(toplevel.loadDOM()); il.append(classGen.loadTranslet()); il.append(new INVOKEINTERFACE(setFilter, 2)); - } + } - il.append(RETURN); + il.append(RETURN); - // Compute max locals + stack and add method to class - classGen.addMethod(toplevel); + // Compute max locals + stack and add method to class + classGen.addMethod(toplevel); - return("("+DOM_INTF_SIG+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+")V"); - } + return("("+DOM_INTF_SIG+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+")V"); + } - /** - * This method returns a vector with variables/params and keys in the - * order in which they are to be compiled for initialization. The order - * is determined by analyzing the dependencies between them. The XSLT 1.0 - * spec does not allow a key to depend on a variable. However, for - * compatibility with Xalan interpretive, that type of dependency is - * allowed and, therefore, consider to determine the partial order. - */ - private Vector resolveDependencies(Vector input) { - /* DEBUG CODE - INGORE - for (int i = 0; i < input.size(); i++) { - final TopLevelElement e = (TopLevelElement) input.elementAt(i); - System.out.println("e = " + e + " depends on:"); - Vector dep = e.getDependencies(); - for (int j = 0; j < (dep != null ? dep.size() : 0); j++) { - System.out.println("\t" + dep.elementAt(j)); - } - } - System.out.println("================================="); - */ - - Vector result = new Vector(); - while (input.size() > 0) { + /** + * This method returns a vector with variables/params and keys in the + * order in which they are to be compiled for initialization. The order + * is determined by analyzing the dependencies between them. The XSLT 1.0 + * spec does not allow a key to depend on a variable. However, for + * compatibility with Xalan interpretive, that type of dependency is + * allowed and, therefore, consider to determine the partial order. + */ + private Vector resolveDependencies(Vector input) { + /* DEBUG CODE - INGORE + for (int i = 0; i < input.size(); i++) { + final TopLevelElement e = (TopLevelElement) input.elementAt(i); + System.out.println("e = " + e + " depends on:"); + Vector dep = e.getDependencies(); + for (int j = 0; j < (dep != null ? dep.size() : 0); j++) { + System.out.println("\t" + dep.elementAt(j)); + } + } + System.out.println("================================="); + */ + + Vector result = new Vector(); + while (input.size() > 0) { boolean changed = false; for (int i = 0; i < input.size(); ) { - final TopLevelElement vde = (TopLevelElement) input.elementAt(i); - final Vector dep = vde.getDependencies(); - if (dep == null || result.containsAll(dep)) { - result.addElement(vde); - input.remove(i); - changed = true; - } - else { - i++; - } + final TopLevelElement vde = (TopLevelElement) input.elementAt(i); + final Vector dep = vde.getDependencies(); + if (dep == null || result.containsAll(dep)) { + result.addElement(vde); + input.remove(i); + changed = true; + } + else { + i++; + } } // If nothing was changed in this pass then we have a circular ref if (!changed) { - ErrorMsg err = new ErrorMsg(ErrorMsg.CIRCULAR_VARIABLE_ERR, - input.toString(), this); - getParser().reportError(Constants.ERROR, err); - return(result); + ErrorMsg err = new ErrorMsg(ErrorMsg.CIRCULAR_VARIABLE_ERR, + input.toString(), this); + getParser().reportError(Constants.ERROR, err); + return(result); } - } + } - /* DEBUG CODE - INGORE - System.out.println("================================="); - for (int i = 0; i < result.size(); i++) { - final TopLevelElement e = (TopLevelElement) result.elementAt(i); - System.out.println("e = " + e); - } - */ + /* DEBUG CODE - INGORE + System.out.println("================================="); + for (int i = 0; i < result.size(); i++) { + final TopLevelElement e = (TopLevelElement) result.elementAt(i); + System.out.println("e = " + e); + } + */ - return result; - } + return result; + } - /** - * Compile a buildKeys() method into the output class. Note that keys - * for the input document are created in topLevel(), not in this method. - * However, we still need this method to create keys for documents loaded - * via the XPath document() function. - */ - private String compileBuildKeys(ClassGenerator classGen) { - final ConstantPoolGen cpg = classGen.getConstantPool(); + /** + * Compile a buildKeys() method into the output class. Note that keys + * for the input document are created in topLevel(), not in this method. + * However, we still need this method to create keys for documents loaded + * via the XPath document() function. + */ + private String compileBuildKeys(ClassGenerator classGen) { + final ConstantPoolGen cpg = classGen.getConstantPool(); - final org.apache.bcel.generic.Type[] argTypes = { + final org.apache.bcel.generic.Type[] argTypes = { Util.getJCRefType(DOM_INTF_SIG), Util.getJCRefType(NODE_ITERATOR_SIG), Util.getJCRefType(TRANSLET_OUTPUT_SIG), org.apache.bcel.generic.Type.INT - }; + }; - final String[] argNames = { + final String[] argNames = { DOCUMENT_PNAME, ITERATOR_PNAME, TRANSLET_OUTPUT_PNAME, "current" - }; + }; - final InstructionList il = new InstructionList(); + final InstructionList il = new InstructionList(); - final MethodGenerator buildKeys = + final MethodGenerator buildKeys = new MethodGenerator(ACC_PUBLIC, - org.apache.bcel.generic.Type.VOID, - argTypes, argNames, - "buildKeys", _className, il, - classGen.getConstantPool()); + org.apache.bcel.generic.Type.VOID, + argTypes, argNames, + "buildKeys", _className, il, + classGen.getConstantPool()); - buildKeys.addException("org.apache.xalan.xsltc.TransletException"); + buildKeys.addException("org.apache.xalan.xsltc.TransletException"); - final Enumeration elements = elements(); - while (elements.hasMoreElements()) { + final Enumeration elements = elements(); + while (elements.hasMoreElements()) { // xsl:key final Object element = elements.nextElement(); if (element instanceof Key) { - final Key key = (Key)element; - key.translate(classGen, buildKeys); - _keys.put(key.getName(),key); + final Key key = (Key)element; + key.translate(classGen, buildKeys); + _keys.put(key.getName(),key); } - } + } - il.append(RETURN); + il.append(RETURN); - // Add method to class - classGen.addMethod(buildKeys); + // Add method to class + classGen.addMethod(buildKeys); - return("("+DOM_INTF_SIG+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+"I)V"); - } - - /** - * Compile transform() into the output class. This method is used to - * initialize global variables and global parameters. The current node - * is set to be the document's root node. + return("("+DOM_INTF_SIG+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+"I)V"); + } + + /** + * Compile transform() into the output class. This method is used to + * initialize global variables and global parameters. The current node + * is set to be the document's root node. + */ + private void compileTransform(ClassGenerator classGen) { + final ConstantPoolGen cpg = classGen.getConstantPool(); + + /* + * Define the the method transform with the following signature: + * void transform(DOM, NodeIterator, HandlerBase) */ - private void compileTransform(ClassGenerator classGen) { - final ConstantPoolGen cpg = classGen.getConstantPool(); - - /* - * Define the the method transform with the following signature: - * void transform(DOM, NodeIterator, HandlerBase) - */ - final org.apache.bcel.generic.Type[] argTypes = + final org.apache.bcel.generic.Type[] argTypes = new org.apache.bcel.generic.Type[3]; - argTypes[0] = Util.getJCRefType(DOM_INTF_SIG); - argTypes[1] = Util.getJCRefType(NODE_ITERATOR_SIG); - argTypes[2] = Util.getJCRefType(TRANSLET_OUTPUT_SIG); + argTypes[0] = Util.getJCRefType(DOM_INTF_SIG); + argTypes[1] = Util.getJCRefType(NODE_ITERATOR_SIG); + argTypes[2] = Util.getJCRefType(TRANSLET_OUTPUT_SIG); - final String[] argNames = new String[3]; - argNames[0] = DOCUMENT_PNAME; - argNames[1] = ITERATOR_PNAME; - argNames[2] = TRANSLET_OUTPUT_PNAME; + final String[] argNames = new String[3]; + argNames[0] = DOCUMENT_PNAME; + argNames[1] = ITERATOR_PNAME; + argNames[2] = TRANSLET_OUTPUT_PNAME; - final InstructionList il = new InstructionList(); - final MethodGenerator transf = + final InstructionList il = new InstructionList(); + final MethodGenerator transf = new MethodGenerator(ACC_PUBLIC, - org.apache.bcel.generic.Type.VOID, - argTypes, argNames, - "transform", - _className, - il, - classGen.getConstantPool()); - transf.addException("org.apache.xalan.xsltc.TransletException"); - - // Define and initialize current with the root node - final LocalVariableGen current = + org.apache.bcel.generic.Type.VOID, + argTypes, argNames, + "transform", + _className, + il, + classGen.getConstantPool()); + transf.addException("org.apache.xalan.xsltc.TransletException"); + + // Define and initialize current with the root node + final LocalVariableGen current = transf.addLocalVariable("current", - org.apache.bcel.generic.Type.INT, - null, null); - final String applyTemplatesSig = classGen.getApplyTemplatesSig(); - final int applyTemplates = cpg.addMethodref(getClassName(), - "applyTemplates", - applyTemplatesSig); - final int domField = cpg.addFieldref(getClassName(), - DOM_FIELD, - DOM_INTF_SIG); - - // push translet for PUTFIELD - il.append(classGen.loadTranslet()); - // prepare appropriate DOM implementation + org.apache.bcel.generic.Type.INT, + null, null); + final String applyTemplatesSig = classGen.getApplyTemplatesSig(); + final int applyTemplates = cpg.addMethodref(getClassName(), + "applyTemplates", + applyTemplatesSig); + final int domField = cpg.addFieldref(getClassName(), + DOM_FIELD, + DOM_INTF_SIG); + + // push translet for PUTFIELD + il.append(classGen.loadTranslet()); + // prepare appropriate DOM implementation - if (isMultiDocument()) { + if (isMultiDocument()) { il.append(new NEW(cpg.addClass(MULTI_DOM_CLASS))); il.append(DUP); - } + } - il.append(classGen.loadTranslet()); - il.append(transf.loadDOM()); - il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS, - "makeDOMAdapter", - "("+DOM_INTF_SIG+")"+ - DOM_ADAPTER_SIG))); - // DOMAdapter is on the stack - - if (isMultiDocument()) { + il.append(classGen.loadTranslet()); + il.append(transf.loadDOM()); + il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS, + "makeDOMAdapter", + "("+DOM_INTF_SIG+")"+ + DOM_ADAPTER_SIG))); + // DOMAdapter is on the stack + + if (isMultiDocument()) { final int init = cpg.addMethodref(MULTI_DOM_CLASS, - "", - "("+DOM_INTF_SIG+")V"); + "", + "("+DOM_INTF_SIG+")V"); il.append(new INVOKESPECIAL(init)); // MultiDOM is on the stack - } + } - //store to _dom variable - il.append(new PUTFIELD(domField)); - - // continue with globals initialization - final int gitr = cpg.addInterfaceMethodref(DOM_INTF, - "getIterator", - "()"+NODE_ITERATOR_SIG); - il.append(transf.loadDOM()); - il.append(new INVOKEINTERFACE(gitr, 1)); - il.append(transf.nextNode()); - current.setStart(il.append(new ISTORE(current.getIndex()))); - - // Transfer the output settings to the output post-processor - il.append(classGen.loadTranslet()); - il.append(transf.loadHandler()); - final int index = cpg.addMethodref(TRANSLET_CLASS, - "transferOutputSettings", - "("+OUTPUT_HANDLER_SIG+")V"); - il.append(new INVOKEVIRTUAL(index)); - - /* - * Compile buildKeys() method. Note that this method is not - * invoked here as keys for the input document are now created - * in topLevel(). However, this method is still needed by the - * LoadDocument class. - */ - final String keySig = compileBuildKeys(classGen); - final int keyIdx = cpg.addMethodref(getClassName(), - "buildKeys", keySig); + //store to _dom variable + il.append(new PUTFIELD(domField)); + + // continue with globals initialization + final int gitr = cpg.addInterfaceMethodref(DOM_INTF, + "getIterator", + "()"+NODE_ITERATOR_SIG); + il.append(transf.loadDOM()); + il.append(new INVOKEINTERFACE(gitr, 1)); + il.append(transf.nextNode()); + current.setStart(il.append(new ISTORE(current.getIndex()))); + + // Transfer the output settings to the output post-processor + il.append(classGen.loadTranslet()); + il.append(transf.loadHandler()); + final int index = cpg.addMethodref(TRANSLET_CLASS, + "transferOutputSettings", + "("+OUTPUT_HANDLER_SIG+")V"); + il.append(new INVOKEVIRTUAL(index)); + + /* + * Compile buildKeys() method. Note that this method is not + * invoked here as keys for the input document are now created + * in topLevel(). However, this method is still needed by the + * LoadDocument class. + */ + final String keySig = compileBuildKeys(classGen); + final int keyIdx = cpg.addMethodref(getClassName(), + "buildKeys", keySig); - // Look for top-level elements that need handling - final Enumeration toplevel = elements(); - if (_globals.size() > 0 || toplevel.hasMoreElements()) { + // Look for top-level elements that need handling + final Enumeration toplevel = elements(); + if (_globals.size() > 0 || toplevel.hasMoreElements()) { // Compile method for handling top-level elements final String topLevelSig = compileTopLevel(classGen); // Get a reference to that method final int topLevelIdx = cpg.addMethodref(getClassName(), - "topLevel", - topLevelSig); + "topLevel", + topLevelSig); // Push all parameters on the stack and call topLevel() il.append(classGen.loadTranslet()); // The 'this' pointer il.append(classGen.loadTranslet()); @@ -1457,105 +1472,105 @@ private void compileTransform(ClassGenerator classGen) { il.append(transf.loadIterator()); il.append(transf.loadHandler()); // The output handler il.append(new INVOKEVIRTUAL(topLevelIdx)); - } - - // start document - il.append(transf.loadHandler()); - il.append(transf.startDocument()); - - // push first arg for applyTemplates - il.append(classGen.loadTranslet()); - // push translet for GETFIELD to get DOM arg - il.append(classGen.loadTranslet()); - il.append(new GETFIELD(domField)); - // push remaining 2 args - il.append(transf.loadIterator()); - il.append(transf.loadHandler()); - il.append(new INVOKEVIRTUAL(applyTemplates)); - // endDocument - il.append(transf.loadHandler()); - il.append(transf.endDocument()); - - il.append(RETURN); - - // Compute max locals + stack and add method to class - classGen.addMethod(transf); - } - - /** - * Peephole optimization: Remove sequences of [ALOAD, POP]. - */ - private void peepHoleOptimization(MethodGenerator methodGen) { - final String pattern = "`aload'`pop'`instruction'"; - final InstructionList il = methodGen.getInstructionList(); - final InstructionFinder find = new InstructionFinder(il); - for(Iterator iter=find.search(pattern); iter.hasNext(); ) { + } + + // start document + il.append(transf.loadHandler()); + il.append(transf.startDocument()); + + // push first arg for applyTemplates + il.append(classGen.loadTranslet()); + // push translet for GETFIELD to get DOM arg + il.append(classGen.loadTranslet()); + il.append(new GETFIELD(domField)); + // push remaining 2 args + il.append(transf.loadIterator()); + il.append(transf.loadHandler()); + il.append(new INVOKEVIRTUAL(applyTemplates)); + // endDocument + il.append(transf.loadHandler()); + il.append(transf.endDocument()); + + il.append(RETURN); + + // Compute max locals + stack and add method to class + classGen.addMethod(transf); + } + + /** + * Peephole optimization: Remove sequences of [ALOAD, POP]. + */ + private void peepHoleOptimization(MethodGenerator methodGen) { + final String pattern = "`aload'`pop'`instruction'"; + final InstructionList il = methodGen.getInstructionList(); + final InstructionFinder find = new InstructionFinder(il); + for(Iterator iter=find.search(pattern); iter.hasNext(); ) { InstructionHandle[] match = (InstructionHandle[])iter.next(); try { - il.delete(match[0], match[1]); + il.delete(match[0], match[1]); } catch (TargetLostException e) { - // TODO: move target down into the list - } - } + // TODO: move target down into the list + } } + } - public int addParam(Param param) { - _globals.addElement(param); - return _globals.size() - 1; - } + public int addParam(Param param) { + _globals.addElement(param); + return _globals.size() - 1; + } - public int addVariable(Variable global) { - _globals.addElement(global); - return _globals.size() - 1; - } + public int addVariable(Variable global) { + _globals.addElement(global); + return _globals.size() - 1; + } - public void display(int indent) { - indent(indent); - Util.println("Stylesheet"); - displayContents(indent + IndentIncrement); - } + public void display(int indent) { + indent(indent); + Util.println("Stylesheet"); + displayContents(indent + IndentIncrement); + } - // do we need this wrapper ????? - public String getNamespace(String prefix) { - return lookupNamespace(prefix); - } + // do we need this wrapper ????? + public String getNamespace(String prefix) { + return lookupNamespace(prefix); + } - public String getClassName() { - return _className; - } + public String getClassName() { + return _className; + } - public Vector getTemplates() { - return _templates; - } + public Vector getTemplates() { + return _templates; + } - public Vector getAllValidTemplates() { - // Return templates if no imported/included stylesheets - if (_includedStylesheets == null) { - return _templates; - } - - // Is returned value cached? - if (_allValidTemplates == null) { - Vector templates = new Vector(); - int size = _includedStylesheets.size(); - for (int i = 0; i < size; i++) { - Stylesheet included =(Stylesheet)_includedStylesheets.elementAt(i); - templates.addAll(included.getAllValidTemplates()); - } - templates.addAll(_templates); - - // Cache results in top-level stylesheet only - if (_parentStylesheet != null) { - return templates; - } - _allValidTemplates = templates; - } + public Vector getAllValidTemplates() { + // Return templates if no imported/included stylesheets + if (_includedStylesheets == null) { + return _templates; + } - return _allValidTemplates; + // Is returned value cached? + if (_allValidTemplates == null) { + Vector templates = new Vector(); + int size = _includedStylesheets.size(); + for (int i = 0; i < size; i++) { + Stylesheet included =(Stylesheet)_includedStylesheets.elementAt(i); + templates.addAll(included.getAllValidTemplates()); + } + templates.addAll(_templates); + + // Cache results in top-level stylesheet only + if (_parentStylesheet != null) { + return templates; + } + _allValidTemplates = templates; } + + return _allValidTemplates; + } - protected void addTemplate(Template template) { - _templates.addElement(template); - } + protected void addTemplate(Template template) { + _templates.addElement(template); + } } diff --git a/xalan/src/main/java/org/apache/xalan/xsltc/compiler/XslElement.java b/xalan/src/main/java/org/apache/xalan/xsltc/compiler/XslElement.java index ecf59ad15..83a7249d8 100644 --- a/xalan/src/main/java/org/apache/xalan/xsltc/compiler/XslElement.java +++ b/xalan/src/main/java/org/apache/xalan/xsltc/compiler/XslElement.java @@ -44,56 +44,56 @@ */ final class XslElement extends Instruction { - private String _prefix; - private boolean _ignore = false; - private boolean _isLiteralName = true; - private AttributeValueTemplate _name; - private AttributeValueTemplate _namespace; - - /** - * Displays the contents of the element - */ - public void display(int indent) { - indent(indent); - Util.println("Element " + _name); - displayContents(indent + IndentIncrement); - } - - /** - * This method is now deprecated. The new implemation of this class - * never declares the default NS. - */ - public boolean declaresDefaultNS() { - return false; - } - - public void parseContents(Parser parser) { - final SymbolTable stable = parser.getSymbolTable(); - - // Handle the 'name' attribute - String name = getAttribute("name"); - if (name == EMPTYSTRING) { + private String _prefix; + private boolean _ignore = false; + private boolean _isLiteralName = true; + private boolean _isLiteralNamespace = false; + private AttributeValueTemplate _name; + private AttributeValueTemplate _namespace; + + /** + * Displays the contents of the element + */ + public void display(int indent) { + indent(indent); + Util.println("Element " + _name); + displayContents(indent + IndentIncrement); + } + + /** + * This method is now deprecated. The new implemation of this class + * never declares the default NS. + */ + public boolean declaresDefaultNS() { + return false; + } + + public void parseContents(Parser parser) { + final SymbolTable stable = parser.getSymbolTable(); + + // Handle the 'name' attribute + String name = getAttribute("name"); + if (name == EMPTYSTRING) { ErrorMsg msg = new ErrorMsg(ErrorMsg.ILLEGAL_ELEM_NAME_ERR, - name, this); + name, this); parser.reportError(WARNING, msg); parseChildren(parser); _ignore = true; // Ignore the element if the QName is invalid return; - } - - // Get namespace attribute - String namespace = getAttribute("namespace"); - - // Optimize compilation when name is known at compile time - _isLiteralName = Util.isLiteral(name); - if (_isLiteralName) { - if (!XML11Char.isXML11ValidQName(name)) { - ErrorMsg msg = new ErrorMsg(ErrorMsg.ILLEGAL_ELEM_NAME_ERR, - name, this); - parser.reportError(WARNING, msg); - parseChildren(parser); - _ignore = true; // Ignore the element if the QName is invalid - return; + } + + String namespace = getAttribute("namespace"); + + // Optimize compilation when name is known at compile time + _isLiteralName = Util.isLiteral(name); + if (_isLiteralName) { + if (!XML11Char.isXML11ValidQName(name)) { + ErrorMsg msg = new ErrorMsg(ErrorMsg.ILLEGAL_ELEM_NAME_ERR, + name, this); + parser.reportError(WARNING, msg); + parseChildren(parser); + _ignore = true; // Ignore the element if the QName is invalid + return; } final QName qname = parser.getQNameSafe(name); @@ -101,223 +101,257 @@ public void parseContents(Parser parser) { String local = qname.getLocalPart(); if (prefix == null) { - prefix = EMPTYSTRING; + prefix = EMPTYSTRING; } if (!hasAttribute("namespace")) { - namespace = lookupNamespace(prefix); - if (namespace == null) { - ErrorMsg err = new ErrorMsg(ErrorMsg.NAMESPACE_UNDEF_ERR, - prefix, this); - parser.reportError(WARNING, err); - parseChildren(parser); - _ignore = true; // Ignore the element if prefix is undeclared - return; - } - _prefix = prefix; - _namespace = new AttributeValueTemplate(namespace, parser, this); + namespace = lookupNamespace(prefix); + if (namespace == null) { + ErrorMsg err = new ErrorMsg(ErrorMsg.NAMESPACE_UNDEF_ERR, + prefix, this); + parser.reportError(WARNING, err); + parseChildren(parser); + _ignore = true; // Ignore the element if prefix is undeclared + return; + } + _prefix = prefix; + _namespace = new AttributeValueTemplate(namespace, parser, this); } else { - if (prefix == EMPTYSTRING) { - if (Util.isLiteral(namespace)) { - prefix = lookupPrefix(namespace); - if (prefix == null) { - prefix = stable.generateNamespacePrefix(); - } - } - - // Prepend prefix to local name - final StringBuffer newName = new StringBuffer(prefix); - if (prefix != EMPTYSTRING) { - newName.append(':'); - } - name = newName.append(local).toString(); - } - _prefix = prefix; - _namespace = new AttributeValueTemplate(namespace, parser, this); - } - } - else { - // name attribute contains variable parts. If there is no namespace - // attribute, the generated code needs to be prepared to look up - // any prefix in the stylesheet at run-time. - _namespace = (namespace == EMPTYSTRING) ? null : - new AttributeValueTemplate(namespace, parser, this); - } - - _name = new AttributeValueTemplate(name, parser, this); - - final String useSets = getAttribute("use-attribute-sets"); - if (useSets.length() > 0) { - if (!Util.isValidQNames(useSets)) { - ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, useSets, this); - parser.reportError(Constants.ERROR, err); + if (prefix == EMPTYSTRING) { + if (Util.isLiteral(namespace)) { + prefix = lookupPrefix(namespace); + if (prefix == null) { + prefix = stable.generateNamespacePrefix(); } - setFirstElement(new UseAttributeSets(useSets, parser)); - } + } + + // Prepend prefix to local name + final StringBuffer newName = new StringBuffer(prefix); + if (prefix != EMPTYSTRING) { + newName.append(':'); + } + name = newName.append(local).toString(); + } + _prefix = prefix; + _namespace = new AttributeValueTemplate(namespace, parser, this); + } + } + else { + // name attribute contains variable parts. If there is no namespace + // attribute, the generated code needs to be prepared to look up + // any prefix in the stylesheet at run-time. + // if the namespace is literal, we can avoid generating a new + // prefix every time though + if (Util.isLiteral(namespace)) { + _isLiteralNamespace = true; + } + _namespace = (namespace == EMPTYSTRING) ? null : + new AttributeValueTemplate(namespace, parser, this); + } + + _name = new AttributeValueTemplate(name, parser, this); - parseChildren(parser); + final String useSets = getAttribute("use-attribute-sets"); + if (useSets.length() > 0) { + if (!Util.isValidQNames(useSets)) { + ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, useSets, this); + parser.reportError(Constants.ERROR, err); + } + setFirstElement(new UseAttributeSets(useSets, parser)); } - /** - * Run type check on element name & contents - */ - public Type typeCheck(SymbolTable stable) throws TypeCheckError { - if (!_ignore) { + parseChildren(parser); + } + + /** + * Run type check on element name & contents + */ + public Type typeCheck(SymbolTable stable) throws TypeCheckError { + if (!_ignore) { _name.typeCheck(stable); if (_namespace != null) { - _namespace.typeCheck(stable); + _namespace.typeCheck(stable); } - } - typeCheckContents(stable); - return Type.Void; } - - /** - * This method is called when the name of the element is known at compile time. - * In this case, there is no need to inspect the element name at runtime to - * determine if a prefix exists, needs to be generated, etc. - */ - public void translateLiteral(ClassGenerator classGen, MethodGenerator methodGen) { - final ConstantPoolGen cpg = classGen.getConstantPool(); - final InstructionList il = methodGen.getInstructionList(); - - if (!_ignore) { + typeCheckContents(stable); + return Type.Void; + } + + /** + * This method is called when the name of the element is known at compile time. + * In this case, there is no need to inspect the element name at runtime to + * determine if a prefix exists, needs to be generated, etc. + */ + public void translateLiteral(ClassGenerator classGen, MethodGenerator methodGen) { + final ConstantPoolGen cpg = classGen.getConstantPool(); + final InstructionList il = methodGen.getInstructionList(); + + if (!_ignore) { il.append(methodGen.loadHandler()); _name.translate(classGen, methodGen); il.append(DUP2); il.append(methodGen.startElement()); if (_namespace != null) { - il.append(methodGen.loadHandler()); - il.append(new PUSH(cpg, _prefix)); - _namespace.translate(classGen,methodGen); - il.append(methodGen.namespace()); + il.append(methodGen.loadHandler()); + il.append(new PUSH(cpg, _prefix)); + _namespace.translate(classGen,methodGen); + il.append(methodGen.namespace()); } - } + } - translateContents(classGen, methodGen); + translateContents(classGen, methodGen); - if (!_ignore) { + if (!_ignore) { il.append(methodGen.endElement()); - } } - - /** - * At runtime the compilation of xsl:element results in code that: (i) - * evaluates the avt for the name, (ii) checks for a prefix in the name - * (iii) generates a new prefix and create a new qname when necessary - * (iv) calls startElement() on the handler (v) looks up a uri in the XML - * when the prefix is not known at compile time (vi) calls namespace() - * on the handler (vii) evaluates the contents (viii) calls endElement(). - */ - public void translate(ClassGenerator classGen, MethodGenerator methodGen) { - LocalVariableGen local = null; - final ConstantPoolGen cpg = classGen.getConstantPool(); - final InstructionList il = methodGen.getInstructionList(); - - // Optimize translation if element name is a literal - if (_isLiteralName) { + } + + /** + * At runtime the compilation of xsl:element results in code that: (i) + * evaluates the avt for the name, (ii) checks for a prefix in the name + * (iii) generates a new prefix and create a new qname when necessary + * (iv) calls startElement() on the handler (v) looks up a uri in the XML + * when the prefix is not known at compile time (vi) calls namespace() + * on the handler (vii) evaluates the contents (viii) calls endElement(). + */ + public void translate(ClassGenerator classGen, MethodGenerator methodGen) { + LocalVariableGen local = null; + final ConstantPoolGen cpg = classGen.getConstantPool(); + final InstructionList il = methodGen.getInstructionList(); + + // Optimize translation if element name is a literal + if (_isLiteralName) { translateLiteral(classGen, methodGen); return; - } + } - if (!_ignore) { + if (!_ignore) { - // if the qname is an AVT, then the qname has to be checked at runtime if it is a valid qname - LocalVariableGen nameValue = - methodGen.addLocalVariable2("nameValue", - Util.getJCRefType(STRING_SIG), - null); + // if the qname is an AVT, then the qname has to be checked at runtime if it is a valid qname + LocalVariableGen nameValue = + methodGen.addLocalVariable2("nameValue", + Util.getJCRefType(STRING_SIG), + null); - // store the name into a variable first so _name.translate only needs to be called once - _name.translate(classGen, methodGen); - nameValue.setStart(il.append(new ASTORE(nameValue.getIndex()))); - il.append(new ALOAD(nameValue.getIndex())); + // store the name into a variable first so _name.translate only needs to be called once + _name.translate(classGen, methodGen); + nameValue.setStart(il.append(new ASTORE(nameValue.getIndex()))); + il.append(new ALOAD(nameValue.getIndex())); - // call checkQName if the name is an AVT - final int check = cpg.addMethodref(BASIS_LIBRARY_CLASS, "checkQName", - "(" - +STRING_SIG - +")V"); - il.append(new INVOKESTATIC(check)); + // call checkQName if the name is an AVT + final int check = cpg.addMethodref(BASIS_LIBRARY_CLASS, "checkQName", + "(" + +STRING_SIG + +")V"); + il.append(new INVOKESTATIC(check)); - // Push handler for call to endElement() - il.append(methodGen.loadHandler()); + // Push handler for call to endElement() + il.append(methodGen.loadHandler()); - // load name value again - nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex()))); - if (_namespace != null) { - _namespace.translate(classGen, methodGen); + // If the namespace is a literal, we'll want to avoid creating a new + // prefix for it + if(_isLiteralNamespace){ + // we want to call to BasisLibrary.addPrefix(String qname, String namespace, Map prefixMap); + // So store the namespace in a var + LocalVariableGen namespaceValue = methodGen.addLocalVariable2( + "namespaceValue", Util.getJCRefType(STRING_SIG), null); + _namespace.translate(classGen, methodGen); + namespaceValue.setStart(il.append(new ASTORE(namespaceValue.getIndex()))); + + String transletClassName = getXSLTC().getClassName(); + // load name value again + nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex()))); + + il.append(new ALOAD(namespaceValue.getIndex())); + il.append(new GETSTATIC(cpg.addFieldref( + transletClassName, + STATIC_NS_MAP_FIELD, + MAP_SIG))); + il.append( + new INVOKESTATIC( + cpg.addMethodref(BASIS_LIBRARY_CLASS, + ADD_NAMESPACE_PREFIX_REF, + ADD_NAMESPACE_PREFIX_SIG))); + namespaceValue.setEnd(il.append(new ALOAD(namespaceValue.getIndex()))); + } + else{ + // load name value again + nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex()))); + _namespace.translate(classGen, methodGen); + } } else { - // If name is an AVT and namespace is not specified, need to - // look up any prefix in the stylesheet by calling - // BasisLibrary.lookupStylesheetQNameNamespace( - // name, stylesheetNode, ancestorsArray, - // prefixURIsIndexArray, prefixURIPairsArray, - // !ignoreDefaultNamespace) - String transletClassName = getXSLTC().getClassName(); - il.append(DUP); - il.append(new PUSH(cpg, getNodeIDForStylesheetNSLookup())); - il.append(new GETSTATIC(cpg.addFieldref( - transletClassName, - STATIC_NS_ANCESTORS_ARRAY_FIELD, - NS_ANCESTORS_INDEX_SIG))); - il.append(new GETSTATIC(cpg.addFieldref( - transletClassName, - STATIC_PREFIX_URIS_IDX_ARRAY_FIELD, - PREFIX_URIS_IDX_SIG))); - il.append(new GETSTATIC(cpg.addFieldref( - transletClassName, - STATIC_PREFIX_URIS_ARRAY_FIELD, - PREFIX_URIS_ARRAY_SIG))); - // Default namespace is significant - il.append(ICONST_0); - il.append( - new INVOKESTATIC( - cpg.addMethodref(BASIS_LIBRARY_CLASS, - LOOKUP_STYLESHEET_QNAME_NS_REF, - LOOKUP_STYLESHEET_QNAME_NS_SIG))); + // load name value again + nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex()))); + // If name is an AVT and namespace is not specified, need to + // look up any prefix in the stylesheet by calling + // BasisLibrary.lookupStylesheetQNameNamespace( + // name, stylesheetNode, ancestorsArray, + // prefixURIsIndexArray, prefixURIPairsArray, + // !ignoreDefaultNamespace) + String transletClassName = getXSLTC().getClassName(); + il.append(DUP); + il.append(new PUSH(cpg, getNodeIDForStylesheetNSLookup())); + il.append(new GETSTATIC(cpg.addFieldref( + transletClassName, + STATIC_NS_ANCESTORS_ARRAY_FIELD, + NS_ANCESTORS_INDEX_SIG))); + il.append(new GETSTATIC(cpg.addFieldref( + transletClassName, + STATIC_PREFIX_URIS_IDX_ARRAY_FIELD, + PREFIX_URIS_IDX_SIG))); + il.append(new GETSTATIC(cpg.addFieldref( + transletClassName, + STATIC_PREFIX_URIS_ARRAY_FIELD, + PREFIX_URIS_ARRAY_SIG))); + // Default namespace is significant + il.append(ICONST_0); + il.append( + new INVOKESTATIC( + cpg.addMethodref(BASIS_LIBRARY_CLASS, + LOOKUP_STYLESHEET_QNAME_NS_REF, + LOOKUP_STYLESHEET_QNAME_NS_SIG))); } - // Push additional arguments + // Push additional arguments il.append(methodGen.loadHandler()); il.append(methodGen.loadDOM()); il.append(methodGen.loadCurrentNode()); - // Invoke BasisLibrary.startXslElemCheckQName() - il.append(new INVOKESTATIC( - cpg.addMethodref(BASIS_LIBRARY_CLASS, "startXslElement", - "(" + STRING_SIG - + STRING_SIG - + TRANSLET_OUTPUT_SIG - + DOM_INTF_SIG + "I)" + STRING_SIG))); + // Invoke BasisLibrary.startXslElemCheckQName() + il.append(new INVOKESTATIC( + cpg.addMethodref(BASIS_LIBRARY_CLASS, "startXslElement", + "(" + STRING_SIG + + STRING_SIG + + TRANSLET_OUTPUT_SIG + + DOM_INTF_SIG + "I)" + STRING_SIG))); - } + } - translateContents(classGen, methodGen); + translateContents(classGen, methodGen); - if (!_ignore) { + if (!_ignore) { il.append(methodGen.endElement()); - } } + } - /** - * Override this method to make sure that xsl:attributes are not - * copied to output if this xsl:element is to be ignored - */ - public void translateContents(ClassGenerator classGen, + /** + * Override this method to make sure that xsl:attributes are not + * copied to output if this xsl:element is to be ignored + */ + public void translateContents(ClassGenerator classGen, MethodGenerator methodGen) { - final int n = elementCount(); - for (int i = 0; i < n; i++) { + final int n = elementCount(); + for (int i = 0; i < n; i++) { final SyntaxTreeNode item = - (SyntaxTreeNode)getContents().elementAt(i); + (SyntaxTreeNode)getContents().elementAt(i); if (_ignore && item instanceof XslAttribute) continue; item.translate(classGen, methodGen); - } } + } } diff --git a/xalan/src/main/java/org/apache/xalan/xsltc/runtime/BasisLibrary.java b/xalan/src/main/java/org/apache/xalan/xsltc/runtime/BasisLibrary.java index d049df2c0..8af9ca99d 100644 --- a/xalan/src/main/java/org/apache/xalan/xsltc/runtime/BasisLibrary.java +++ b/xalan/src/main/java/org/apache/xalan/xsltc/runtime/BasisLibrary.java @@ -27,6 +27,9 @@ import java.text.NumberFormat; import java.util.Locale; import java.util.ResourceBundle; +import java.util.HashMap; +import java.util.Map; +import java.util.Collections; import javax.xml.transform.dom.DOMSource; @@ -58,192 +61,192 @@ */ public final class BasisLibrary { - private final static String EMPTYSTRING = ""; - - /** - * Standard function count(node-set) - */ - public static int countF(DTMAxisIterator iterator) { - return iterator.getLast(); - } - - /** - * Standard function position() - * @deprecated This method exists only for backwards compatibility with old - * translets. New code should not reference it. - */ - public static int positionF(DTMAxisIterator iterator) { - return iterator.isReverse() - ? iterator.getLast() - iterator.getPosition() + 1 - : iterator.getPosition(); - } - - /** - * XSLT Standard function sum(node-set). - * stringToDouble is inlined - */ - public static double sumF(DTMAxisIterator iterator, DOM dom) { - try { + private final static String EMPTYSTRING = ""; + + /** + * Standard function count(node-set) + */ + public static int countF(DTMAxisIterator iterator) { + return iterator.getLast(); + } + + /** + * Standard function position() + * @deprecated This method exists only for backwards compatibility with old + * translets. New code should not reference it. + */ + public static int positionF(DTMAxisIterator iterator) { + return iterator.isReverse() + ? iterator.getLast() - iterator.getPosition() + 1 + : iterator.getPosition(); + } + + /** + * XSLT Standard function sum(node-set). + * stringToDouble is inlined + */ + public static double sumF(DTMAxisIterator iterator, DOM dom) { + try { double result = 0.0; int node; while ((node = iterator.next()) != DTMAxisIterator.END) { - result += Double.parseDouble(dom.getStringValueX(node)); + result += Double.parseDouble(dom.getStringValueX(node)); } return result; - } - catch (NumberFormatException e) { + } + catch (NumberFormatException e) { return Double.NaN; - } } + } - /** - * XSLT Standard function string() - */ - public static String stringF(int node, DOM dom) { - return dom.getStringValueX(node); - } + /** + * XSLT Standard function string() + */ + public static String stringF(int node, DOM dom) { + return dom.getStringValueX(node); + } - /** - * XSLT Standard function string(value) - */ - public static String stringF(Object obj, DOM dom) { - if (obj instanceof DTMAxisIterator) { + /** + * XSLT Standard function string(value) + */ + public static String stringF(Object obj, DOM dom) { + if (obj instanceof DTMAxisIterator) { return dom.getStringValueX(((DTMAxisIterator)obj).reset().next()); - } - else if (obj instanceof Node) { + } + else if (obj instanceof Node) { return dom.getStringValueX(((Node)obj).node); - } - else if (obj instanceof DOM) { + } + else if (obj instanceof DOM) { return ((DOM)obj).getStringValue(); - } - else { + } + else { return obj.toString(); - } } + } - /** - * XSLT Standard function string(value) - */ - public static String stringF(Object obj, int node, DOM dom) { - if (obj instanceof DTMAxisIterator) { + /** + * XSLT Standard function string(value) + */ + public static String stringF(Object obj, int node, DOM dom) { + if (obj instanceof DTMAxisIterator) { return dom.getStringValueX(((DTMAxisIterator)obj).reset().next()); - } - else if (obj instanceof Node) { + } + else if (obj instanceof Node) { return dom.getStringValueX(((Node)obj).node); - } - else if (obj instanceof DOM) { + } + else if (obj instanceof DOM) { // When the first argument is a DOM we want the whole // DOM and not just a single node - that would not make sense. //return ((DOM)obj).getStringValueX(node); return ((DOM)obj).getStringValue(); - } - else if (obj instanceof Double) { + } + else if (obj instanceof Double) { Double d = (Double)obj; final String result = d.toString(); final int length = result.length(); if ((result.charAt(length-2)=='.') && - (result.charAt(length-1) == '0')) - return result.substring(0, length-2); + (result.charAt(length-1) == '0')) + return result.substring(0, length-2); else - return result; - } - else { + return result; + } + else { if (obj != null) - return obj.toString(); + return obj.toString(); else - return stringF(node, dom); - } - } - - /** - * XSLT Standard function number() - */ - public static double numberF(int node, DOM dom) { - return stringToReal(dom.getStringValueX(node)); - } - - /** - * XSLT Standard function number(value) - */ - public static double numberF(Object obj, DOM dom) { - if (obj instanceof Double) { + return stringF(node, dom); + } + } + + /** + * XSLT Standard function number() + */ + public static double numberF(int node, DOM dom) { + return stringToReal(dom.getStringValueX(node)); + } + + /** + * XSLT Standard function number(value) + */ + public static double numberF(Object obj, DOM dom) { + if (obj instanceof Double) { return ((Double) obj).doubleValue(); - } - else if (obj instanceof Integer) { + } + else if (obj instanceof Integer) { return ((Integer) obj).doubleValue(); - } - else if (obj instanceof Boolean) { + } + else if (obj instanceof Boolean) { return ((Boolean) obj).booleanValue() ? 1.0 : 0.0; - } - else if (obj instanceof String) { + } + else if (obj instanceof String) { return stringToReal((String) obj); - } - else if (obj instanceof DTMAxisIterator) { + } + else if (obj instanceof DTMAxisIterator) { DTMAxisIterator iter = (DTMAxisIterator) obj; return stringToReal(dom.getStringValueX(iter.reset().next())); - } - else if (obj instanceof Node) { + } + else if (obj instanceof Node) { return stringToReal(dom.getStringValueX(((Node) obj).node)); - } - else if (obj instanceof DOM) { + } + else if (obj instanceof DOM) { return stringToReal(((DOM) obj).getStringValue()); - } - else { + } + else { final String className = obj.getClass().getName(); runTimeError(INVALID_ARGUMENT_ERR, className, "number()"); return 0.0; - } - } - - /** - * XSLT Standard function round() - */ - public static double roundF(double d) { - return (d<-0.5 || d>0.0)?Math.floor(d+0.5):((d==0.0)? - d:(Double.isNaN(d)?Double.NaN:-0.0)); } - - /** - * XSLT Standard function boolean() - */ - public static boolean booleanF(Object obj) { - if (obj instanceof Double) { + } + + /** + * XSLT Standard function round() + */ + public static double roundF(double d) { + return (d<-0.5 || d>0.0)?Math.floor(d+0.5):((d==0.0)? + d:(Double.isNaN(d)?Double.NaN:-0.0)); + } + + /** + * XSLT Standard function boolean() + */ + public static boolean booleanF(Object obj) { + if (obj instanceof Double) { final double temp = ((Double) obj).doubleValue(); return temp != 0.0 && !Double.isNaN(temp); - } - else if (obj instanceof Integer) { + } + else if (obj instanceof Integer) { return ((Integer) obj).doubleValue() != 0; - } - else if (obj instanceof Boolean) { + } + else if (obj instanceof Boolean) { return ((Boolean) obj).booleanValue(); - } - else if (obj instanceof String) { + } + else if (obj instanceof String) { return !((String) obj).equals(EMPTYSTRING); - } - else if (obj instanceof DTMAxisIterator) { + } + else if (obj instanceof DTMAxisIterator) { DTMAxisIterator iter = (DTMAxisIterator) obj; return iter.reset().next() != DTMAxisIterator.END; - } - else if (obj instanceof Node) { + } + else if (obj instanceof Node) { return true; - } - else if (obj instanceof DOM) { + } + else if (obj instanceof DOM) { String temp = ((DOM) obj).getStringValue(); return !temp.equals(EMPTYSTRING); - } - else { + } + else { final String className = obj.getClass().getName(); runTimeError(INVALID_ARGUMENT_ERR, className, "boolean()"); - } - return false; } + return false; + } - /** - * XSLT Standard function substring(). Must take a double because of - * conversions resulting into NaNs and rounding. - */ - public static String substringF(String value, double start) { - try { + /** + * XSLT Standard function substring(). Must take a double because of + * conversions resulting into NaNs and rounding. + */ + public static String substringF(String value, double start) { + try { final int strlen = value.length(); int istart = (int)Math.round(start) - 1; @@ -252,19 +255,19 @@ public static String substringF(String value, double start) { if (istart < 1) istart = 0; return value.substring(istart); - } - catch (IndexOutOfBoundsException e) { + } + catch (IndexOutOfBoundsException e) { runTimeError(RUN_TIME_INTERNAL_ERR, "substring()"); return null; - } } + } - /** - * XSLT Standard function substring(). Must take a double because of - * conversions resulting into NaNs and rounding. - */ - public static String substringF(String value, double start, double length) { - try { + /** + * XSLT Standard function substring(). Must take a double because of + * conversions resulting into NaNs and rounding. + */ + public static String substringF(String value, double start, double length) { + try { final int strlen = value.length(); int istart = (int)Math.round(start) - 1; int isum = istart + (int)Math.round(length); @@ -272,207 +275,207 @@ public static String substringF(String value, double start, double length) { if (Double.isInfinite(length)) isum = Integer.MAX_VALUE; if (Double.isNaN(start) || Double.isNaN(length)) - return(EMPTYSTRING); + return(EMPTYSTRING); if (Double.isInfinite(start)) return(EMPTYSTRING); if (istart > strlen) return(EMPTYSTRING); if (isum < 0) return(EMPTYSTRING); if (istart < 0) istart = 0; if (isum > strlen) - return value.substring(istart); + return value.substring(istart); else - return value.substring(istart, isum); - } - catch (IndexOutOfBoundsException e) { + return value.substring(istart, isum); + } + catch (IndexOutOfBoundsException e) { runTimeError(RUN_TIME_INTERNAL_ERR, "substring()"); return null; - } } + } - /** - * XSLT Standard function substring-after(). - */ - public static String substring_afterF(String value, String substring) { - final int index = value.indexOf(substring); - if (index >= 0) + /** + * XSLT Standard function substring-after(). + */ + public static String substring_afterF(String value, String substring) { + final int index = value.indexOf(substring); + if (index >= 0) return value.substring(index + substring.length()); - else + else return EMPTYSTRING; - } - - /** - * XSLT Standard function substring-before(). - */ - public static String substring_beforeF(String value, String substring) { - final int index = value.indexOf(substring); - if (index >= 0) + } + + /** + * XSLT Standard function substring-before(). + */ + public static String substring_beforeF(String value, String substring) { + final int index = value.indexOf(substring); + if (index >= 0) return value.substring(0, index); - else + else return EMPTYSTRING; - } - - /** - * XSLT Standard function translate(). - */ - public static String translateF(String value, String from, String to) { - final int tol = to.length(); - final int froml = from.length(); - final int valuel = value.length(); - - final StringBuffer result = new StringBuffer(); - for (int j, i = 0; i < valuel; i++) { + } + + /** + * XSLT Standard function translate(). + */ + public static String translateF(String value, String from, String to) { + final int tol = to.length(); + final int froml = from.length(); + final int valuel = value.length(); + + final StringBuffer result = new StringBuffer(); + for (int j, i = 0; i < valuel; i++) { final char ch = value.charAt(i); for (j = 0; j < froml; j++) { - if (ch == from.charAt(j)) { - if (j < tol) - result.append(to.charAt(j)); - break; - } + if (ch == from.charAt(j)) { + if (j < tol) + result.append(to.charAt(j)); + break; + } } if (j == froml) - result.append(ch); - } - return result.toString(); - } - - /** - * XSLT Standard function normalize-space(). - */ - public static String normalize_spaceF(int node, DOM dom) { - return normalize_spaceF(dom.getStringValueX(node)); - } - - /** - * XSLT Standard function normalize-space(string). - */ - public static String normalize_spaceF(String value) { - int i = 0, n = value.length(); - StringBuffer result = new StringBuffer(); - - while (i < n && isWhiteSpace(value.charAt(i))) + result.append(ch); + } + return result.toString(); + } + + /** + * XSLT Standard function normalize-space(). + */ + public static String normalize_spaceF(int node, DOM dom) { + return normalize_spaceF(dom.getStringValueX(node)); + } + + /** + * XSLT Standard function normalize-space(string). + */ + public static String normalize_spaceF(String value) { + int i = 0, n = value.length(); + StringBuffer result = new StringBuffer(); + + while (i < n && isWhiteSpace(value.charAt(i))) i++; - while (true) { + while (true) { while (i < n && !isWhiteSpace(value.charAt(i))) { - result.append(value.charAt(i++)); + result.append(value.charAt(i++)); } if (i == n) - break; + break; while (i < n && isWhiteSpace(value.charAt(i))) { - i++; + i++; } if (i < n) - result.append(' '); - } - return result.toString(); + result.append(' '); } + return result.toString(); + } - /** - * XSLT Standard function generate-id(). - */ - public static String generate_idF(int node) { - if (node > 0) + /** + * XSLT Standard function generate-id(). + */ + public static String generate_idF(int node) { + if (node > 0) // Only generate ID if node exists return "N" + node; - else + else // Otherwise return an empty string return EMPTYSTRING; - } + } - /** - * utility function for calls to local-name(). - */ - public static String getLocalName(String value) { - int idx = value.lastIndexOf(':'); - if (idx >= 0) value = value.substring(idx + 1); - idx = value.lastIndexOf('@'); - if (idx >= 0) value = value.substring(idx + 1); - return(value); - } - - /** - * External functions that cannot be resolved are replaced with a call - * to this method. This method will generate a runtime errors. A good - * stylesheet checks whether the function exists using conditional - * constructs, and never really tries to call it if it doesn't exist. - * But simple stylesheets may result in a call to this method. - * The compiler should generate a warning if it encounters a call to - * an unresolved external function. - */ - public static void unresolved_externalF(String name) { - runTimeError(EXTERNAL_FUNC_ERR, name); - } - - /** - * Utility function to throw a runtime error on the use of an extension - * function when the secure processing feature is set to true. - */ - public static void unallowed_extension_functionF(String name) { - runTimeError(UNALLOWED_EXTENSION_FUNCTION_ERR, name); - } - - /** - * Utility function to throw a runtime error on the use of an extension - * element when the secure processing feature is set to true. - */ - public static void unallowed_extension_elementF(String name) { - runTimeError(UNALLOWED_EXTENSION_ELEMENT_ERR, name); - } - - /** - * Utility function to throw a runtime error for an unsupported element. - * - * This is only used in forward-compatibility mode, when the control flow - * cannot be determined. In 1.0 mode, the error message is emitted at - * compile time. - */ - public static void unsupported_ElementF(String qname, boolean isExtension) { - if (isExtension) + /** + * utility function for calls to local-name(). + */ + public static String getLocalName(String value) { + int idx = value.lastIndexOf(':'); + if (idx >= 0) value = value.substring(idx + 1); + idx = value.lastIndexOf('@'); + if (idx >= 0) value = value.substring(idx + 1); + return(value); + } + + /** + * External functions that cannot be resolved are replaced with a call + * to this method. This method will generate a runtime errors. A good + * stylesheet checks whether the function exists using conditional + * constructs, and never really tries to call it if it doesn't exist. + * But simple stylesheets may result in a call to this method. + * The compiler should generate a warning if it encounters a call to + * an unresolved external function. + */ + public static void unresolved_externalF(String name) { + runTimeError(EXTERNAL_FUNC_ERR, name); + } + + /** + * Utility function to throw a runtime error on the use of an extension + * function when the secure processing feature is set to true. + */ + public static void unallowed_extension_functionF(String name) { + runTimeError(UNALLOWED_EXTENSION_FUNCTION_ERR, name); + } + + /** + * Utility function to throw a runtime error on the use of an extension + * element when the secure processing feature is set to true. + */ + public static void unallowed_extension_elementF(String name) { + runTimeError(UNALLOWED_EXTENSION_ELEMENT_ERR, name); + } + + /** + * Utility function to throw a runtime error for an unsupported element. + * + * This is only used in forward-compatibility mode, when the control flow + * cannot be determined. In 1.0 mode, the error message is emitted at + * compile time. + */ + public static void unsupported_ElementF(String qname, boolean isExtension) { + if (isExtension) runTimeError(UNSUPPORTED_EXT_ERR, qname); - else + else runTimeError(UNSUPPORTED_XSL_ERR, qname); - } - - /** - * XSLT Standard function namespace-uri(node-set). - */ - public static String namespace_uriF(DTMAxisIterator iter, DOM dom) { - return namespace_uriF(iter.next(), dom); - } - - /** - * XSLT Standard function system-property(name) - */ - public static String system_propertyF(String name) { - if (name.equals("xsl:version")) + } + + /** + * XSLT Standard function namespace-uri(node-set). + */ + public static String namespace_uriF(DTMAxisIterator iter, DOM dom) { + return namespace_uriF(iter.next(), dom); + } + + /** + * XSLT Standard function system-property(name) + */ + public static String system_propertyF(String name) { + if (name.equals("xsl:version")) return("1.0"); - if (name.equals("xsl:vendor")) + if (name.equals("xsl:vendor")) return("Apache Software Foundation (Xalan XSLTC)"); - if (name.equals("xsl:vendor-url")) + if (name.equals("xsl:vendor-url")) return("http://xml.apache.org/xalan-j"); - runTimeError(INVALID_ARGUMENT_ERR, name, "system-property()"); - return(EMPTYSTRING); - } - - /** - * XSLT Standard function namespace-uri(). - */ - public static String namespace_uriF(int node, DOM dom) { - final String value = dom.getNodeName(node); - final int colon = value.lastIndexOf(':'); - if (colon >= 0) + runTimeError(INVALID_ARGUMENT_ERR, name, "system-property()"); + return(EMPTYSTRING); + } + + /** + * XSLT Standard function namespace-uri(). + */ + public static String namespace_uriF(int node, DOM dom) { + final String value = dom.getNodeName(node); + final int colon = value.lastIndexOf(':'); + if (colon >= 0) return value.substring(0, colon); - else + else return EMPTYSTRING; - } - - /** - * Implements the object-type() extension function. - * - * @see EXSLT - */ - public static String objectTypeF(Object obj) + } + + /** + * Implements the object-type() extension function. + * + * @see EXSLT + */ + public static String objectTypeF(Object obj) { if (obj instanceof String) return "string"; @@ -488,34 +491,34 @@ else if (obj instanceof DTMAxisIterator) return "unknown"; } - /** - * Implements the nodeset() extension function. - */ - public static DTMAxisIterator nodesetF(Object obj) { - if (obj instanceof DOM) { - //final DOMAdapter adapter = (DOMAdapter) obj; - final DOM dom = (DOM)obj; - return new SingletonIterator(dom.getDocument(), true); - } - else if (obj instanceof DTMAxisIterator) { - return (DTMAxisIterator) obj; - } - else { + /** + * Implements the nodeset() extension function. + */ + public static DTMAxisIterator nodesetF(Object obj) { + if (obj instanceof DOM) { + //final DOMAdapter adapter = (DOMAdapter) obj; + final DOM dom = (DOM)obj; + return new SingletonIterator(dom.getDocument(), true); + } + else if (obj instanceof DTMAxisIterator) { + return (DTMAxisIterator) obj; + } + else { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, "node-set", className); return null; - } } + } - //-- Begin utility functions + //-- Begin utility functions - private static boolean isWhiteSpace(char ch) { - return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'; - } + private static boolean isWhiteSpace(char ch) { + return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'; + } - private static boolean compareStrings(String lstring, String rstring, - int op, DOM dom) { - switch (op) { + private static boolean compareStrings(String lstring, String rstring, + int op, DOM dom) { + switch (op) { case Operators.EQ: return lstring.equals(rstring); @@ -534,1198 +537,1232 @@ private static boolean compareStrings(String lstring, String rstring, case Operators.LE: return numberF(lstring, dom) <= numberF(rstring, dom); - default: + default: runTimeError(RUN_TIME_INTERNAL_ERR, "compare()"); return false; - } } + } - /** - * Utility function: node-set/node-set compare. - */ - public static boolean compare(DTMAxisIterator left, DTMAxisIterator right, + /** + * Utility function: node-set/node-set compare. + */ + public static boolean compare(DTMAxisIterator left, DTMAxisIterator right, int op, DOM dom) { - int lnode; - left.reset(); + int lnode; + left.reset(); - while ((lnode = left.next()) != DTMAxisIterator.END) { + while ((lnode = left.next()) != DTMAxisIterator.END) { final String lvalue = dom.getStringValueX(lnode); int rnode; right.reset(); while ((rnode = right.next()) != DTMAxisIterator.END) { - // String value must be the same if both nodes are the same - if (lnode == rnode) { - if (op == Operators.EQ) { - return true; - } else if (op == Operators.NE) { - continue; - } - } - if (compareStrings(lvalue, dom.getStringValueX(rnode), op, - dom)) { - return true; - } + // String value must be the same if both nodes are the same + if (lnode == rnode) { + if (op == Operators.EQ) { + return true; + } else if (op == Operators.NE) { + continue; + } + } + if (compareStrings(lvalue, dom.getStringValueX(rnode), op, + dom)) { + return true; + } } - } - return false; - } + } + return false; + } - public static boolean compare(int node, DTMAxisIterator iterator, + public static boolean compare(int node, DTMAxisIterator iterator, int op, DOM dom) { - //iterator.reset(); + //iterator.reset(); - int rnode; - String value; + int rnode; + String value; - switch(op) { + switch(op) { case Operators.EQ: - rnode = iterator.next(); - if (rnode != DTMAxisIterator.END) { - value = dom.getStringValueX(node); - do { - if (node == rnode - || value.equals(dom.getStringValueX(rnode))) { - return true; - } - } while ((rnode = iterator.next()) != DTMAxisIterator.END); - } + rnode = iterator.next(); + if (rnode != DTMAxisIterator.END) { + value = dom.getStringValueX(node); + do { + if (node == rnode + || value.equals(dom.getStringValueX(rnode))) { + return true; + } + } while ((rnode = iterator.next()) != DTMAxisIterator.END); + } break; case Operators.NE: - rnode = iterator.next(); - if (rnode != DTMAxisIterator.END) { - value = dom.getStringValueX(node); - do { - if (node != rnode - && !value.equals(dom.getStringValueX(rnode))) { - return true; - } - } while ((rnode = iterator.next()) != DTMAxisIterator.END); - } + rnode = iterator.next(); + if (rnode != DTMAxisIterator.END) { + value = dom.getStringValueX(node); + do { + if (node != rnode + && !value.equals(dom.getStringValueX(rnode))) { + return true; + } + } while ((rnode = iterator.next()) != DTMAxisIterator.END); + } break; case Operators.LT: // Assume we're comparing document order here while ((rnode = iterator.next()) != DTMAxisIterator.END) { - if (rnode > node) return true; + if (rnode > node) return true; } break; case Operators.GT: // Assume we're comparing document order here while ((rnode = iterator.next()) != DTMAxisIterator.END) { - if (rnode < node) return true; + if (rnode < node) return true; } break; - } - return(false); - } - - /** - * Utility function: node-set/number compare. - */ - public static boolean compare(DTMAxisIterator left, final double rnumber, + } + return(false); + } + + /** + * Utility function: node-set/number compare. + */ + public static boolean compare(DTMAxisIterator left, final double rnumber, final int op, DOM dom) { - int node; - //left.reset(); + int node; + //left.reset(); - switch (op) { + switch (op) { case Operators.EQ: while ((node = left.next()) != DTMAxisIterator.END) { - if (numberF(dom.getStringValueX(node), dom) == rnumber) - return true; + if (numberF(dom.getStringValueX(node), dom) == rnumber) + return true; } break; case Operators.NE: while ((node = left.next()) != DTMAxisIterator.END) { - if (numberF(dom.getStringValueX(node), dom) != rnumber) - return true; + if (numberF(dom.getStringValueX(node), dom) != rnumber) + return true; } break; case Operators.GT: while ((node = left.next()) != DTMAxisIterator.END) { - if (numberF(dom.getStringValueX(node), dom) > rnumber) - return true; + if (numberF(dom.getStringValueX(node), dom) > rnumber) + return true; } break; case Operators.LT: while ((node = left.next()) != DTMAxisIterator.END) { - if (numberF(dom.getStringValueX(node), dom) < rnumber) - return true; + if (numberF(dom.getStringValueX(node), dom) < rnumber) + return true; } break; case Operators.GE: while ((node = left.next()) != DTMAxisIterator.END) { - if (numberF(dom.getStringValueX(node), dom) >= rnumber) - return true; + if (numberF(dom.getStringValueX(node), dom) >= rnumber) + return true; } break; case Operators.LE: while ((node = left.next()) != DTMAxisIterator.END) { - if (numberF(dom.getStringValueX(node), dom) <= rnumber) - return true; + if (numberF(dom.getStringValueX(node), dom) <= rnumber) + return true; } break; - default: + default: runTimeError(RUN_TIME_INTERNAL_ERR, "compare()"); - } - - return false; } - /** - * Utility function: node-set/string comparison. - */ - public static boolean compare(DTMAxisIterator left, final String rstring, + return false; + } + + /** + * Utility function: node-set/string comparison. + */ + public static boolean compare(DTMAxisIterator left, final String rstring, int op, DOM dom) { - int node; - //left.reset(); - while ((node = left.next()) != DTMAxisIterator.END) { + int node; + //left.reset(); + while ((node = left.next()) != DTMAxisIterator.END) { if (compareStrings(dom.getStringValueX(node), rstring, op, dom)) { - return true; + return true; } - } - return false; } + return false; + } - public static boolean compare(Object left, Object right, + public static boolean compare(Object left, Object right, int op, DOM dom) { - boolean result = false; - boolean hasSimpleArgs = hasSimpleType(left) && hasSimpleType(right); - - if (op != Operators.EQ && op != Operators.NE) { - // If node-boolean comparison -> convert node to boolean - if (left instanceof Node || right instanceof Node) { - if (left instanceof Boolean) { - right = new Boolean(booleanF(right)); - hasSimpleArgs = true; - } - if (right instanceof Boolean) { - left = new Boolean(booleanF(left)); - hasSimpleArgs = true; - } - } + boolean result = false; + boolean hasSimpleArgs = hasSimpleType(left) && hasSimpleType(right); + + if (op != Operators.EQ && op != Operators.NE) { + // If node-boolean comparison -> convert node to boolean + if (left instanceof Node || right instanceof Node) { + if (left instanceof Boolean) { + right = new Boolean(booleanF(right)); + hasSimpleArgs = true; + } + if (right instanceof Boolean) { + left = new Boolean(booleanF(left)); + hasSimpleArgs = true; + } + } - if (hasSimpleArgs) { - switch (op) { - case Operators.GT: - return numberF(left, dom) > numberF(right, dom); + if (hasSimpleArgs) { + switch (op) { + case Operators.GT: + return numberF(left, dom) > numberF(right, dom); - case Operators.LT: - return numberF(left, dom) < numberF(right, dom); + case Operators.LT: + return numberF(left, dom) < numberF(right, dom); - case Operators.GE: - return numberF(left, dom) >= numberF(right, dom); + case Operators.GE: + return numberF(left, dom) >= numberF(right, dom); - case Operators.LE: - return numberF(left, dom) <= numberF(right, dom); + case Operators.LE: + return numberF(left, dom) <= numberF(right, dom); - default: - runTimeError(RUN_TIME_INTERNAL_ERR, "compare()"); - } - } - // falls through - } + default: + runTimeError(RUN_TIME_INTERNAL_ERR, "compare()"); + } + } + // falls through + } - if (hasSimpleArgs) { - if (left instanceof Boolean || right instanceof Boolean) { - result = booleanF(left) == booleanF(right); - } - else if (left instanceof Double || right instanceof Double || - left instanceof Integer || right instanceof Integer) { - result = numberF(left, dom) == numberF(right, dom); - } - else { // compare them as strings - result = stringF(left, dom).equals(stringF(right, dom)); - } + if (hasSimpleArgs) { + if (left instanceof Boolean || right instanceof Boolean) { + result = booleanF(left) == booleanF(right); + } + else if (left instanceof Double || right instanceof Double || + left instanceof Integer || right instanceof Integer) { + result = numberF(left, dom) == numberF(right, dom); + } + else { // compare them as strings + result = stringF(left, dom).equals(stringF(right, dom)); + } - if (op == Operators.NE) { - result = !result; - } - } - else { - if (left instanceof Node) { - left = new SingletonIterator(((Node)left).node); - } - if (right instanceof Node) { - right = new SingletonIterator(((Node)right).node); - } + if (op == Operators.NE) { + result = !result; + } + } + else { + if (left instanceof Node) { + left = new SingletonIterator(((Node)left).node); + } + if (right instanceof Node) { + right = new SingletonIterator(((Node)right).node); + } - if (hasSimpleType(left) || - left instanceof DOM && right instanceof DTMAxisIterator) { - // swap operands and operator - final Object temp = right; right = left; left = temp; - op = Operators.swapOp(op); - } + if (hasSimpleType(left) || + left instanceof DOM && right instanceof DTMAxisIterator) { + // swap operands and operator + final Object temp = right; right = left; left = temp; + op = Operators.swapOp(op); + } - if (left instanceof DOM) { - if (right instanceof Boolean) { - result = ((Boolean)right).booleanValue(); - return result == (op == Operators.EQ); - } - - final String sleft = ((DOM)left).getStringValue(); - - if (right instanceof Number) { - result = ((Number)right).doubleValue() == - stringToReal(sleft); - } - else if (right instanceof String) { - result = sleft.equals((String)right); - } - else if (right instanceof DOM) { - result = sleft.equals(((DOM)right).getStringValue()); - } - - if (op == Operators.NE) { - result = !result; - } - return result; - } + if (left instanceof DOM) { + if (right instanceof Boolean) { + result = ((Boolean)right).booleanValue(); + return result == (op == Operators.EQ); + } + + final String sleft = ((DOM)left).getStringValue(); + + if (right instanceof Number) { + result = ((Number)right).doubleValue() == + stringToReal(sleft); + } + else if (right instanceof String) { + result = sleft.equals((String)right); + } + else if (right instanceof DOM) { + result = sleft.equals(((DOM)right).getStringValue()); + } + + if (op == Operators.NE) { + result = !result; + } + return result; + } - // Next, node-set/t for t in {real, string, node-set, result-tree} + // Next, node-set/t for t in {real, string, node-set, result-tree} - DTMAxisIterator iter = ((DTMAxisIterator)left).reset(); + DTMAxisIterator iter = ((DTMAxisIterator)left).reset(); - if (right instanceof DTMAxisIterator) { - result = compare(iter, (DTMAxisIterator)right, op, dom); - } - else if (right instanceof String) { - result = compare(iter, (String)right, op, dom); - } - else if (right instanceof Number) { - final double temp = ((Number)right).doubleValue(); - result = compare(iter, temp, op, dom); - } - else if (right instanceof Boolean) { - boolean temp = ((Boolean)right).booleanValue(); - result = (iter.reset().next() != DTMAxisIterator.END) == temp; - } - else if (right instanceof DOM) { - result = compare(iter, ((DOM)right).getStringValue(), - op, dom); - } - else if (right == null) { - return(false); - } - else { - final String className = right.getClass().getName(); - runTimeError(INVALID_ARGUMENT_ERR, className, "compare()"); - } - } - return result; + if (right instanceof DTMAxisIterator) { + result = compare(iter, (DTMAxisIterator)right, op, dom); + } + else if (right instanceof String) { + result = compare(iter, (String)right, op, dom); + } + else if (right instanceof Number) { + final double temp = ((Number)right).doubleValue(); + result = compare(iter, temp, op, dom); + } + else if (right instanceof Boolean) { + boolean temp = ((Boolean)right).booleanValue(); + result = (iter.reset().next() != DTMAxisIterator.END) == temp; + } + else if (right instanceof DOM) { + result = compare(iter, ((DOM)right).getStringValue(), + op, dom); + } + else if (right == null) { + return(false); + } + else { + final String className = right.getClass().getName(); + runTimeError(INVALID_ARGUMENT_ERR, className, "compare()"); + } + } + return result; } - /** - * Utility function: used to test context node's language - */ - public static boolean testLanguage(String testLang, DOM dom, int node) { - // language for context node (if any) - String nodeLang = dom.getLanguage(node); - if (nodeLang == null) + /** + * Utility function: used to test context node's language + */ + public static boolean testLanguage(String testLang, DOM dom, int node) { + // language for context node (if any) + String nodeLang = dom.getLanguage(node); + if (nodeLang == null) return(false); - else + else nodeLang = nodeLang.toLowerCase(); - // compare context node's language agains test language - testLang = testLang.toLowerCase(); - if (testLang.length() == 2) { + // compare context node's language agains test language + testLang = testLang.toLowerCase(); + if (testLang.length() == 2) { return(nodeLang.startsWith(testLang)); - } - else { + } + else { return(nodeLang.equals(testLang)); - } } + } - private static boolean hasSimpleType(Object obj) { - return obj instanceof Boolean || obj instanceof Double || + private static boolean hasSimpleType(Object obj) { + return obj instanceof Boolean || obj instanceof Double || obj instanceof Integer || obj instanceof String || obj instanceof Node || obj instanceof DOM; - } + } - /** - * Utility function: used in StringType to convert a string to a real. - */ - public static double stringToReal(String s) { - try { + /** + * Utility function: used in StringType to convert a string to a real. + */ + public static double stringToReal(String s) { + try { return Double.valueOf(s).doubleValue(); - } - catch (NumberFormatException e) { + } + catch (NumberFormatException e) { return Double.NaN; - } } + } - /** - * Utility function: used in StringType to convert a string to an int. - */ - public static int stringToInt(String s) { - try { + /** + * Utility function: used in StringType to convert a string to an int. + */ + public static int stringToInt(String s) { + try { return Integer.parseInt(s); - } - catch (NumberFormatException e) { + } + catch (NumberFormatException e) { return(-1); // ??? - } } + } - private static final int DOUBLE_FRACTION_DIGITS = 340; - private static final double lowerBounds = 0.001; - private static final double upperBounds = 10000000; - private static DecimalFormat defaultFormatter; - private static String defaultPattern = ""; + private static final int DOUBLE_FRACTION_DIGITS = 340; + private static final double lowerBounds = 0.001; + private static final double upperBounds = 10000000; + private static DecimalFormat defaultFormatter; + private static String defaultPattern = ""; - static { - NumberFormat f = NumberFormat.getInstance(Locale.getDefault()); - defaultFormatter = (f instanceof DecimalFormat) ? + static { + NumberFormat f = NumberFormat.getInstance(Locale.getDefault()); + defaultFormatter = (f instanceof DecimalFormat) ? (DecimalFormat) f : new DecimalFormat(); - // Set max fraction digits so that truncation does not occur. Setting - // the max to Integer.MAX_VALUE may cause problems with some JDK's. - defaultFormatter.setMaximumFractionDigits(DOUBLE_FRACTION_DIGITS); - defaultFormatter.setMinimumFractionDigits(0); - defaultFormatter.setMinimumIntegerDigits(1); - defaultFormatter.setGroupingUsed(false); - } - - /** - * Utility function: used in RealType to convert a real to a string. - * Removes the decimal if null. - */ - public static String realToString(double d) { - final double m = Math.abs(d); - if ((m >= lowerBounds) && (m < upperBounds)) { + // Set max fraction digits so that truncation does not occur. Setting + // the max to Integer.MAX_VALUE may cause problems with some JDK's. + defaultFormatter.setMaximumFractionDigits(DOUBLE_FRACTION_DIGITS); + defaultFormatter.setMinimumFractionDigits(0); + defaultFormatter.setMinimumIntegerDigits(1); + defaultFormatter.setGroupingUsed(false); + } + + /** + * Utility function: used in RealType to convert a real to a string. + * Removes the decimal if null. + */ + public static String realToString(double d) { + final double m = Math.abs(d); + if ((m >= lowerBounds) && (m < upperBounds)) { final String result = Double.toString(d); final int length = result.length(); // Remove leading zeros. if ((result.charAt(length-2) == '.') && - (result.charAt(length-1) == '0')) - return result.substring(0, length-2); + (result.charAt(length-1) == '0')) + return result.substring(0, length-2); else - return result; - } - else { + return result; + } + else { if (Double.isNaN(d) || Double.isInfinite(d)) - return(Double.toString(d)); + return(Double.toString(d)); return formatNumber(d, defaultPattern, defaultFormatter); - } - } - - /** - * Utility function: used in RealType to convert a real to an integer - */ - public static int realToInt(double d) { - return (int)d; } - - /** - * Utility function: used to format/adjust a double to a string. The - * DecimalFormat object comes from the 'formatSymbols' hashtable in - * AbstractTranslet. - */ - private static FieldPosition _fieldPosition = new FieldPosition(0); - - public static String formatNumber(double number, String pattern, - DecimalFormat formatter) { - // bugzilla fix 12813 - if (formatter == null) { + } + + /** + * Utility function: used in RealType to convert a real to an integer + */ + public static int realToInt(double d) { + return (int)d; + } + + /** + * Utility function: used to format/adjust a double to a string. The + * DecimalFormat object comes from the 'formatSymbols' hashtable in + * AbstractTranslet. + */ + private static FieldPosition _fieldPosition = new FieldPosition(0); + + public static String formatNumber(double number, String pattern, + DecimalFormat formatter) { + // bugzilla fix 12813 + if (formatter == null) { formatter = defaultFormatter; - } - try { + } + try { StringBuffer result = new StringBuffer(); if (pattern != defaultPattern) { - formatter.applyLocalizedPattern(pattern); + formatter.applyLocalizedPattern(pattern); } - formatter.format(number, result, _fieldPosition); + formatter.format(number, result, _fieldPosition); return result.toString(); - } - catch (IllegalArgumentException e) { + } + catch (IllegalArgumentException e) { runTimeError(FORMAT_NUMBER_ERR, Double.toString(number), pattern); return(EMPTYSTRING); - } } + } - /** - * Utility function: used to convert references to node-sets. If the - * obj is an instanceof Node then create a singleton iterator. - */ - public static DTMAxisIterator referenceToNodeSet(Object obj) { - // Convert var/param -> node - if (obj instanceof Node) { + /** + * Utility function: used to convert references to node-sets. If the + * obj is an instanceof Node then create a singleton iterator. + */ + public static DTMAxisIterator referenceToNodeSet(Object obj) { + // Convert var/param -> node + if (obj instanceof Node) { return(new SingletonIterator(((Node)obj).node)); - } - // Convert var/param -> node-set - else if (obj instanceof DTMAxisIterator) { - return(((DTMAxisIterator)obj).cloneIterator().reset()); - } - else { + } + // Convert var/param -> node-set + else if (obj instanceof DTMAxisIterator) { + return(((DTMAxisIterator)obj).cloneIterator().reset()); + } + else { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, className, "node-set"); return null; - } } + } - /** - * Utility function: used to convert reference to org.w3c.dom.NodeList. - */ - public static NodeList referenceToNodeList(Object obj, DOM dom) { - if (obj instanceof Node || obj instanceof DTMAxisIterator) { - DTMAxisIterator iter = referenceToNodeSet(obj); - return dom.makeNodeList(iter); - } - else if (obj instanceof DOM) { - dom = (DOM)obj; - return dom.makeNodeList(DTMDefaultBase.ROOTNODE); - } - else { + /** + * Utility function: used to convert reference to org.w3c.dom.NodeList. + */ + public static NodeList referenceToNodeList(Object obj, DOM dom) { + if (obj instanceof Node || obj instanceof DTMAxisIterator) { + DTMAxisIterator iter = referenceToNodeSet(obj); + return dom.makeNodeList(iter); + } + else if (obj instanceof DOM) { + dom = (DOM)obj; + return dom.makeNodeList(DTMDefaultBase.ROOTNODE); + } + else { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, className, - "org.w3c.dom.NodeList"); + "org.w3c.dom.NodeList"); return null; - } } + } - /** - * Utility function: used to convert reference to org.w3c.dom.Node. - */ - public static org.w3c.dom.Node referenceToNode(Object obj, DOM dom) { - if (obj instanceof Node || obj instanceof DTMAxisIterator) { - DTMAxisIterator iter = referenceToNodeSet(obj); - return dom.makeNode(iter); - } - else if (obj instanceof DOM) { - dom = (DOM)obj; - DTMAxisIterator iter = dom.getChildren(DTMDefaultBase.ROOTNODE); - return dom.makeNode(iter); - } - else { + /** + * Utility function: used to convert reference to org.w3c.dom.Node. + */ + public static org.w3c.dom.Node referenceToNode(Object obj, DOM dom) { + if (obj instanceof Node || obj instanceof DTMAxisIterator) { + DTMAxisIterator iter = referenceToNodeSet(obj); + return dom.makeNode(iter); + } + else if (obj instanceof DOM) { + dom = (DOM)obj; + DTMAxisIterator iter = dom.getChildren(DTMDefaultBase.ROOTNODE); + return dom.makeNode(iter); + } + else { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, className, "org.w3c.dom.Node"); return null; - } } + } - /** - * Utility function: used to convert reference to long. - */ - public static long referenceToLong(Object obj) { - if (obj instanceof Number) { - return ((Number) obj).longValue(); // handles Integer and Double - } - else { + /** + * Utility function: used to convert reference to long. + */ + public static long referenceToLong(Object obj) { + if (obj instanceof Number) { + return ((Number) obj).longValue(); // handles Integer and Double + } + else { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, className, Long.TYPE); return 0; - } } + } - /** - * Utility function: used to convert reference to double. - */ - public static double referenceToDouble(Object obj) { - if (obj instanceof Number) { - return ((Number) obj).doubleValue(); // handles Integer and Double - } - else { + /** + * Utility function: used to convert reference to double. + */ + public static double referenceToDouble(Object obj) { + if (obj instanceof Number) { + return ((Number) obj).doubleValue(); // handles Integer and Double + } + else { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, className, Double.TYPE); return 0; - } } + } - /** - * Utility function: used to convert reference to boolean. - */ - public static boolean referenceToBoolean(Object obj) { - if (obj instanceof Boolean) { - return ((Boolean) obj).booleanValue(); - } - else { + /** + * Utility function: used to convert reference to boolean. + */ + public static boolean referenceToBoolean(Object obj) { + if (obj instanceof Boolean) { + return ((Boolean) obj).booleanValue(); + } + else { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, className, Boolean.TYPE); return false; - } } + } - /** - * Utility function: used to convert reference to String. - */ - public static String referenceToString(Object obj, DOM dom) { - if (obj instanceof String) { - return (String) obj; - } - else if (obj instanceof DTMAxisIterator) { + /** + * Utility function: used to convert reference to String. + */ + public static String referenceToString(Object obj, DOM dom) { + if (obj instanceof String) { + return (String) obj; + } + else if (obj instanceof DTMAxisIterator) { return dom.getStringValueX(((DTMAxisIterator)obj).reset().next()); - } - else if (obj instanceof Node) { + } + else if (obj instanceof Node) { return dom.getStringValueX(((Node)obj).node); - } - else if (obj instanceof DOM) { + } + else if (obj instanceof DOM) { return ((DOM) obj).getStringValue(); - } - else { + } + else { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, className, String.class); return null; - } } + } - /** - * Utility function used to convert a w3c Node into an internal DOM iterator. - */ - public static DTMAxisIterator node2Iterator(org.w3c.dom.Node node, - Translet translet, DOM dom) + /** + * Utility function used to convert a w3c Node into an internal DOM iterator. + */ + public static DTMAxisIterator node2Iterator(org.w3c.dom.Node node, + Translet translet, DOM dom) { - final org.w3c.dom.Node inNode = node; - // Create a dummy NodeList which only contains the given node to make - // use of the nodeList2Iterator() interface. - org.w3c.dom.NodeList nodelist = new org.w3c.dom.NodeList() { - public int getLength() { - return 1; - } + final org.w3c.dom.Node inNode = node; + // Create a dummy NodeList which only contains the given node to make + // use of the nodeList2Iterator() interface. + org.w3c.dom.NodeList nodelist = new org.w3c.dom.NodeList() { + public int getLength() { + return 1; + } - public org.w3c.dom.Node item(int index) { - if (index == 0) - return inNode; - else - return null; - } + public org.w3c.dom.Node item(int index) { + if (index == 0) + return inNode; + else + return null; + } }; - return nodeList2Iterator(nodelist, translet, dom); + return nodeList2Iterator(nodelist, translet, dom); } - /** - * In a perfect world, this would be the implementation for - * nodeList2Iterator. In reality, though, this causes a - * ClassCastException in getDTMHandleFromNode because SAXImpl is - * not an instance of DOM2DTM. So we use the more lengthy - * implementation below until this issue has been addressed. - * - * @see org.apache.xml.dtm.ref.DTMManagerDefault#getDTMHandleFromNode - */ - private static DTMAxisIterator nodeList2IteratorUsingHandleFromNode( - org.w3c.dom.NodeList nodeList, - Translet translet, DOM dom) + /** + * In a perfect world, this would be the implementation for + * nodeList2Iterator. In reality, though, this causes a + * ClassCastException in getDTMHandleFromNode because SAXImpl is + * not an instance of DOM2DTM. So we use the more lengthy + * implementation below until this issue has been addressed. + * + * @see org.apache.xml.dtm.ref.DTMManagerDefault#getDTMHandleFromNode + */ + private static DTMAxisIterator nodeList2IteratorUsingHandleFromNode( + org.w3c.dom.NodeList nodeList, + Translet translet, DOM dom) { - final int n = nodeList.getLength(); - final int[] dtmHandles = new int[n]; - DTMManager dtmManager = null; - if (dom instanceof MultiDOM) - dtmManager = ((MultiDOM) dom).getDTMManager(); - for (int i = 0; i < n; ++i) { - org.w3c.dom.Node node = nodeList.item(i); - int handle; - if (dtmManager != null) { - handle = dtmManager.getDTMHandleFromNode(node); - } - else if (node instanceof DTMNodeProxy - && ((DTMNodeProxy) node).getDTM() == dom) { - handle = ((DTMNodeProxy) node).getDTMNodeNumber(); - } - else { - runTimeError(RUN_TIME_INTERNAL_ERR, "need MultiDOM"); - return null; - } - dtmHandles[i] = handle; - System.out.println("Node " + i + " has handle 0x" + - Integer.toString(handle, 16)); - } - return new ArrayNodeListIterator(dtmHandles); - } - - /** - * Utility function used to convert a w3c NodeList into a internal - * DOM iterator. - */ - public static DTMAxisIterator nodeList2Iterator( - org.w3c.dom.NodeList nodeList, - Translet translet, DOM dom) + final int n = nodeList.getLength(); + final int[] dtmHandles = new int[n]; + DTMManager dtmManager = null; + if (dom instanceof MultiDOM) + dtmManager = ((MultiDOM) dom).getDTMManager(); + for (int i = 0; i < n; ++i) { + org.w3c.dom.Node node = nodeList.item(i); + int handle; + if (dtmManager != null) { + handle = dtmManager.getDTMHandleFromNode(node); + } + else if (node instanceof DTMNodeProxy + && ((DTMNodeProxy) node).getDTM() == dom) { + handle = ((DTMNodeProxy) node).getDTMNodeNumber(); + } + else { + runTimeError(RUN_TIME_INTERNAL_ERR, "need MultiDOM"); + return null; + } + dtmHandles[i] = handle; + System.out.println("Node " + i + " has handle 0x" + + Integer.toString(handle, 16)); + } + return new ArrayNodeListIterator(dtmHandles); + } + + /** + * Utility function used to convert a w3c NodeList into a internal + * DOM iterator. + */ + public static DTMAxisIterator nodeList2Iterator( + org.w3c.dom.NodeList nodeList, + Translet translet, DOM dom) { - // First pass: build w3c DOM for all nodes not proxied from our DOM. - // - // Notice: this looses some (esp. parent) context for these nodes, - // so some way to wrap the original nodes inside a DTMAxisIterator - // might be preferable in the long run. - int n = 0; // allow for change in list length, just in case. - Document doc = null; - DTMManager dtmManager = null; - int[] proxyNodes = new int[nodeList.getLength()]; - if (dom instanceof MultiDOM) - dtmManager = ((MultiDOM) dom).getDTMManager(); - for (int i = 0; i < nodeList.getLength(); ++i) { - org.w3c.dom.Node node = nodeList.item(i); - if (node instanceof DTMNodeProxy) { - DTMNodeProxy proxy = (DTMNodeProxy)node; - DTM nodeDTM = proxy.getDTM(); - int handle = proxy.getDTMNodeNumber(); - boolean isOurDOM = (nodeDTM == dom); - if (!isOurDOM && dtmManager != null) { - try { - isOurDOM = (nodeDTM == dtmManager.getDTM(handle)); - } - catch (ArrayIndexOutOfBoundsException e) { - // invalid node handle, so definitely not our doc - } - } - if (isOurDOM) { - proxyNodes[i] = handle; - ++n; - continue; - } - } - proxyNodes[i] = DTM.NULL; - int nodeType = node.getNodeType(); - if (doc == null) { - if (dom instanceof MultiDOM == false) { - runTimeError(RUN_TIME_INTERNAL_ERR, "need MultiDOM"); - return null; - } - try { - AbstractTranslet at = (AbstractTranslet) translet; - doc = at.newDocument("", "__top__"); - } - catch (javax.xml.parsers.ParserConfigurationException e) { - runTimeError(RUN_TIME_INTERNAL_ERR, e.getMessage()); - return null; - } - } - // Use one dummy element as container for each node of the - // list. That way, it is easier to detect resp. avoid - // funny things which change the number of nodes, - // e.g. auto-concatenation of text nodes. - Element mid; - switch (nodeType) { - case org.w3c.dom.Node.ELEMENT_NODE: - case org.w3c.dom.Node.TEXT_NODE: - case org.w3c.dom.Node.CDATA_SECTION_NODE: - case org.w3c.dom.Node.COMMENT_NODE: - case org.w3c.dom.Node.ENTITY_REFERENCE_NODE: - case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: - mid = doc.createElementNS(null, "__dummy__"); - mid.appendChild(doc.importNode(node, true)); - doc.getDocumentElement().appendChild(mid); - ++n; - break; - case org.w3c.dom.Node.ATTRIBUTE_NODE: - // The mid element also serves as a container for - // attributes, avoiding problems with conflicting - // attributes or node order. - mid = doc.createElementNS(null, "__dummy__"); - mid.setAttributeNodeNS((Attr)doc.importNode(node, true)); - doc.getDocumentElement().appendChild(mid); - ++n; - break; - default: - // Better play it safe for all types we aren't sure we know - // how to deal with. - runTimeError(RUN_TIME_INTERNAL_ERR, - "Don't know how to convert node type " - + nodeType); - } - } + // First pass: build w3c DOM for all nodes not proxied from our DOM. + // + // Notice: this looses some (esp. parent) context for these nodes, + // so some way to wrap the original nodes inside a DTMAxisIterator + // might be preferable in the long run. + int n = 0; // allow for change in list length, just in case. + Document doc = null; + DTMManager dtmManager = null; + int[] proxyNodes = new int[nodeList.getLength()]; + if (dom instanceof MultiDOM) + dtmManager = ((MultiDOM) dom).getDTMManager(); + for (int i = 0; i < nodeList.getLength(); ++i) { + org.w3c.dom.Node node = nodeList.item(i); + if (node instanceof DTMNodeProxy) { + DTMNodeProxy proxy = (DTMNodeProxy)node; + DTM nodeDTM = proxy.getDTM(); + int handle = proxy.getDTMNodeNumber(); + boolean isOurDOM = (nodeDTM == dom); + if (!isOurDOM && dtmManager != null) { + try { + isOurDOM = (nodeDTM == dtmManager.getDTM(handle)); + } + catch (ArrayIndexOutOfBoundsException e) { + // invalid node handle, so definitely not our doc + } + } + if (isOurDOM) { + proxyNodes[i] = handle; + ++n; + continue; + } + } + proxyNodes[i] = DTM.NULL; + int nodeType = node.getNodeType(); + if (doc == null) { + if (dom instanceof MultiDOM == false) { + runTimeError(RUN_TIME_INTERNAL_ERR, "need MultiDOM"); + return null; + } + try { + AbstractTranslet at = (AbstractTranslet) translet; + doc = at.newDocument("", "__top__"); + } + catch (javax.xml.parsers.ParserConfigurationException e) { + runTimeError(RUN_TIME_INTERNAL_ERR, e.getMessage()); + return null; + } + } + // Use one dummy element as container for each node of the + // list. That way, it is easier to detect resp. avoid + // funny things which change the number of nodes, + // e.g. auto-concatenation of text nodes. + Element mid; + switch (nodeType) { + case org.w3c.dom.Node.ELEMENT_NODE: + case org.w3c.dom.Node.TEXT_NODE: + case org.w3c.dom.Node.CDATA_SECTION_NODE: + case org.w3c.dom.Node.COMMENT_NODE: + case org.w3c.dom.Node.ENTITY_REFERENCE_NODE: + case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: + mid = doc.createElementNS(null, "__dummy__"); + mid.appendChild(doc.importNode(node, true)); + doc.getDocumentElement().appendChild(mid); + ++n; + break; + case org.w3c.dom.Node.ATTRIBUTE_NODE: + // The mid element also serves as a container for + // attributes, avoiding problems with conflicting + // attributes or node order. + mid = doc.createElementNS(null, "__dummy__"); + mid.setAttributeNodeNS((Attr)doc.importNode(node, true)); + doc.getDocumentElement().appendChild(mid); + ++n; + break; + default: + // Better play it safe for all types we aren't sure we know + // how to deal with. + runTimeError(RUN_TIME_INTERNAL_ERR, + "Don't know how to convert node type " + + nodeType); + } + } - // w3cDOM -> DTM -> DOMImpl - DTMAxisIterator iter = null, childIter = null, attrIter = null; - if (doc != null) { - final MultiDOM multiDOM = (MultiDOM) dom; - DOM idom = (DOM)dtmManager.getDTM(new DOMSource(doc), false, + // w3cDOM -> DTM -> DOMImpl + DTMAxisIterator iter = null, childIter = null, attrIter = null; + if (doc != null) { + final MultiDOM multiDOM = (MultiDOM) dom; + DOM idom = (DOM)dtmManager.getDTM(new DOMSource(doc), false, null, true, false); - // Create DOMAdapter and register with MultiDOM - DOMAdapter domAdapter = new DOMAdapter(idom, + // Create DOMAdapter and register with MultiDOM + DOMAdapter domAdapter = new DOMAdapter(idom, translet.getNamesArray(), translet.getUrisArray(), translet.getTypesArray(), - translet.getNamespaceArray()); - multiDOM.addDOMAdapter(domAdapter); - - DTMAxisIterator iter1 = idom.getAxisIterator(Axis.CHILD); - DTMAxisIterator iter2 = idom.getAxisIterator(Axis.CHILD); - iter = new AbsoluteIterator( - new StepIterator(iter1, iter2)); - - iter.setStartNode(DTMDefaultBase.ROOTNODE); - - childIter = idom.getAxisIterator(Axis.CHILD); - attrIter = idom.getAxisIterator(Axis.ATTRIBUTE); - } - - // Second pass: find DTM handles for every node in the list. - int[] dtmHandles = new int[n]; - n = 0; - for (int i = 0; i < nodeList.getLength(); ++i) { - if (proxyNodes[i] != DTM.NULL) { - dtmHandles[n++] = proxyNodes[i]; - continue; - } - org.w3c.dom.Node node = nodeList.item(i); - DTMAxisIterator iter3 = null; - int nodeType = node.getNodeType(); - switch (nodeType) { - case org.w3c.dom.Node.ELEMENT_NODE: - case org.w3c.dom.Node.TEXT_NODE: - case org.w3c.dom.Node.CDATA_SECTION_NODE: - case org.w3c.dom.Node.COMMENT_NODE: - case org.w3c.dom.Node.ENTITY_REFERENCE_NODE: - case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: - iter3 = childIter; - break; - case org.w3c.dom.Node.ATTRIBUTE_NODE: - iter3 = attrIter; - break; - default: - // Should not happen, as first run should have got all these - throw new InternalRuntimeError("Mismatched cases"); - } - if (iter3 != null) { - iter3.setStartNode(iter.next()); - dtmHandles[n] = iter3.next(); - // For now, play it self and perform extra checks: - if (dtmHandles[n] == DTMAxisIterator.END) - throw new InternalRuntimeError("Expected element missing at " + i); - if (iter3.next() != DTMAxisIterator.END) - throw new InternalRuntimeError("Too many elements at " + i); - ++n; - } - } - if (n != dtmHandles.length) - throw new InternalRuntimeError("Nodes lost in second pass"); + translet.getNamespaceArray()); + multiDOM.addDOMAdapter(domAdapter); + + DTMAxisIterator iter1 = idom.getAxisIterator(Axis.CHILD); + DTMAxisIterator iter2 = idom.getAxisIterator(Axis.CHILD); + iter = new AbsoluteIterator( + new StepIterator(iter1, iter2)); + + iter.setStartNode(DTMDefaultBase.ROOTNODE); + + childIter = idom.getAxisIterator(Axis.CHILD); + attrIter = idom.getAxisIterator(Axis.ATTRIBUTE); + } + + // Second pass: find DTM handles for every node in the list. + int[] dtmHandles = new int[n]; + n = 0; + for (int i = 0; i < nodeList.getLength(); ++i) { + if (proxyNodes[i] != DTM.NULL) { + dtmHandles[n++] = proxyNodes[i]; + continue; + } + org.w3c.dom.Node node = nodeList.item(i); + DTMAxisIterator iter3 = null; + int nodeType = node.getNodeType(); + switch (nodeType) { + case org.w3c.dom.Node.ELEMENT_NODE: + case org.w3c.dom.Node.TEXT_NODE: + case org.w3c.dom.Node.CDATA_SECTION_NODE: + case org.w3c.dom.Node.COMMENT_NODE: + case org.w3c.dom.Node.ENTITY_REFERENCE_NODE: + case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: + iter3 = childIter; + break; + case org.w3c.dom.Node.ATTRIBUTE_NODE: + iter3 = attrIter; + break; + default: + // Should not happen, as first run should have got all these + throw new InternalRuntimeError("Mismatched cases"); + } + if (iter3 != null) { + iter3.setStartNode(iter.next()); + dtmHandles[n] = iter3.next(); + // For now, play it self and perform extra checks: + if (dtmHandles[n] == DTMAxisIterator.END) + throw new InternalRuntimeError("Expected element missing at " + i); + if (iter3.next() != DTMAxisIterator.END) + throw new InternalRuntimeError("Too many elements at " + i); + ++n; + } + } + if (n != dtmHandles.length) + throw new InternalRuntimeError("Nodes lost in second pass"); - return new ArrayNodeListIterator(dtmHandles); + return new ArrayNodeListIterator(dtmHandles); } - /** - * Utility function used to convert references to DOMs. - */ - public static DOM referenceToResultTree(Object obj) { - try { + /** + * Utility function used to convert references to DOMs. + */ + public static DOM referenceToResultTree(Object obj) { + try { return ((DOM) obj); - } - catch (IllegalArgumentException e) { + } + catch (IllegalArgumentException e) { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, "reference", className); return null; - } - } - - /** - * Utility function: used with nth position filters to convert a sequence - * of nodes to just one single node (the one at position n). - */ - public static DTMAxisIterator getSingleNode(DTMAxisIterator iterator) { - int node = iterator.next(); - return(new SingletonIterator(node)); } - - /** - * Utility function: used in xsl:copy. - */ - private static char[] _characterArray = new char[32]; - - public static void copy(Object obj, - SerializationHandler handler, - int node, - DOM dom) { - try { + } + + /** + * Utility function: used with nth position filters to convert a sequence + * of nodes to just one single node (the one at position n). + */ + public static DTMAxisIterator getSingleNode(DTMAxisIterator iterator) { + int node = iterator.next(); + return(new SingletonIterator(node)); + } + + /** + * Utility function: used in xsl:copy. + */ + private static char[] _characterArray = new char[32]; + + public static void copy(Object obj, + SerializationHandler handler, + int node, + DOM dom) { + try { if (obj instanceof DTMAxisIterator) { - DTMAxisIterator iter = (DTMAxisIterator) obj; - dom.copy(iter.reset(), handler); + DTMAxisIterator iter = (DTMAxisIterator) obj; + dom.copy(iter.reset(), handler); } else if (obj instanceof Node) { - dom.copy(((Node) obj).node, handler); + dom.copy(((Node) obj).node, handler); } else if (obj instanceof DOM) { - //((DOM)obj).copy(((org.apache.xml.dtm.ref.DTMDefaultBase)((DOMAdapter)obj).getDOMImpl()).getDocument(), handler); - DOM newDom = (DOM)obj; - newDom.copy(newDom.getDocument(), handler); + //((DOM)obj).copy(((org.apache.xml.dtm.ref.DTMDefaultBase)((DOMAdapter)obj).getDOMImpl()).getDocument(), handler); + DOM newDom = (DOM)obj; + newDom.copy(newDom.getDocument(), handler); } else { - String string = obj.toString(); // or call stringF() - final int length = string.length(); - if (length > _characterArray.length) - _characterArray = new char[length]; - string.getChars(0, length, _characterArray, 0); - handler.characters(_characterArray, 0, length); + String string = obj.toString(); // or call stringF() + final int length = string.length(); + if (length > _characterArray.length) + _characterArray = new char[length]; + string.getChars(0, length, _characterArray, 0); + handler.characters(_characterArray, 0, length); } - } - catch (SAXException e) { + } + catch (SAXException e) { runTimeError(RUN_TIME_COPY_ERR); - } } + } - /** - * Utility function to check if xsl:attribute has a valid qname - * This method should only be invoked if the name attribute is an AVT - */ - public static void checkAttribQName(String name) { - final int firstOccur = name.indexOf(':'); - final int lastOccur = name.lastIndexOf(':'); - final String localName = name.substring(lastOccur + 1); + /** + * Utility function to check if xsl:attribute has a valid qname + * This method should only be invoked if the name attribute is an AVT + */ + public static void checkAttribQName(String name) { + final int firstOccur = name.indexOf(':'); + final int lastOccur = name.lastIndexOf(':'); + final String localName = name.substring(lastOccur + 1); - if (firstOccur > 0) { - final String newPrefix = name.substring(0, firstOccur); + if (firstOccur > 0) { + final String newPrefix = name.substring(0, firstOccur); - if (firstOccur != lastOccur) { - final String oriPrefix = name.substring(firstOccur+1, lastOccur); - if (!XML11Char.isXML11ValidNCName(oriPrefix)) { - // even though the orignal prefix is ignored, it should still get checked for valid NCName - runTimeError(INVALID_QNAME_ERR,oriPrefix+":"+localName); - } - } - - // prefix must be a valid NCName - if (!XML11Char.isXML11ValidNCName(newPrefix)) { - runTimeError(INVALID_QNAME_ERR,newPrefix+":"+localName); - } + if (firstOccur != lastOccur) { + final String oriPrefix = name.substring(firstOccur+1, lastOccur); + if (!XML11Char.isXML11ValidNCName(oriPrefix)) { + // even though the orignal prefix is ignored, it should still get checked for valid NCName + runTimeError(INVALID_QNAME_ERR,oriPrefix+":"+localName); } + } + + // prefix must be a valid NCName + if (!XML11Char.isXML11ValidNCName(newPrefix)) { + runTimeError(INVALID_QNAME_ERR,newPrefix+":"+localName); + } + } - // local name must be a valid NCName and must not be XMLNS - if ((!XML11Char.isXML11ValidNCName(localName))||(localName.equals(Constants.XMLNS_PREFIX))) { - runTimeError(INVALID_QNAME_ERR,localName); - } + // local name must be a valid NCName and must not be XMLNS + if ((!XML11Char.isXML11ValidNCName(localName))||(localName.equals(Constants.XMLNS_PREFIX))) { + runTimeError(INVALID_QNAME_ERR,localName); } + } - /** - * Utility function to check if a name is a valid ncname - * This method should only be invoked if the attribute value is an AVT - */ - public static void checkNCName(String name) { - if (!XML11Char.isXML11ValidNCName(name)) { - runTimeError(INVALID_NCNAME_ERR,name); - } - } - - /** - * Utility function to check if a name is a valid qname - * This method should only be invoked if the attribute value is an AVT - */ - public static void checkQName(String name) { - if (!XML11Char.isXML11ValidQName(name)) { - runTimeError(INVALID_QNAME_ERR,name); - } - } + /** + * Utility function to check if a name is a valid ncname + * This method should only be invoked if the attribute value is an AVT + */ + public static void checkNCName(String name) { + if (!XML11Char.isXML11ValidNCName(name)) { + runTimeError(INVALID_NCNAME_ERR,name); + } + } + + /** + * Utility function to check if a name is a valid qname + * This method should only be invoked if the attribute value is an AVT + */ + public static void checkQName(String name) { + if (!XML11Char.isXML11ValidQName(name)) { + runTimeError(INVALID_QNAME_ERR,name); + } + } - /** - * Utility function for the implementation of xsl:element. - */ - public static String startXslElement(String qname, String namespace, - SerializationHandler handler, DOM dom, int node) + /** + * Utility function for the implementation of xsl:element. + */ + public static String startXslElement(String qname, String namespace, + SerializationHandler handler, DOM dom, int node) { - try { - // Get prefix from qname - String prefix; - final int index = qname.indexOf(':'); + try { + // Get prefix from qname + String prefix; + final int index = qname.indexOf(':'); - if (index > 0) { - prefix = qname.substring(0, index); + if (index > 0) { + prefix = qname.substring(0, index); - // Handle case when prefix is not known at compile time - if (namespace == null || namespace.length() == 0) { - runTimeError(NAMESPACE_PREFIX_ERR,prefix); - } + // Handle case when prefix is not known at compile time + if (namespace == null || namespace.length() == 0) { + runTimeError(NAMESPACE_PREFIX_ERR,prefix); + } - handler.startElement(namespace, qname.substring(index+1), - qname); - handler.namespaceAfterStartElement(prefix, namespace); - } - else { - // Need to generate a prefix? - if (namespace != null && namespace.length() > 0) { - prefix = generatePrefix(); - qname = prefix + ':' + qname; - handler.startElement(namespace, qname, qname); - handler.namespaceAfterStartElement(prefix, namespace); - } - else { - handler.startElement(null, null, qname); - } - } + handler.startElement(namespace, qname.substring(index+1), + qname); + handler.namespaceAfterStartElement(prefix, namespace); } - catch (SAXException e) { - throw new RuntimeException(e.getMessage()); + else { + // Need to generate a prefix? + if (namespace != null && namespace.length() > 0) { + prefix = generatePrefix(namespace); + qname = prefix + ':' + qname; + handler.startElement(namespace, qname, qname); + handler.namespaceAfterStartElement(prefix, namespace); + } + else { + handler.startElement(null, null, qname); + } } + } + catch (SAXException e) { + throw new RuntimeException(e.getMessage()); + } - return qname; + return qname; } - /** - *

Look up the namespace for a lexical QName using the namespace - * declarations available at a particular location in the stylesheet.

- *

See {@link org.apache.xalan.xsltc.compiler.Stylesheet#compileStaticInitializer(org.apache.xalan.xsltc.compiler.util.ClassGenerator)} - * for more information about the ancestorNodeIDs, - * prefixURIsIndex and prefixURIPairs - * - * @param lexicalQName The QName as a java.lang.String - * @param stylesheetNodeID An int representing the element in - * the stylesheet relative to which the namespace of - * the lexical QName is to be determined - * @param ancestorNodeIDs An int array, indexed by stylesheet - * node IDs, containing the ID of the nearest ancestor - * node in the stylesheet that has namespace - * declarations, or -1 if there is no - * such ancestor - * @param prefixURIsIndex An int array, indexed by stylesheet - * node IDs, containing the index into the - * prefixURIPairs array of the first - * prefix declared on that stylesheet node - * @param prefixURIPairs A java.lang.String array that contains - * pairs of - * @param ignoreDefault A boolean indicating whether any - * default namespace decarlation should be considered - * @return The namespace of the lexical QName or a zero-length string if - * the QName is in no namespace or no namespace declaration for the - * prefix of the QName was found - */ - public static String lookupStylesheetQNameNamespace(String lexicalQName, - int stylesheetNodeID, - int[] ancestorNodeIDs, - int[] prefixURIsIndex, - String[] prefixURIPairs, - boolean ignoreDefault) { - String prefix = getPrefix(lexicalQName); - String uri = ""; - - if (prefix == null && !ignoreDefault) { - prefix = ""; + /** + *

Look up the namespace for a lexical QName using the namespace + * declarations available at a particular location in the stylesheet.

+ *

See {@link org.apache.xalan.xsltc.compiler.Stylesheet#compileStaticInitializer(org.apache.xalan.xsltc.compiler.util.ClassGenerator)} + * for more information about the ancestorNodeIDs, + * prefixURIsIndex and prefixURIPairs + * + * @param lexicalQName The QName as a java.lang.String + * @param stylesheetNodeID An int representing the element in + * the stylesheet relative to which the namespace of + * the lexical QName is to be determined + * @param ancestorNodeIDs An int array, indexed by stylesheet + * node IDs, containing the ID of the nearest ancestor + * node in the stylesheet that has namespace + * declarations, or -1 if there is no + * such ancestor + * @param prefixURIsIndex An int array, indexed by stylesheet + * node IDs, containing the index into the + * prefixURIPairs array of the first + * prefix declared on that stylesheet node + * @param prefixURIPairs A java.lang.String array that contains + * pairs of + * @param ignoreDefault A boolean indicating whether any + * default namespace decarlation should be considered + * @return The namespace of the lexical QName or a zero-length string if + * the QName is in no namespace or no namespace declaration for the + * prefix of the QName was found + */ + public static String lookupStylesheetQNameNamespace(String lexicalQName, + int stylesheetNodeID, + int[] ancestorNodeIDs, + int[] prefixURIsIndex, + String[] prefixURIPairs, + boolean ignoreDefault) { + String prefix = getPrefix(lexicalQName); + String uri = ""; + + if (prefix == null && !ignoreDefault) { + prefix = ""; + } + + if (prefix != null) { + // Loop from current node in the stylesheet to its ancestors + nodeLoop: + for (int currentNodeID = stylesheetNodeID; + currentNodeID >= 0; + currentNodeID = ancestorNodeIDs[currentNodeID]) { + // Look at all declarations on the current stylesheet node + // The prefixURIsIndex is an array of indices into the + // prefixURIPairs array that are stored in ascending order. + // The declarations for a node I are in elements + // prefixURIsIndex[I] to prefixURIsIndex[I+1]-1 (or + // prefixURIPairs.length-1 if I is the last node) + int prefixStartIdx = prefixURIsIndex[currentNodeID]; + int prefixLimitIdx = (currentNodeID+1 < prefixURIsIndex.length) + ? prefixURIsIndex[currentNodeID + 1] + : prefixURIPairs.length; + + for (int prefixIdx = prefixStartIdx; + prefixIdx < prefixLimitIdx; + prefixIdx = prefixIdx + 2) { + // Did we find the declaration of our prefix + if (prefix.equals(prefixURIPairs[prefixIdx])) { + uri = prefixURIPairs[prefixIdx+1]; + break nodeLoop; + } } - - if (prefix != null) { - // Loop from current node in the stylesheet to its ancestors - nodeLoop: - for (int currentNodeID = stylesheetNodeID; - currentNodeID >= 0; - currentNodeID = ancestorNodeIDs[currentNodeID]) { - // Look at all declarations on the current stylesheet node - // The prefixURIsIndex is an array of indices into the - // prefixURIPairs array that are stored in ascending order. - // The declarations for a node I are in elements - // prefixURIsIndex[I] to prefixURIsIndex[I+1]-1 (or - // prefixURIPairs.length-1 if I is the last node) - int prefixStartIdx = prefixURIsIndex[currentNodeID]; - int prefixLimitIdx = (currentNodeID+1 < prefixURIsIndex.length) - ? prefixURIsIndex[currentNodeID + 1] - : prefixURIPairs.length; - - for (int prefixIdx = prefixStartIdx; - prefixIdx < prefixLimitIdx; - prefixIdx = prefixIdx + 2) { - // Did we find the declaration of our prefix - if (prefix.equals(prefixURIPairs[prefixIdx])) { - uri = prefixURIPairs[prefixIdx+1]; - break nodeLoop; - } - } - } - } - - return uri; - } - - /** - *

Look up the namespace for a lexical QName using the namespace - * declarations available at a particular location in the stylesheet and - * return the expanded QName

- *

See {@link org.apache.xalan.xsltc.compiler.Stylesheet#compileStaticInitializer(org.apache.xalan.xsltc.compiler.util.ClassGenerator)} - * for more information about the ancestorNodeIDs, - * prefixURIsIndex and prefixURIPairs - * - * @param lexicalQName The QName as a java.lang.String - * @param stylesheetNodeID An int representing the element in - * the stylesheet relative to which the namespace of - * the lexical QName is to be determined - * @param ancestorNodeIDs An int array, indexed by stylesheet - * node IDs, containing the ID of the nearest ancestor - * node in the stylesheet that has namespace - * declarations, or -1 if there is no - * such ancestor - * @param prefixURIsIndex An int array, indexed by stylesheet - * node IDs, containing the index into the - * prefixURIPairs array of the first - * prefix declared on that stylesheet node - * @param prefixURIPairs A java.lang.String array that contains - * pairs of - * @param ignoreDefault A boolean indicating whether any - * default namespace decarlation should be considered - * @return The expanded QName in the form "uri:localName" or just - * "localName" if the QName is in no namespace or no namespace - * declaration for the prefix of the QName was found - */ - public static String expandStylesheetQNameRef(String lexicalQName, - int stylesheetNodeID, - int[] ancestorNodeIDs, - int[] prefixURIsIndex, - String[] prefixURIPairs, - boolean ignoreDefault) { - String expandedQName; - String prefix = getPrefix(lexicalQName); - String localName = (prefix != null) - ? lexicalQName.substring(prefix.length()+1) - : lexicalQName; - String uri = lookupStylesheetQNameNamespace(lexicalQName, - stylesheetNodeID, - ancestorNodeIDs, - prefixURIsIndex, - prefixURIPairs, - ignoreDefault); - - // Handle case when prefix is not resolved - if (prefix != null && prefix.length() != 0 - && (uri == null || uri.length() == 0)) { - runTimeError(NAMESPACE_PREFIX_ERR, prefix); - } - - if (uri.length() == 0) { - expandedQName = localName; - } else { - expandedQName = uri + ':' + localName; - } - - return expandedQName; - } - - /** - * This function is used in the execution of xsl:element - */ - public static String getPrefix(String qname) { - final int index = qname.indexOf(':'); - return (index > 0) ? qname.substring(0, index) : null; - } - - /** - * This function is used in the execution of xsl:element - */ - private static int prefixIndex = 0; // not thread safe!! - public static String generatePrefix() { - return ("ns" + prefixIndex++); - } - - public static final String RUN_TIME_INTERNAL_ERR = - "RUN_TIME_INTERNAL_ERR"; - public static final String RUN_TIME_COPY_ERR = - "RUN_TIME_COPY_ERR"; - public static final String DATA_CONVERSION_ERR = - "DATA_CONVERSION_ERR"; - public static final String EXTERNAL_FUNC_ERR = - "EXTERNAL_FUNC_ERR"; - public static final String EQUALITY_EXPR_ERR = - "EQUALITY_EXPR_ERR"; - public static final String INVALID_ARGUMENT_ERR = - "INVALID_ARGUMENT_ERR"; - public static final String FORMAT_NUMBER_ERR = - "FORMAT_NUMBER_ERR"; - public static final String ITERATOR_CLONE_ERR = - "ITERATOR_CLONE_ERR"; - public static final String AXIS_SUPPORT_ERR = - "AXIS_SUPPORT_ERR"; - public static final String TYPED_AXIS_SUPPORT_ERR = - "TYPED_AXIS_SUPPORT_ERR"; - public static final String STRAY_ATTRIBUTE_ERR = - "STRAY_ATTRIBUTE_ERR"; - public static final String STRAY_NAMESPACE_ERR = - "STRAY_NAMESPACE_ERR"; - public static final String NAMESPACE_PREFIX_ERR = - "NAMESPACE_PREFIX_ERR"; - public static final String DOM_ADAPTER_INIT_ERR = - "DOM_ADAPTER_INIT_ERR"; - public static final String PARSER_DTD_SUPPORT_ERR = - "PARSER_DTD_SUPPORT_ERR"; - public static final String NAMESPACES_SUPPORT_ERR = - "NAMESPACES_SUPPORT_ERR"; - public static final String CANT_RESOLVE_RELATIVE_URI_ERR = - "CANT_RESOLVE_RELATIVE_URI_ERR"; - public static final String UNSUPPORTED_XSL_ERR = - "UNSUPPORTED_XSL_ERR"; - public static final String UNSUPPORTED_EXT_ERR = - "UNSUPPORTED_EXT_ERR"; - public static final String UNKNOWN_TRANSLET_VERSION_ERR = - "UNKNOWN_TRANSLET_VERSION_ERR"; - public static final String INVALID_QNAME_ERR = "INVALID_QNAME_ERR"; - public static final String INVALID_NCNAME_ERR = "INVALID_NCNAME_ERR"; - public static final String UNALLOWED_EXTENSION_FUNCTION_ERR = "UNALLOWED_EXTENSION_FUNCTION_ERR"; - public static final String UNALLOWED_EXTENSION_ELEMENT_ERR = "UNALLOWED_EXTENSION_ELEMENT_ERR"; - - // All error messages are localized and are stored in resource bundles. - private static ResourceBundle m_bundle; + } + } + + return uri; + } + + /** + *

Look up the namespace for a lexical QName using the namespace + * declarations available at a particular location in the stylesheet and + * return the expanded QName

+ *

See {@link org.apache.xalan.xsltc.compiler.Stylesheet#compileStaticInitializer(org.apache.xalan.xsltc.compiler.util.ClassGenerator)} + * for more information about the ancestorNodeIDs, + * prefixURIsIndex and prefixURIPairs + * + * @param lexicalQName The QName as a java.lang.String + * @param stylesheetNodeID An int representing the element in + * the stylesheet relative to which the namespace of + * the lexical QName is to be determined + * @param ancestorNodeIDs An int array, indexed by stylesheet + * node IDs, containing the ID of the nearest ancestor + * node in the stylesheet that has namespace + * declarations, or -1 if there is no + * such ancestor + * @param prefixURIsIndex An int array, indexed by stylesheet + * node IDs, containing the index into the + * prefixURIPairs array of the first + * prefix declared on that stylesheet node + * @param prefixURIPairs A java.lang.String array that contains + * pairs of + * @param ignoreDefault A boolean indicating whether any + * default namespace decarlation should be considered + * @return The expanded QName in the form "uri:localName" or just + * "localName" if the QName is in no namespace or no namespace + * declaration for the prefix of the QName was found + */ + public static String expandStylesheetQNameRef(String lexicalQName, + int stylesheetNodeID, + int[] ancestorNodeIDs, + int[] prefixURIsIndex, + String[] prefixURIPairs, + boolean ignoreDefault) { + String expandedQName; + String prefix = getPrefix(lexicalQName); + String localName = (prefix != null) + ? lexicalQName.substring(prefix.length()+1) + : lexicalQName; + String uri = lookupStylesheetQNameNamespace(lexicalQName, + stylesheetNodeID, + ancestorNodeIDs, + prefixURIsIndex, + prefixURIPairs, + ignoreDefault); + + // Handle case when prefix is not resolved + if (prefix != null && prefix.length() != 0 + && (uri == null || uri.length() == 0)) { + runTimeError(NAMESPACE_PREFIX_ERR, prefix); + } + + if (uri.length() == 0) { + expandedQName = localName; + } else { + expandedQName = uri + ':' + localName; + } + + return expandedQName; + } + + /** + * This function is used in the execution of xsl:element + */ + public static String getPrefix(String qname) { + final int index = qname.indexOf(':'); + return (index > 0) ? qname.substring(0, index) : null; + } + + /** + * This function is used in the execution of xsl:element + */ + private static int prefixIndex = 0; // not thread safe!! + private static Map nsMap = Collections.synchronizedMap(new HashMap()); + public static String generatePrefix() { + return ("ns" + prefixIndex++); + } + // This will record a new prefix used globally by XSLTC + // it *shouldn't be used anymore, but there might still be an edge case + public static String generatePrefix(String namespace) { + if(nsMap.containsKey(namespace)){ + return nsMap.get(namespace); + } + else{ + // Create a prefix, add to map and return it + String result = generatePrefix(); + nsMap.put(namespace,result); + return result; + } + } + // This will record a new prefix (if there isn't one already) + // and add it to the qname if it doesn't already have a prefix. + // This stores the new prefix in the map belonging to the translet + // so we don't leak prefix between separate translets. + public static String addPrefix(String qname, String namespace, Map prefixMap){ + // if it already has a prefix we don't need to do anything + if(qname.indexOf(':') == -1){ + if(prefixMap.containsKey(namespace)){ + return prefixMap.get(namespace)+":"+qname; + } + else{ + String prefix = "ns"+prefixMap.size(); + prefixMap.put(namespace,prefix); + return prefix+":"+qname; + } + } + else{ + return qname; + } + } + + public static final String RUN_TIME_INTERNAL_ERR = + "RUN_TIME_INTERNAL_ERR"; + public static final String RUN_TIME_COPY_ERR = + "RUN_TIME_COPY_ERR"; + public static final String DATA_CONVERSION_ERR = + "DATA_CONVERSION_ERR"; + public static final String EXTERNAL_FUNC_ERR = + "EXTERNAL_FUNC_ERR"; + public static final String EQUALITY_EXPR_ERR = + "EQUALITY_EXPR_ERR"; + public static final String INVALID_ARGUMENT_ERR = + "INVALID_ARGUMENT_ERR"; + public static final String FORMAT_NUMBER_ERR = + "FORMAT_NUMBER_ERR"; + public static final String ITERATOR_CLONE_ERR = + "ITERATOR_CLONE_ERR"; + public static final String AXIS_SUPPORT_ERR = + "AXIS_SUPPORT_ERR"; + public static final String TYPED_AXIS_SUPPORT_ERR = + "TYPED_AXIS_SUPPORT_ERR"; + public static final String STRAY_ATTRIBUTE_ERR = + "STRAY_ATTRIBUTE_ERR"; + public static final String STRAY_NAMESPACE_ERR = + "STRAY_NAMESPACE_ERR"; + public static final String NAMESPACE_PREFIX_ERR = + "NAMESPACE_PREFIX_ERR"; + public static final String DOM_ADAPTER_INIT_ERR = + "DOM_ADAPTER_INIT_ERR"; + public static final String PARSER_DTD_SUPPORT_ERR = + "PARSER_DTD_SUPPORT_ERR"; + public static final String NAMESPACES_SUPPORT_ERR = + "NAMESPACES_SUPPORT_ERR"; + public static final String CANT_RESOLVE_RELATIVE_URI_ERR = + "CANT_RESOLVE_RELATIVE_URI_ERR"; + public static final String UNSUPPORTED_XSL_ERR = + "UNSUPPORTED_XSL_ERR"; + public static final String UNSUPPORTED_EXT_ERR = + "UNSUPPORTED_EXT_ERR"; + public static final String UNKNOWN_TRANSLET_VERSION_ERR = + "UNKNOWN_TRANSLET_VERSION_ERR"; + public static final String INVALID_QNAME_ERR = "INVALID_QNAME_ERR"; + public static final String INVALID_NCNAME_ERR = "INVALID_NCNAME_ERR"; + public static final String UNALLOWED_EXTENSION_FUNCTION_ERR = "UNALLOWED_EXTENSION_FUNCTION_ERR"; + public static final String UNALLOWED_EXTENSION_ELEMENT_ERR = "UNALLOWED_EXTENSION_ELEMENT_ERR"; + + // All error messages are localized and are stored in resource bundles. + private static ResourceBundle m_bundle; - public final static String ERROR_MESSAGES_KEY = "error-messages"; - - static { - String resource = "org.apache.xalan.xsltc.runtime.ErrorMessages"; - m_bundle = ResourceBundle.getBundle(resource); - } - - /** - * Print a run-time error message. - */ - public static void runTimeError(String code) { - throw new RuntimeException(m_bundle.getString(code)); - } - - public static void runTimeError(String code, Object[] args) { - final String message = MessageFormat.format(m_bundle.getString(code), - args); - throw new RuntimeException(message); - } - - public static void runTimeError(String code, Object arg0) { - runTimeError(code, new Object[]{ arg0 } ); - } - - public static void runTimeError(String code, Object arg0, Object arg1) { - runTimeError(code, new Object[]{ arg0, arg1 } ); - } - - public static void consoleOutput(String msg) { - System.out.println(msg); - } - - /** - * Replace a certain character in a string with a new substring. - */ - public static String replace(String base, char ch, String str) { - return (base.indexOf(ch) < 0) ? base : + public final static String ERROR_MESSAGES_KEY = "error-messages"; + + static { + String resource = "org.apache.xalan.xsltc.runtime.ErrorMessages"; + m_bundle = ResourceBundle.getBundle(resource); + } + + /** + * Print a run-time error message. + */ + public static void runTimeError(String code) { + throw new RuntimeException(m_bundle.getString(code)); + } + + public static void runTimeError(String code, Object[] args) { + final String message = MessageFormat.format(m_bundle.getString(code), + args); + throw new RuntimeException(message); + } + + public static void runTimeError(String code, Object arg0) { + runTimeError(code, new Object[]{ arg0 } ); + } + + public static void runTimeError(String code, Object arg0, Object arg1) { + runTimeError(code, new Object[]{ arg0, arg1 } ); + } + + public static void consoleOutput(String msg) { + System.out.println(msg); + } + + /** + * Replace a certain character in a string with a new substring. + */ + public static String replace(String base, char ch, String str) { + return (base.indexOf(ch) < 0) ? base : replace(base, String.valueOf(ch), new String[] { str }); - } + } - public static String replace(String base, String delim, String[] str) { - final int len = base.length(); - final StringBuffer result = new StringBuffer(); + public static String replace(String base, String delim, String[] str) { + final int len = base.length(); + final StringBuffer result = new StringBuffer(); - for (int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { final char ch = base.charAt(i); final int k = delim.indexOf(ch); if (k >= 0) { - result.append(str[k]); + result.append(str[k]); } else { - result.append(ch); + result.append(ch); } - } - return result.toString(); } + return result.toString(); + } - /** - * Utility method to allow setting parameters of the form - * {namespaceuri}localName - * which get mapped to an instance variable in the class - * Hence a parameter of the form "{http://foo.bar}xyz" - * will be replaced with the corresponding values - * by the BasisLibrary's utility method mapQNametoJavaName - * and thus get mapped to legal java variable names - */ - public static String mapQNameToJavaName (String base ) { - return replace(base, ".-:/{}?#%*", - new String[] { "$dot$", "$dash$" ,"$colon$", "$slash$", - "","$colon$","$ques$","$hash$","$per$", - "$aster$"}); + /** + * Utility method to allow setting parameters of the form + * {namespaceuri}localName + * which get mapped to an instance variable in the class + * Hence a parameter of the form "{http://foo.bar}xyz" + * will be replaced with the corresponding values + * by the BasisLibrary's utility method mapQNametoJavaName + * and thus get mapped to legal java variable names + */ + public static String mapQNameToJavaName (String base ) { + return replace(base, ".-:/{}?#%*", + new String[] { "$dot$", "$dash$" ,"$colon$", "$slash$", + "","$colon$","$ques$","$hash$","$per$", + "$aster$"}); - } + } - //-- End utility functions + //-- End utility functions } From 2580b64aa742844f7a00af33598e115c202f7735 Mon Sep 17 00:00:00 2001 From: Andreas Martens Date: Fri, 27 Sep 2024 16:54:32 +0100 Subject: [PATCH 2/2] put crazy indentation back --- .../xalan/xsltc/compiler/Constants.java | 595 ++-- .../xalan/xsltc/compiler/Stylesheet.java | 2354 +++++++-------- .../xalan/xsltc/compiler/XslElement.java | 490 +-- .../xalan/xsltc/runtime/BasisLibrary.java | 2640 ++++++++--------- 4 files changed, 3040 insertions(+), 3039 deletions(-) diff --git a/xalan/src/main/java/org/apache/xalan/xsltc/compiler/Constants.java b/xalan/src/main/java/org/apache/xalan/xsltc/compiler/Constants.java index f671dc65a..0b6da35bc 100644 --- a/xalan/src/main/java/org/apache/xalan/xsltc/compiler/Constants.java +++ b/xalan/src/main/java/org/apache/xalan/xsltc/compiler/Constants.java @@ -30,519 +30,520 @@ */ public interface Constants extends InstructionConstants { - // Error categories used to report errors to Parser.reportError() - - // Unexpected internal errors, such as null-ptr exceptions, etc. - // Immediately terminates compilation, no translet produced - public final int INTERNAL = 0; - // XSLT elements that are not implemented and unsupported ext. - // Immediately terminates compilation, no translet produced - public final int UNSUPPORTED = 1; - // Fatal error in the stylesheet input (parsing or content) - // Immediately terminates compilation, no translet produced - public final int FATAL = 2; - // Other error in the stylesheet input (parsing or content) - // Does not terminate compilation, no translet produced - public final int ERROR = 3; - // Other error in the stylesheet input (content errors only) - // Does not terminate compilation, a translet is produced - public final int WARNING = 4; - - public static final String EMPTYSTRING = ""; - - public static final String NAMESPACE_FEATURE = - "http://xml.org/sax/features/namespaces"; - - public static final String TRANSLET_INTF + // Error categories used to report errors to Parser.reportError() + + // Unexpected internal errors, such as null-ptr exceptions, etc. + // Immediately terminates compilation, no translet produced + public final int INTERNAL = 0; + // XSLT elements that are not implemented and unsupported ext. + // Immediately terminates compilation, no translet produced + public final int UNSUPPORTED = 1; + // Fatal error in the stylesheet input (parsing or content) + // Immediately terminates compilation, no translet produced + public final int FATAL = 2; + // Other error in the stylesheet input (parsing or content) + // Does not terminate compilation, no translet produced + public final int ERROR = 3; + // Other error in the stylesheet input (content errors only) + // Does not terminate compilation, a translet is produced + public final int WARNING = 4; + + public static final String EMPTYSTRING = ""; + + public static final String NAMESPACE_FEATURE = + "http://xml.org/sax/features/namespaces"; + + public static final String TRANSLET_INTF = "org.apache.xalan.xsltc.Translet"; - public static final String TRANSLET_INTF_SIG + public static final String TRANSLET_INTF_SIG = "Lorg/apache/xalan/xsltc/Translet;"; - public static final String ATTRIBUTES_SIG + public static final String ATTRIBUTES_SIG = "Lorg/apache/xalan/xsltc/runtime/Attributes;"; - public static final String NODE_ITERATOR_SIG + public static final String NODE_ITERATOR_SIG = "Lorg/apache/xml/dtm/DTMAxisIterator;"; - public static final String DOM_INTF_SIG + public static final String DOM_INTF_SIG = "Lorg/apache/xalan/xsltc/DOM;"; - public static final String DOM_IMPL_CLASS + public static final String DOM_IMPL_CLASS = "org/apache/xalan/xsltc/DOM"; // xml/dtm/ref/DTMDefaultBaseIterators"; //xalan/xsltc/dom/DOMImpl"; public static final String SAX_IMPL_CLASS = "org/apache/xalan/xsltc/DOM/SAXImpl"; - public static final String DOM_IMPL_SIG + public static final String DOM_IMPL_SIG = "Lorg/apache/xalan/xsltc/dom/SAXImpl;"; //xml/dtm/ref/DTMDefaultBaseIterators"; //xalan/xsltc/dom/DOMImpl;"; public static final String SAX_IMPL_SIG = "Lorg/apache/xalan/xsltc/dom/SAXImpl;"; - public static final String DOM_ADAPTER_CLASS + public static final String DOM_ADAPTER_CLASS = "org/apache/xalan/xsltc/dom/DOMAdapter"; - public static final String DOM_ADAPTER_SIG + public static final String DOM_ADAPTER_SIG = "Lorg/apache/xalan/xsltc/dom/DOMAdapter;"; - public static final String MULTI_DOM_CLASS + public static final String MULTI_DOM_CLASS = "org.apache.xalan.xsltc.dom.MultiDOM"; - public static final String MULTI_DOM_SIG + public static final String MULTI_DOM_SIG = "Lorg/apache/xalan/xsltc/dom/MultiDOM;"; - public static final String STRING + public static final String STRING = "java.lang.String"; - public static final int ACC_PUBLIC + public static final int ACC_PUBLIC = org.apache.bcel.Constants.ACC_PUBLIC; - public static final int ACC_SUPER + public static final int ACC_SUPER = org.apache.bcel.Constants.ACC_SUPER; - public static final int ACC_FINAL + public static final int ACC_FINAL = org.apache.bcel.Constants.ACC_FINAL; - public static final int ACC_PRIVATE + public static final int ACC_PRIVATE = org.apache.bcel.Constants.ACC_PRIVATE; - public static final int ACC_PROTECTED + public static final int ACC_PROTECTED = org.apache.bcel.Constants.ACC_PROTECTED; - public static final int ACC_STATIC + public static final int ACC_STATIC = org.apache.bcel.Constants.ACC_STATIC; - public static final String STRING_SIG + public static final String STRING_SIG = "Ljava/lang/String;"; - public static final String STRING_BUFFER_SIG + public static final String STRING_BUFFER_SIG = "Ljava/lang/StringBuffer;"; - public static final String OBJECT_SIG + public static final String OBJECT_SIG = "Ljava/lang/Object;"; - public static final String DOUBLE_SIG + public static final String DOUBLE_SIG = "Ljava/lang/Double;"; - public static final String INTEGER_SIG + public static final String INTEGER_SIG = "Ljava/lang/Integer;"; - public static final String COLLATOR_CLASS - = "java/text/Collator"; - public static final String COLLATOR_SIG - = "Ljava/text/Collator;"; - - public static final String NODE + public static final String COLLATOR_CLASS + = "java/text/Collator"; + public static final String COLLATOR_SIG + = "Ljava/text/Collator;"; + + public static final String NODE = "int"; - public static final String NODE_ITERATOR + public static final String NODE_ITERATOR = "org.apache.xml.dtm.DTMAxisIterator"; - public static final String NODE_ITERATOR_BASE + public static final String NODE_ITERATOR_BASE = "org.apache.xml.dtm.ref.DTMAxisIteratorBase"; - public static final String SORT_ITERATOR + public static final String SORT_ITERATOR = "org.apache.xalan.xsltc.dom.SortingIterator"; - public static final String SORT_ITERATOR_SIG + public static final String SORT_ITERATOR_SIG = "Lorg.apache.xalan.xsltc.dom.SortingIterator;"; - public static final String NODE_SORT_RECORD + public static final String NODE_SORT_RECORD = "org.apache.xalan.xsltc.dom.NodeSortRecord"; - public static final String NODE_SORT_FACTORY + public static final String NODE_SORT_FACTORY = "org/apache/xalan/xsltc/dom/NodeSortRecordFactory"; - public static final String NODE_SORT_RECORD_SIG + public static final String NODE_SORT_RECORD_SIG = "Lorg/apache/xalan/xsltc/dom/NodeSortRecord;"; - public static final String NODE_SORT_FACTORY_SIG + public static final String NODE_SORT_FACTORY_SIG = "Lorg/apache/xalan/xsltc/dom/NodeSortRecordFactory;"; - public static final String LOCALE_CLASS - = "java.util.Locale"; - public static final String LOCALE_SIG + public static final String LOCALE_CLASS + = "java.util.Locale"; + public static final String LOCALE_SIG = "Ljava/util/Locale;"; - public static final String STRING_VALUE_HANDLER + public static final String STRING_VALUE_HANDLER = "org.apache.xalan.xsltc.runtime.StringValueHandler"; - public static final String STRING_VALUE_HANDLER_SIG + public static final String STRING_VALUE_HANDLER_SIG = "Lorg/apache/xalan/xsltc/runtime/StringValueHandler;"; - public static final String OUTPUT_HANDLER + public static final String OUTPUT_HANDLER = SerializerBase.PKG_PATH+"/SerializationHandler"; - public static final String OUTPUT_HANDLER_SIG + public static final String OUTPUT_HANDLER_SIG = "L"+SerializerBase.PKG_PATH+"/SerializationHandler;"; - public static final String FILTER_INTERFACE + public static final String FILTER_INTERFACE = "org.apache.xalan.xsltc.dom.Filter"; - public static final String FILTER_INTERFACE_SIG + public static final String FILTER_INTERFACE_SIG = "Lorg/apache/xalan/xsltc/dom/Filter;"; - public static final String UNION_ITERATOR_CLASS + public static final String UNION_ITERATOR_CLASS = "org.apache.xalan.xsltc.dom.UnionIterator"; - public static final String STEP_ITERATOR_CLASS + public static final String STEP_ITERATOR_CLASS = "org.apache.xalan.xsltc.dom.StepIterator"; - public static final String CACHED_NODE_LIST_ITERATOR_CLASS + public static final String CACHED_NODE_LIST_ITERATOR_CLASS = "org.apache.xalan.xsltc.dom.CachedNodeListIterator"; - public static final String NTH_ITERATOR_CLASS + public static final String NTH_ITERATOR_CLASS = "org.apache.xalan.xsltc.dom.NthIterator"; - public static final String ABSOLUTE_ITERATOR + public static final String ABSOLUTE_ITERATOR = "org.apache.xalan.xsltc.dom.AbsoluteIterator"; - public static final String DUP_FILTERED_ITERATOR + public static final String DUP_FILTERED_ITERATOR = "org.apache.xalan.xsltc.dom.DupFilterIterator"; - public static final String CURRENT_NODE_LIST_ITERATOR + public static final String CURRENT_NODE_LIST_ITERATOR = "org.apache.xalan.xsltc.dom.CurrentNodeListIterator"; - public static final String CURRENT_NODE_LIST_FILTER + public static final String CURRENT_NODE_LIST_FILTER = "org.apache.xalan.xsltc.dom.CurrentNodeListFilter"; - public static final String CURRENT_NODE_LIST_ITERATOR_SIG + public static final String CURRENT_NODE_LIST_ITERATOR_SIG = "Lorg/apache/xalan/xsltc/dom/CurrentNodeListIterator;"; - public static final String CURRENT_NODE_LIST_FILTER_SIG + public static final String CURRENT_NODE_LIST_FILTER_SIG = "Lorg/apache/xalan/xsltc/dom/CurrentNodeListFilter;"; - public static final String FILTER_STEP_ITERATOR + public static final String FILTER_STEP_ITERATOR = "org.apache.xalan.xsltc.dom.FilteredStepIterator"; - public static final String FILTER_ITERATOR + public static final String FILTER_ITERATOR = "org.apache.xalan.xsltc.dom.FilterIterator"; - public static final String SINGLETON_ITERATOR + public static final String SINGLETON_ITERATOR = "org.apache.xalan.xsltc.dom.SingletonIterator"; - public static final String MATCHING_ITERATOR + public static final String MATCHING_ITERATOR = "org.apache.xalan.xsltc.dom.MatchingIterator"; - public static final String HASHMAP_CLASS = "java.util.HashMap"; - public static final String HASHMAP_SIG = "Ljava/util/HashMap;"; - public static final String MAP_SIG = "Ljava/util/Map;"; + public static final String HASHMAP_CLASS = "java.util.HashMap"; + public static final String HASHMAP_SIG = "Ljava/util/HashMap;"; + public static final String MAP_SIG = "Ljava/util/Map;"; - public static final String NODE_SIG + public static final String NODE_SIG = "I"; - public static final String GET_PARENT + public static final String GET_PARENT = "getParent"; - public static final String GET_PARENT_SIG + public static final String GET_PARENT_SIG = "(" + NODE_SIG + ")" + NODE_SIG; - public static final String NEXT_SIG + public static final String NEXT_SIG = "()" + NODE_SIG; - public static final String NEXT + public static final String NEXT = "next"; public static final String NEXTID = "nextNodeID"; - public static final String MAKE_NODE + public static final String MAKE_NODE = "makeNode"; - public static final String MAKE_NODE_LIST + public static final String MAKE_NODE_LIST = "makeNodeList"; - public static final String GET_UNPARSED_ENTITY_URI - = "getUnparsedEntityURI"; - public static final String STRING_TO_REAL + public static final String GET_UNPARSED_ENTITY_URI + = "getUnparsedEntityURI"; + public static final String STRING_TO_REAL = "stringToReal"; - public static final String STRING_TO_REAL_SIG + public static final String STRING_TO_REAL_SIG = "(" + STRING_SIG + ")D"; - public static final String STRING_TO_INT + public static final String STRING_TO_INT = "stringToInt"; - public static final String STRING_TO_INT_SIG + public static final String STRING_TO_INT_SIG = "(" + STRING_SIG + ")I"; - public static final String XSLT_PACKAGE + public static final String XSLT_PACKAGE = "org.apache.xalan.xsltc"; - public static final String COMPILER_PACKAGE + public static final String COMPILER_PACKAGE = XSLT_PACKAGE + ".compiler"; - public static final String RUNTIME_PACKAGE + public static final String RUNTIME_PACKAGE = XSLT_PACKAGE + ".runtime"; - public static final String TRANSLET_CLASS + public static final String TRANSLET_CLASS = RUNTIME_PACKAGE + ".AbstractTranslet"; - public static final String TRANSLET_SIG + public static final String TRANSLET_SIG = "Lorg/apache/xalan/xsltc/runtime/AbstractTranslet;"; - public static final String UNION_ITERATOR_SIG + public static final String UNION_ITERATOR_SIG = "Lorg/apache/xalan/xsltc/dom/UnionIterator;"; - public static final String TRANSLET_OUTPUT_SIG + public static final String TRANSLET_OUTPUT_SIG = "L"+SerializerBase.PKG_PATH+"/SerializationHandler;"; - public static final String MAKE_NODE_SIG + public static final String MAKE_NODE_SIG = "(I)Lorg/w3c/dom/Node;"; - public static final String MAKE_NODE_SIG2 + public static final String MAKE_NODE_SIG2 = "(" + NODE_ITERATOR_SIG + ")Lorg/w3c/dom/Node;"; - public static final String MAKE_NODE_LIST_SIG + public static final String MAKE_NODE_LIST_SIG = "(I)Lorg/w3c/dom/NodeList;"; - public static final String MAKE_NODE_LIST_SIG2 + public static final String MAKE_NODE_LIST_SIG2 = "(" + NODE_ITERATOR_SIG + ")Lorg/w3c/dom/NodeList;"; - public static final String STREAM_XML_OUTPUT - = SerializerBase.PKG_NAME+".ToXMLStream"; + public static final String STREAM_XML_OUTPUT + = SerializerBase.PKG_NAME+".ToXMLStream"; - public static final String OUTPUT_BASE - = SerializerBase.PKG_NAME+".SerializerBase"; + public static final String OUTPUT_BASE + = SerializerBase.PKG_NAME+".SerializerBase"; - public static final String LOAD_DOCUMENT_CLASS + public static final String LOAD_DOCUMENT_CLASS = "org.apache.xalan.xsltc.dom.LoadDocument"; - public static final String KEY_INDEX_CLASS + public static final String KEY_INDEX_CLASS = "org/apache/xalan/xsltc/dom/KeyIndex"; - public static final String KEY_INDEX_SIG + public static final String KEY_INDEX_SIG = "Lorg/apache/xalan/xsltc/dom/KeyIndex;"; - public static final String KEY_INDEX_ITERATOR_SIG + public static final String KEY_INDEX_ITERATOR_SIG = "Lorg/apache/xalan/xsltc/dom/KeyIndex$KeyIndexIterator;"; - public static final String DOM_INTF + public static final String DOM_INTF = "org.apache.xalan.xsltc.DOM"; - public static final String DOM_IMPL + public static final String DOM_IMPL = "org.apache.xalan.xsltc.dom.SAXImpl"; public static final String SAX_IMPL = "org.apache.xalan.xsltc.dom.SAXImpl"; - public static final String STRING_CLASS + public static final String STRING_CLASS = "java.lang.String"; - public static final String OBJECT_CLASS + public static final String OBJECT_CLASS = "java.lang.Object"; - public static final String BOOLEAN_CLASS + public static final String BOOLEAN_CLASS = "java.lang.Boolean"; - public static final String STRING_BUFFER_CLASS + public static final String STRING_BUFFER_CLASS = "java.lang.StringBuffer"; - public static final String STRING_WRITER - = "java.io.StringWriter"; - public static final String WRITER_SIG - = "Ljava/io/Writer;"; + public static final String STRING_WRITER + = "java.io.StringWriter"; + public static final String WRITER_SIG + = "Ljava/io/Writer;"; - public static final String TRANSLET_OUTPUT_BASE + public static final String TRANSLET_OUTPUT_BASE = "org.apache.xalan.xsltc.TransletOutputBase"; - // output interface - public static final String TRANSLET_OUTPUT_INTERFACE + // output interface + public static final String TRANSLET_OUTPUT_INTERFACE = SerializerBase.PKG_NAME+".SerializationHandler"; - public static final String BASIS_LIBRARY_CLASS + public static final String BASIS_LIBRARY_CLASS = "org.apache.xalan.xsltc.runtime.BasisLibrary"; - public static final String ATTRIBUTE_LIST_IMPL_CLASS + public static final String ATTRIBUTE_LIST_IMPL_CLASS = "org.apache.xalan.xsltc.runtime.AttributeListImpl"; - public static final String DOUBLE_CLASS + public static final String DOUBLE_CLASS = "java.lang.Double"; - public static final String INTEGER_CLASS + public static final String INTEGER_CLASS = "java.lang.Integer"; - public static final String RUNTIME_NODE_CLASS + public static final String RUNTIME_NODE_CLASS = "org.apache.xalan.xsltc.runtime.Node"; - public static final String MATH_CLASS + public static final String MATH_CLASS = "java.lang.Math"; - public static final String BOOLEAN_VALUE + public static final String BOOLEAN_VALUE = "booleanValue"; - public static final String BOOLEAN_VALUE_SIG + public static final String BOOLEAN_VALUE_SIG = "()Z"; - public static final String INT_VALUE + public static final String INT_VALUE = "intValue"; - public static final String INT_VALUE_SIG + public static final String INT_VALUE_SIG = "()I"; - public static final String DOUBLE_VALUE + public static final String DOUBLE_VALUE = "doubleValue"; - public static final String DOUBLE_VALUE_SIG + public static final String DOUBLE_VALUE_SIG = "()D"; - public static final String DOM_PNAME + public static final String DOM_PNAME = "dom"; - public static final String NODE_PNAME + public static final String NODE_PNAME = "node"; - public static final String TRANSLET_OUTPUT_PNAME + public static final String TRANSLET_OUTPUT_PNAME = "handler"; - public static final String ITERATOR_PNAME + public static final String ITERATOR_PNAME = "iterator"; - public static final String DOCUMENT_PNAME + public static final String DOCUMENT_PNAME = "document"; - public static final String TRANSLET_PNAME + public static final String TRANSLET_PNAME = "translet"; - public static final String INVOKE_METHOD + public static final String INVOKE_METHOD = "invokeMethod"; - public static final String GET_NODE_NAME + public static final String GET_NODE_NAME = "getNodeNameX"; - public static final String CHARACTERSW + public static final String CHARACTERSW = "characters"; - public static final String GET_CHILDREN + public static final String GET_CHILDREN = "getChildren"; - public static final String GET_TYPED_CHILDREN + public static final String GET_TYPED_CHILDREN = "getTypedChildren"; - public static final String CHARACTERS + public static final String CHARACTERS = "characters"; - public static final String APPLY_TEMPLATES + public static final String APPLY_TEMPLATES = "applyTemplates"; - public static final String GET_NODE_TYPE + public static final String GET_NODE_TYPE = "getNodeType"; - public static final String GET_NODE_VALUE + public static final String GET_NODE_VALUE = "getStringValueX"; - public static final String GET_ELEMENT_VALUE + public static final String GET_ELEMENT_VALUE = "getElementValue"; - public static final String GET_ATTRIBUTE_VALUE + public static final String GET_ATTRIBUTE_VALUE = "getAttributeValue"; - public static final String HAS_ATTRIBUTE + public static final String HAS_ATTRIBUTE = "hasAttribute"; - public static final String ADD_ITERATOR + public static final String ADD_ITERATOR = "addIterator"; - public static final String SET_START_NODE + public static final String SET_START_NODE = "setStartNode"; - public static final String RESET + public static final String RESET = "reset"; - public static final String ATTR_SET_SIG + public static final String ATTR_SET_SIG = "(" + DOM_INTF_SIG + NODE_ITERATOR_SIG + TRANSLET_OUTPUT_SIG + ")V"; - public static final String GET_NODE_NAME_SIG + public static final String GET_NODE_NAME_SIG = "(" + NODE_SIG + ")" + STRING_SIG; - public static final String CHARACTERSW_SIG + public static final String CHARACTERSW_SIG = "(" + STRING_SIG + TRANSLET_OUTPUT_SIG + ")V"; - public static final String CHARACTERS_SIG + public static final String CHARACTERS_SIG = "(" + NODE_SIG + TRANSLET_OUTPUT_SIG + ")V"; - public static final String GET_CHILDREN_SIG + public static final String GET_CHILDREN_SIG = "(" + NODE_SIG +")" + NODE_ITERATOR_SIG; - public static final String GET_TYPED_CHILDREN_SIG + public static final String GET_TYPED_CHILDREN_SIG = "(I)" + NODE_ITERATOR_SIG; - public static final String GET_NODE_TYPE_SIG + public static final String GET_NODE_TYPE_SIG = "()S"; - public static final String GET_NODE_VALUE_SIG + public static final String GET_NODE_VALUE_SIG = "(I)" + STRING_SIG; - public static final String GET_ELEMENT_VALUE_SIG + public static final String GET_ELEMENT_VALUE_SIG = "(I)" + STRING_SIG; - public static final String GET_ATTRIBUTE_VALUE_SIG + public static final String GET_ATTRIBUTE_VALUE_SIG = "(II)" + STRING_SIG; - public static final String HAS_ATTRIBUTE_SIG + public static final String HAS_ATTRIBUTE_SIG = "(II)Z"; - public static final String GET_ITERATOR_SIG + public static final String GET_ITERATOR_SIG = "()" + NODE_ITERATOR_SIG; - public static final String NAMES_INDEX + public static final String NAMES_INDEX = "namesArray"; - public static final String NAMES_INDEX_SIG + public static final String NAMES_INDEX_SIG = "[" + STRING_SIG; - public static final String URIS_INDEX - = "urisArray"; - public static final String URIS_INDEX_SIG - = "[" + STRING_SIG; - public static final String TYPES_INDEX - = "typesArray"; - public static final String TYPES_INDEX_SIG - = "[I"; - public static final String NAMESPACE_INDEX + public static final String URIS_INDEX + = "urisArray"; + public static final String URIS_INDEX_SIG + = "[" + STRING_SIG; + public static final String TYPES_INDEX + = "typesArray"; + public static final String TYPES_INDEX_SIG + = "[I"; + public static final String NAMESPACE_INDEX = "namespaceArray"; - public static final String NAMESPACE_INDEX_SIG + public static final String NAMESPACE_INDEX_SIG = "[" + STRING_SIG; - public static final String NS_ANCESTORS_INDEX_SIG - = "[I"; - public static final String PREFIX_URIS_IDX_SIG - = "[I"; - public static final String PREFIX_URIS_ARRAY_SIG - = "[" + STRING_SIG; - public static final String HASIDCALL_INDEX - = "_hasIdCall"; - public static final String HASIDCALL_INDEX_SIG - = "Z"; - public static final String TRANSLET_VERSION_INDEX - = "transletVersion"; - public static final String TRANSLET_VERSION_INDEX_SIG - = "I"; - public static final String LOOKUP_STYLESHEET_QNAME_NS_REF - = "lookupStylesheetQNameNamespace"; - public static final String LOOKUP_STYLESHEET_QNAME_NS_SIG - = "(" + STRING_SIG - + "I" - + NS_ANCESTORS_INDEX_SIG - + PREFIX_URIS_IDX_SIG - + PREFIX_URIS_ARRAY_SIG - + "Z)" + STRING_SIG; - public static final String EXPAND_STYLESHEET_QNAME_REF - = "expandStylesheetQNameRef"; - public static final String EXPAND_STYLESHEET_QNAME_SIG - = "(" + STRING_SIG - + "I" - + NS_ANCESTORS_INDEX_SIG - + PREFIX_URIS_IDX_SIG - + PREFIX_URIS_ARRAY_SIG - + "Z)" + STRING_SIG; - public static final String ADD_NAMESPACE_PREFIX_REF - = "addPrefix"; - public static final String ADD_NAMESPACE_PREFIX_SIG - = "(" + STRING_SIG - + STRING_SIG - + "Ljava/util/Map;"+ - ")" + STRING_SIG; - public static final String DOM_FIELD + public static final String NS_ANCESTORS_INDEX_SIG + = "[I"; + public static final String PREFIX_URIS_IDX_SIG + = "[I"; + public static final String PREFIX_URIS_ARRAY_SIG + = "[" + STRING_SIG; + public static final String HASIDCALL_INDEX + = "_hasIdCall"; + public static final String HASIDCALL_INDEX_SIG + = "Z"; + public static final String TRANSLET_VERSION_INDEX + = "transletVersion"; + public static final String TRANSLET_VERSION_INDEX_SIG + = "I"; + public static final String LOOKUP_STYLESHEET_QNAME_NS_REF + = "lookupStylesheetQNameNamespace"; + public static final String LOOKUP_STYLESHEET_QNAME_NS_SIG + = "(" + STRING_SIG + + "I" + + NS_ANCESTORS_INDEX_SIG + + PREFIX_URIS_IDX_SIG + + PREFIX_URIS_ARRAY_SIG + + "Z)" + STRING_SIG; + public static final String EXPAND_STYLESHEET_QNAME_REF + = "expandStylesheetQNameRef"; + public static final String EXPAND_STYLESHEET_QNAME_SIG + = "(" + STRING_SIG + + "I" + + NS_ANCESTORS_INDEX_SIG + + PREFIX_URIS_IDX_SIG + + PREFIX_URIS_ARRAY_SIG + + "Z)" + STRING_SIG; + public static final String ADD_NAMESPACE_PREFIX_REF + = "addPrefix"; + public static final String ADD_NAMESPACE_PREFIX_SIG + = "(" + STRING_SIG + + STRING_SIG + + "Ljava/util/Map;"+ + ")" + STRING_SIG; + + public static final String DOM_FIELD = "_dom"; - public static final String STATIC_NAMES_ARRAY_FIELD - = "_sNamesArray"; - public static final String STATIC_URIS_ARRAY_FIELD - = "_sUrisArray"; - public static final String STATIC_TYPES_ARRAY_FIELD - = "_sTypesArray"; - public static final String STATIC_NAMESPACE_ARRAY_FIELD - = "_sNamespaceArray"; - public static final String STATIC_NS_ANCESTORS_ARRAY_FIELD - = "_sNamespaceAncestorsArray"; - public static final String STATIC_PREFIX_URIS_IDX_ARRAY_FIELD - = "_sPrefixURIsIdxArray"; - public static final String STATIC_PREFIX_URIS_ARRAY_FIELD - = "_sPrefixURIPairsArray"; - public static final String STATIC_CHAR_DATA_FIELD - = "_scharData"; - public static final String STATIC_CHAR_DATA_FIELD_SIG - = "[C"; - public static final String STATIC_NS_MAP_FIELD = "_sNamespaceMap"; - public static final String FORMAT_SYMBOLS_FIELD + public static final String STATIC_NAMES_ARRAY_FIELD + = "_sNamesArray"; + public static final String STATIC_URIS_ARRAY_FIELD + = "_sUrisArray"; + public static final String STATIC_TYPES_ARRAY_FIELD + = "_sTypesArray"; + public static final String STATIC_NAMESPACE_ARRAY_FIELD + = "_sNamespaceArray"; + public static final String STATIC_NS_ANCESTORS_ARRAY_FIELD + = "_sNamespaceAncestorsArray"; + public static final String STATIC_PREFIX_URIS_IDX_ARRAY_FIELD + = "_sPrefixURIsIdxArray"; + public static final String STATIC_PREFIX_URIS_ARRAY_FIELD + = "_sPrefixURIPairsArray"; + public static final String STATIC_CHAR_DATA_FIELD + = "_scharData"; + public static final String STATIC_CHAR_DATA_FIELD_SIG + = "[C"; + public static final String STATIC_NS_MAP_FIELD = "_sNamespaceMap"; + public static final String FORMAT_SYMBOLS_FIELD = "format_symbols"; - public static final String ITERATOR_FIELD_SIG + public static final String ITERATOR_FIELD_SIG = NODE_ITERATOR_SIG; - public static final String NODE_FIELD + public static final String NODE_FIELD = "node"; - public static final String NODE_FIELD_SIG + public static final String NODE_FIELD_SIG = "I"; - public static final String EMPTYATTR_FIELD + public static final String EMPTYATTR_FIELD = "EmptyAttributes"; - public static final String ATTRIBUTE_LIST_FIELD + public static final String ATTRIBUTE_LIST_FIELD = "attributeList"; - public static final String CLEAR_ATTRIBUTES + public static final String CLEAR_ATTRIBUTES = "clear"; - public static final String ADD_ATTRIBUTE + public static final String ADD_ATTRIBUTE = "addAttribute"; - public static final String ATTRIBUTE_LIST_IMPL_SIG + public static final String ATTRIBUTE_LIST_IMPL_SIG = "Lorg/apache/xalan/xsltc/runtime/AttributeListImpl;"; - public static final String CLEAR_ATTRIBUTES_SIG + public static final String CLEAR_ATTRIBUTES_SIG = "()" + ATTRIBUTE_LIST_IMPL_SIG; - public static final String ADD_ATTRIBUTE_SIG + public static final String ADD_ATTRIBUTE_SIG = "(" + STRING_SIG + STRING_SIG + ")" + ATTRIBUTE_LIST_IMPL_SIG; - public static final String ADD_ITERATOR_SIG + public static final String ADD_ITERATOR_SIG = "(" + NODE_ITERATOR_SIG +")" + UNION_ITERATOR_SIG; - public static final String ORDER_ITERATOR + public static final String ORDER_ITERATOR = "orderNodes"; - public static final String ORDER_ITERATOR_SIG + public static final String ORDER_ITERATOR_SIG = "("+NODE_ITERATOR_SIG+"I)"+NODE_ITERATOR_SIG; - public static final String SET_START_NODE_SIG + public static final String SET_START_NODE_SIG = "(" + NODE_SIG + ")" + NODE_ITERATOR_SIG; - public static final String NODE_COUNTER + public static final String NODE_COUNTER = "org.apache.xalan.xsltc.dom.NodeCounter"; - public static final String NODE_COUNTER_SIG + public static final String NODE_COUNTER_SIG = "Lorg/apache/xalan/xsltc/dom/NodeCounter;"; - public static final String DEFAULT_NODE_COUNTER + public static final String DEFAULT_NODE_COUNTER = "org.apache.xalan.xsltc.dom.DefaultNodeCounter"; - public static final String DEFAULT_NODE_COUNTER_SIG + public static final String DEFAULT_NODE_COUNTER_SIG = "Lorg/apache/xalan/xsltc/dom/DefaultNodeCounter;"; - public static final String TRANSLET_FIELD + public static final String TRANSLET_FIELD = "translet"; - public static final String TRANSLET_FIELD_SIG + public static final String TRANSLET_FIELD_SIG = TRANSLET_SIG; - public static final String RESET_SIG + public static final String RESET_SIG = "()" + NODE_ITERATOR_SIG; - public static final String GET_PARAMETER + public static final String GET_PARAMETER = "getParameter"; - public static final String ADD_PARAMETER + public static final String ADD_PARAMETER = "addParameter"; - public static final String PUSH_PARAM_FRAME + public static final String PUSH_PARAM_FRAME = "pushParamFrame"; - public static final String PUSH_PARAM_FRAME_SIG + public static final String PUSH_PARAM_FRAME_SIG = "()V"; - public static final String POP_PARAM_FRAME + public static final String POP_PARAM_FRAME = "popParamFrame"; - public static final String POP_PARAM_FRAME_SIG + public static final String POP_PARAM_FRAME_SIG = "()V"; - public static final String GET_PARAMETER_SIG + public static final String GET_PARAMETER_SIG = "(" + STRING_SIG + ")" + OBJECT_SIG; - public static final String ADD_PARAMETER_SIG + public static final String ADD_PARAMETER_SIG = "(" + STRING_SIG + OBJECT_SIG + "Z)" + OBJECT_SIG; - public static final String STRIP_SPACE + public static final String STRIP_SPACE = "stripSpace"; - public static final String STRIP_SPACE_INTF + public static final String STRIP_SPACE_INTF = "org/apache/xalan/xsltc/StripFilter"; - public static final String STRIP_SPACE_SIG + public static final String STRIP_SPACE_SIG = "Lorg/apache/xalan/xsltc/StripFilter;"; - public static final String STRIP_SPACE_PARAMS + public static final String STRIP_SPACE_PARAMS = "(Lorg/apache/xalan/xsltc/DOM;II)Z"; - public static final String GET_NODE_VALUE_ITERATOR + public static final String GET_NODE_VALUE_ITERATOR = "getNodeValueIterator"; - public static final String GET_NODE_VALUE_ITERATOR_SIG + public static final String GET_NODE_VALUE_ITERATOR_SIG = "("+NODE_ITERATOR_SIG+"I"+STRING_SIG+"Z)"+NODE_ITERATOR_SIG; - public static final String GET_UNPARSED_ENTITY_URI_SIG - = "("+STRING_SIG+")"+STRING_SIG; + public static final String GET_UNPARSED_ENTITY_URI_SIG + = "("+STRING_SIG+")"+STRING_SIG; - public static final int POSITION_INDEX = 2; - public static final int LAST_INDEX = 3; + public static final int POSITION_INDEX = 2; + public static final int LAST_INDEX = 3; - public static final String XMLNS_PREFIX = "xmlns"; - public static final String XMLNS_STRING = "xmlns:"; - public static final String XMLNS_URI + public static final String XMLNS_PREFIX = "xmlns"; + public static final String XMLNS_STRING = "xmlns:"; + public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/"; - public static final String XSLT_URI + public static final String XSLT_URI = "http://www.w3.org/1999/XSL/Transform"; - public static final String XHTML_URI + public static final String XHTML_URI = "http://www.w3.org/1999/xhtml"; - public static final String TRANSLET_URI + public static final String TRANSLET_URI = "http://xml.apache.org/xalan/xsltc"; - public static final String REDIRECT_URI - = "http://xml.apache.org/xalan/redirect"; - public static final String FALLBACK_CLASS + public static final String REDIRECT_URI + = "http://xml.apache.org/xalan/redirect"; + public static final String FALLBACK_CLASS = "org.apache.xalan.xsltc.compiler.Fallback"; - public static final int RTF_INITIAL_SIZE = 32; + public static final int RTF_INITIAL_SIZE = 32; } diff --git a/xalan/src/main/java/org/apache/xalan/xsltc/compiler/Stylesheet.java b/xalan/src/main/java/org/apache/xalan/xsltc/compiler/Stylesheet.java index fcc94ad53..224f17e62 100644 --- a/xalan/src/main/java/org/apache/xalan/xsltc/compiler/Stylesheet.java +++ b/xalan/src/main/java/org/apache/xalan/xsltc/compiler/Stylesheet.java @@ -60,775 +60,775 @@ public final class Stylesheet extends SyntaxTreeNode { - /** - * XSLT version defined in the stylesheet. - */ - private String _version; + /** + * XSLT version defined in the stylesheet. + */ + private String _version; - /** - * Internal name of this stylesheet used as a key into the symbol table. - */ - private QName _name; + /** + * Internal name of this stylesheet used as a key into the symbol table. + */ + private QName _name; - /** - * A URI that represents the system ID for this stylesheet. - */ - private String _systemId; + /** + * A URI that represents the system ID for this stylesheet. + */ + private String _systemId; - /** - * A reference to the parent stylesheet or null if topmost. - */ - private Stylesheet _parentStylesheet; + /** + * A reference to the parent stylesheet or null if topmost. + */ + private Stylesheet _parentStylesheet; - /** - * Contains global variables and parameters defined in the stylesheet. - */ - private Vector _globals = new Vector(); - - /** - * Used to cache the result returned by hasLocalParams(). - */ - private Boolean _hasLocalParams = null; - - /** - * The name of the class being generated. - */ - private String _className; + /** + * Contains global variables and parameters defined in the stylesheet. + */ + private Vector _globals = new Vector(); + + /** + * Used to cache the result returned by hasLocalParams(). + */ + private Boolean _hasLocalParams = null; + + /** + * The name of the class being generated. + */ + private String _className; - /** - * Contains all templates defined in this stylesheet - */ - private final Vector _templates = new Vector(); + /** + * Contains all templates defined in this stylesheet + */ + private final Vector _templates = new Vector(); - /** - * Used to cache result of getAllValidTemplates(). Only - * set in top-level stylesheets that include/import other stylesheets. - */ - private Vector _allValidTemplates = null; - - private Vector _elementsWithNamespacesUsedDynamically = null; - - /** - * Counter to generate unique mode suffixes. - */ - private int _nextModeSerial = 1; + /** + * Used to cache result of getAllValidTemplates(). Only + * set in top-level stylesheets that include/import other stylesheets. + */ + private Vector _allValidTemplates = null; + + private Vector _elementsWithNamespacesUsedDynamically = null; + + /** + * Counter to generate unique mode suffixes. + */ + private int _nextModeSerial = 1; - /** - * Mapping between mode names and Mode instances. - */ - private final Hashtable _modes = new Hashtable(); + /** + * Mapping between mode names and Mode instances. + */ + private final Hashtable _modes = new Hashtable(); - /** - * A reference to the default Mode object. - */ - private Mode _defaultMode; - - /** - * Mapping between extension URIs and their prefixes. - */ - private final Hashtable _extensions = new Hashtable(); - - /** - * Reference to the stylesheet from which this stylesheet was - * imported (if any). - */ - public Stylesheet _importedFrom = null; + /** + * A reference to the default Mode object. + */ + private Mode _defaultMode; + + /** + * Mapping between extension URIs and their prefixes. + */ + private final Hashtable _extensions = new Hashtable(); + + /** + * Reference to the stylesheet from which this stylesheet was + * imported (if any). + */ + public Stylesheet _importedFrom = null; - /** - * Reference to the stylesheet from which this stylesheet was - * included (if any). - */ - public Stylesheet _includedFrom = null; + /** + * Reference to the stylesheet from which this stylesheet was + * included (if any). + */ + public Stylesheet _includedFrom = null; - /** - * Array of all the stylesheets imported or included from this one. - */ - private Vector _includedStylesheets = null; + /** + * Array of all the stylesheets imported or included from this one. + */ + private Vector _includedStylesheets = null; - /** - * Import precendence for this stylesheet. - */ - private int _importPrecedence = 1; - - /** - * Minimum precendence of any descendant stylesheet by inclusion or - * importation. - */ - private int _minimumDescendantPrecedence = -1; - - /** - * Mapping between key names and Key objects (needed by Key/IdPattern). - */ - private Hashtable _keys = new Hashtable(); - - /** - * A reference to the SourceLoader set by the user (a URIResolver - * if the JAXP API is being used). - */ - private SourceLoader _loader = null; - - /** - * Flag indicating if format-number() is called. - */ - private boolean _numberFormattingUsed = false; - - /** - * Flag indicating if this is a simplified stylesheets. A template - * matching on "/" must be added in this case. - */ - private boolean _simplified = false; - - /** - * Flag indicating if multi-document support is needed. - */ - private boolean _multiDocument = false; + /** + * Import precendence for this stylesheet. + */ + private int _importPrecedence = 1; + + /** + * Minimum precendence of any descendant stylesheet by inclusion or + * importation. + */ + private int _minimumDescendantPrecedence = -1; + + /** + * Mapping between key names and Key objects (needed by Key/IdPattern). + */ + private Hashtable _keys = new Hashtable(); + + /** + * A reference to the SourceLoader set by the user (a URIResolver + * if the JAXP API is being used). + */ + private SourceLoader _loader = null; + + /** + * Flag indicating if format-number() is called. + */ + private boolean _numberFormattingUsed = false; + + /** + * Flag indicating if this is a simplified stylesheets. A template + * matching on "/" must be added in this case. + */ + private boolean _simplified = false; + + /** + * Flag indicating if multi-document support is needed. + */ + private boolean _multiDocument = false; - /** - * Flag indicating if nodset() is called. - */ - private boolean _callsNodeset = false; - - /** - * Flag indicating if id() is called. - */ - private boolean _hasIdCall = false; + /** + * Flag indicating if nodset() is called. + */ + private boolean _callsNodeset = false; + + /** + * Flag indicating if id() is called. + */ + private boolean _hasIdCall = false; - /** - * Set to true to enable template inlining optimization. - * @see XSLTC#_templateInlining - */ - private boolean _templateInlining = false; - - /** - * A reference to the last xsl:output object found in the styleshet. - */ - private Output _lastOutputElement = null; + /** + * Set to true to enable template inlining optimization. + * @see XSLTC#_templateInlining + */ + private boolean _templateInlining = false; + + /** + * A reference to the last xsl:output object found in the styleshet. + */ + private Output _lastOutputElement = null; - /** - * Output properties for this stylesheet. - */ - private Properties _outputProperties = null; + /** + * Output properties for this stylesheet. + */ + private Properties _outputProperties = null; - /** - * Output method for this stylesheet (must be set to one of - * the constants defined below). - */ - private int _outputMethod = UNKNOWN_OUTPUT; - - // Output method constants - public static final int UNKNOWN_OUTPUT = 0; - public static final int XML_OUTPUT = 1; - public static final int HTML_OUTPUT = 2; - public static final int TEXT_OUTPUT = 3; + /** + * Output method for this stylesheet (must be set to one of + * the constants defined below). + */ + private int _outputMethod = UNKNOWN_OUTPUT; + + // Output method constants + public static final int UNKNOWN_OUTPUT = 0; + public static final int XML_OUTPUT = 1; + public static final int HTML_OUTPUT = 2; + public static final int TEXT_OUTPUT = 3; - /** - * Return the output method - */ - public int getOutputMethod() { - return _outputMethod; - } + /** + * Return the output method + */ + public int getOutputMethod() { + return _outputMethod; + } - /** - * Check and set the output method - */ - private void checkOutputMethod() { - if (_lastOutputElement != null) { + /** + * Check and set the output method + */ + private void checkOutputMethod() { + if (_lastOutputElement != null) { String method = _lastOutputElement.getOutputMethod(); if (method != null) { - if (method.equals("xml")) - _outputMethod = XML_OUTPUT; - else if (method.equals("html")) - _outputMethod = HTML_OUTPUT; - else if (method.equals("text")) - _outputMethod = TEXT_OUTPUT; + if (method.equals("xml")) + _outputMethod = XML_OUTPUT; + else if (method.equals("html")) + _outputMethod = HTML_OUTPUT; + else if (method.equals("text")) + _outputMethod = TEXT_OUTPUT; } + } } - } - public boolean getTemplateInlining() { - return _templateInlining; - } + public boolean getTemplateInlining() { + return _templateInlining; + } - public void setTemplateInlining(boolean flag) { - _templateInlining = flag; - } + public void setTemplateInlining(boolean flag) { + _templateInlining = flag; + } - public boolean isSimplified() { - return(_simplified); - } + public boolean isSimplified() { + return(_simplified); + } - public void setSimplified() { - _simplified = true; - } + public void setSimplified() { + _simplified = true; + } - public void setHasIdCall(boolean flag) { - _hasIdCall = flag; - } + public void setHasIdCall(boolean flag) { + _hasIdCall = flag; + } - public void setOutputProperty(String key, String value) { - if (_outputProperties == null) { + public void setOutputProperty(String key, String value) { + if (_outputProperties == null) { _outputProperties = new Properties(); + } + _outputProperties.setProperty(key, value); } - _outputProperties.setProperty(key, value); - } - public void setOutputProperties(Properties props) { - _outputProperties = props; - } + public void setOutputProperties(Properties props) { + _outputProperties = props; + } - public Properties getOutputProperties() { - return _outputProperties; - } + public Properties getOutputProperties() { + return _outputProperties; + } - public Output getLastOutputElement() { - return _lastOutputElement; - } + public Output getLastOutputElement() { + return _lastOutputElement; + } - public void setMultiDocument(boolean flag) { - _multiDocument = flag; - } - - public boolean isMultiDocument() { - return _multiDocument; - } - - public void setCallsNodeset(boolean flag) { - if (flag) setMultiDocument(flag); - _callsNodeset = flag; - } - - public boolean callsNodeset() { - return _callsNodeset; - } - - public void numberFormattingUsed() { - _numberFormattingUsed = true; - /* - * Fix for bug 23046, if the stylesheet is included, set the - * numberFormattingUsed flag to the parent stylesheet too. - * AbstractTranslet.addDecimalFormat() will be inlined once for the - * outer most stylesheet. - */ - Stylesheet parent = getParentStylesheet(); - if (null != parent) parent.numberFormattingUsed(); - } + public void setMultiDocument(boolean flag) { + _multiDocument = flag; + } - public void setImportPrecedence(final int precedence) { - // Set import precedence for this stylesheet - _importPrecedence = precedence; + public boolean isMultiDocument() { + return _multiDocument; + } - // Set import precedence for all included stylesheets - final Enumeration elements = elements(); - while (elements.hasMoreElements()) { + public void setCallsNodeset(boolean flag) { + if (flag) setMultiDocument(flag); + _callsNodeset = flag; + } + + public boolean callsNodeset() { + return _callsNodeset; + } + + public void numberFormattingUsed() { + _numberFormattingUsed = true; + /* + * Fix for bug 23046, if the stylesheet is included, set the + * numberFormattingUsed flag to the parent stylesheet too. + * AbstractTranslet.addDecimalFormat() will be inlined once for the + * outer most stylesheet. + */ + Stylesheet parent = getParentStylesheet(); + if (null != parent) parent.numberFormattingUsed(); + } + + public void setImportPrecedence(final int precedence) { + // Set import precedence for this stylesheet + _importPrecedence = precedence; + + // Set import precedence for all included stylesheets + final Enumeration elements = elements(); + while (elements.hasMoreElements()) { SyntaxTreeNode child = (SyntaxTreeNode)elements.nextElement(); if (child instanceof Include) { - Stylesheet included = ((Include)child).getIncludedStylesheet(); - if (included != null && included._includedFrom == this) { - included.setImportPrecedence(precedence); - } + Stylesheet included = ((Include)child).getIncludedStylesheet(); + if (included != null && included._includedFrom == this) { + included.setImportPrecedence(precedence); + } } - } + } - // Set import precedence for the stylesheet that imported this one - if (_importedFrom != null) { + // Set import precedence for the stylesheet that imported this one + if (_importedFrom != null) { if (_importedFrom.getImportPrecedence() < precedence) { - final Parser parser = getParser(); - final int nextPrecedence = parser.getNextImportPrecedence(); - _importedFrom.setImportPrecedence(nextPrecedence); + final Parser parser = getParser(); + final int nextPrecedence = parser.getNextImportPrecedence(); + _importedFrom.setImportPrecedence(nextPrecedence); } - } - // Set import precedence for the stylesheet that included this one - else if (_includedFrom != null) { + } + // Set import precedence for the stylesheet that included this one + else if (_includedFrom != null) { if (_includedFrom.getImportPrecedence() != precedence) - _includedFrom.setImportPrecedence(precedence); + _includedFrom.setImportPrecedence(precedence); + } } - } - public int getImportPrecedence() { - return _importPrecedence; - } - - /** - * Get the minimum of the precedence of this stylesheet, any stylesheet - * imported by this stylesheet and any include/import descendant of this - * stylesheet. - */ - public int getMinimumDescendantPrecedence() { - if (_minimumDescendantPrecedence == -1) { - // Start with precedence of current stylesheet as a basis. - int min = getImportPrecedence(); - - // Recursively examine all imported/included stylesheets. - final int inclImpCount = (_includedStylesheets != null) - ? _includedStylesheets.size() - : 0; - - for (int i = 0; i < inclImpCount; i++) { - int prec = ((Stylesheet)_includedStylesheets.elementAt(i)) - .getMinimumDescendantPrecedence(); - - if (prec < min) { - min = prec; - } - } + public int getImportPrecedence() { + return _importPrecedence; + } - _minimumDescendantPrecedence = min; + /** + * Get the minimum of the precedence of this stylesheet, any stylesheet + * imported by this stylesheet and any include/import descendant of this + * stylesheet. + */ + public int getMinimumDescendantPrecedence() { + if (_minimumDescendantPrecedence == -1) { + // Start with precedence of current stylesheet as a basis. + int min = getImportPrecedence(); + + // Recursively examine all imported/included stylesheets. + final int inclImpCount = (_includedStylesheets != null) + ? _includedStylesheets.size() + : 0; + + for (int i = 0; i < inclImpCount; i++) { + int prec = ((Stylesheet)_includedStylesheets.elementAt(i)) + .getMinimumDescendantPrecedence(); + + if (prec < min) { + min = prec; + } + } + + _minimumDescendantPrecedence = min; + } + return _minimumDescendantPrecedence; } - return _minimumDescendantPrecedence; - } - public boolean checkForLoop(String systemId) { - // Return true if this stylesheet includes/imports itself - if (_systemId != null && _systemId.equals(systemId)) { + public boolean checkForLoop(String systemId) { + // Return true if this stylesheet includes/imports itself + if (_systemId != null && _systemId.equals(systemId)) { return true; - } - // Then check with any stylesheets that included/imported this one - if (_parentStylesheet != null) + } + // Then check with any stylesheets that included/imported this one + if (_parentStylesheet != null) return _parentStylesheet.checkForLoop(systemId); - // Otherwise OK - return false; - } + // Otherwise OK + return false; + } - public void setParser(Parser parser) { - super.setParser(parser); - _name = makeStylesheetName("__stylesheet_"); - } + public void setParser(Parser parser) { + super.setParser(parser); + _name = makeStylesheetName("__stylesheet_"); + } - public void setParentStylesheet(Stylesheet parent) { - _parentStylesheet = parent; - } + public void setParentStylesheet(Stylesheet parent) { + _parentStylesheet = parent; + } - public Stylesheet getParentStylesheet() { - return _parentStylesheet; - } + public Stylesheet getParentStylesheet() { + return _parentStylesheet; + } - public void setImportingStylesheet(Stylesheet parent) { - _importedFrom = parent; - parent.addIncludedStylesheet(this); - } + public void setImportingStylesheet(Stylesheet parent) { + _importedFrom = parent; + parent.addIncludedStylesheet(this); + } - public void setIncludingStylesheet(Stylesheet parent) { - _includedFrom = parent; - parent.addIncludedStylesheet(this); - } + public void setIncludingStylesheet(Stylesheet parent) { + _includedFrom = parent; + parent.addIncludedStylesheet(this); + } - public void addIncludedStylesheet(Stylesheet child) { - if (_includedStylesheets == null) { - _includedStylesheets = new Vector(); + public void addIncludedStylesheet(Stylesheet child) { + if (_includedStylesheets == null) { + _includedStylesheets = new Vector(); + } + _includedStylesheets.addElement(child); } - _includedStylesheets.addElement(child); - } - public void setSystemId(String systemId) { - if (systemId != null) { - _systemId = SystemIDResolver.getAbsoluteURI(systemId); + public void setSystemId(String systemId) { + if (systemId != null) { + _systemId = SystemIDResolver.getAbsoluteURI(systemId); + } } - } - public String getSystemId() { - return _systemId; - } + public String getSystemId() { + return _systemId; + } - public void setSourceLoader(SourceLoader loader) { - _loader = loader; - } + public void setSourceLoader(SourceLoader loader) { + _loader = loader; + } - public SourceLoader getSourceLoader() { - return _loader; - } - - private QName makeStylesheetName(String prefix) { - return getParser().getQName(prefix+getXSLTC().nextStylesheetSerial()); - } - - /** - * Returns true if this stylesheet has global vars or params. - */ - public boolean hasGlobals() { - return _globals.size() > 0; - } - - /** - * Returns true if at least one template in the stylesheet has params - * defined. Uses the variable _hasLocalParams to cache the - * result. - */ - public boolean hasLocalParams() { - if (_hasLocalParams == null) { + public SourceLoader getSourceLoader() { + return _loader; + } + + private QName makeStylesheetName(String prefix) { + return getParser().getQName(prefix+getXSLTC().nextStylesheetSerial()); + } + + /** + * Returns true if this stylesheet has global vars or params. + */ + public boolean hasGlobals() { + return _globals.size() > 0; + } + + /** + * Returns true if at least one template in the stylesheet has params + * defined. Uses the variable _hasLocalParams to cache the + * result. + */ + public boolean hasLocalParams() { + if (_hasLocalParams == null) { Vector templates = getAllValidTemplates(); final int n = templates.size(); for (int i = 0; i < n; i++) { - final Template template = (Template)templates.elementAt(i); - if (template.hasParams()) { - _hasLocalParams = Boolean.TRUE; - return true; - } + final Template template = (Template)templates.elementAt(i); + if (template.hasParams()) { + _hasLocalParams = Boolean.TRUE; + return true; + } } _hasLocalParams = Boolean.FALSE; return false; - } - else { + } + else { return _hasLocalParams.booleanValue(); + } + } + + /** + * Adds a single prefix mapping to this syntax tree node. + * @param prefix Namespace prefix. + * @param uri Namespace URI. + */ + protected void addPrefixMapping(String prefix, String uri) { + if (prefix.equals(EMPTYSTRING) && uri.equals(XHTML_URI)) return; + super.addPrefixMapping(prefix, uri); } - } - - /** - * Adds a single prefix mapping to this syntax tree node. - * @param prefix Namespace prefix. - * @param uri Namespace URI. - */ - protected void addPrefixMapping(String prefix, String uri) { - if (prefix.equals(EMPTYSTRING) && uri.equals(XHTML_URI)) return; - super.addPrefixMapping(prefix, uri); - } - - /** - * Store extension URIs - */ - private void extensionURI(String prefixes, SymbolTable stable) { - if (prefixes != null) { + + /** + * Store extension URIs + */ + private void extensionURI(String prefixes, SymbolTable stable) { + if (prefixes != null) { StringTokenizer tokens = new StringTokenizer(prefixes); while (tokens.hasMoreTokens()) { - final String prefix = tokens.nextToken(); - final String uri = lookupNamespace(prefix); - if (uri != null) { - _extensions.put(uri, prefix); - } + final String prefix = tokens.nextToken(); + final String uri = lookupNamespace(prefix); + if (uri != null) { + _extensions.put(uri, prefix); + } } + } } - } - - public boolean isExtension(String uri) { - return (_extensions.get(uri) != null); - } - - public void declareExtensionPrefixes(Parser parser) { - final SymbolTable stable = parser.getSymbolTable(); - final String extensionPrefixes = getAttribute("extension-element-prefixes"); - extensionURI(extensionPrefixes, stable); - } - - /** - * Parse the version and uri fields of the stylesheet and add an - * entry to the symbol table mapping the name __stylesheet_ - * to an instance of this class. - */ - public void parseContents(Parser parser) { - final SymbolTable stable = parser.getSymbolTable(); - /* - // Make sure the XSL version set in this stylesheet - if ((_version == null) || (_version.equals(EMPTYSTRING))) { - reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR,"version"); + public boolean isExtension(String uri) { + return (_extensions.get(uri) != null); } - // Verify that the version is 1.0 and nothing else - else if (!_version.equals("1.0")) { - reportError(this, parser, ErrorMsg.XSL_VERSION_ERR, _version); - } - */ - // Add the implicit mapping of 'xml' to the XML namespace URI - addPrefixMapping("xml", "http://www.w3.org/XML/1998/namespace"); + public void declareExtensionPrefixes(Parser parser) { + final SymbolTable stable = parser.getSymbolTable(); + final String extensionPrefixes = getAttribute("extension-element-prefixes"); + extensionURI(extensionPrefixes, stable); + } - // Report and error if more than one stylesheet defined - final Stylesheet sheet = stable.addStylesheet(_name, this); - if (sheet != null) { + /** + * Parse the version and uri fields of the stylesheet and add an + * entry to the symbol table mapping the name __stylesheet_ + * to an instance of this class. + */ + public void parseContents(Parser parser) { + final SymbolTable stable = parser.getSymbolTable(); + + /* + // Make sure the XSL version set in this stylesheet + if ((_version == null) || (_version.equals(EMPTYSTRING))) { + reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR,"version"); + } + // Verify that the version is 1.0 and nothing else + else if (!_version.equals("1.0")) { + reportError(this, parser, ErrorMsg.XSL_VERSION_ERR, _version); + } + */ + + // Add the implicit mapping of 'xml' to the XML namespace URI + addPrefixMapping("xml", "http://www.w3.org/XML/1998/namespace"); + + // Report and error if more than one stylesheet defined + final Stylesheet sheet = stable.addStylesheet(_name, this); + if (sheet != null) { // Error: more that one stylesheet defined ErrorMsg err = new ErrorMsg(ErrorMsg.MULTIPLE_STYLESHEET_ERR,this); parser.reportError(Constants.ERROR, err); - } - - // If this is a simplified stylesheet we must create a template that - // grabs the root node of the input doc ( ). - // This template needs the current element (the one passed to this - // method) as its only child, so the Template class has a special - // method that handles this (parseSimplified()). - if (_simplified) { + } + + // If this is a simplified stylesheet we must create a template that + // grabs the root node of the input doc ( ). + // This template needs the current element (the one passed to this + // method) as its only child, so the Template class has a special + // method that handles this (parseSimplified()). + if (_simplified) { stable.excludeURI(XSLT_URI); Template template = new Template(); template.parseSimplified(this, parser); - } - // Parse the children of this node - else { + } + // Parse the children of this node + else { parseOwnChildren(parser); + } } - } - /** - * Parse all direct children of the element. - */ - public final void parseOwnChildren(Parser parser) { - final SymbolTable stable = parser.getSymbolTable(); - final String excludePrefixes = getAttribute("exclude-result-prefixes"); - final String extensionPrefixes = getAttribute("extension-element-prefixes"); + /** + * Parse all direct children of the element. + */ + public final void parseOwnChildren(Parser parser) { + final SymbolTable stable = parser.getSymbolTable(); + final String excludePrefixes = getAttribute("exclude-result-prefixes"); + final String extensionPrefixes = getAttribute("extension-element-prefixes"); - // Exclude XSLT uri - stable.pushExcludedNamespacesContext(); - stable.excludeURI(Constants.XSLT_URI); - stable.excludeNamespaces(excludePrefixes); - stable.excludeNamespaces(extensionPrefixes); - - final Vector contents = getContents(); - final int count = contents.size(); - - // We have to scan the stylesheet element's top-level elements for - // variables and/or parameters before we parse the other elements - for (int i = 0; i < count; i++) { + // Exclude XSLT uri + stable.pushExcludedNamespacesContext(); + stable.excludeURI(Constants.XSLT_URI); + stable.excludeNamespaces(excludePrefixes); + stable.excludeNamespaces(extensionPrefixes); + + final Vector contents = getContents(); + final int count = contents.size(); + + // We have to scan the stylesheet element's top-level elements for + // variables and/or parameters before we parse the other elements + for (int i = 0; i < count; i++) { SyntaxTreeNode child = (SyntaxTreeNode)contents.elementAt(i); if ((child instanceof VariableBase) || - (child instanceof NamespaceAlias)) { - parser.getSymbolTable().setCurrentNode(child); - child.parseContents(parser); + (child instanceof NamespaceAlias)) { + parser.getSymbolTable().setCurrentNode(child); + child.parseContents(parser); } - } + } - // Now go through all the other top-level elements... - for (int i = 0; i < count; i++) { + // Now go through all the other top-level elements... + for (int i = 0; i < count; i++) { SyntaxTreeNode child = (SyntaxTreeNode)contents.elementAt(i); if (!(child instanceof VariableBase) && - !(child instanceof NamespaceAlias)) { - parser.getSymbolTable().setCurrentNode(child); - child.parseContents(parser); + !(child instanceof NamespaceAlias)) { + parser.getSymbolTable().setCurrentNode(child); + child.parseContents(parser); } // All template code should be compiled as methods if the // element was ever used in this stylesheet if (!_templateInlining && (child instanceof Template)) { - Template template = (Template)child; - String name = "template$dot$" + template.getPosition(); - template.setName(parser.getQName(name)); + Template template = (Template)child; + String name = "template$dot$" + template.getPosition(); + template.setName(parser.getQName(name)); } - } + } - stable.popExcludedNamespacesContext(); - } + stable.popExcludedNamespacesContext(); + } - public void processModes() { - if (_defaultMode == null) + public void processModes() { + if (_defaultMode == null) _defaultMode = new Mode(null, this, Constants.EMPTYSTRING); - _defaultMode.processPatterns(_keys); - final Enumeration modes = _modes.elements(); - while (modes.hasMoreElements()) { + _defaultMode.processPatterns(_keys); + final Enumeration modes = _modes.elements(); + while (modes.hasMoreElements()) { final Mode mode = (Mode)modes.nextElement(); mode.processPatterns(_keys); + } } - } - private void compileModes(ClassGenerator classGen) { - _defaultMode.compileApplyTemplates(classGen); - final Enumeration modes = _modes.elements(); - while (modes.hasMoreElements()) { + private void compileModes(ClassGenerator classGen) { + _defaultMode.compileApplyTemplates(classGen); + final Enumeration modes = _modes.elements(); + while (modes.hasMoreElements()) { final Mode mode = (Mode)modes.nextElement(); mode.compileApplyTemplates(classGen); + } } - } - public Mode getMode(QName modeName) { - if (modeName == null) { + public Mode getMode(QName modeName) { + if (modeName == null) { if (_defaultMode == null) { - _defaultMode = new Mode(null, this, Constants.EMPTYSTRING); + _defaultMode = new Mode(null, this, Constants.EMPTYSTRING); } return _defaultMode; - } - else { + } + else { Mode mode = (Mode)_modes.get(modeName); if (mode == null) { - final String suffix = Integer.toString(_nextModeSerial++); - _modes.put(modeName, mode = new Mode(modeName, this, suffix)); + final String suffix = Integer.toString(_nextModeSerial++); + _modes.put(modeName, mode = new Mode(modeName, this, suffix)); } return mode; + } } - } - /** - * Type check all the children of this node. - */ - public Type typeCheck(SymbolTable stable) throws TypeCheckError { - final int count = _globals.size(); - for (int i = 0; i < count; i++) { + /** + * Type check all the children of this node. + */ + public Type typeCheck(SymbolTable stable) throws TypeCheckError { + final int count = _globals.size(); + for (int i = 0; i < count; i++) { final VariableBase var = (VariableBase)_globals.elementAt(i); var.typeCheck(stable); + } + return typeCheckContents(stable); + } + + /** + * Translate the stylesheet into JVM bytecodes. + */ + public void translate(ClassGenerator classGen, MethodGenerator methodGen) { + translate(); + } + + private void addDOMField(ClassGenerator classGen) { + final FieldGen fgen = new FieldGen(ACC_PUBLIC, + Util.getJCRefType(DOM_INTF_SIG), + DOM_FIELD, + classGen.getConstantPool()); + classGen.addField(fgen.getField()); } - return typeCheckContents(stable); - } - - /** - * Translate the stylesheet into JVM bytecodes. - */ - public void translate(ClassGenerator classGen, MethodGenerator methodGen) { - translate(); - } - - private void addDOMField(ClassGenerator classGen) { - final FieldGen fgen = new FieldGen(ACC_PUBLIC, - Util.getJCRefType(DOM_INTF_SIG), - DOM_FIELD, - classGen.getConstantPool()); - classGen.addField(fgen.getField()); - } - /** - * Add a static field - */ - private void addStaticField(ClassGenerator classGen, String type, - String name) + /** + * Add a static field + */ + private void addStaticField(ClassGenerator classGen, String type, + String name) { - final FieldGen fgen = new FieldGen(ACC_PROTECTED|ACC_STATIC, - Util.getJCRefType(type), - name, - classGen.getConstantPool()); - classGen.addField(fgen.getField()); + final FieldGen fgen = new FieldGen(ACC_PROTECTED|ACC_STATIC, + Util.getJCRefType(type), + name, + classGen.getConstantPool()); + classGen.addField(fgen.getField()); } - /** - * Translate the stylesheet into JVM bytecodes. - */ - public void translate() { - _className = getXSLTC().getClassName(); + /** + * Translate the stylesheet into JVM bytecodes. + */ + public void translate() { + _className = getXSLTC().getClassName(); - // Define a new class by extending TRANSLET_CLASS - final ClassGenerator classGen = + // Define a new class by extending TRANSLET_CLASS + final ClassGenerator classGen = new ClassGenerator(_className, - TRANSLET_CLASS, - Constants.EMPTYSTRING, - ACC_PUBLIC | ACC_SUPER, - null, this); + TRANSLET_CLASS, + Constants.EMPTYSTRING, + ACC_PUBLIC | ACC_SUPER, + null, this); - addDOMField(classGen); + addDOMField(classGen); - // Compile transform() to initialize parameters, globals & output - // and run the transformation - compileTransform(classGen); + // Compile transform() to initialize parameters, globals & output + // and run the transformation + compileTransform(classGen); - // Translate all non-template elements and filter out all templates - final Enumeration elements = elements(); - while (elements.hasMoreElements()) { + // Translate all non-template elements and filter out all templates + final Enumeration elements = elements(); + while (elements.hasMoreElements()) { Object element = elements.nextElement(); // xsl:template if (element instanceof Template) { - // Separate templates by modes - final Template template = (Template)element; - //_templates.addElement(template); - getMode(template.getModeName()).addTemplate(template); + // Separate templates by modes + final Template template = (Template)element; + //_templates.addElement(template); + getMode(template.getModeName()).addTemplate(template); } // xsl:attribute-set else if (element instanceof AttributeSet) { - ((AttributeSet)element).translate(classGen, null); + ((AttributeSet)element).translate(classGen, null); } else if (element instanceof Output) { - // save the element for later to pass to compileConstructor - Output output = (Output)element; - if (output.enabled()) _lastOutputElement = output; + // save the element for later to pass to compileConstructor + Output output = (Output)element; + if (output.enabled()) _lastOutputElement = output; } else { - // Global variables and parameters are handled elsewhere. - // Other top-level non-template elements are ignored. Literal - // elements outside of templates will never be output. + // Global variables and parameters are handled elsewhere. + // Other top-level non-template elements are ignored. Literal + // elements outside of templates will never be output. } - } + } - checkOutputMethod(); - processModes(); - compileModes(classGen); - compileStaticInitializer(classGen); - compileConstructor(classGen, _lastOutputElement); + checkOutputMethod(); + processModes(); + compileModes(classGen); + compileStaticInitializer(classGen); + compileConstructor(classGen, _lastOutputElement); - if (!getParser().errorsFound()) { + if (!getParser().errorsFound()) { getXSLTC().dumpClass(classGen.getJavaClass()); + } } - } - - /** - *

Compile the namesArray, urisArray, typesArray, namespaceArray, - * namespaceAncestorsArray, prefixURIsIdxArray and prefixURIPairsArray into - * the static initializer. They are read-only from the - * translet. All translet instances can share a single - * copy of this informtion.

- *

The namespaceAncestorsArray, - * prefixURIsIdxArray and prefixURIPairsArray - * contain namespace information accessible from the stylesheet: - *

- *
namespaceAncestorsArray
- *
Array indexed by integer stylesheet node IDs containing node IDs of - * the nearest ancestor node in the stylesheet with namespace - * declarations or -1 if there is no such ancestor. There - * can be more than one disjoint tree of nodes - one for each stylesheet - * module
- *
prefixURIsIdxArray
- *
Array indexed by integer stylesheet node IDs containing the index - * into prefixURIPairsArray of the first namespace prefix - * declared for the node. The values are stored in ascending order, so - * the next value in this array (if any) can be used to find the last such - * prefix-URI pair
- *
prefixURIPairsArray
- *
Array of pairs of namespace prefixes and URIs. A zero-length - * string represents the default namespace if it appears as a prefix and - * a namespace undeclaration if it appears as a URI.
- *
- *

- *

For this stylesheet - *


-   * <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
-   *   <xsl:template match="/">
-   *     <xsl:for-each select="*" xmlns:foo="foouri">
-   *       <xsl:element name="{n}" xmlns:foo="baruri">
-   *     </xsl:for-each>
-   *     <out xmlns="lumpit"/>
-   *     <xsl:element name="{n}" xmlns="foouri"/>
-   *     <xsl:element name="{n}" namespace="{ns}" xmlns="limpit"/gt;
-   *   </xsl:template>
-   * </xsl:stylesheet>
-   * 
- * there will be four stylesheet nodes whose namespace information is - * needed, and - *
    - *
  • namespaceAncestorsArray will have the value - * [-1,0,1,0];
  • - *
  • prefixURIsIdxArray will have the value - * [0,4,6,8]; and
  • - *
  • prefixURIPairsArray will have the value - * ["xml","http://www.w3.org/XML/1998/namespace", - * "xsl","http://www.w3.org/1999/XSL/Transform" - * "foo","foouri","foo","baruri","","foouri"].
  • - *
- *

- */ - private void compileStaticInitializer(ClassGenerator classGen) { - final ConstantPoolGen cpg = classGen.getConstantPool(); - final InstructionList il = new InstructionList(); - - final MethodGenerator staticConst = + + /** + *

Compile the namesArray, urisArray, typesArray, namespaceArray, + * namespaceAncestorsArray, prefixURIsIdxArray and prefixURIPairsArray into + * the static initializer. They are read-only from the + * translet. All translet instances can share a single + * copy of this informtion.

+ *

The namespaceAncestorsArray, + * prefixURIsIdxArray and prefixURIPairsArray + * contain namespace information accessible from the stylesheet: + *

+ *
namespaceAncestorsArray
+ *
Array indexed by integer stylesheet node IDs containing node IDs of + * the nearest ancestor node in the stylesheet with namespace + * declarations or -1 if there is no such ancestor. There + * can be more than one disjoint tree of nodes - one for each stylesheet + * module
+ *
prefixURIsIdxArray
+ *
Array indexed by integer stylesheet node IDs containing the index + * into prefixURIPairsArray of the first namespace prefix + * declared for the node. The values are stored in ascending order, so + * the next value in this array (if any) can be used to find the last such + * prefix-URI pair
+ *
prefixURIPairsArray
+ *
Array of pairs of namespace prefixes and URIs. A zero-length + * string represents the default namespace if it appears as a prefix and + * a namespace undeclaration if it appears as a URI.
+ *
+ *

+ *

For this stylesheet + *


+     * <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+     *   <xsl:template match="/">
+     *     <xsl:for-each select="*" xmlns:foo="foouri">
+     *       <xsl:element name="{n}" xmlns:foo="baruri">
+     *     </xsl:for-each>
+     *     <out xmlns="lumpit"/>
+     *     <xsl:element name="{n}" xmlns="foouri"/>
+     *     <xsl:element name="{n}" namespace="{ns}" xmlns="limpit"/gt;
+     *   </xsl:template>
+     * </xsl:stylesheet>
+     * 
+ * there will be four stylesheet nodes whose namespace information is + * needed, and + *
    + *
  • namespaceAncestorsArray will have the value + * [-1,0,1,0];
  • + *
  • prefixURIsIdxArray will have the value + * [0,4,6,8]; and
  • + *
  • prefixURIPairsArray will have the value + * ["xml","http://www.w3.org/XML/1998/namespace", + * "xsl","http://www.w3.org/1999/XSL/Transform" + * "foo","foouri","foo","baruri","","foouri"].
  • + *
+ *

+ */ + private void compileStaticInitializer(ClassGenerator classGen) { + final ConstantPoolGen cpg = classGen.getConstantPool(); + final InstructionList il = new InstructionList(); + + final MethodGenerator staticConst = new MethodGenerator(ACC_PUBLIC|ACC_STATIC, - org.apache.bcel.generic.Type.VOID, - null, null, "", - _className, il, cpg); - - addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMES_ARRAY_FIELD); - addStaticField(classGen, "[" + STRING_SIG, STATIC_URIS_ARRAY_FIELD); - addStaticField(classGen, "[I", STATIC_TYPES_ARRAY_FIELD); - addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMESPACE_ARRAY_FIELD); - addStaticField(classGen, MAP_SIG, STATIC_NS_MAP_FIELD ); - // Create fields of type char[] that will contain literal text from - // the stylesheet. - final int charDataFieldCount = getXSLTC().getCharacterDataCount(); - for (int i = 0; i < charDataFieldCount; i++) { - addStaticField(classGen, STATIC_CHAR_DATA_FIELD_SIG, - STATIC_CHAR_DATA_FIELD+i); - } - - // Put the names array into the translet - used for dom/translet mapping - final Vector namesIndex = getXSLTC().getNamesIndex(); - int size = namesIndex.size(); - String[] namesArray = new String[size]; - String[] urisArray = new String[size]; - int[] typesArray = new int[size]; + org.apache.bcel.generic.Type.VOID, + null, null, "", + _className, il, cpg); + + addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMES_ARRAY_FIELD); + addStaticField(classGen, "[" + STRING_SIG, STATIC_URIS_ARRAY_FIELD); + addStaticField(classGen, "[I", STATIC_TYPES_ARRAY_FIELD); + addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMESPACE_ARRAY_FIELD); + addStaticField(classGen, MAP_SIG, STATIC_NS_MAP_FIELD ); + // Create fields of type char[] that will contain literal text from + // the stylesheet. + final int charDataFieldCount = getXSLTC().getCharacterDataCount(); + for (int i = 0; i < charDataFieldCount; i++) { + addStaticField(classGen, STATIC_CHAR_DATA_FIELD_SIG, + STATIC_CHAR_DATA_FIELD+i); + } + + // Put the names array into the translet - used for dom/translet mapping + final Vector namesIndex = getXSLTC().getNamesIndex(); + int size = namesIndex.size(); + String[] namesArray = new String[size]; + String[] urisArray = new String[size]; + int[] typesArray = new int[size]; - int index; - for (int i = 0; i < size; i++) { + int index; + for (int i = 0; i < size; i++) { String encodedName = (String)namesIndex.elementAt(i); if ((index = encodedName.lastIndexOf(':')) > -1) { - urisArray[i] = encodedName.substring(0, index); + urisArray[i] = encodedName.substring(0, index); } index = index + 1; @@ -839,364 +839,364 @@ private void compileStaticInitializer(ClassGenerator classGen) { typesArray[i] = DTM.NAMESPACE_NODE; index++; } else { - typesArray[i] = DTM.ELEMENT_NODE; + typesArray[i] = DTM.ELEMENT_NODE; } if (index == 0) { - namesArray[i] = encodedName; + namesArray[i] = encodedName; } else { - namesArray[i] = encodedName.substring(index); + namesArray[i] = encodedName.substring(index); } - } + } - staticConst.markChunkStart(); - il.append(new PUSH(cpg, size)); - il.append(new ANEWARRAY(cpg.addClass(STRING))); - int namesArrayRef = cpg.addFieldref(_className, - STATIC_NAMES_ARRAY_FIELD, - NAMES_INDEX_SIG); - il.append(new PUTSTATIC(namesArrayRef)); - staticConst.markChunkEnd(); + staticConst.markChunkStart(); + il.append(new PUSH(cpg, size)); + il.append(new ANEWARRAY(cpg.addClass(STRING))); + int namesArrayRef = cpg.addFieldref(_className, + STATIC_NAMES_ARRAY_FIELD, + NAMES_INDEX_SIG); + il.append(new PUTSTATIC(namesArrayRef)); + staticConst.markChunkEnd(); - for (int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { final String name = namesArray[i]; - staticConst.markChunkStart(); + staticConst.markChunkStart(); il.append(new GETSTATIC(namesArrayRef)); il.append(new PUSH(cpg, i)); il.append(new PUSH(cpg, name)); il.append(AASTORE); - staticConst.markChunkEnd(); - } + staticConst.markChunkEnd(); + } - staticConst.markChunkStart(); - il.append(new PUSH(cpg, size)); - il.append(new ANEWARRAY(cpg.addClass(STRING))); - int urisArrayRef = cpg.addFieldref(_className, - STATIC_URIS_ARRAY_FIELD, - URIS_INDEX_SIG); - il.append(new PUTSTATIC(urisArrayRef)); - staticConst.markChunkEnd(); + staticConst.markChunkStart(); + il.append(new PUSH(cpg, size)); + il.append(new ANEWARRAY(cpg.addClass(STRING))); + int urisArrayRef = cpg.addFieldref(_className, + STATIC_URIS_ARRAY_FIELD, + URIS_INDEX_SIG); + il.append(new PUTSTATIC(urisArrayRef)); + staticConst.markChunkEnd(); - for (int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { final String uri = urisArray[i]; - staticConst.markChunkStart(); + staticConst.markChunkStart(); il.append(new GETSTATIC(urisArrayRef)); il.append(new PUSH(cpg, i)); il.append(new PUSH(cpg, uri)); il.append(AASTORE); - staticConst.markChunkEnd(); - } + staticConst.markChunkEnd(); + } - staticConst.markChunkStart(); - il.append(new PUSH(cpg, size)); - il.append(new NEWARRAY(BasicType.INT)); - int typesArrayRef = cpg.addFieldref(_className, - STATIC_TYPES_ARRAY_FIELD, - TYPES_INDEX_SIG); - il.append(new PUTSTATIC(typesArrayRef)); - staticConst.markChunkEnd(); + staticConst.markChunkStart(); + il.append(new PUSH(cpg, size)); + il.append(new NEWARRAY(BasicType.INT)); + int typesArrayRef = cpg.addFieldref(_className, + STATIC_TYPES_ARRAY_FIELD, + TYPES_INDEX_SIG); + il.append(new PUTSTATIC(typesArrayRef)); + staticConst.markChunkEnd(); - for (int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { final int nodeType = typesArray[i]; - staticConst.markChunkStart(); + staticConst.markChunkStart(); il.append(new GETSTATIC(typesArrayRef)); il.append(new PUSH(cpg, i)); il.append(new PUSH(cpg, nodeType)); il.append(IASTORE); - staticConst.markChunkEnd(); - } + staticConst.markChunkEnd(); + } - // Put the namespace names array into the translet - final Vector namespaces = getXSLTC().getNamespaceIndex(); - staticConst.markChunkStart(); - il.append(new PUSH(cpg, namespaces.size())); - il.append(new ANEWARRAY(cpg.addClass(STRING))); - int namespaceArrayRef = cpg.addFieldref(_className, - STATIC_NAMESPACE_ARRAY_FIELD, - NAMESPACE_INDEX_SIG); - il.append(new PUTSTATIC(namespaceArrayRef)); - staticConst.markChunkEnd(); + // Put the namespace names array into the translet + final Vector namespaces = getXSLTC().getNamespaceIndex(); + staticConst.markChunkStart(); + il.append(new PUSH(cpg, namespaces.size())); + il.append(new ANEWARRAY(cpg.addClass(STRING))); + int namespaceArrayRef = cpg.addFieldref(_className, + STATIC_NAMESPACE_ARRAY_FIELD, + NAMESPACE_INDEX_SIG); + il.append(new PUTSTATIC(namespaceArrayRef)); + staticConst.markChunkEnd(); - for (int i = 0; i < namespaces.size(); i++) { + for (int i = 0; i < namespaces.size(); i++) { final String ns = (String)namespaces.elementAt(i); - staticConst.markChunkStart(); + staticConst.markChunkStart(); il.append(new GETSTATIC(namespaceArrayRef)); il.append(new PUSH(cpg, i)); il.append(new PUSH(cpg, ns)); il.append(AASTORE); - staticConst.markChunkEnd(); - } - - // Create the namespace -> prefix map - staticConst.markChunkStart(); - il.append(new NEW(cpg.addClass(HASHMAP_CLASS))); - il.append(DUP); - final int init = cpg.addMethodref(HASHMAP_CLASS, "","()V"); - il.append(new INVOKESPECIAL(init)); - - int nsMapRef = cpg.addFieldref(_className, - STATIC_NS_MAP_FIELD, - MAP_SIG); - il.append(new PUTSTATIC(nsMapRef)); - staticConst.markChunkEnd(); - - - // Put the tree of stylesheet namespace declarations into the translet - final Vector namespaceAncestors = getXSLTC().getNSAncestorPointers(); - if (namespaceAncestors != null && namespaceAncestors.size() != 0) { - addStaticField(classGen, NS_ANCESTORS_INDEX_SIG, - STATIC_NS_ANCESTORS_ARRAY_FIELD); - staticConst.markChunkStart(); - il.append(new PUSH(cpg, namespaceAncestors.size())); - il.append(new NEWARRAY(BasicType.INT)); - int namespaceAncestorsArrayRef = - cpg.addFieldref(_className, STATIC_NS_ANCESTORS_ARRAY_FIELD, - NS_ANCESTORS_INDEX_SIG); - il.append(new PUTSTATIC(namespaceAncestorsArrayRef)); - staticConst.markChunkEnd(); - for (int i = 0; i < namespaceAncestors.size(); i++) { - int ancestor = ((Integer) namespaceAncestors.get(i)).intValue(); - staticConst.markChunkStart(); - il.append(new GETSTATIC(namespaceAncestorsArrayRef)); - il.append(new PUSH(cpg, i)); - il.append(new PUSH(cpg, ancestor)); - il.append(IASTORE); - staticConst.markChunkEnd(); - } - } - // Put the array of indices into the namespace prefix/URI pairs array - // into the translet - final Vector prefixURIPairsIdx = getXSLTC().getPrefixURIPairsIdx(); - if (prefixURIPairsIdx != null && prefixURIPairsIdx.size() != 0) { - addStaticField(classGen, PREFIX_URIS_IDX_SIG, - STATIC_PREFIX_URIS_IDX_ARRAY_FIELD); - staticConst.markChunkStart(); - il.append(new PUSH(cpg, prefixURIPairsIdx.size())); - il.append(new NEWARRAY(BasicType.INT)); - int prefixURIPairsIdxArrayRef = - cpg.addFieldref(_className, - STATIC_PREFIX_URIS_IDX_ARRAY_FIELD, - PREFIX_URIS_IDX_SIG); - il.append(new PUTSTATIC(prefixURIPairsIdxArrayRef)); - staticConst.markChunkEnd(); - for (int i = 0; i < prefixURIPairsIdx.size(); i++) { - int idx = ((Integer) prefixURIPairsIdx.get(i)).intValue(); - staticConst.markChunkStart(); - il.append(new GETSTATIC(prefixURIPairsIdxArrayRef)); - il.append(new PUSH(cpg, i)); - il.append(new PUSH(cpg, idx)); - il.append(IASTORE); - staticConst.markChunkEnd(); - } - } - - // Put the array of pairs of namespace prefixes and URIs into the - // translet - final Vector prefixURIPairs = getXSLTC().getPrefixURIPairs(); - if (prefixURIPairs != null && prefixURIPairs.size() != 0) { - addStaticField(classGen, PREFIX_URIS_ARRAY_SIG, - STATIC_PREFIX_URIS_ARRAY_FIELD); - - staticConst.markChunkStart(); - il.append(new PUSH(cpg, prefixURIPairs.size())); - il.append(new ANEWARRAY(cpg.addClass(STRING))); - int prefixURIPairsRef = - cpg.addFieldref(_className, - STATIC_PREFIX_URIS_ARRAY_FIELD, - PREFIX_URIS_ARRAY_SIG); - il.append(new PUTSTATIC(prefixURIPairsRef)); - staticConst.markChunkEnd(); - for (int i = 0; i < prefixURIPairs.size(); i++) { - String prefixOrURI = (String) prefixURIPairs.get(i); + staticConst.markChunkEnd(); + } + + // Create the namespace -> prefix map staticConst.markChunkStart(); - il.append(new GETSTATIC(prefixURIPairsRef)); - il.append(new PUSH(cpg, i)); - il.append(new PUSH(cpg, prefixOrURI)); - il.append(AASTORE); + il.append(new NEW(cpg.addClass(HASHMAP_CLASS))); + il.append(DUP); + final int init = cpg.addMethodref(HASHMAP_CLASS, "","()V"); + il.append(new INVOKESPECIAL(init)); + + int nsMapRef = cpg.addFieldref(_className, + STATIC_NS_MAP_FIELD, + MAP_SIG); + il.append(new PUTSTATIC(nsMapRef)); staticConst.markChunkEnd(); - } - } - // Grab all the literal text in the stylesheet and put it in a char[] - final int charDataCount = getXSLTC().getCharacterDataCount(); - final int toCharArray = cpg.addMethodref(STRING, "toCharArray", "()[C"); - for (int i = 0; i < charDataCount; i++) { - staticConst.markChunkStart(); - il.append(new PUSH(cpg, getXSLTC().getCharacterData(i))); - il.append(new INVOKEVIRTUAL(toCharArray)); - il.append(new PUTSTATIC(cpg.addFieldref(_className, - STATIC_CHAR_DATA_FIELD+i, - STATIC_CHAR_DATA_FIELD_SIG))); - staticConst.markChunkEnd(); - } - il.append(RETURN); + // Put the tree of stylesheet namespace declarations into the translet + final Vector namespaceAncestors = getXSLTC().getNSAncestorPointers(); + if (namespaceAncestors != null && namespaceAncestors.size() != 0) { + addStaticField(classGen, NS_ANCESTORS_INDEX_SIG, + STATIC_NS_ANCESTORS_ARRAY_FIELD); + staticConst.markChunkStart(); + il.append(new PUSH(cpg, namespaceAncestors.size())); + il.append(new NEWARRAY(BasicType.INT)); + int namespaceAncestorsArrayRef = + cpg.addFieldref(_className, STATIC_NS_ANCESTORS_ARRAY_FIELD, + NS_ANCESTORS_INDEX_SIG); + il.append(new PUTSTATIC(namespaceAncestorsArrayRef)); + staticConst.markChunkEnd(); + for (int i = 0; i < namespaceAncestors.size(); i++) { + int ancestor = ((Integer) namespaceAncestors.get(i)).intValue(); + staticConst.markChunkStart(); + il.append(new GETSTATIC(namespaceAncestorsArrayRef)); + il.append(new PUSH(cpg, i)); + il.append(new PUSH(cpg, ancestor)); + il.append(IASTORE); + staticConst.markChunkEnd(); + } + } + // Put the array of indices into the namespace prefix/URI pairs array + // into the translet + final Vector prefixURIPairsIdx = getXSLTC().getPrefixURIPairsIdx(); + if (prefixURIPairsIdx != null && prefixURIPairsIdx.size() != 0) { + addStaticField(classGen, PREFIX_URIS_IDX_SIG, + STATIC_PREFIX_URIS_IDX_ARRAY_FIELD); + staticConst.markChunkStart(); + il.append(new PUSH(cpg, prefixURIPairsIdx.size())); + il.append(new NEWARRAY(BasicType.INT)); + int prefixURIPairsIdxArrayRef = + cpg.addFieldref(_className, + STATIC_PREFIX_URIS_IDX_ARRAY_FIELD, + PREFIX_URIS_IDX_SIG); + il.append(new PUTSTATIC(prefixURIPairsIdxArrayRef)); + staticConst.markChunkEnd(); + for (int i = 0; i < prefixURIPairsIdx.size(); i++) { + int idx = ((Integer) prefixURIPairsIdx.get(i)).intValue(); + staticConst.markChunkStart(); + il.append(new GETSTATIC(prefixURIPairsIdxArrayRef)); + il.append(new PUSH(cpg, i)); + il.append(new PUSH(cpg, idx)); + il.append(IASTORE); + staticConst.markChunkEnd(); + } + } + + // Put the array of pairs of namespace prefixes and URIs into the + // translet + final Vector prefixURIPairs = getXSLTC().getPrefixURIPairs(); + if (prefixURIPairs != null && prefixURIPairs.size() != 0) { + addStaticField(classGen, PREFIX_URIS_ARRAY_SIG, + STATIC_PREFIX_URIS_ARRAY_FIELD); + + staticConst.markChunkStart(); + il.append(new PUSH(cpg, prefixURIPairs.size())); + il.append(new ANEWARRAY(cpg.addClass(STRING))); + int prefixURIPairsRef = + cpg.addFieldref(_className, + STATIC_PREFIX_URIS_ARRAY_FIELD, + PREFIX_URIS_ARRAY_SIG); + il.append(new PUTSTATIC(prefixURIPairsRef)); + staticConst.markChunkEnd(); + for (int i = 0; i < prefixURIPairs.size(); i++) { + String prefixOrURI = (String) prefixURIPairs.get(i); + staticConst.markChunkStart(); + il.append(new GETSTATIC(prefixURIPairsRef)); + il.append(new PUSH(cpg, i)); + il.append(new PUSH(cpg, prefixOrURI)); + il.append(AASTORE); + staticConst.markChunkEnd(); + } + } - classGen.addMethod(staticConst); + // Grab all the literal text in the stylesheet and put it in a char[] + final int charDataCount = getXSLTC().getCharacterDataCount(); + final int toCharArray = cpg.addMethodref(STRING, "toCharArray", "()[C"); + for (int i = 0; i < charDataCount; i++) { + staticConst.markChunkStart(); + il.append(new PUSH(cpg, getXSLTC().getCharacterData(i))); + il.append(new INVOKEVIRTUAL(toCharArray)); + il.append(new PUTSTATIC(cpg.addFieldref(_className, + STATIC_CHAR_DATA_FIELD+i, + STATIC_CHAR_DATA_FIELD_SIG))); + staticConst.markChunkEnd(); + } + + il.append(RETURN); + + classGen.addMethod(staticConst); - } + } - /** - * Compile the translet's constructor - */ - private void compileConstructor(ClassGenerator classGen, Output output) { + /** + * Compile the translet's constructor + */ + private void compileConstructor(ClassGenerator classGen, Output output) { - final ConstantPoolGen cpg = classGen.getConstantPool(); - final InstructionList il = new InstructionList(); + final ConstantPoolGen cpg = classGen.getConstantPool(); + final InstructionList il = new InstructionList(); - final MethodGenerator constructor = + final MethodGenerator constructor = new MethodGenerator(ACC_PUBLIC, - org.apache.bcel.generic.Type.VOID, - null, null, "", - _className, il, cpg); - - // Call the constructor in the AbstractTranslet superclass - il.append(classGen.loadTranslet()); - il.append(new INVOKESPECIAL(cpg.addMethodref(TRANSLET_CLASS, - "", "()V"))); + org.apache.bcel.generic.Type.VOID, + null, null, "", + _className, il, cpg); + + // Call the constructor in the AbstractTranslet superclass + il.append(classGen.loadTranslet()); + il.append(new INVOKESPECIAL(cpg.addMethodref(TRANSLET_CLASS, + "", "()V"))); - constructor.markChunkStart(); - il.append(classGen.loadTranslet()); - il.append(new GETSTATIC(cpg.addFieldref(_className, - STATIC_NAMES_ARRAY_FIELD, - NAMES_INDEX_SIG))); - il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, - NAMES_INDEX, - NAMES_INDEX_SIG))); - constructor.markChunkEnd(); + constructor.markChunkStart(); + il.append(classGen.loadTranslet()); + il.append(new GETSTATIC(cpg.addFieldref(_className, + STATIC_NAMES_ARRAY_FIELD, + NAMES_INDEX_SIG))); + il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, + NAMES_INDEX, + NAMES_INDEX_SIG))); + constructor.markChunkEnd(); - constructor.markChunkStart(); - il.append(classGen.loadTranslet()); - il.append(new GETSTATIC(cpg.addFieldref(_className, - STATIC_URIS_ARRAY_FIELD, - URIS_INDEX_SIG))); - il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, - URIS_INDEX, - URIS_INDEX_SIG))); - constructor.markChunkEnd(); - - constructor.markChunkStart(); - il.append(classGen.loadTranslet()); - il.append(new GETSTATIC(cpg.addFieldref(_className, - STATIC_TYPES_ARRAY_FIELD, - TYPES_INDEX_SIG))); - il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, - TYPES_INDEX, - TYPES_INDEX_SIG))); - constructor.markChunkEnd(); - - constructor.markChunkStart(); - il.append(classGen.loadTranslet()); - il.append(new GETSTATIC(cpg.addFieldref(_className, - STATIC_NAMESPACE_ARRAY_FIELD, - NAMESPACE_INDEX_SIG))); - il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, - NAMESPACE_INDEX, - NAMESPACE_INDEX_SIG))); - constructor.markChunkEnd(); - - constructor.markChunkStart(); - il.append(classGen.loadTranslet()); - il.append(new PUSH(cpg, AbstractTranslet.CURRENT_TRANSLET_VERSION)); - il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, - TRANSLET_VERSION_INDEX, - TRANSLET_VERSION_INDEX_SIG))); - constructor.markChunkEnd(); + constructor.markChunkStart(); + il.append(classGen.loadTranslet()); + il.append(new GETSTATIC(cpg.addFieldref(_className, + STATIC_URIS_ARRAY_FIELD, + URIS_INDEX_SIG))); + il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, + URIS_INDEX, + URIS_INDEX_SIG))); + constructor.markChunkEnd(); + + constructor.markChunkStart(); + il.append(classGen.loadTranslet()); + il.append(new GETSTATIC(cpg.addFieldref(_className, + STATIC_TYPES_ARRAY_FIELD, + TYPES_INDEX_SIG))); + il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, + TYPES_INDEX, + TYPES_INDEX_SIG))); + constructor.markChunkEnd(); + + constructor.markChunkStart(); + il.append(classGen.loadTranslet()); + il.append(new GETSTATIC(cpg.addFieldref(_className, + STATIC_NAMESPACE_ARRAY_FIELD, + NAMESPACE_INDEX_SIG))); + il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, + NAMESPACE_INDEX, + NAMESPACE_INDEX_SIG))); + constructor.markChunkEnd(); + + constructor.markChunkStart(); + il.append(classGen.loadTranslet()); + il.append(new PUSH(cpg, AbstractTranslet.CURRENT_TRANSLET_VERSION)); + il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, + TRANSLET_VERSION_INDEX, + TRANSLET_VERSION_INDEX_SIG))); + constructor.markChunkEnd(); - if (_hasIdCall) { - constructor.markChunkStart(); + if (_hasIdCall) { + constructor.markChunkStart(); il.append(classGen.loadTranslet()); il.append(new PUSH(cpg, Boolean.TRUE)); il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, - HASIDCALL_INDEX, - HASIDCALL_INDEX_SIG))); - constructor.markChunkEnd(); - } + HASIDCALL_INDEX, + HASIDCALL_INDEX_SIG))); + constructor.markChunkEnd(); + } - // Compile in code to set the output configuration from - if (output != null) { + // Compile in code to set the output configuration from + if (output != null) { // Set all the output settings files in the translet - constructor.markChunkStart(); + constructor.markChunkStart(); output.translate(classGen, constructor); - constructor.markChunkEnd(); - } + constructor.markChunkEnd(); + } - // Compile default decimal formatting symbols. - // This is an implicit, nameless xsl:decimal-format top-level element. - if (_numberFormattingUsed) { - constructor.markChunkStart(); + // Compile default decimal formatting symbols. + // This is an implicit, nameless xsl:decimal-format top-level element. + if (_numberFormattingUsed) { + constructor.markChunkStart(); DecimalFormatting.translateDefaultDFS(classGen, constructor); - constructor.markChunkEnd(); - } - - il.append(RETURN); - - classGen.addMethod(constructor); - } - - /** - * Compile a topLevel() method into the output class. This method is - * called from transform() to handle all non-template top-level elements. - * Returns the signature of the topLevel() method. - * - * Global variables/params and keys are first sorted to resolve - * dependencies between them. The XSLT 1.0 spec does not allow a key - * to depend on a variable. However, for compatibility with Xalan - * interpretive, that type of dependency is allowed. Note also that - * the buildKeys() method is still generated as it is used by the - * LoadDocument class, but it no longer called from transform(). - */ - private String compileTopLevel(ClassGenerator classGen) { - final ConstantPoolGen cpg = classGen.getConstantPool(); - - final org.apache.bcel.generic.Type[] argTypes = { + constructor.markChunkEnd(); + } + + il.append(RETURN); + + classGen.addMethod(constructor); + } + + /** + * Compile a topLevel() method into the output class. This method is + * called from transform() to handle all non-template top-level elements. + * Returns the signature of the topLevel() method. + * + * Global variables/params and keys are first sorted to resolve + * dependencies between them. The XSLT 1.0 spec does not allow a key + * to depend on a variable. However, for compatibility with Xalan + * interpretive, that type of dependency is allowed. Note also that + * the buildKeys() method is still generated as it is used by the + * LoadDocument class, but it no longer called from transform(). + */ + private String compileTopLevel(ClassGenerator classGen) { + final ConstantPoolGen cpg = classGen.getConstantPool(); + + final org.apache.bcel.generic.Type[] argTypes = { Util.getJCRefType(DOM_INTF_SIG), Util.getJCRefType(NODE_ITERATOR_SIG), Util.getJCRefType(TRANSLET_OUTPUT_SIG) - }; + }; - final String[] argNames = { + final String[] argNames = { DOCUMENT_PNAME, ITERATOR_PNAME, TRANSLET_OUTPUT_PNAME - }; + }; - final InstructionList il = new InstructionList(); + final InstructionList il = new InstructionList(); - final MethodGenerator toplevel = + final MethodGenerator toplevel = new MethodGenerator(ACC_PUBLIC, - org.apache.bcel.generic.Type.VOID, - argTypes, argNames, - "topLevel", _className, il, - classGen.getConstantPool()); + org.apache.bcel.generic.Type.VOID, + argTypes, argNames, + "topLevel", _className, il, + classGen.getConstantPool()); - toplevel.addException("org.apache.xalan.xsltc.TransletException"); + toplevel.addException("org.apache.xalan.xsltc.TransletException"); - // Define and initialize 'current' variable with the root node - final LocalVariableGen current = + // Define and initialize 'current' variable with the root node + final LocalVariableGen current = toplevel.addLocalVariable("current", org.apache.bcel.generic.Type.INT, null, null); - final int setFilter = cpg.addInterfaceMethodref(DOM_INTF, - "setFilter", - "(Lorg/apache/xalan/xsltc/StripFilter;)V"); + final int setFilter = cpg.addInterfaceMethodref(DOM_INTF, + "setFilter", + "(Lorg/apache/xalan/xsltc/StripFilter;)V"); - final int gitr = cpg.addInterfaceMethodref(DOM_INTF, - "getIterator", - "()"+NODE_ITERATOR_SIG); - il.append(toplevel.loadDOM()); - il.append(new INVOKEINTERFACE(gitr, 1)); - il.append(toplevel.nextNode()); - current.setStart(il.append(new ISTORE(current.getIndex()))); + final int gitr = cpg.addInterfaceMethodref(DOM_INTF, + "getIterator", + "()"+NODE_ITERATOR_SIG); + il.append(toplevel.loadDOM()); + il.append(new INVOKEINTERFACE(gitr, 1)); + il.append(toplevel.nextNode()); + current.setStart(il.append(new ISTORE(current.getIndex()))); // Create a new list containing variables/params + keys Vector varDepElements = new Vector(_globals); Enumeration elements = elements(); while (elements.hasMoreElements()) { - final Object element = elements.nextElement(); - if (element instanceof Key) { - varDepElements.add(element); - } + final Object element = elements.nextElement(); + if (element instanceof Key) { + varDepElements.add(element); + } } // Determine a partial order for the variables/params and keys @@ -1205,266 +1205,266 @@ private String compileTopLevel(ClassGenerator classGen) { // Translate vars/params and keys in the right order final int count = varDepElements.size(); for (int i = 0; i < count; i++) { - final TopLevelElement tle = (TopLevelElement) varDepElements.elementAt(i); - tle.translate(classGen, toplevel); - if (tle instanceof Key) { - final Key key = (Key) tle; - _keys.put(key.getName(), key); - } + final TopLevelElement tle = (TopLevelElement) varDepElements.elementAt(i); + tle.translate(classGen, toplevel); + if (tle instanceof Key) { + final Key key = (Key) tle; + _keys.put(key.getName(), key); + } } // Compile code for other top-level elements Vector whitespaceRules = new Vector(); elements = elements(); - while (elements.hasMoreElements()) { + while (elements.hasMoreElements()) { final Object element = elements.nextElement(); // xsl:decimal-format if (element instanceof DecimalFormatting) { - ((DecimalFormatting)element).translate(classGen,toplevel); + ((DecimalFormatting)element).translate(classGen,toplevel); } // xsl:strip/preserve-space else if (element instanceof Whitespace) { - whitespaceRules.addAll(((Whitespace)element).getRules()); + whitespaceRules.addAll(((Whitespace)element).getRules()); } - } + } - // Translate all whitespace strip/preserve rules - if (whitespaceRules.size() > 0) { + // Translate all whitespace strip/preserve rules + if (whitespaceRules.size() > 0) { Whitespace.translateRules(whitespaceRules,classGen); - } + } - if (classGen.containsMethod(STRIP_SPACE, STRIP_SPACE_PARAMS) != null) { + if (classGen.containsMethod(STRIP_SPACE, STRIP_SPACE_PARAMS) != null) { il.append(toplevel.loadDOM()); il.append(classGen.loadTranslet()); il.append(new INVOKEINTERFACE(setFilter, 2)); - } + } - il.append(RETURN); + il.append(RETURN); - // Compute max locals + stack and add method to class - classGen.addMethod(toplevel); + // Compute max locals + stack and add method to class + classGen.addMethod(toplevel); - return("("+DOM_INTF_SIG+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+")V"); - } + return("("+DOM_INTF_SIG+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+")V"); + } - /** - * This method returns a vector with variables/params and keys in the - * order in which they are to be compiled for initialization. The order - * is determined by analyzing the dependencies between them. The XSLT 1.0 - * spec does not allow a key to depend on a variable. However, for - * compatibility with Xalan interpretive, that type of dependency is - * allowed and, therefore, consider to determine the partial order. - */ - private Vector resolveDependencies(Vector input) { - /* DEBUG CODE - INGORE - for (int i = 0; i < input.size(); i++) { - final TopLevelElement e = (TopLevelElement) input.elementAt(i); - System.out.println("e = " + e + " depends on:"); - Vector dep = e.getDependencies(); - for (int j = 0; j < (dep != null ? dep.size() : 0); j++) { - System.out.println("\t" + dep.elementAt(j)); - } - } - System.out.println("================================="); - */ - - Vector result = new Vector(); - while (input.size() > 0) { + /** + * This method returns a vector with variables/params and keys in the + * order in which they are to be compiled for initialization. The order + * is determined by analyzing the dependencies between them. The XSLT 1.0 + * spec does not allow a key to depend on a variable. However, for + * compatibility with Xalan interpretive, that type of dependency is + * allowed and, therefore, consider to determine the partial order. + */ + private Vector resolveDependencies(Vector input) { + /* DEBUG CODE - INGORE + for (int i = 0; i < input.size(); i++) { + final TopLevelElement e = (TopLevelElement) input.elementAt(i); + System.out.println("e = " + e + " depends on:"); + Vector dep = e.getDependencies(); + for (int j = 0; j < (dep != null ? dep.size() : 0); j++) { + System.out.println("\t" + dep.elementAt(j)); + } + } + System.out.println("================================="); + */ + + Vector result = new Vector(); + while (input.size() > 0) { boolean changed = false; for (int i = 0; i < input.size(); ) { - final TopLevelElement vde = (TopLevelElement) input.elementAt(i); - final Vector dep = vde.getDependencies(); - if (dep == null || result.containsAll(dep)) { - result.addElement(vde); - input.remove(i); - changed = true; - } - else { - i++; - } + final TopLevelElement vde = (TopLevelElement) input.elementAt(i); + final Vector dep = vde.getDependencies(); + if (dep == null || result.containsAll(dep)) { + result.addElement(vde); + input.remove(i); + changed = true; + } + else { + i++; + } } // If nothing was changed in this pass then we have a circular ref if (!changed) { - ErrorMsg err = new ErrorMsg(ErrorMsg.CIRCULAR_VARIABLE_ERR, - input.toString(), this); - getParser().reportError(Constants.ERROR, err); - return(result); + ErrorMsg err = new ErrorMsg(ErrorMsg.CIRCULAR_VARIABLE_ERR, + input.toString(), this); + getParser().reportError(Constants.ERROR, err); + return(result); } - } + } - /* DEBUG CODE - INGORE - System.out.println("================================="); - for (int i = 0; i < result.size(); i++) { - final TopLevelElement e = (TopLevelElement) result.elementAt(i); - System.out.println("e = " + e); - } - */ + /* DEBUG CODE - INGORE + System.out.println("================================="); + for (int i = 0; i < result.size(); i++) { + final TopLevelElement e = (TopLevelElement) result.elementAt(i); + System.out.println("e = " + e); + } + */ - return result; - } + return result; + } - /** - * Compile a buildKeys() method into the output class. Note that keys - * for the input document are created in topLevel(), not in this method. - * However, we still need this method to create keys for documents loaded - * via the XPath document() function. - */ - private String compileBuildKeys(ClassGenerator classGen) { - final ConstantPoolGen cpg = classGen.getConstantPool(); + /** + * Compile a buildKeys() method into the output class. Note that keys + * for the input document are created in topLevel(), not in this method. + * However, we still need this method to create keys for documents loaded + * via the XPath document() function. + */ + private String compileBuildKeys(ClassGenerator classGen) { + final ConstantPoolGen cpg = classGen.getConstantPool(); - final org.apache.bcel.generic.Type[] argTypes = { + final org.apache.bcel.generic.Type[] argTypes = { Util.getJCRefType(DOM_INTF_SIG), Util.getJCRefType(NODE_ITERATOR_SIG), Util.getJCRefType(TRANSLET_OUTPUT_SIG), org.apache.bcel.generic.Type.INT - }; + }; - final String[] argNames = { + final String[] argNames = { DOCUMENT_PNAME, ITERATOR_PNAME, TRANSLET_OUTPUT_PNAME, "current" - }; + }; - final InstructionList il = new InstructionList(); + final InstructionList il = new InstructionList(); - final MethodGenerator buildKeys = + final MethodGenerator buildKeys = new MethodGenerator(ACC_PUBLIC, - org.apache.bcel.generic.Type.VOID, - argTypes, argNames, - "buildKeys", _className, il, - classGen.getConstantPool()); + org.apache.bcel.generic.Type.VOID, + argTypes, argNames, + "buildKeys", _className, il, + classGen.getConstantPool()); - buildKeys.addException("org.apache.xalan.xsltc.TransletException"); + buildKeys.addException("org.apache.xalan.xsltc.TransletException"); - final Enumeration elements = elements(); - while (elements.hasMoreElements()) { + final Enumeration elements = elements(); + while (elements.hasMoreElements()) { // xsl:key final Object element = elements.nextElement(); if (element instanceof Key) { - final Key key = (Key)element; - key.translate(classGen, buildKeys); - _keys.put(key.getName(),key); + final Key key = (Key)element; + key.translate(classGen, buildKeys); + _keys.put(key.getName(),key); } - } + } - il.append(RETURN); + il.append(RETURN); - // Add method to class - classGen.addMethod(buildKeys); + // Add method to class + classGen.addMethod(buildKeys); - return("("+DOM_INTF_SIG+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+"I)V"); - } - - /** - * Compile transform() into the output class. This method is used to - * initialize global variables and global parameters. The current node - * is set to be the document's root node. - */ - private void compileTransform(ClassGenerator classGen) { - final ConstantPoolGen cpg = classGen.getConstantPool(); - - /* - * Define the the method transform with the following signature: - * void transform(DOM, NodeIterator, HandlerBase) + return("("+DOM_INTF_SIG+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+"I)V"); + } + + /** + * Compile transform() into the output class. This method is used to + * initialize global variables and global parameters. The current node + * is set to be the document's root node. */ - final org.apache.bcel.generic.Type[] argTypes = + private void compileTransform(ClassGenerator classGen) { + final ConstantPoolGen cpg = classGen.getConstantPool(); + + /* + * Define the the method transform with the following signature: + * void transform(DOM, NodeIterator, HandlerBase) + */ + final org.apache.bcel.generic.Type[] argTypes = new org.apache.bcel.generic.Type[3]; - argTypes[0] = Util.getJCRefType(DOM_INTF_SIG); - argTypes[1] = Util.getJCRefType(NODE_ITERATOR_SIG); - argTypes[2] = Util.getJCRefType(TRANSLET_OUTPUT_SIG); + argTypes[0] = Util.getJCRefType(DOM_INTF_SIG); + argTypes[1] = Util.getJCRefType(NODE_ITERATOR_SIG); + argTypes[2] = Util.getJCRefType(TRANSLET_OUTPUT_SIG); - final String[] argNames = new String[3]; - argNames[0] = DOCUMENT_PNAME; - argNames[1] = ITERATOR_PNAME; - argNames[2] = TRANSLET_OUTPUT_PNAME; + final String[] argNames = new String[3]; + argNames[0] = DOCUMENT_PNAME; + argNames[1] = ITERATOR_PNAME; + argNames[2] = TRANSLET_OUTPUT_PNAME; - final InstructionList il = new InstructionList(); - final MethodGenerator transf = + final InstructionList il = new InstructionList(); + final MethodGenerator transf = new MethodGenerator(ACC_PUBLIC, - org.apache.bcel.generic.Type.VOID, - argTypes, argNames, - "transform", - _className, - il, - classGen.getConstantPool()); - transf.addException("org.apache.xalan.xsltc.TransletException"); - - // Define and initialize current with the root node - final LocalVariableGen current = + org.apache.bcel.generic.Type.VOID, + argTypes, argNames, + "transform", + _className, + il, + classGen.getConstantPool()); + transf.addException("org.apache.xalan.xsltc.TransletException"); + + // Define and initialize current with the root node + final LocalVariableGen current = transf.addLocalVariable("current", - org.apache.bcel.generic.Type.INT, - null, null); - final String applyTemplatesSig = classGen.getApplyTemplatesSig(); - final int applyTemplates = cpg.addMethodref(getClassName(), - "applyTemplates", - applyTemplatesSig); - final int domField = cpg.addFieldref(getClassName(), - DOM_FIELD, - DOM_INTF_SIG); - - // push translet for PUTFIELD - il.append(classGen.loadTranslet()); - // prepare appropriate DOM implementation + org.apache.bcel.generic.Type.INT, + null, null); + final String applyTemplatesSig = classGen.getApplyTemplatesSig(); + final int applyTemplates = cpg.addMethodref(getClassName(), + "applyTemplates", + applyTemplatesSig); + final int domField = cpg.addFieldref(getClassName(), + DOM_FIELD, + DOM_INTF_SIG); + + // push translet for PUTFIELD + il.append(classGen.loadTranslet()); + // prepare appropriate DOM implementation - if (isMultiDocument()) { + if (isMultiDocument()) { il.append(new NEW(cpg.addClass(MULTI_DOM_CLASS))); il.append(DUP); - } + } - il.append(classGen.loadTranslet()); - il.append(transf.loadDOM()); - il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS, - "makeDOMAdapter", - "("+DOM_INTF_SIG+")"+ - DOM_ADAPTER_SIG))); - // DOMAdapter is on the stack - - if (isMultiDocument()) { + il.append(classGen.loadTranslet()); + il.append(transf.loadDOM()); + il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS, + "makeDOMAdapter", + "("+DOM_INTF_SIG+")"+ + DOM_ADAPTER_SIG))); + // DOMAdapter is on the stack + + if (isMultiDocument()) { final int init = cpg.addMethodref(MULTI_DOM_CLASS, - "", - "("+DOM_INTF_SIG+")V"); + "", + "("+DOM_INTF_SIG+")V"); il.append(new INVOKESPECIAL(init)); // MultiDOM is on the stack - } + } - //store to _dom variable - il.append(new PUTFIELD(domField)); - - // continue with globals initialization - final int gitr = cpg.addInterfaceMethodref(DOM_INTF, - "getIterator", - "()"+NODE_ITERATOR_SIG); - il.append(transf.loadDOM()); - il.append(new INVOKEINTERFACE(gitr, 1)); - il.append(transf.nextNode()); - current.setStart(il.append(new ISTORE(current.getIndex()))); - - // Transfer the output settings to the output post-processor - il.append(classGen.loadTranslet()); - il.append(transf.loadHandler()); - final int index = cpg.addMethodref(TRANSLET_CLASS, - "transferOutputSettings", - "("+OUTPUT_HANDLER_SIG+")V"); - il.append(new INVOKEVIRTUAL(index)); - - /* - * Compile buildKeys() method. Note that this method is not - * invoked here as keys for the input document are now created - * in topLevel(). However, this method is still needed by the - * LoadDocument class. - */ - final String keySig = compileBuildKeys(classGen); - final int keyIdx = cpg.addMethodref(getClassName(), - "buildKeys", keySig); + //store to _dom variable + il.append(new PUTFIELD(domField)); + + // continue with globals initialization + final int gitr = cpg.addInterfaceMethodref(DOM_INTF, + "getIterator", + "()"+NODE_ITERATOR_SIG); + il.append(transf.loadDOM()); + il.append(new INVOKEINTERFACE(gitr, 1)); + il.append(transf.nextNode()); + current.setStart(il.append(new ISTORE(current.getIndex()))); + + // Transfer the output settings to the output post-processor + il.append(classGen.loadTranslet()); + il.append(transf.loadHandler()); + final int index = cpg.addMethodref(TRANSLET_CLASS, + "transferOutputSettings", + "("+OUTPUT_HANDLER_SIG+")V"); + il.append(new INVOKEVIRTUAL(index)); + + /* + * Compile buildKeys() method. Note that this method is not + * invoked here as keys for the input document are now created + * in topLevel(). However, this method is still needed by the + * LoadDocument class. + */ + final String keySig = compileBuildKeys(classGen); + final int keyIdx = cpg.addMethodref(getClassName(), + "buildKeys", keySig); - // Look for top-level elements that need handling - final Enumeration toplevel = elements(); - if (_globals.size() > 0 || toplevel.hasMoreElements()) { + // Look for top-level elements that need handling + final Enumeration toplevel = elements(); + if (_globals.size() > 0 || toplevel.hasMoreElements()) { // Compile method for handling top-level elements final String topLevelSig = compileTopLevel(classGen); // Get a reference to that method final int topLevelIdx = cpg.addMethodref(getClassName(), - "topLevel", - topLevelSig); + "topLevel", + topLevelSig); // Push all parameters on the stack and call topLevel() il.append(classGen.loadTranslet()); // The 'this' pointer il.append(classGen.loadTranslet()); @@ -1472,105 +1472,105 @@ private void compileTransform(ClassGenerator classGen) { il.append(transf.loadIterator()); il.append(transf.loadHandler()); // The output handler il.append(new INVOKEVIRTUAL(topLevelIdx)); - } - - // start document - il.append(transf.loadHandler()); - il.append(transf.startDocument()); - - // push first arg for applyTemplates - il.append(classGen.loadTranslet()); - // push translet for GETFIELD to get DOM arg - il.append(classGen.loadTranslet()); - il.append(new GETFIELD(domField)); - // push remaining 2 args - il.append(transf.loadIterator()); - il.append(transf.loadHandler()); - il.append(new INVOKEVIRTUAL(applyTemplates)); - // endDocument - il.append(transf.loadHandler()); - il.append(transf.endDocument()); - - il.append(RETURN); - - // Compute max locals + stack and add method to class - classGen.addMethod(transf); - } - - /** - * Peephole optimization: Remove sequences of [ALOAD, POP]. - */ - private void peepHoleOptimization(MethodGenerator methodGen) { - final String pattern = "`aload'`pop'`instruction'"; - final InstructionList il = methodGen.getInstructionList(); - final InstructionFinder find = new InstructionFinder(il); - for(Iterator iter=find.search(pattern); iter.hasNext(); ) { + } + + // start document + il.append(transf.loadHandler()); + il.append(transf.startDocument()); + + // push first arg for applyTemplates + il.append(classGen.loadTranslet()); + // push translet for GETFIELD to get DOM arg + il.append(classGen.loadTranslet()); + il.append(new GETFIELD(domField)); + // push remaining 2 args + il.append(transf.loadIterator()); + il.append(transf.loadHandler()); + il.append(new INVOKEVIRTUAL(applyTemplates)); + // endDocument + il.append(transf.loadHandler()); + il.append(transf.endDocument()); + + il.append(RETURN); + + // Compute max locals + stack and add method to class + classGen.addMethod(transf); + } + + /** + * Peephole optimization: Remove sequences of [ALOAD, POP]. + */ + private void peepHoleOptimization(MethodGenerator methodGen) { + final String pattern = "`aload'`pop'`instruction'"; + final InstructionList il = methodGen.getInstructionList(); + final InstructionFinder find = new InstructionFinder(il); + for(Iterator iter=find.search(pattern); iter.hasNext(); ) { InstructionHandle[] match = (InstructionHandle[])iter.next(); try { - il.delete(match[0], match[1]); + il.delete(match[0], match[1]); } catch (TargetLostException e) { - // TODO: move target down into the list - } + // TODO: move target down into the list + } + } } - } - - public int addParam(Param param) { - _globals.addElement(param); - return _globals.size() - 1; - } - public int addVariable(Variable global) { - _globals.addElement(global); - return _globals.size() - 1; - } + public int addParam(Param param) { + _globals.addElement(param); + return _globals.size() - 1; + } - public void display(int indent) { - indent(indent); - Util.println("Stylesheet"); - displayContents(indent + IndentIncrement); - } + public int addVariable(Variable global) { + _globals.addElement(global); + return _globals.size() - 1; + } - // do we need this wrapper ????? - public String getNamespace(String prefix) { - return lookupNamespace(prefix); - } + public void display(int indent) { + indent(indent); + Util.println("Stylesheet"); + displayContents(indent + IndentIncrement); + } - public String getClassName() { - return _className; - } + // do we need this wrapper ????? + public String getNamespace(String prefix) { + return lookupNamespace(prefix); + } - public Vector getTemplates() { - return _templates; - } + public String getClassName() { + return _className; + } - public Vector getAllValidTemplates() { - // Return templates if no imported/included stylesheets - if (_includedStylesheets == null) { - return _templates; + public Vector getTemplates() { + return _templates; } + + public Vector getAllValidTemplates() { + // Return templates if no imported/included stylesheets + if (_includedStylesheets == null) { + return _templates; + } - // Is returned value cached? - if (_allValidTemplates == null) { - Vector templates = new Vector(); - int size = _includedStylesheets.size(); - for (int i = 0; i < size; i++) { - Stylesheet included =(Stylesheet)_includedStylesheets.elementAt(i); - templates.addAll(included.getAllValidTemplates()); - } - templates.addAll(_templates); - - // Cache results in top-level stylesheet only - if (_parentStylesheet != null) { - return templates; - } - _allValidTemplates = templates; - } + // Is returned value cached? + if (_allValidTemplates == null) { + Vector templates = new Vector(); + int size = _includedStylesheets.size(); + for (int i = 0; i < size; i++) { + Stylesheet included =(Stylesheet)_includedStylesheets.elementAt(i); + templates.addAll(included.getAllValidTemplates()); + } + templates.addAll(_templates); + + // Cache results in top-level stylesheet only + if (_parentStylesheet != null) { + return templates; + } + _allValidTemplates = templates; + } - return _allValidTemplates; - } + return _allValidTemplates; + } - protected void addTemplate(Template template) { - _templates.addElement(template); - } + protected void addTemplate(Template template) { + _templates.addElement(template); + } } diff --git a/xalan/src/main/java/org/apache/xalan/xsltc/compiler/XslElement.java b/xalan/src/main/java/org/apache/xalan/xsltc/compiler/XslElement.java index 83a7249d8..2beaa06a5 100644 --- a/xalan/src/main/java/org/apache/xalan/xsltc/compiler/XslElement.java +++ b/xalan/src/main/java/org/apache/xalan/xsltc/compiler/XslElement.java @@ -44,56 +44,56 @@ */ final class XslElement extends Instruction { - private String _prefix; - private boolean _ignore = false; - private boolean _isLiteralName = true; - private boolean _isLiteralNamespace = false; - private AttributeValueTemplate _name; - private AttributeValueTemplate _namespace; - - /** - * Displays the contents of the element - */ - public void display(int indent) { - indent(indent); - Util.println("Element " + _name); - displayContents(indent + IndentIncrement); - } - - /** - * This method is now deprecated. The new implemation of this class - * never declares the default NS. - */ - public boolean declaresDefaultNS() { - return false; - } - - public void parseContents(Parser parser) { - final SymbolTable stable = parser.getSymbolTable(); - - // Handle the 'name' attribute - String name = getAttribute("name"); - if (name == EMPTYSTRING) { + private String _prefix; + private boolean _ignore = false; + private boolean _isLiteralName = true; + private boolean _isLiteralNamespace = false; + private AttributeValueTemplate _name; + private AttributeValueTemplate _namespace; + + /** + * Displays the contents of the element + */ + public void display(int indent) { + indent(indent); + Util.println("Element " + _name); + displayContents(indent + IndentIncrement); + } + + /** + * This method is now deprecated. The new implemation of this class + * never declares the default NS. + */ + public boolean declaresDefaultNS() { + return false; + } + + public void parseContents(Parser parser) { + final SymbolTable stable = parser.getSymbolTable(); + + // Handle the 'name' attribute + String name = getAttribute("name"); + if (name == EMPTYSTRING) { ErrorMsg msg = new ErrorMsg(ErrorMsg.ILLEGAL_ELEM_NAME_ERR, - name, this); + name, this); parser.reportError(WARNING, msg); parseChildren(parser); _ignore = true; // Ignore the element if the QName is invalid return; - } - - String namespace = getAttribute("namespace"); - - // Optimize compilation when name is known at compile time - _isLiteralName = Util.isLiteral(name); - if (_isLiteralName) { - if (!XML11Char.isXML11ValidQName(name)) { - ErrorMsg msg = new ErrorMsg(ErrorMsg.ILLEGAL_ELEM_NAME_ERR, - name, this); - parser.reportError(WARNING, msg); - parseChildren(parser); - _ignore = true; // Ignore the element if the QName is invalid - return; + } + + String namespace = getAttribute("namespace"); + + // Optimize compilation when name is known at compile time + _isLiteralName = Util.isLiteral(name); + if (_isLiteralName) { + if (!XML11Char.isXML11ValidQName(name)) { + ErrorMsg msg = new ErrorMsg(ErrorMsg.ILLEGAL_ELEM_NAME_ERR, + name, this); + parser.reportError(WARNING, msg); + parseChildren(parser); + _ignore = true; // Ignore the element if the QName is invalid + return; } final QName qname = parser.getQNameSafe(name); @@ -101,257 +101,257 @@ public void parseContents(Parser parser) { String local = qname.getLocalPart(); if (prefix == null) { - prefix = EMPTYSTRING; + prefix = EMPTYSTRING; } if (!hasAttribute("namespace")) { - namespace = lookupNamespace(prefix); - if (namespace == null) { - ErrorMsg err = new ErrorMsg(ErrorMsg.NAMESPACE_UNDEF_ERR, - prefix, this); - parser.reportError(WARNING, err); - parseChildren(parser); - _ignore = true; // Ignore the element if prefix is undeclared - return; - } - _prefix = prefix; - _namespace = new AttributeValueTemplate(namespace, parser, this); + namespace = lookupNamespace(prefix); + if (namespace == null) { + ErrorMsg err = new ErrorMsg(ErrorMsg.NAMESPACE_UNDEF_ERR, + prefix, this); + parser.reportError(WARNING, err); + parseChildren(parser); + _ignore = true; // Ignore the element if prefix is undeclared + return; + } + _prefix = prefix; + _namespace = new AttributeValueTemplate(namespace, parser, this); } else { - if (prefix == EMPTYSTRING) { - if (Util.isLiteral(namespace)) { - prefix = lookupPrefix(namespace); - if (prefix == null) { - prefix = stable.generateNamespacePrefix(); - } - } - - // Prepend prefix to local name - final StringBuffer newName = new StringBuffer(prefix); - if (prefix != EMPTYSTRING) { - newName.append(':'); - } - name = newName.append(local).toString(); - } - _prefix = prefix; - _namespace = new AttributeValueTemplate(namespace, parser, this); + if (prefix == EMPTYSTRING) { + if (Util.isLiteral(namespace)) { + prefix = lookupPrefix(namespace); + if (prefix == null) { + prefix = stable.generateNamespacePrefix(); + } + } + + // Prepend prefix to local name + final StringBuffer newName = new StringBuffer(prefix); + if (prefix != EMPTYSTRING) { + newName.append(':'); + } + name = newName.append(local).toString(); + } + _prefix = prefix; + _namespace = new AttributeValueTemplate(namespace, parser, this); } - } - else { - // name attribute contains variable parts. If there is no namespace - // attribute, the generated code needs to be prepared to look up - // any prefix in the stylesheet at run-time. - // if the namespace is literal, we can avoid generating a new - // prefix every time though - if (Util.isLiteral(namespace)) { - _isLiteralNamespace = true; - } - _namespace = (namespace == EMPTYSTRING) ? null : - new AttributeValueTemplate(namespace, parser, this); - } + } + else { + // name attribute contains variable parts. If there is no namespace + // attribute, the generated code needs to be prepared to look up + // any prefix in the stylesheet at run-time. + // if the namespace is literal, we can avoid generating a new + // prefix every time though + if (Util.isLiteral(namespace)) { + _isLiteralNamespace = true; + } + _namespace = (namespace == EMPTYSTRING) ? null : + new AttributeValueTemplate(namespace, parser, this); + } - _name = new AttributeValueTemplate(name, parser, this); + _name = new AttributeValueTemplate(name, parser, this); - final String useSets = getAttribute("use-attribute-sets"); - if (useSets.length() > 0) { - if (!Util.isValidQNames(useSets)) { - ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, useSets, this); - parser.reportError(Constants.ERROR, err); - } + final String useSets = getAttribute("use-attribute-sets"); + if (useSets.length() > 0) { + if (!Util.isValidQNames(useSets)) { + ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, useSets, this); + parser.reportError(Constants.ERROR, err); + } setFirstElement(new UseAttributeSets(useSets, parser)); - } + } - parseChildren(parser); - } + parseChildren(parser); + } - /** - * Run type check on element name & contents - */ - public Type typeCheck(SymbolTable stable) throws TypeCheckError { - if (!_ignore) { + /** + * Run type check on element name & contents + */ + public Type typeCheck(SymbolTable stable) throws TypeCheckError { + if (!_ignore) { _name.typeCheck(stable); if (_namespace != null) { - _namespace.typeCheck(stable); + _namespace.typeCheck(stable); } + } + typeCheckContents(stable); + return Type.Void; } - typeCheckContents(stable); - return Type.Void; - } - - /** - * This method is called when the name of the element is known at compile time. - * In this case, there is no need to inspect the element name at runtime to - * determine if a prefix exists, needs to be generated, etc. - */ - public void translateLiteral(ClassGenerator classGen, MethodGenerator methodGen) { - final ConstantPoolGen cpg = classGen.getConstantPool(); - final InstructionList il = methodGen.getInstructionList(); - - if (!_ignore) { + + /** + * This method is called when the name of the element is known at compile time. + * In this case, there is no need to inspect the element name at runtime to + * determine if a prefix exists, needs to be generated, etc. + */ + public void translateLiteral(ClassGenerator classGen, MethodGenerator methodGen) { + final ConstantPoolGen cpg = classGen.getConstantPool(); + final InstructionList il = methodGen.getInstructionList(); + + if (!_ignore) { il.append(methodGen.loadHandler()); _name.translate(classGen, methodGen); il.append(DUP2); il.append(methodGen.startElement()); if (_namespace != null) { - il.append(methodGen.loadHandler()); - il.append(new PUSH(cpg, _prefix)); - _namespace.translate(classGen,methodGen); - il.append(methodGen.namespace()); + il.append(methodGen.loadHandler()); + il.append(new PUSH(cpg, _prefix)); + _namespace.translate(classGen,methodGen); + il.append(methodGen.namespace()); } - } + } - translateContents(classGen, methodGen); + translateContents(classGen, methodGen); - if (!_ignore) { + if (!_ignore) { il.append(methodGen.endElement()); + } } - } - - /** - * At runtime the compilation of xsl:element results in code that: (i) - * evaluates the avt for the name, (ii) checks for a prefix in the name - * (iii) generates a new prefix and create a new qname when necessary - * (iv) calls startElement() on the handler (v) looks up a uri in the XML - * when the prefix is not known at compile time (vi) calls namespace() - * on the handler (vii) evaluates the contents (viii) calls endElement(). - */ - public void translate(ClassGenerator classGen, MethodGenerator methodGen) { - LocalVariableGen local = null; - final ConstantPoolGen cpg = classGen.getConstantPool(); - final InstructionList il = methodGen.getInstructionList(); - - // Optimize translation if element name is a literal - if (_isLiteralName) { + + /** + * At runtime the compilation of xsl:element results in code that: (i) + * evaluates the avt for the name, (ii) checks for a prefix in the name + * (iii) generates a new prefix and create a new qname when necessary + * (iv) calls startElement() on the handler (v) looks up a uri in the XML + * when the prefix is not known at compile time (vi) calls namespace() + * on the handler (vii) evaluates the contents (viii) calls endElement(). + */ + public void translate(ClassGenerator classGen, MethodGenerator methodGen) { + LocalVariableGen local = null; + final ConstantPoolGen cpg = classGen.getConstantPool(); + final InstructionList il = methodGen.getInstructionList(); + + // Optimize translation if element name is a literal + if (_isLiteralName) { translateLiteral(classGen, methodGen); return; - } + } - if (!_ignore) { + if (!_ignore) { - // if the qname is an AVT, then the qname has to be checked at runtime if it is a valid qname - LocalVariableGen nameValue = - methodGen.addLocalVariable2("nameValue", - Util.getJCRefType(STRING_SIG), - null); + // if the qname is an AVT, then the qname has to be checked at runtime if it is a valid qname + LocalVariableGen nameValue = + methodGen.addLocalVariable2("nameValue", + Util.getJCRefType(STRING_SIG), + null); - // store the name into a variable first so _name.translate only needs to be called once - _name.translate(classGen, methodGen); - nameValue.setStart(il.append(new ASTORE(nameValue.getIndex()))); - il.append(new ALOAD(nameValue.getIndex())); + // store the name into a variable first so _name.translate only needs to be called once + _name.translate(classGen, methodGen); + nameValue.setStart(il.append(new ASTORE(nameValue.getIndex()))); + il.append(new ALOAD(nameValue.getIndex())); - // call checkQName if the name is an AVT - final int check = cpg.addMethodref(BASIS_LIBRARY_CLASS, "checkQName", - "(" - +STRING_SIG - +")V"); - il.append(new INVOKESTATIC(check)); + // call checkQName if the name is an AVT + final int check = cpg.addMethodref(BASIS_LIBRARY_CLASS, "checkQName", + "(" + +STRING_SIG + +")V"); + il.append(new INVOKESTATIC(check)); - // Push handler for call to endElement() - il.append(methodGen.loadHandler()); + // Push handler for call to endElement() + il.append(methodGen.loadHandler()); - if (_namespace != null) { - // If the namespace is a literal, we'll want to avoid creating a new - // prefix for it - if(_isLiteralNamespace){ - // we want to call to BasisLibrary.addPrefix(String qname, String namespace, Map prefixMap); - // So store the namespace in a var - LocalVariableGen namespaceValue = methodGen.addLocalVariable2( - "namespaceValue", Util.getJCRefType(STRING_SIG), null); - _namespace.translate(classGen, methodGen); - namespaceValue.setStart(il.append(new ASTORE(namespaceValue.getIndex()))); - - String transletClassName = getXSLTC().getClassName(); - // load name value again - nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex()))); - - il.append(new ALOAD(namespaceValue.getIndex())); - il.append(new GETSTATIC(cpg.addFieldref( - transletClassName, - STATIC_NS_MAP_FIELD, - MAP_SIG))); - il.append( - new INVOKESTATIC( - cpg.addMethodref(BASIS_LIBRARY_CLASS, - ADD_NAMESPACE_PREFIX_REF, - ADD_NAMESPACE_PREFIX_SIG))); - namespaceValue.setEnd(il.append(new ALOAD(namespaceValue.getIndex()))); - } - else{ - // load name value again - nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex()))); - _namespace.translate(classGen, methodGen); - } - } - else { - // load name value again - nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex()))); - // If name is an AVT and namespace is not specified, need to - // look up any prefix in the stylesheet by calling - // BasisLibrary.lookupStylesheetQNameNamespace( - // name, stylesheetNode, ancestorsArray, - // prefixURIsIndexArray, prefixURIPairsArray, - // !ignoreDefaultNamespace) - String transletClassName = getXSLTC().getClassName(); - il.append(DUP); - il.append(new PUSH(cpg, getNodeIDForStylesheetNSLookup())); - il.append(new GETSTATIC(cpg.addFieldref( - transletClassName, - STATIC_NS_ANCESTORS_ARRAY_FIELD, - NS_ANCESTORS_INDEX_SIG))); - il.append(new GETSTATIC(cpg.addFieldref( - transletClassName, - STATIC_PREFIX_URIS_IDX_ARRAY_FIELD, - PREFIX_URIS_IDX_SIG))); - il.append(new GETSTATIC(cpg.addFieldref( - transletClassName, - STATIC_PREFIX_URIS_ARRAY_FIELD, - PREFIX_URIS_ARRAY_SIG))); - // Default namespace is significant - il.append(ICONST_0); - il.append( - new INVOKESTATIC( - cpg.addMethodref(BASIS_LIBRARY_CLASS, - LOOKUP_STYLESHEET_QNAME_NS_REF, - LOOKUP_STYLESHEET_QNAME_NS_SIG))); + if (_namespace != null) { + // If the namespace is a literal, we'll want to avoid creating a new + // prefix for it + if(_isLiteralNamespace){ + // we want to call to BasisLibrary.addPrefix(String qname, String namespace, Map prefixMap); + // So store the namespace in a var + LocalVariableGen namespaceValue = methodGen.addLocalVariable2( + "namespaceValue", Util.getJCRefType(STRING_SIG), null); + _namespace.translate(classGen, methodGen); + namespaceValue.setStart(il.append(new ASTORE(namespaceValue.getIndex()))); + + String transletClassName = getXSLTC().getClassName(); + // load name value again + nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex()))); + + il.append(new ALOAD(namespaceValue.getIndex())); + il.append(new GETSTATIC(cpg.addFieldref( + transletClassName, + STATIC_NS_MAP_FIELD, + MAP_SIG))); + il.append( + new INVOKESTATIC( + cpg.addMethodref(BASIS_LIBRARY_CLASS, + ADD_NAMESPACE_PREFIX_REF, + ADD_NAMESPACE_PREFIX_SIG))); + namespaceValue.setEnd(il.append(new ALOAD(namespaceValue.getIndex()))); + } + else{ + // load name value again + nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex()))); + _namespace.translate(classGen, methodGen); + } + } + else { + // load name value again + nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex()))); + // If name is an AVT and namespace is not specified, need to + // look up any prefix in the stylesheet by calling + // BasisLibrary.lookupStylesheetQNameNamespace( + // name, stylesheetNode, ancestorsArray, + // prefixURIsIndexArray, prefixURIPairsArray, + // !ignoreDefaultNamespace) + String transletClassName = getXSLTC().getClassName(); + il.append(DUP); + il.append(new PUSH(cpg, getNodeIDForStylesheetNSLookup())); + il.append(new GETSTATIC(cpg.addFieldref( + transletClassName, + STATIC_NS_ANCESTORS_ARRAY_FIELD, + NS_ANCESTORS_INDEX_SIG))); + il.append(new GETSTATIC(cpg.addFieldref( + transletClassName, + STATIC_PREFIX_URIS_IDX_ARRAY_FIELD, + PREFIX_URIS_IDX_SIG))); + il.append(new GETSTATIC(cpg.addFieldref( + transletClassName, + STATIC_PREFIX_URIS_ARRAY_FIELD, + PREFIX_URIS_ARRAY_SIG))); + // Default namespace is significant + il.append(ICONST_0); + il.append( + new INVOKESTATIC( + cpg.addMethodref(BASIS_LIBRARY_CLASS, + LOOKUP_STYLESHEET_QNAME_NS_REF, + LOOKUP_STYLESHEET_QNAME_NS_SIG))); } - // Push additional arguments + // Push additional arguments il.append(methodGen.loadHandler()); il.append(methodGen.loadDOM()); il.append(methodGen.loadCurrentNode()); - // Invoke BasisLibrary.startXslElemCheckQName() - il.append(new INVOKESTATIC( - cpg.addMethodref(BASIS_LIBRARY_CLASS, "startXslElement", - "(" + STRING_SIG - + STRING_SIG - + TRANSLET_OUTPUT_SIG - + DOM_INTF_SIG + "I)" + STRING_SIG))); + // Invoke BasisLibrary.startXslElemCheckQName() + il.append(new INVOKESTATIC( + cpg.addMethodref(BASIS_LIBRARY_CLASS, "startXslElement", + "(" + STRING_SIG + + STRING_SIG + + TRANSLET_OUTPUT_SIG + + DOM_INTF_SIG + "I)" + STRING_SIG))); - } + } - translateContents(classGen, methodGen); + translateContents(classGen, methodGen); - if (!_ignore) { + if (!_ignore) { il.append(methodGen.endElement()); + } } - } - /** - * Override this method to make sure that xsl:attributes are not - * copied to output if this xsl:element is to be ignored - */ - public void translateContents(ClassGenerator classGen, + /** + * Override this method to make sure that xsl:attributes are not + * copied to output if this xsl:element is to be ignored + */ + public void translateContents(ClassGenerator classGen, MethodGenerator methodGen) { - final int n = elementCount(); - for (int i = 0; i < n; i++) { + final int n = elementCount(); + for (int i = 0; i < n; i++) { final SyntaxTreeNode item = - (SyntaxTreeNode)getContents().elementAt(i); + (SyntaxTreeNode)getContents().elementAt(i); if (_ignore && item instanceof XslAttribute) continue; item.translate(classGen, methodGen); + } } - } } diff --git a/xalan/src/main/java/org/apache/xalan/xsltc/runtime/BasisLibrary.java b/xalan/src/main/java/org/apache/xalan/xsltc/runtime/BasisLibrary.java index 8af9ca99d..c0ff81884 100644 --- a/xalan/src/main/java/org/apache/xalan/xsltc/runtime/BasisLibrary.java +++ b/xalan/src/main/java/org/apache/xalan/xsltc/runtime/BasisLibrary.java @@ -61,192 +61,192 @@ */ public final class BasisLibrary { - private final static String EMPTYSTRING = ""; - - /** - * Standard function count(node-set) - */ - public static int countF(DTMAxisIterator iterator) { - return iterator.getLast(); - } - - /** - * Standard function position() - * @deprecated This method exists only for backwards compatibility with old - * translets. New code should not reference it. - */ - public static int positionF(DTMAxisIterator iterator) { - return iterator.isReverse() - ? iterator.getLast() - iterator.getPosition() + 1 - : iterator.getPosition(); - } - - /** - * XSLT Standard function sum(node-set). - * stringToDouble is inlined - */ - public static double sumF(DTMAxisIterator iterator, DOM dom) { - try { + private final static String EMPTYSTRING = ""; + + /** + * Standard function count(node-set) + */ + public static int countF(DTMAxisIterator iterator) { + return iterator.getLast(); + } + + /** + * Standard function position() + * @deprecated This method exists only for backwards compatibility with old + * translets. New code should not reference it. + */ + public static int positionF(DTMAxisIterator iterator) { + return iterator.isReverse() + ? iterator.getLast() - iterator.getPosition() + 1 + : iterator.getPosition(); + } + + /** + * XSLT Standard function sum(node-set). + * stringToDouble is inlined + */ + public static double sumF(DTMAxisIterator iterator, DOM dom) { + try { double result = 0.0; int node; while ((node = iterator.next()) != DTMAxisIterator.END) { - result += Double.parseDouble(dom.getStringValueX(node)); + result += Double.parseDouble(dom.getStringValueX(node)); } return result; - } - catch (NumberFormatException e) { + } + catch (NumberFormatException e) { return Double.NaN; + } } - } - /** - * XSLT Standard function string() - */ - public static String stringF(int node, DOM dom) { - return dom.getStringValueX(node); - } + /** + * XSLT Standard function string() + */ + public static String stringF(int node, DOM dom) { + return dom.getStringValueX(node); + } - /** - * XSLT Standard function string(value) - */ - public static String stringF(Object obj, DOM dom) { - if (obj instanceof DTMAxisIterator) { + /** + * XSLT Standard function string(value) + */ + public static String stringF(Object obj, DOM dom) { + if (obj instanceof DTMAxisIterator) { return dom.getStringValueX(((DTMAxisIterator)obj).reset().next()); - } - else if (obj instanceof Node) { + } + else if (obj instanceof Node) { return dom.getStringValueX(((Node)obj).node); - } - else if (obj instanceof DOM) { + } + else if (obj instanceof DOM) { return ((DOM)obj).getStringValue(); - } - else { + } + else { return obj.toString(); + } } - } - /** - * XSLT Standard function string(value) - */ - public static String stringF(Object obj, int node, DOM dom) { - if (obj instanceof DTMAxisIterator) { + /** + * XSLT Standard function string(value) + */ + public static String stringF(Object obj, int node, DOM dom) { + if (obj instanceof DTMAxisIterator) { return dom.getStringValueX(((DTMAxisIterator)obj).reset().next()); - } - else if (obj instanceof Node) { + } + else if (obj instanceof Node) { return dom.getStringValueX(((Node)obj).node); - } - else if (obj instanceof DOM) { + } + else if (obj instanceof DOM) { // When the first argument is a DOM we want the whole // DOM and not just a single node - that would not make sense. //return ((DOM)obj).getStringValueX(node); return ((DOM)obj).getStringValue(); - } - else if (obj instanceof Double) { + } + else if (obj instanceof Double) { Double d = (Double)obj; final String result = d.toString(); final int length = result.length(); if ((result.charAt(length-2)=='.') && - (result.charAt(length-1) == '0')) - return result.substring(0, length-2); + (result.charAt(length-1) == '0')) + return result.substring(0, length-2); else - return result; - } - else { + return result; + } + else { if (obj != null) - return obj.toString(); + return obj.toString(); else - return stringF(node, dom); - } - } - - /** - * XSLT Standard function number() - */ - public static double numberF(int node, DOM dom) { - return stringToReal(dom.getStringValueX(node)); - } - - /** - * XSLT Standard function number(value) - */ - public static double numberF(Object obj, DOM dom) { - if (obj instanceof Double) { - return ((Double) obj).doubleValue(); + return stringF(node, dom); + } } - else if (obj instanceof Integer) { - return ((Integer) obj).doubleValue(); + + /** + * XSLT Standard function number() + */ + public static double numberF(int node, DOM dom) { + return stringToReal(dom.getStringValueX(node)); } - else if (obj instanceof Boolean) { + + /** + * XSLT Standard function number(value) + */ + public static double numberF(Object obj, DOM dom) { + if (obj instanceof Double) { + return ((Double) obj).doubleValue(); + } + else if (obj instanceof Integer) { + return ((Integer) obj).doubleValue(); + } + else if (obj instanceof Boolean) { return ((Boolean) obj).booleanValue() ? 1.0 : 0.0; - } - else if (obj instanceof String) { + } + else if (obj instanceof String) { return stringToReal((String) obj); - } - else if (obj instanceof DTMAxisIterator) { + } + else if (obj instanceof DTMAxisIterator) { DTMAxisIterator iter = (DTMAxisIterator) obj; return stringToReal(dom.getStringValueX(iter.reset().next())); - } - else if (obj instanceof Node) { + } + else if (obj instanceof Node) { return stringToReal(dom.getStringValueX(((Node) obj).node)); - } - else if (obj instanceof DOM) { + } + else if (obj instanceof DOM) { return stringToReal(((DOM) obj).getStringValue()); - } - else { + } + else { final String className = obj.getClass().getName(); runTimeError(INVALID_ARGUMENT_ERR, className, "number()"); return 0.0; + } + } + + /** + * XSLT Standard function round() + */ + public static double roundF(double d) { + return (d<-0.5 || d>0.0)?Math.floor(d+0.5):((d==0.0)? + d:(Double.isNaN(d)?Double.NaN:-0.0)); } - } - - /** - * XSLT Standard function round() - */ - public static double roundF(double d) { - return (d<-0.5 || d>0.0)?Math.floor(d+0.5):((d==0.0)? - d:(Double.isNaN(d)?Double.NaN:-0.0)); - } - - /** - * XSLT Standard function boolean() - */ - public static boolean booleanF(Object obj) { - if (obj instanceof Double) { + + /** + * XSLT Standard function boolean() + */ + public static boolean booleanF(Object obj) { + if (obj instanceof Double) { final double temp = ((Double) obj).doubleValue(); return temp != 0.0 && !Double.isNaN(temp); - } - else if (obj instanceof Integer) { + } + else if (obj instanceof Integer) { return ((Integer) obj).doubleValue() != 0; - } - else if (obj instanceof Boolean) { + } + else if (obj instanceof Boolean) { return ((Boolean) obj).booleanValue(); - } - else if (obj instanceof String) { + } + else if (obj instanceof String) { return !((String) obj).equals(EMPTYSTRING); - } - else if (obj instanceof DTMAxisIterator) { + } + else if (obj instanceof DTMAxisIterator) { DTMAxisIterator iter = (DTMAxisIterator) obj; return iter.reset().next() != DTMAxisIterator.END; - } - else if (obj instanceof Node) { + } + else if (obj instanceof Node) { return true; - } - else if (obj instanceof DOM) { + } + else if (obj instanceof DOM) { String temp = ((DOM) obj).getStringValue(); return !temp.equals(EMPTYSTRING); - } - else { + } + else { final String className = obj.getClass().getName(); runTimeError(INVALID_ARGUMENT_ERR, className, "boolean()"); + } + return false; } - return false; - } - /** - * XSLT Standard function substring(). Must take a double because of - * conversions resulting into NaNs and rounding. - */ - public static String substringF(String value, double start) { - try { + /** + * XSLT Standard function substring(). Must take a double because of + * conversions resulting into NaNs and rounding. + */ + public static String substringF(String value, double start) { + try { final int strlen = value.length(); int istart = (int)Math.round(start) - 1; @@ -255,19 +255,19 @@ public static String substringF(String value, double start) { if (istart < 1) istart = 0; return value.substring(istart); - } - catch (IndexOutOfBoundsException e) { + } + catch (IndexOutOfBoundsException e) { runTimeError(RUN_TIME_INTERNAL_ERR, "substring()"); return null; + } } - } - /** - * XSLT Standard function substring(). Must take a double because of - * conversions resulting into NaNs and rounding. - */ - public static String substringF(String value, double start, double length) { - try { + /** + * XSLT Standard function substring(). Must take a double because of + * conversions resulting into NaNs and rounding. + */ + public static String substringF(String value, double start, double length) { + try { final int strlen = value.length(); int istart = (int)Math.round(start) - 1; int isum = istart + (int)Math.round(length); @@ -275,207 +275,207 @@ public static String substringF(String value, double start, double length) { if (Double.isInfinite(length)) isum = Integer.MAX_VALUE; if (Double.isNaN(start) || Double.isNaN(length)) - return(EMPTYSTRING); + return(EMPTYSTRING); if (Double.isInfinite(start)) return(EMPTYSTRING); if (istart > strlen) return(EMPTYSTRING); if (isum < 0) return(EMPTYSTRING); if (istart < 0) istart = 0; if (isum > strlen) - return value.substring(istart); + return value.substring(istart); else - return value.substring(istart, isum); - } - catch (IndexOutOfBoundsException e) { + return value.substring(istart, isum); + } + catch (IndexOutOfBoundsException e) { runTimeError(RUN_TIME_INTERNAL_ERR, "substring()"); return null; + } } - } - /** - * XSLT Standard function substring-after(). - */ - public static String substring_afterF(String value, String substring) { - final int index = value.indexOf(substring); - if (index >= 0) + /** + * XSLT Standard function substring-after(). + */ + public static String substring_afterF(String value, String substring) { + final int index = value.indexOf(substring); + if (index >= 0) return value.substring(index + substring.length()); - else + else return EMPTYSTRING; - } - - /** - * XSLT Standard function substring-before(). - */ - public static String substring_beforeF(String value, String substring) { - final int index = value.indexOf(substring); - if (index >= 0) + } + + /** + * XSLT Standard function substring-before(). + */ + public static String substring_beforeF(String value, String substring) { + final int index = value.indexOf(substring); + if (index >= 0) return value.substring(0, index); - else + else return EMPTYSTRING; - } - - /** - * XSLT Standard function translate(). - */ - public static String translateF(String value, String from, String to) { - final int tol = to.length(); - final int froml = from.length(); - final int valuel = value.length(); - - final StringBuffer result = new StringBuffer(); - for (int j, i = 0; i < valuel; i++) { + } + + /** + * XSLT Standard function translate(). + */ + public static String translateF(String value, String from, String to) { + final int tol = to.length(); + final int froml = from.length(); + final int valuel = value.length(); + + final StringBuffer result = new StringBuffer(); + for (int j, i = 0; i < valuel; i++) { final char ch = value.charAt(i); for (j = 0; j < froml; j++) { - if (ch == from.charAt(j)) { - if (j < tol) - result.append(to.charAt(j)); - break; - } + if (ch == from.charAt(j)) { + if (j < tol) + result.append(to.charAt(j)); + break; + } } if (j == froml) - result.append(ch); - } - return result.toString(); - } - - /** - * XSLT Standard function normalize-space(). - */ - public static String normalize_spaceF(int node, DOM dom) { - return normalize_spaceF(dom.getStringValueX(node)); - } - - /** - * XSLT Standard function normalize-space(string). - */ - public static String normalize_spaceF(String value) { - int i = 0, n = value.length(); - StringBuffer result = new StringBuffer(); - - while (i < n && isWhiteSpace(value.charAt(i))) + result.append(ch); + } + return result.toString(); + } + + /** + * XSLT Standard function normalize-space(). + */ + public static String normalize_spaceF(int node, DOM dom) { + return normalize_spaceF(dom.getStringValueX(node)); + } + + /** + * XSLT Standard function normalize-space(string). + */ + public static String normalize_spaceF(String value) { + int i = 0, n = value.length(); + StringBuffer result = new StringBuffer(); + + while (i < n && isWhiteSpace(value.charAt(i))) i++; - while (true) { + while (true) { while (i < n && !isWhiteSpace(value.charAt(i))) { - result.append(value.charAt(i++)); + result.append(value.charAt(i++)); } if (i == n) - break; + break; while (i < n && isWhiteSpace(value.charAt(i))) { - i++; + i++; } if (i < n) - result.append(' '); + result.append(' '); + } + return result.toString(); } - return result.toString(); - } - /** - * XSLT Standard function generate-id(). - */ - public static String generate_idF(int node) { - if (node > 0) + /** + * XSLT Standard function generate-id(). + */ + public static String generate_idF(int node) { + if (node > 0) // Only generate ID if node exists return "N" + node; - else + else // Otherwise return an empty string return EMPTYSTRING; - } + } - /** - * utility function for calls to local-name(). - */ - public static String getLocalName(String value) { - int idx = value.lastIndexOf(':'); - if (idx >= 0) value = value.substring(idx + 1); - idx = value.lastIndexOf('@'); - if (idx >= 0) value = value.substring(idx + 1); - return(value); - } - - /** - * External functions that cannot be resolved are replaced with a call - * to this method. This method will generate a runtime errors. A good - * stylesheet checks whether the function exists using conditional - * constructs, and never really tries to call it if it doesn't exist. - * But simple stylesheets may result in a call to this method. - * The compiler should generate a warning if it encounters a call to - * an unresolved external function. - */ - public static void unresolved_externalF(String name) { - runTimeError(EXTERNAL_FUNC_ERR, name); - } - - /** - * Utility function to throw a runtime error on the use of an extension - * function when the secure processing feature is set to true. - */ - public static void unallowed_extension_functionF(String name) { - runTimeError(UNALLOWED_EXTENSION_FUNCTION_ERR, name); - } - - /** - * Utility function to throw a runtime error on the use of an extension - * element when the secure processing feature is set to true. - */ - public static void unallowed_extension_elementF(String name) { - runTimeError(UNALLOWED_EXTENSION_ELEMENT_ERR, name); - } - - /** - * Utility function to throw a runtime error for an unsupported element. - * - * This is only used in forward-compatibility mode, when the control flow - * cannot be determined. In 1.0 mode, the error message is emitted at - * compile time. - */ - public static void unsupported_ElementF(String qname, boolean isExtension) { - if (isExtension) + /** + * utility function for calls to local-name(). + */ + public static String getLocalName(String value) { + int idx = value.lastIndexOf(':'); + if (idx >= 0) value = value.substring(idx + 1); + idx = value.lastIndexOf('@'); + if (idx >= 0) value = value.substring(idx + 1); + return(value); + } + + /** + * External functions that cannot be resolved are replaced with a call + * to this method. This method will generate a runtime errors. A good + * stylesheet checks whether the function exists using conditional + * constructs, and never really tries to call it if it doesn't exist. + * But simple stylesheets may result in a call to this method. + * The compiler should generate a warning if it encounters a call to + * an unresolved external function. + */ + public static void unresolved_externalF(String name) { + runTimeError(EXTERNAL_FUNC_ERR, name); + } + + /** + * Utility function to throw a runtime error on the use of an extension + * function when the secure processing feature is set to true. + */ + public static void unallowed_extension_functionF(String name) { + runTimeError(UNALLOWED_EXTENSION_FUNCTION_ERR, name); + } + + /** + * Utility function to throw a runtime error on the use of an extension + * element when the secure processing feature is set to true. + */ + public static void unallowed_extension_elementF(String name) { + runTimeError(UNALLOWED_EXTENSION_ELEMENT_ERR, name); + } + + /** + * Utility function to throw a runtime error for an unsupported element. + * + * This is only used in forward-compatibility mode, when the control flow + * cannot be determined. In 1.0 mode, the error message is emitted at + * compile time. + */ + public static void unsupported_ElementF(String qname, boolean isExtension) { + if (isExtension) runTimeError(UNSUPPORTED_EXT_ERR, qname); - else + else runTimeError(UNSUPPORTED_XSL_ERR, qname); - } - - /** - * XSLT Standard function namespace-uri(node-set). - */ - public static String namespace_uriF(DTMAxisIterator iter, DOM dom) { - return namespace_uriF(iter.next(), dom); - } - - /** - * XSLT Standard function system-property(name) - */ - public static String system_propertyF(String name) { - if (name.equals("xsl:version")) + } + + /** + * XSLT Standard function namespace-uri(node-set). + */ + public static String namespace_uriF(DTMAxisIterator iter, DOM dom) { + return namespace_uriF(iter.next(), dom); + } + + /** + * XSLT Standard function system-property(name) + */ + public static String system_propertyF(String name) { + if (name.equals("xsl:version")) return("1.0"); - if (name.equals("xsl:vendor")) + if (name.equals("xsl:vendor")) return("Apache Software Foundation (Xalan XSLTC)"); - if (name.equals("xsl:vendor-url")) + if (name.equals("xsl:vendor-url")) return("http://xml.apache.org/xalan-j"); - runTimeError(INVALID_ARGUMENT_ERR, name, "system-property()"); - return(EMPTYSTRING); - } - - /** - * XSLT Standard function namespace-uri(). - */ - public static String namespace_uriF(int node, DOM dom) { - final String value = dom.getNodeName(node); - final int colon = value.lastIndexOf(':'); - if (colon >= 0) + runTimeError(INVALID_ARGUMENT_ERR, name, "system-property()"); + return(EMPTYSTRING); + } + + /** + * XSLT Standard function namespace-uri(). + */ + public static String namespace_uriF(int node, DOM dom) { + final String value = dom.getNodeName(node); + final int colon = value.lastIndexOf(':'); + if (colon >= 0) return value.substring(0, colon); - else + else return EMPTYSTRING; - } - - /** - * Implements the object-type() extension function. - * - * @see EXSLT - */ - public static String objectTypeF(Object obj) + } + + /** + * Implements the object-type() extension function. + * + * @see EXSLT + */ + public static String objectTypeF(Object obj) { if (obj instanceof String) return "string"; @@ -491,34 +491,34 @@ else if (obj instanceof DTMAxisIterator) return "unknown"; } - /** - * Implements the nodeset() extension function. - */ - public static DTMAxisIterator nodesetF(Object obj) { - if (obj instanceof DOM) { - //final DOMAdapter adapter = (DOMAdapter) obj; - final DOM dom = (DOM)obj; - return new SingletonIterator(dom.getDocument(), true); - } - else if (obj instanceof DTMAxisIterator) { - return (DTMAxisIterator) obj; - } - else { + /** + * Implements the nodeset() extension function. + */ + public static DTMAxisIterator nodesetF(Object obj) { + if (obj instanceof DOM) { + //final DOMAdapter adapter = (DOMAdapter) obj; + final DOM dom = (DOM)obj; + return new SingletonIterator(dom.getDocument(), true); + } + else if (obj instanceof DTMAxisIterator) { + return (DTMAxisIterator) obj; + } + else { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, "node-set", className); return null; + } } - } - //-- Begin utility functions + //-- Begin utility functions - private static boolean isWhiteSpace(char ch) { - return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'; - } + private static boolean isWhiteSpace(char ch) { + return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'; + } - private static boolean compareStrings(String lstring, String rstring, - int op, DOM dom) { - switch (op) { + private static boolean compareStrings(String lstring, String rstring, + int op, DOM dom) { + switch (op) { case Operators.EQ: return lstring.equals(rstring); @@ -537,1232 +537,1232 @@ private static boolean compareStrings(String lstring, String rstring, case Operators.LE: return numberF(lstring, dom) <= numberF(rstring, dom); - default: + default: runTimeError(RUN_TIME_INTERNAL_ERR, "compare()"); return false; + } } - } - /** - * Utility function: node-set/node-set compare. - */ - public static boolean compare(DTMAxisIterator left, DTMAxisIterator right, + /** + * Utility function: node-set/node-set compare. + */ + public static boolean compare(DTMAxisIterator left, DTMAxisIterator right, int op, DOM dom) { - int lnode; - left.reset(); + int lnode; + left.reset(); - while ((lnode = left.next()) != DTMAxisIterator.END) { + while ((lnode = left.next()) != DTMAxisIterator.END) { final String lvalue = dom.getStringValueX(lnode); int rnode; right.reset(); while ((rnode = right.next()) != DTMAxisIterator.END) { - // String value must be the same if both nodes are the same - if (lnode == rnode) { - if (op == Operators.EQ) { - return true; - } else if (op == Operators.NE) { - continue; - } - } - if (compareStrings(lvalue, dom.getStringValueX(rnode), op, - dom)) { - return true; - } + // String value must be the same if both nodes are the same + if (lnode == rnode) { + if (op == Operators.EQ) { + return true; + } else if (op == Operators.NE) { + continue; + } + } + if (compareStrings(lvalue, dom.getStringValueX(rnode), op, + dom)) { + return true; + } } - } - return false; - } + } + return false; + } - public static boolean compare(int node, DTMAxisIterator iterator, + public static boolean compare(int node, DTMAxisIterator iterator, int op, DOM dom) { - //iterator.reset(); + //iterator.reset(); - int rnode; - String value; + int rnode; + String value; - switch(op) { + switch(op) { case Operators.EQ: - rnode = iterator.next(); - if (rnode != DTMAxisIterator.END) { - value = dom.getStringValueX(node); - do { - if (node == rnode - || value.equals(dom.getStringValueX(rnode))) { - return true; - } - } while ((rnode = iterator.next()) != DTMAxisIterator.END); - } + rnode = iterator.next(); + if (rnode != DTMAxisIterator.END) { + value = dom.getStringValueX(node); + do { + if (node == rnode + || value.equals(dom.getStringValueX(rnode))) { + return true; + } + } while ((rnode = iterator.next()) != DTMAxisIterator.END); + } break; case Operators.NE: - rnode = iterator.next(); - if (rnode != DTMAxisIterator.END) { - value = dom.getStringValueX(node); - do { - if (node != rnode - && !value.equals(dom.getStringValueX(rnode))) { - return true; - } - } while ((rnode = iterator.next()) != DTMAxisIterator.END); - } + rnode = iterator.next(); + if (rnode != DTMAxisIterator.END) { + value = dom.getStringValueX(node); + do { + if (node != rnode + && !value.equals(dom.getStringValueX(rnode))) { + return true; + } + } while ((rnode = iterator.next()) != DTMAxisIterator.END); + } break; case Operators.LT: // Assume we're comparing document order here while ((rnode = iterator.next()) != DTMAxisIterator.END) { - if (rnode > node) return true; + if (rnode > node) return true; } break; case Operators.GT: // Assume we're comparing document order here while ((rnode = iterator.next()) != DTMAxisIterator.END) { - if (rnode < node) return true; + if (rnode < node) return true; } break; - } - return(false); - } - - /** - * Utility function: node-set/number compare. - */ - public static boolean compare(DTMAxisIterator left, final double rnumber, + } + return(false); + } + + /** + * Utility function: node-set/number compare. + */ + public static boolean compare(DTMAxisIterator left, final double rnumber, final int op, DOM dom) { - int node; - //left.reset(); + int node; + //left.reset(); - switch (op) { + switch (op) { case Operators.EQ: while ((node = left.next()) != DTMAxisIterator.END) { - if (numberF(dom.getStringValueX(node), dom) == rnumber) - return true; + if (numberF(dom.getStringValueX(node), dom) == rnumber) + return true; } break; case Operators.NE: while ((node = left.next()) != DTMAxisIterator.END) { - if (numberF(dom.getStringValueX(node), dom) != rnumber) - return true; + if (numberF(dom.getStringValueX(node), dom) != rnumber) + return true; } break; case Operators.GT: while ((node = left.next()) != DTMAxisIterator.END) { - if (numberF(dom.getStringValueX(node), dom) > rnumber) - return true; + if (numberF(dom.getStringValueX(node), dom) > rnumber) + return true; } break; case Operators.LT: while ((node = left.next()) != DTMAxisIterator.END) { - if (numberF(dom.getStringValueX(node), dom) < rnumber) - return true; + if (numberF(dom.getStringValueX(node), dom) < rnumber) + return true; } break; case Operators.GE: while ((node = left.next()) != DTMAxisIterator.END) { - if (numberF(dom.getStringValueX(node), dom) >= rnumber) - return true; + if (numberF(dom.getStringValueX(node), dom) >= rnumber) + return true; } break; case Operators.LE: while ((node = left.next()) != DTMAxisIterator.END) { - if (numberF(dom.getStringValueX(node), dom) <= rnumber) - return true; + if (numberF(dom.getStringValueX(node), dom) <= rnumber) + return true; } break; - default: + default: runTimeError(RUN_TIME_INTERNAL_ERR, "compare()"); - } + } - return false; - } + return false; + } - /** - * Utility function: node-set/string comparison. - */ - public static boolean compare(DTMAxisIterator left, final String rstring, + /** + * Utility function: node-set/string comparison. + */ + public static boolean compare(DTMAxisIterator left, final String rstring, int op, DOM dom) { - int node; - //left.reset(); - while ((node = left.next()) != DTMAxisIterator.END) { + int node; + //left.reset(); + while ((node = left.next()) != DTMAxisIterator.END) { if (compareStrings(dom.getStringValueX(node), rstring, op, dom)) { - return true; + return true; } + } + return false; } - return false; - } - public static boolean compare(Object left, Object right, + public static boolean compare(Object left, Object right, int op, DOM dom) { - boolean result = false; - boolean hasSimpleArgs = hasSimpleType(left) && hasSimpleType(right); - - if (op != Operators.EQ && op != Operators.NE) { - // If node-boolean comparison -> convert node to boolean - if (left instanceof Node || right instanceof Node) { - if (left instanceof Boolean) { - right = new Boolean(booleanF(right)); - hasSimpleArgs = true; - } - if (right instanceof Boolean) { - left = new Boolean(booleanF(left)); - hasSimpleArgs = true; - } - } + boolean result = false; + boolean hasSimpleArgs = hasSimpleType(left) && hasSimpleType(right); + + if (op != Operators.EQ && op != Operators.NE) { + // If node-boolean comparison -> convert node to boolean + if (left instanceof Node || right instanceof Node) { + if (left instanceof Boolean) { + right = new Boolean(booleanF(right)); + hasSimpleArgs = true; + } + if (right instanceof Boolean) { + left = new Boolean(booleanF(left)); + hasSimpleArgs = true; + } + } - if (hasSimpleArgs) { - switch (op) { - case Operators.GT: - return numberF(left, dom) > numberF(right, dom); + if (hasSimpleArgs) { + switch (op) { + case Operators.GT: + return numberF(left, dom) > numberF(right, dom); - case Operators.LT: - return numberF(left, dom) < numberF(right, dom); + case Operators.LT: + return numberF(left, dom) < numberF(right, dom); - case Operators.GE: - return numberF(left, dom) >= numberF(right, dom); + case Operators.GE: + return numberF(left, dom) >= numberF(right, dom); - case Operators.LE: - return numberF(left, dom) <= numberF(right, dom); + case Operators.LE: + return numberF(left, dom) <= numberF(right, dom); - default: - runTimeError(RUN_TIME_INTERNAL_ERR, "compare()"); - } - } - // falls through - } + default: + runTimeError(RUN_TIME_INTERNAL_ERR, "compare()"); + } + } + // falls through + } - if (hasSimpleArgs) { - if (left instanceof Boolean || right instanceof Boolean) { - result = booleanF(left) == booleanF(right); - } - else if (left instanceof Double || right instanceof Double || - left instanceof Integer || right instanceof Integer) { - result = numberF(left, dom) == numberF(right, dom); - } - else { // compare them as strings - result = stringF(left, dom).equals(stringF(right, dom)); - } + if (hasSimpleArgs) { + if (left instanceof Boolean || right instanceof Boolean) { + result = booleanF(left) == booleanF(right); + } + else if (left instanceof Double || right instanceof Double || + left instanceof Integer || right instanceof Integer) { + result = numberF(left, dom) == numberF(right, dom); + } + else { // compare them as strings + result = stringF(left, dom).equals(stringF(right, dom)); + } - if (op == Operators.NE) { - result = !result; - } - } - else { - if (left instanceof Node) { - left = new SingletonIterator(((Node)left).node); - } - if (right instanceof Node) { - right = new SingletonIterator(((Node)right).node); - } + if (op == Operators.NE) { + result = !result; + } + } + else { + if (left instanceof Node) { + left = new SingletonIterator(((Node)left).node); + } + if (right instanceof Node) { + right = new SingletonIterator(((Node)right).node); + } - if (hasSimpleType(left) || - left instanceof DOM && right instanceof DTMAxisIterator) { - // swap operands and operator - final Object temp = right; right = left; left = temp; - op = Operators.swapOp(op); - } + if (hasSimpleType(left) || + left instanceof DOM && right instanceof DTMAxisIterator) { + // swap operands and operator + final Object temp = right; right = left; left = temp; + op = Operators.swapOp(op); + } - if (left instanceof DOM) { - if (right instanceof Boolean) { - result = ((Boolean)right).booleanValue(); - return result == (op == Operators.EQ); - } - - final String sleft = ((DOM)left).getStringValue(); - - if (right instanceof Number) { - result = ((Number)right).doubleValue() == - stringToReal(sleft); - } - else if (right instanceof String) { - result = sleft.equals((String)right); - } - else if (right instanceof DOM) { - result = sleft.equals(((DOM)right).getStringValue()); - } - - if (op == Operators.NE) { - result = !result; - } - return result; - } + if (left instanceof DOM) { + if (right instanceof Boolean) { + result = ((Boolean)right).booleanValue(); + return result == (op == Operators.EQ); + } + + final String sleft = ((DOM)left).getStringValue(); + + if (right instanceof Number) { + result = ((Number)right).doubleValue() == + stringToReal(sleft); + } + else if (right instanceof String) { + result = sleft.equals((String)right); + } + else if (right instanceof DOM) { + result = sleft.equals(((DOM)right).getStringValue()); + } + + if (op == Operators.NE) { + result = !result; + } + return result; + } - // Next, node-set/t for t in {real, string, node-set, result-tree} + // Next, node-set/t for t in {real, string, node-set, result-tree} - DTMAxisIterator iter = ((DTMAxisIterator)left).reset(); + DTMAxisIterator iter = ((DTMAxisIterator)left).reset(); - if (right instanceof DTMAxisIterator) { - result = compare(iter, (DTMAxisIterator)right, op, dom); - } - else if (right instanceof String) { - result = compare(iter, (String)right, op, dom); - } - else if (right instanceof Number) { - final double temp = ((Number)right).doubleValue(); - result = compare(iter, temp, op, dom); - } - else if (right instanceof Boolean) { - boolean temp = ((Boolean)right).booleanValue(); - result = (iter.reset().next() != DTMAxisIterator.END) == temp; - } - else if (right instanceof DOM) { - result = compare(iter, ((DOM)right).getStringValue(), - op, dom); - } - else if (right == null) { - return(false); - } - else { - final String className = right.getClass().getName(); - runTimeError(INVALID_ARGUMENT_ERR, className, "compare()"); - } - } - return result; + if (right instanceof DTMAxisIterator) { + result = compare(iter, (DTMAxisIterator)right, op, dom); + } + else if (right instanceof String) { + result = compare(iter, (String)right, op, dom); + } + else if (right instanceof Number) { + final double temp = ((Number)right).doubleValue(); + result = compare(iter, temp, op, dom); + } + else if (right instanceof Boolean) { + boolean temp = ((Boolean)right).booleanValue(); + result = (iter.reset().next() != DTMAxisIterator.END) == temp; + } + else if (right instanceof DOM) { + result = compare(iter, ((DOM)right).getStringValue(), + op, dom); + } + else if (right == null) { + return(false); + } + else { + final String className = right.getClass().getName(); + runTimeError(INVALID_ARGUMENT_ERR, className, "compare()"); + } + } + return result; } - /** - * Utility function: used to test context node's language - */ - public static boolean testLanguage(String testLang, DOM dom, int node) { - // language for context node (if any) - String nodeLang = dom.getLanguage(node); - if (nodeLang == null) + /** + * Utility function: used to test context node's language + */ + public static boolean testLanguage(String testLang, DOM dom, int node) { + // language for context node (if any) + String nodeLang = dom.getLanguage(node); + if (nodeLang == null) return(false); - else + else nodeLang = nodeLang.toLowerCase(); - // compare context node's language agains test language - testLang = testLang.toLowerCase(); - if (testLang.length() == 2) { + // compare context node's language agains test language + testLang = testLang.toLowerCase(); + if (testLang.length() == 2) { return(nodeLang.startsWith(testLang)); - } - else { + } + else { return(nodeLang.equals(testLang)); + } } - } - private static boolean hasSimpleType(Object obj) { - return obj instanceof Boolean || obj instanceof Double || + private static boolean hasSimpleType(Object obj) { + return obj instanceof Boolean || obj instanceof Double || obj instanceof Integer || obj instanceof String || obj instanceof Node || obj instanceof DOM; - } + } - /** - * Utility function: used in StringType to convert a string to a real. - */ - public static double stringToReal(String s) { - try { + /** + * Utility function: used in StringType to convert a string to a real. + */ + public static double stringToReal(String s) { + try { return Double.valueOf(s).doubleValue(); - } - catch (NumberFormatException e) { + } + catch (NumberFormatException e) { return Double.NaN; + } } - } - /** - * Utility function: used in StringType to convert a string to an int. - */ - public static int stringToInt(String s) { - try { + /** + * Utility function: used in StringType to convert a string to an int. + */ + public static int stringToInt(String s) { + try { return Integer.parseInt(s); - } - catch (NumberFormatException e) { + } + catch (NumberFormatException e) { return(-1); // ??? + } } - } - private static final int DOUBLE_FRACTION_DIGITS = 340; - private static final double lowerBounds = 0.001; - private static final double upperBounds = 10000000; - private static DecimalFormat defaultFormatter; - private static String defaultPattern = ""; + private static final int DOUBLE_FRACTION_DIGITS = 340; + private static final double lowerBounds = 0.001; + private static final double upperBounds = 10000000; + private static DecimalFormat defaultFormatter; + private static String defaultPattern = ""; - static { - NumberFormat f = NumberFormat.getInstance(Locale.getDefault()); - defaultFormatter = (f instanceof DecimalFormat) ? + static { + NumberFormat f = NumberFormat.getInstance(Locale.getDefault()); + defaultFormatter = (f instanceof DecimalFormat) ? (DecimalFormat) f : new DecimalFormat(); - // Set max fraction digits so that truncation does not occur. Setting - // the max to Integer.MAX_VALUE may cause problems with some JDK's. - defaultFormatter.setMaximumFractionDigits(DOUBLE_FRACTION_DIGITS); - defaultFormatter.setMinimumFractionDigits(0); - defaultFormatter.setMinimumIntegerDigits(1); - defaultFormatter.setGroupingUsed(false); - } - - /** - * Utility function: used in RealType to convert a real to a string. - * Removes the decimal if null. - */ - public static String realToString(double d) { - final double m = Math.abs(d); - if ((m >= lowerBounds) && (m < upperBounds)) { + // Set max fraction digits so that truncation does not occur. Setting + // the max to Integer.MAX_VALUE may cause problems with some JDK's. + defaultFormatter.setMaximumFractionDigits(DOUBLE_FRACTION_DIGITS); + defaultFormatter.setMinimumFractionDigits(0); + defaultFormatter.setMinimumIntegerDigits(1); + defaultFormatter.setGroupingUsed(false); + } + + /** + * Utility function: used in RealType to convert a real to a string. + * Removes the decimal if null. + */ + public static String realToString(double d) { + final double m = Math.abs(d); + if ((m >= lowerBounds) && (m < upperBounds)) { final String result = Double.toString(d); final int length = result.length(); // Remove leading zeros. if ((result.charAt(length-2) == '.') && - (result.charAt(length-1) == '0')) - return result.substring(0, length-2); + (result.charAt(length-1) == '0')) + return result.substring(0, length-2); else - return result; - } - else { + return result; + } + else { if (Double.isNaN(d) || Double.isInfinite(d)) - return(Double.toString(d)); + return(Double.toString(d)); return formatNumber(d, defaultPattern, defaultFormatter); + } } - } - - /** - * Utility function: used in RealType to convert a real to an integer - */ - public static int realToInt(double d) { - return (int)d; - } - - /** - * Utility function: used to format/adjust a double to a string. The - * DecimalFormat object comes from the 'formatSymbols' hashtable in - * AbstractTranslet. - */ - private static FieldPosition _fieldPosition = new FieldPosition(0); - - public static String formatNumber(double number, String pattern, - DecimalFormat formatter) { - // bugzilla fix 12813 - if (formatter == null) { - formatter = defaultFormatter; + + /** + * Utility function: used in RealType to convert a real to an integer + */ + public static int realToInt(double d) { + return (int)d; } - try { + + /** + * Utility function: used to format/adjust a double to a string. The + * DecimalFormat object comes from the 'formatSymbols' hashtable in + * AbstractTranslet. + */ + private static FieldPosition _fieldPosition = new FieldPosition(0); + + public static String formatNumber(double number, String pattern, + DecimalFormat formatter) { + // bugzilla fix 12813 + if (formatter == null) { + formatter = defaultFormatter; + } + try { StringBuffer result = new StringBuffer(); if (pattern != defaultPattern) { - formatter.applyLocalizedPattern(pattern); + formatter.applyLocalizedPattern(pattern); } - formatter.format(number, result, _fieldPosition); + formatter.format(number, result, _fieldPosition); return result.toString(); - } - catch (IllegalArgumentException e) { + } + catch (IllegalArgumentException e) { runTimeError(FORMAT_NUMBER_ERR, Double.toString(number), pattern); return(EMPTYSTRING); + } } - } - /** - * Utility function: used to convert references to node-sets. If the - * obj is an instanceof Node then create a singleton iterator. - */ - public static DTMAxisIterator referenceToNodeSet(Object obj) { - // Convert var/param -> node - if (obj instanceof Node) { + /** + * Utility function: used to convert references to node-sets. If the + * obj is an instanceof Node then create a singleton iterator. + */ + public static DTMAxisIterator referenceToNodeSet(Object obj) { + // Convert var/param -> node + if (obj instanceof Node) { return(new SingletonIterator(((Node)obj).node)); - } - // Convert var/param -> node-set - else if (obj instanceof DTMAxisIterator) { - return(((DTMAxisIterator)obj).cloneIterator().reset()); - } - else { + } + // Convert var/param -> node-set + else if (obj instanceof DTMAxisIterator) { + return(((DTMAxisIterator)obj).cloneIterator().reset()); + } + else { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, className, "node-set"); return null; + } } - } - /** - * Utility function: used to convert reference to org.w3c.dom.NodeList. - */ - public static NodeList referenceToNodeList(Object obj, DOM dom) { - if (obj instanceof Node || obj instanceof DTMAxisIterator) { - DTMAxisIterator iter = referenceToNodeSet(obj); - return dom.makeNodeList(iter); - } - else if (obj instanceof DOM) { - dom = (DOM)obj; - return dom.makeNodeList(DTMDefaultBase.ROOTNODE); - } - else { + /** + * Utility function: used to convert reference to org.w3c.dom.NodeList. + */ + public static NodeList referenceToNodeList(Object obj, DOM dom) { + if (obj instanceof Node || obj instanceof DTMAxisIterator) { + DTMAxisIterator iter = referenceToNodeSet(obj); + return dom.makeNodeList(iter); + } + else if (obj instanceof DOM) { + dom = (DOM)obj; + return dom.makeNodeList(DTMDefaultBase.ROOTNODE); + } + else { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, className, - "org.w3c.dom.NodeList"); + "org.w3c.dom.NodeList"); return null; + } } - } - /** - * Utility function: used to convert reference to org.w3c.dom.Node. - */ - public static org.w3c.dom.Node referenceToNode(Object obj, DOM dom) { - if (obj instanceof Node || obj instanceof DTMAxisIterator) { - DTMAxisIterator iter = referenceToNodeSet(obj); - return dom.makeNode(iter); - } - else if (obj instanceof DOM) { - dom = (DOM)obj; - DTMAxisIterator iter = dom.getChildren(DTMDefaultBase.ROOTNODE); - return dom.makeNode(iter); - } - else { + /** + * Utility function: used to convert reference to org.w3c.dom.Node. + */ + public static org.w3c.dom.Node referenceToNode(Object obj, DOM dom) { + if (obj instanceof Node || obj instanceof DTMAxisIterator) { + DTMAxisIterator iter = referenceToNodeSet(obj); + return dom.makeNode(iter); + } + else if (obj instanceof DOM) { + dom = (DOM)obj; + DTMAxisIterator iter = dom.getChildren(DTMDefaultBase.ROOTNODE); + return dom.makeNode(iter); + } + else { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, className, "org.w3c.dom.Node"); return null; + } } - } - /** - * Utility function: used to convert reference to long. - */ - public static long referenceToLong(Object obj) { - if (obj instanceof Number) { - return ((Number) obj).longValue(); // handles Integer and Double - } - else { + /** + * Utility function: used to convert reference to long. + */ + public static long referenceToLong(Object obj) { + if (obj instanceof Number) { + return ((Number) obj).longValue(); // handles Integer and Double + } + else { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, className, Long.TYPE); return 0; + } } - } - /** - * Utility function: used to convert reference to double. - */ - public static double referenceToDouble(Object obj) { - if (obj instanceof Number) { - return ((Number) obj).doubleValue(); // handles Integer and Double - } - else { + /** + * Utility function: used to convert reference to double. + */ + public static double referenceToDouble(Object obj) { + if (obj instanceof Number) { + return ((Number) obj).doubleValue(); // handles Integer and Double + } + else { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, className, Double.TYPE); return 0; + } } - } - /** - * Utility function: used to convert reference to boolean. - */ - public static boolean referenceToBoolean(Object obj) { - if (obj instanceof Boolean) { - return ((Boolean) obj).booleanValue(); - } - else { + /** + * Utility function: used to convert reference to boolean. + */ + public static boolean referenceToBoolean(Object obj) { + if (obj instanceof Boolean) { + return ((Boolean) obj).booleanValue(); + } + else { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, className, Boolean.TYPE); return false; + } } - } - /** - * Utility function: used to convert reference to String. - */ - public static String referenceToString(Object obj, DOM dom) { - if (obj instanceof String) { - return (String) obj; - } - else if (obj instanceof DTMAxisIterator) { + /** + * Utility function: used to convert reference to String. + */ + public static String referenceToString(Object obj, DOM dom) { + if (obj instanceof String) { + return (String) obj; + } + else if (obj instanceof DTMAxisIterator) { return dom.getStringValueX(((DTMAxisIterator)obj).reset().next()); - } - else if (obj instanceof Node) { + } + else if (obj instanceof Node) { return dom.getStringValueX(((Node)obj).node); - } - else if (obj instanceof DOM) { + } + else if (obj instanceof DOM) { return ((DOM) obj).getStringValue(); - } - else { + } + else { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, className, String.class); return null; + } } - } - /** - * Utility function used to convert a w3c Node into an internal DOM iterator. - */ - public static DTMAxisIterator node2Iterator(org.w3c.dom.Node node, - Translet translet, DOM dom) + /** + * Utility function used to convert a w3c Node into an internal DOM iterator. + */ + public static DTMAxisIterator node2Iterator(org.w3c.dom.Node node, + Translet translet, DOM dom) { - final org.w3c.dom.Node inNode = node; - // Create a dummy NodeList which only contains the given node to make - // use of the nodeList2Iterator() interface. - org.w3c.dom.NodeList nodelist = new org.w3c.dom.NodeList() { - public int getLength() { - return 1; - } + final org.w3c.dom.Node inNode = node; + // Create a dummy NodeList which only contains the given node to make + // use of the nodeList2Iterator() interface. + org.w3c.dom.NodeList nodelist = new org.w3c.dom.NodeList() { + public int getLength() { + return 1; + } - public org.w3c.dom.Node item(int index) { - if (index == 0) - return inNode; - else - return null; - } + public org.w3c.dom.Node item(int index) { + if (index == 0) + return inNode; + else + return null; + } }; - return nodeList2Iterator(nodelist, translet, dom); + return nodeList2Iterator(nodelist, translet, dom); } - /** - * In a perfect world, this would be the implementation for - * nodeList2Iterator. In reality, though, this causes a - * ClassCastException in getDTMHandleFromNode because SAXImpl is - * not an instance of DOM2DTM. So we use the more lengthy - * implementation below until this issue has been addressed. - * - * @see org.apache.xml.dtm.ref.DTMManagerDefault#getDTMHandleFromNode - */ - private static DTMAxisIterator nodeList2IteratorUsingHandleFromNode( - org.w3c.dom.NodeList nodeList, - Translet translet, DOM dom) + /** + * In a perfect world, this would be the implementation for + * nodeList2Iterator. In reality, though, this causes a + * ClassCastException in getDTMHandleFromNode because SAXImpl is + * not an instance of DOM2DTM. So we use the more lengthy + * implementation below until this issue has been addressed. + * + * @see org.apache.xml.dtm.ref.DTMManagerDefault#getDTMHandleFromNode + */ + private static DTMAxisIterator nodeList2IteratorUsingHandleFromNode( + org.w3c.dom.NodeList nodeList, + Translet translet, DOM dom) { - final int n = nodeList.getLength(); - final int[] dtmHandles = new int[n]; - DTMManager dtmManager = null; - if (dom instanceof MultiDOM) - dtmManager = ((MultiDOM) dom).getDTMManager(); - for (int i = 0; i < n; ++i) { - org.w3c.dom.Node node = nodeList.item(i); - int handle; - if (dtmManager != null) { - handle = dtmManager.getDTMHandleFromNode(node); - } - else if (node instanceof DTMNodeProxy - && ((DTMNodeProxy) node).getDTM() == dom) { - handle = ((DTMNodeProxy) node).getDTMNodeNumber(); - } - else { - runTimeError(RUN_TIME_INTERNAL_ERR, "need MultiDOM"); - return null; - } - dtmHandles[i] = handle; - System.out.println("Node " + i + " has handle 0x" + - Integer.toString(handle, 16)); - } - return new ArrayNodeListIterator(dtmHandles); - } - - /** - * Utility function used to convert a w3c NodeList into a internal - * DOM iterator. - */ - public static DTMAxisIterator nodeList2Iterator( - org.w3c.dom.NodeList nodeList, - Translet translet, DOM dom) + final int n = nodeList.getLength(); + final int[] dtmHandles = new int[n]; + DTMManager dtmManager = null; + if (dom instanceof MultiDOM) + dtmManager = ((MultiDOM) dom).getDTMManager(); + for (int i = 0; i < n; ++i) { + org.w3c.dom.Node node = nodeList.item(i); + int handle; + if (dtmManager != null) { + handle = dtmManager.getDTMHandleFromNode(node); + } + else if (node instanceof DTMNodeProxy + && ((DTMNodeProxy) node).getDTM() == dom) { + handle = ((DTMNodeProxy) node).getDTMNodeNumber(); + } + else { + runTimeError(RUN_TIME_INTERNAL_ERR, "need MultiDOM"); + return null; + } + dtmHandles[i] = handle; + System.out.println("Node " + i + " has handle 0x" + + Integer.toString(handle, 16)); + } + return new ArrayNodeListIterator(dtmHandles); + } + + /** + * Utility function used to convert a w3c NodeList into a internal + * DOM iterator. + */ + public static DTMAxisIterator nodeList2Iterator( + org.w3c.dom.NodeList nodeList, + Translet translet, DOM dom) { - // First pass: build w3c DOM for all nodes not proxied from our DOM. - // - // Notice: this looses some (esp. parent) context for these nodes, - // so some way to wrap the original nodes inside a DTMAxisIterator - // might be preferable in the long run. - int n = 0; // allow for change in list length, just in case. - Document doc = null; - DTMManager dtmManager = null; - int[] proxyNodes = new int[nodeList.getLength()]; - if (dom instanceof MultiDOM) - dtmManager = ((MultiDOM) dom).getDTMManager(); - for (int i = 0; i < nodeList.getLength(); ++i) { - org.w3c.dom.Node node = nodeList.item(i); - if (node instanceof DTMNodeProxy) { - DTMNodeProxy proxy = (DTMNodeProxy)node; - DTM nodeDTM = proxy.getDTM(); - int handle = proxy.getDTMNodeNumber(); - boolean isOurDOM = (nodeDTM == dom); - if (!isOurDOM && dtmManager != null) { - try { - isOurDOM = (nodeDTM == dtmManager.getDTM(handle)); - } - catch (ArrayIndexOutOfBoundsException e) { - // invalid node handle, so definitely not our doc - } - } - if (isOurDOM) { - proxyNodes[i] = handle; - ++n; - continue; - } - } - proxyNodes[i] = DTM.NULL; - int nodeType = node.getNodeType(); - if (doc == null) { - if (dom instanceof MultiDOM == false) { - runTimeError(RUN_TIME_INTERNAL_ERR, "need MultiDOM"); - return null; - } - try { - AbstractTranslet at = (AbstractTranslet) translet; - doc = at.newDocument("", "__top__"); - } - catch (javax.xml.parsers.ParserConfigurationException e) { - runTimeError(RUN_TIME_INTERNAL_ERR, e.getMessage()); - return null; - } - } - // Use one dummy element as container for each node of the - // list. That way, it is easier to detect resp. avoid - // funny things which change the number of nodes, - // e.g. auto-concatenation of text nodes. - Element mid; - switch (nodeType) { - case org.w3c.dom.Node.ELEMENT_NODE: - case org.w3c.dom.Node.TEXT_NODE: - case org.w3c.dom.Node.CDATA_SECTION_NODE: - case org.w3c.dom.Node.COMMENT_NODE: - case org.w3c.dom.Node.ENTITY_REFERENCE_NODE: - case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: - mid = doc.createElementNS(null, "__dummy__"); - mid.appendChild(doc.importNode(node, true)); - doc.getDocumentElement().appendChild(mid); - ++n; - break; - case org.w3c.dom.Node.ATTRIBUTE_NODE: - // The mid element also serves as a container for - // attributes, avoiding problems with conflicting - // attributes or node order. - mid = doc.createElementNS(null, "__dummy__"); - mid.setAttributeNodeNS((Attr)doc.importNode(node, true)); - doc.getDocumentElement().appendChild(mid); - ++n; - break; - default: - // Better play it safe for all types we aren't sure we know - // how to deal with. - runTimeError(RUN_TIME_INTERNAL_ERR, - "Don't know how to convert node type " - + nodeType); - } - } + // First pass: build w3c DOM for all nodes not proxied from our DOM. + // + // Notice: this looses some (esp. parent) context for these nodes, + // so some way to wrap the original nodes inside a DTMAxisIterator + // might be preferable in the long run. + int n = 0; // allow for change in list length, just in case. + Document doc = null; + DTMManager dtmManager = null; + int[] proxyNodes = new int[nodeList.getLength()]; + if (dom instanceof MultiDOM) + dtmManager = ((MultiDOM) dom).getDTMManager(); + for (int i = 0; i < nodeList.getLength(); ++i) { + org.w3c.dom.Node node = nodeList.item(i); + if (node instanceof DTMNodeProxy) { + DTMNodeProxy proxy = (DTMNodeProxy)node; + DTM nodeDTM = proxy.getDTM(); + int handle = proxy.getDTMNodeNumber(); + boolean isOurDOM = (nodeDTM == dom); + if (!isOurDOM && dtmManager != null) { + try { + isOurDOM = (nodeDTM == dtmManager.getDTM(handle)); + } + catch (ArrayIndexOutOfBoundsException e) { + // invalid node handle, so definitely not our doc + } + } + if (isOurDOM) { + proxyNodes[i] = handle; + ++n; + continue; + } + } + proxyNodes[i] = DTM.NULL; + int nodeType = node.getNodeType(); + if (doc == null) { + if (dom instanceof MultiDOM == false) { + runTimeError(RUN_TIME_INTERNAL_ERR, "need MultiDOM"); + return null; + } + try { + AbstractTranslet at = (AbstractTranslet) translet; + doc = at.newDocument("", "__top__"); + } + catch (javax.xml.parsers.ParserConfigurationException e) { + runTimeError(RUN_TIME_INTERNAL_ERR, e.getMessage()); + return null; + } + } + // Use one dummy element as container for each node of the + // list. That way, it is easier to detect resp. avoid + // funny things which change the number of nodes, + // e.g. auto-concatenation of text nodes. + Element mid; + switch (nodeType) { + case org.w3c.dom.Node.ELEMENT_NODE: + case org.w3c.dom.Node.TEXT_NODE: + case org.w3c.dom.Node.CDATA_SECTION_NODE: + case org.w3c.dom.Node.COMMENT_NODE: + case org.w3c.dom.Node.ENTITY_REFERENCE_NODE: + case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: + mid = doc.createElementNS(null, "__dummy__"); + mid.appendChild(doc.importNode(node, true)); + doc.getDocumentElement().appendChild(mid); + ++n; + break; + case org.w3c.dom.Node.ATTRIBUTE_NODE: + // The mid element also serves as a container for + // attributes, avoiding problems with conflicting + // attributes or node order. + mid = doc.createElementNS(null, "__dummy__"); + mid.setAttributeNodeNS((Attr)doc.importNode(node, true)); + doc.getDocumentElement().appendChild(mid); + ++n; + break; + default: + // Better play it safe for all types we aren't sure we know + // how to deal with. + runTimeError(RUN_TIME_INTERNAL_ERR, + "Don't know how to convert node type " + + nodeType); + } + } - // w3cDOM -> DTM -> DOMImpl - DTMAxisIterator iter = null, childIter = null, attrIter = null; - if (doc != null) { - final MultiDOM multiDOM = (MultiDOM) dom; - DOM idom = (DOM)dtmManager.getDTM(new DOMSource(doc), false, + // w3cDOM -> DTM -> DOMImpl + DTMAxisIterator iter = null, childIter = null, attrIter = null; + if (doc != null) { + final MultiDOM multiDOM = (MultiDOM) dom; + DOM idom = (DOM)dtmManager.getDTM(new DOMSource(doc), false, null, true, false); - // Create DOMAdapter and register with MultiDOM - DOMAdapter domAdapter = new DOMAdapter(idom, + // Create DOMAdapter and register with MultiDOM + DOMAdapter domAdapter = new DOMAdapter(idom, translet.getNamesArray(), translet.getUrisArray(), translet.getTypesArray(), - translet.getNamespaceArray()); - multiDOM.addDOMAdapter(domAdapter); - - DTMAxisIterator iter1 = idom.getAxisIterator(Axis.CHILD); - DTMAxisIterator iter2 = idom.getAxisIterator(Axis.CHILD); - iter = new AbsoluteIterator( - new StepIterator(iter1, iter2)); - - iter.setStartNode(DTMDefaultBase.ROOTNODE); - - childIter = idom.getAxisIterator(Axis.CHILD); - attrIter = idom.getAxisIterator(Axis.ATTRIBUTE); - } - - // Second pass: find DTM handles for every node in the list. - int[] dtmHandles = new int[n]; - n = 0; - for (int i = 0; i < nodeList.getLength(); ++i) { - if (proxyNodes[i] != DTM.NULL) { - dtmHandles[n++] = proxyNodes[i]; - continue; - } - org.w3c.dom.Node node = nodeList.item(i); - DTMAxisIterator iter3 = null; - int nodeType = node.getNodeType(); - switch (nodeType) { - case org.w3c.dom.Node.ELEMENT_NODE: - case org.w3c.dom.Node.TEXT_NODE: - case org.w3c.dom.Node.CDATA_SECTION_NODE: - case org.w3c.dom.Node.COMMENT_NODE: - case org.w3c.dom.Node.ENTITY_REFERENCE_NODE: - case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: - iter3 = childIter; - break; - case org.w3c.dom.Node.ATTRIBUTE_NODE: - iter3 = attrIter; - break; - default: - // Should not happen, as first run should have got all these - throw new InternalRuntimeError("Mismatched cases"); - } - if (iter3 != null) { - iter3.setStartNode(iter.next()); - dtmHandles[n] = iter3.next(); - // For now, play it self and perform extra checks: - if (dtmHandles[n] == DTMAxisIterator.END) - throw new InternalRuntimeError("Expected element missing at " + i); - if (iter3.next() != DTMAxisIterator.END) - throw new InternalRuntimeError("Too many elements at " + i); - ++n; - } - } - if (n != dtmHandles.length) - throw new InternalRuntimeError("Nodes lost in second pass"); + translet.getNamespaceArray()); + multiDOM.addDOMAdapter(domAdapter); + + DTMAxisIterator iter1 = idom.getAxisIterator(Axis.CHILD); + DTMAxisIterator iter2 = idom.getAxisIterator(Axis.CHILD); + iter = new AbsoluteIterator( + new StepIterator(iter1, iter2)); + + iter.setStartNode(DTMDefaultBase.ROOTNODE); + + childIter = idom.getAxisIterator(Axis.CHILD); + attrIter = idom.getAxisIterator(Axis.ATTRIBUTE); + } + + // Second pass: find DTM handles for every node in the list. + int[] dtmHandles = new int[n]; + n = 0; + for (int i = 0; i < nodeList.getLength(); ++i) { + if (proxyNodes[i] != DTM.NULL) { + dtmHandles[n++] = proxyNodes[i]; + continue; + } + org.w3c.dom.Node node = nodeList.item(i); + DTMAxisIterator iter3 = null; + int nodeType = node.getNodeType(); + switch (nodeType) { + case org.w3c.dom.Node.ELEMENT_NODE: + case org.w3c.dom.Node.TEXT_NODE: + case org.w3c.dom.Node.CDATA_SECTION_NODE: + case org.w3c.dom.Node.COMMENT_NODE: + case org.w3c.dom.Node.ENTITY_REFERENCE_NODE: + case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: + iter3 = childIter; + break; + case org.w3c.dom.Node.ATTRIBUTE_NODE: + iter3 = attrIter; + break; + default: + // Should not happen, as first run should have got all these + throw new InternalRuntimeError("Mismatched cases"); + } + if (iter3 != null) { + iter3.setStartNode(iter.next()); + dtmHandles[n] = iter3.next(); + // For now, play it self and perform extra checks: + if (dtmHandles[n] == DTMAxisIterator.END) + throw new InternalRuntimeError("Expected element missing at " + i); + if (iter3.next() != DTMAxisIterator.END) + throw new InternalRuntimeError("Too many elements at " + i); + ++n; + } + } + if (n != dtmHandles.length) + throw new InternalRuntimeError("Nodes lost in second pass"); - return new ArrayNodeListIterator(dtmHandles); + return new ArrayNodeListIterator(dtmHandles); } - /** - * Utility function used to convert references to DOMs. - */ - public static DOM referenceToResultTree(Object obj) { - try { + /** + * Utility function used to convert references to DOMs. + */ + public static DOM referenceToResultTree(Object obj) { + try { return ((DOM) obj); - } - catch (IllegalArgumentException e) { + } + catch (IllegalArgumentException e) { final String className = obj.getClass().getName(); runTimeError(DATA_CONVERSION_ERR, "reference", className); return null; + } + } + + /** + * Utility function: used with nth position filters to convert a sequence + * of nodes to just one single node (the one at position n). + */ + public static DTMAxisIterator getSingleNode(DTMAxisIterator iterator) { + int node = iterator.next(); + return(new SingletonIterator(node)); } - } - - /** - * Utility function: used with nth position filters to convert a sequence - * of nodes to just one single node (the one at position n). - */ - public static DTMAxisIterator getSingleNode(DTMAxisIterator iterator) { - int node = iterator.next(); - return(new SingletonIterator(node)); - } - - /** - * Utility function: used in xsl:copy. - */ - private static char[] _characterArray = new char[32]; - - public static void copy(Object obj, - SerializationHandler handler, - int node, - DOM dom) { - try { + + /** + * Utility function: used in xsl:copy. + */ + private static char[] _characterArray = new char[32]; + + public static void copy(Object obj, + SerializationHandler handler, + int node, + DOM dom) { + try { if (obj instanceof DTMAxisIterator) { - DTMAxisIterator iter = (DTMAxisIterator) obj; - dom.copy(iter.reset(), handler); + DTMAxisIterator iter = (DTMAxisIterator) obj; + dom.copy(iter.reset(), handler); } else if (obj instanceof Node) { - dom.copy(((Node) obj).node, handler); + dom.copy(((Node) obj).node, handler); } else if (obj instanceof DOM) { - //((DOM)obj).copy(((org.apache.xml.dtm.ref.DTMDefaultBase)((DOMAdapter)obj).getDOMImpl()).getDocument(), handler); - DOM newDom = (DOM)obj; - newDom.copy(newDom.getDocument(), handler); + //((DOM)obj).copy(((org.apache.xml.dtm.ref.DTMDefaultBase)((DOMAdapter)obj).getDOMImpl()).getDocument(), handler); + DOM newDom = (DOM)obj; + newDom.copy(newDom.getDocument(), handler); } else { - String string = obj.toString(); // or call stringF() - final int length = string.length(); - if (length > _characterArray.length) - _characterArray = new char[length]; - string.getChars(0, length, _characterArray, 0); - handler.characters(_characterArray, 0, length); + String string = obj.toString(); // or call stringF() + final int length = string.length(); + if (length > _characterArray.length) + _characterArray = new char[length]; + string.getChars(0, length, _characterArray, 0); + handler.characters(_characterArray, 0, length); } - } - catch (SAXException e) { + } + catch (SAXException e) { runTimeError(RUN_TIME_COPY_ERR); + } } - } - /** - * Utility function to check if xsl:attribute has a valid qname - * This method should only be invoked if the name attribute is an AVT - */ - public static void checkAttribQName(String name) { - final int firstOccur = name.indexOf(':'); - final int lastOccur = name.lastIndexOf(':'); - final String localName = name.substring(lastOccur + 1); + /** + * Utility function to check if xsl:attribute has a valid qname + * This method should only be invoked if the name attribute is an AVT + */ + public static void checkAttribQName(String name) { + final int firstOccur = name.indexOf(':'); + final int lastOccur = name.lastIndexOf(':'); + final String localName = name.substring(lastOccur + 1); - if (firstOccur > 0) { - final String newPrefix = name.substring(0, firstOccur); + if (firstOccur > 0) { + final String newPrefix = name.substring(0, firstOccur); - if (firstOccur != lastOccur) { - final String oriPrefix = name.substring(firstOccur+1, lastOccur); - if (!XML11Char.isXML11ValidNCName(oriPrefix)) { - // even though the orignal prefix is ignored, it should still get checked for valid NCName - runTimeError(INVALID_QNAME_ERR,oriPrefix+":"+localName); - } - } + if (firstOccur != lastOccur) { + final String oriPrefix = name.substring(firstOccur+1, lastOccur); + if (!XML11Char.isXML11ValidNCName(oriPrefix)) { + // even though the orignal prefix is ignored, it should still get checked for valid NCName + runTimeError(INVALID_QNAME_ERR,oriPrefix+":"+localName); + } + } - // prefix must be a valid NCName - if (!XML11Char.isXML11ValidNCName(newPrefix)) { - runTimeError(INVALID_QNAME_ERR,newPrefix+":"+localName); - } - } + // prefix must be a valid NCName + if (!XML11Char.isXML11ValidNCName(newPrefix)) { + runTimeError(INVALID_QNAME_ERR,newPrefix+":"+localName); + } + } - // local name must be a valid NCName and must not be XMLNS - if ((!XML11Char.isXML11ValidNCName(localName))||(localName.equals(Constants.XMLNS_PREFIX))) { - runTimeError(INVALID_QNAME_ERR,localName); + // local name must be a valid NCName and must not be XMLNS + if ((!XML11Char.isXML11ValidNCName(localName))||(localName.equals(Constants.XMLNS_PREFIX))) { + runTimeError(INVALID_QNAME_ERR,localName); + } } - } - /** - * Utility function to check if a name is a valid ncname - * This method should only be invoked if the attribute value is an AVT - */ - public static void checkNCName(String name) { - if (!XML11Char.isXML11ValidNCName(name)) { - runTimeError(INVALID_NCNAME_ERR,name); - } - } - - /** - * Utility function to check if a name is a valid qname - * This method should only be invoked if the attribute value is an AVT - */ - public static void checkQName(String name) { - if (!XML11Char.isXML11ValidQName(name)) { - runTimeError(INVALID_QNAME_ERR,name); - } - } + /** + * Utility function to check if a name is a valid ncname + * This method should only be invoked if the attribute value is an AVT + */ + public static void checkNCName(String name) { + if (!XML11Char.isXML11ValidNCName(name)) { + runTimeError(INVALID_NCNAME_ERR,name); + } + } + + /** + * Utility function to check if a name is a valid qname + * This method should only be invoked if the attribute value is an AVT + */ + public static void checkQName(String name) { + if (!XML11Char.isXML11ValidQName(name)) { + runTimeError(INVALID_QNAME_ERR,name); + } + } - /** - * Utility function for the implementation of xsl:element. - */ - public static String startXslElement(String qname, String namespace, - SerializationHandler handler, DOM dom, int node) + /** + * Utility function for the implementation of xsl:element. + */ + public static String startXslElement(String qname, String namespace, + SerializationHandler handler, DOM dom, int node) { - try { - // Get prefix from qname - String prefix; - final int index = qname.indexOf(':'); + try { + // Get prefix from qname + String prefix; + final int index = qname.indexOf(':'); - if (index > 0) { - prefix = qname.substring(0, index); + if (index > 0) { + prefix = qname.substring(0, index); - // Handle case when prefix is not known at compile time - if (namespace == null || namespace.length() == 0) { - runTimeError(NAMESPACE_PREFIX_ERR,prefix); - } + // Handle case when prefix is not known at compile time + if (namespace == null || namespace.length() == 0) { + runTimeError(NAMESPACE_PREFIX_ERR,prefix); + } - handler.startElement(namespace, qname.substring(index+1), - qname); - handler.namespaceAfterStartElement(prefix, namespace); + handler.startElement(namespace, qname.substring(index+1), + qname); + handler.namespaceAfterStartElement(prefix, namespace); + } + else { + // Need to generate a prefix? + if (namespace != null && namespace.length() > 0) { + prefix = generatePrefix(); + qname = prefix + ':' + qname; + handler.startElement(namespace, qname, qname); + handler.namespaceAfterStartElement(prefix, namespace); + } + else { + handler.startElement(null, null, qname); + } + } } - else { - // Need to generate a prefix? - if (namespace != null && namespace.length() > 0) { - prefix = generatePrefix(namespace); - qname = prefix + ':' + qname; - handler.startElement(namespace, qname, qname); - handler.namespaceAfterStartElement(prefix, namespace); - } - else { - handler.startElement(null, null, qname); - } + catch (SAXException e) { + throw new RuntimeException(e.getMessage()); } - } - catch (SAXException e) { - throw new RuntimeException(e.getMessage()); - } - return qname; + return qname; } - /** - *

Look up the namespace for a lexical QName using the namespace - * declarations available at a particular location in the stylesheet.

- *

See {@link org.apache.xalan.xsltc.compiler.Stylesheet#compileStaticInitializer(org.apache.xalan.xsltc.compiler.util.ClassGenerator)} - * for more information about the ancestorNodeIDs, - * prefixURIsIndex and prefixURIPairs - * - * @param lexicalQName The QName as a java.lang.String - * @param stylesheetNodeID An int representing the element in - * the stylesheet relative to which the namespace of - * the lexical QName is to be determined - * @param ancestorNodeIDs An int array, indexed by stylesheet - * node IDs, containing the ID of the nearest ancestor - * node in the stylesheet that has namespace - * declarations, or -1 if there is no - * such ancestor - * @param prefixURIsIndex An int array, indexed by stylesheet - * node IDs, containing the index into the - * prefixURIPairs array of the first - * prefix declared on that stylesheet node - * @param prefixURIPairs A java.lang.String array that contains - * pairs of - * @param ignoreDefault A boolean indicating whether any - * default namespace decarlation should be considered - * @return The namespace of the lexical QName or a zero-length string if - * the QName is in no namespace or no namespace declaration for the - * prefix of the QName was found - */ - public static String lookupStylesheetQNameNamespace(String lexicalQName, - int stylesheetNodeID, - int[] ancestorNodeIDs, - int[] prefixURIsIndex, - String[] prefixURIPairs, - boolean ignoreDefault) { - String prefix = getPrefix(lexicalQName); - String uri = ""; - - if (prefix == null && !ignoreDefault) { - prefix = ""; - } - - if (prefix != null) { - // Loop from current node in the stylesheet to its ancestors - nodeLoop: - for (int currentNodeID = stylesheetNodeID; - currentNodeID >= 0; - currentNodeID = ancestorNodeIDs[currentNodeID]) { - // Look at all declarations on the current stylesheet node - // The prefixURIsIndex is an array of indices into the - // prefixURIPairs array that are stored in ascending order. - // The declarations for a node I are in elements - // prefixURIsIndex[I] to prefixURIsIndex[I+1]-1 (or - // prefixURIPairs.length-1 if I is the last node) - int prefixStartIdx = prefixURIsIndex[currentNodeID]; - int prefixLimitIdx = (currentNodeID+1 < prefixURIsIndex.length) - ? prefixURIsIndex[currentNodeID + 1] - : prefixURIPairs.length; - - for (int prefixIdx = prefixStartIdx; - prefixIdx < prefixLimitIdx; - prefixIdx = prefixIdx + 2) { - // Did we find the declaration of our prefix - if (prefix.equals(prefixURIPairs[prefixIdx])) { - uri = prefixURIPairs[prefixIdx+1]; - break nodeLoop; - } + /** + *

Look up the namespace for a lexical QName using the namespace + * declarations available at a particular location in the stylesheet.

+ *

See {@link org.apache.xalan.xsltc.compiler.Stylesheet#compileStaticInitializer(org.apache.xalan.xsltc.compiler.util.ClassGenerator)} + * for more information about the ancestorNodeIDs, + * prefixURIsIndex and prefixURIPairs + * + * @param lexicalQName The QName as a java.lang.String + * @param stylesheetNodeID An int representing the element in + * the stylesheet relative to which the namespace of + * the lexical QName is to be determined + * @param ancestorNodeIDs An int array, indexed by stylesheet + * node IDs, containing the ID of the nearest ancestor + * node in the stylesheet that has namespace + * declarations, or -1 if there is no + * such ancestor + * @param prefixURIsIndex An int array, indexed by stylesheet + * node IDs, containing the index into the + * prefixURIPairs array of the first + * prefix declared on that stylesheet node + * @param prefixURIPairs A java.lang.String array that contains + * pairs of + * @param ignoreDefault A boolean indicating whether any + * default namespace decarlation should be considered + * @return The namespace of the lexical QName or a zero-length string if + * the QName is in no namespace or no namespace declaration for the + * prefix of the QName was found + */ + public static String lookupStylesheetQNameNamespace(String lexicalQName, + int stylesheetNodeID, + int[] ancestorNodeIDs, + int[] prefixURIsIndex, + String[] prefixURIPairs, + boolean ignoreDefault) { + String prefix = getPrefix(lexicalQName); + String uri = ""; + + if (prefix == null && !ignoreDefault) { + prefix = ""; + } + + if (prefix != null) { + // Loop from current node in the stylesheet to its ancestors + nodeLoop: + for (int currentNodeID = stylesheetNodeID; + currentNodeID >= 0; + currentNodeID = ancestorNodeIDs[currentNodeID]) { + // Look at all declarations on the current stylesheet node + // The prefixURIsIndex is an array of indices into the + // prefixURIPairs array that are stored in ascending order. + // The declarations for a node I are in elements + // prefixURIsIndex[I] to prefixURIsIndex[I+1]-1 (or + // prefixURIPairs.length-1 if I is the last node) + int prefixStartIdx = prefixURIsIndex[currentNodeID]; + int prefixLimitIdx = (currentNodeID+1 < prefixURIsIndex.length) + ? prefixURIsIndex[currentNodeID + 1] + : prefixURIPairs.length; + + for (int prefixIdx = prefixStartIdx; + prefixIdx < prefixLimitIdx; + prefixIdx = prefixIdx + 2) { + // Did we find the declaration of our prefix + if (prefix.equals(prefixURIPairs[prefixIdx])) { + uri = prefixURIPairs[prefixIdx+1]; + break nodeLoop; + } + } + } + } + + return uri; + } + + /** + *

Look up the namespace for a lexical QName using the namespace + * declarations available at a particular location in the stylesheet and + * return the expanded QName

+ *

See {@link org.apache.xalan.xsltc.compiler.Stylesheet#compileStaticInitializer(org.apache.xalan.xsltc.compiler.util.ClassGenerator)} + * for more information about the ancestorNodeIDs, + * prefixURIsIndex and prefixURIPairs + * + * @param lexicalQName The QName as a java.lang.String + * @param stylesheetNodeID An int representing the element in + * the stylesheet relative to which the namespace of + * the lexical QName is to be determined + * @param ancestorNodeIDs An int array, indexed by stylesheet + * node IDs, containing the ID of the nearest ancestor + * node in the stylesheet that has namespace + * declarations, or -1 if there is no + * such ancestor + * @param prefixURIsIndex An int array, indexed by stylesheet + * node IDs, containing the index into the + * prefixURIPairs array of the first + * prefix declared on that stylesheet node + * @param prefixURIPairs A java.lang.String array that contains + * pairs of + * @param ignoreDefault A boolean indicating whether any + * default namespace decarlation should be considered + * @return The expanded QName in the form "uri:localName" or just + * "localName" if the QName is in no namespace or no namespace + * declaration for the prefix of the QName was found + */ + public static String expandStylesheetQNameRef(String lexicalQName, + int stylesheetNodeID, + int[] ancestorNodeIDs, + int[] prefixURIsIndex, + String[] prefixURIPairs, + boolean ignoreDefault) { + String expandedQName; + String prefix = getPrefix(lexicalQName); + String localName = (prefix != null) + ? lexicalQName.substring(prefix.length()+1) + : lexicalQName; + String uri = lookupStylesheetQNameNamespace(lexicalQName, + stylesheetNodeID, + ancestorNodeIDs, + prefixURIsIndex, + prefixURIPairs, + ignoreDefault); + + // Handle case when prefix is not resolved + if (prefix != null && prefix.length() != 0 + && (uri == null || uri.length() == 0)) { + runTimeError(NAMESPACE_PREFIX_ERR, prefix); + } + + if (uri.length() == 0) { + expandedQName = localName; + } else { + expandedQName = uri + ':' + localName; + } + + return expandedQName; + } + + /** + * This function is used in the execution of xsl:element + */ + public static String getPrefix(String qname) { + final int index = qname.indexOf(':'); + return (index > 0) ? qname.substring(0, index) : null; + } + + /** + * This function is used in the execution of xsl:element + */ + private static int prefixIndex = 0; // not thread safe!! + private static Map nsMap = Collections.synchronizedMap(new HashMap()); + public static String generatePrefix() { + return ("ns" + prefixIndex++); + } + // This will record a new prefix used globally by XSLTC + // it *shouldn't be used anymore, but there might still be an edge case + public static String generatePrefix(String namespace) { + if(nsMap.containsKey(namespace)){ + return nsMap.get(namespace); + } + else{ + // Create a prefix, add to map and return it + String result = generatePrefix(); + nsMap.put(namespace,result); + return result; + } + } + // This will record a new prefix (if there isn't one already) + // and add it to the qname if it doesn't already have a prefix. + // This stores the new prefix in the map belonging to the translet + // so we don't leak prefix between separate translets. + public static String addPrefix(String qname, String namespace, Map prefixMap){ + // if it already has a prefix we don't need to do anything + if(qname.indexOf(':') == -1){ + if(prefixMap.containsKey(namespace)){ + return prefixMap.get(namespace)+":"+qname; + } + else{ + String prefix = "ns"+prefixMap.size(); + prefixMap.put(namespace,prefix); + return prefix+":"+qname; + } } - } - } - - return uri; - } - - /** - *

Look up the namespace for a lexical QName using the namespace - * declarations available at a particular location in the stylesheet and - * return the expanded QName

- *

See {@link org.apache.xalan.xsltc.compiler.Stylesheet#compileStaticInitializer(org.apache.xalan.xsltc.compiler.util.ClassGenerator)} - * for more information about the ancestorNodeIDs, - * prefixURIsIndex and prefixURIPairs - * - * @param lexicalQName The QName as a java.lang.String - * @param stylesheetNodeID An int representing the element in - * the stylesheet relative to which the namespace of - * the lexical QName is to be determined - * @param ancestorNodeIDs An int array, indexed by stylesheet - * node IDs, containing the ID of the nearest ancestor - * node in the stylesheet that has namespace - * declarations, or -1 if there is no - * such ancestor - * @param prefixURIsIndex An int array, indexed by stylesheet - * node IDs, containing the index into the - * prefixURIPairs array of the first - * prefix declared on that stylesheet node - * @param prefixURIPairs A java.lang.String array that contains - * pairs of - * @param ignoreDefault A boolean indicating whether any - * default namespace decarlation should be considered - * @return The expanded QName in the form "uri:localName" or just - * "localName" if the QName is in no namespace or no namespace - * declaration for the prefix of the QName was found - */ - public static String expandStylesheetQNameRef(String lexicalQName, - int stylesheetNodeID, - int[] ancestorNodeIDs, - int[] prefixURIsIndex, - String[] prefixURIPairs, - boolean ignoreDefault) { - String expandedQName; - String prefix = getPrefix(lexicalQName); - String localName = (prefix != null) - ? lexicalQName.substring(prefix.length()+1) - : lexicalQName; - String uri = lookupStylesheetQNameNamespace(lexicalQName, - stylesheetNodeID, - ancestorNodeIDs, - prefixURIsIndex, - prefixURIPairs, - ignoreDefault); - - // Handle case when prefix is not resolved - if (prefix != null && prefix.length() != 0 - && (uri == null || uri.length() == 0)) { - runTimeError(NAMESPACE_PREFIX_ERR, prefix); - } - - if (uri.length() == 0) { - expandedQName = localName; - } else { - expandedQName = uri + ':' + localName; - } - - return expandedQName; - } - - /** - * This function is used in the execution of xsl:element - */ - public static String getPrefix(String qname) { - final int index = qname.indexOf(':'); - return (index > 0) ? qname.substring(0, index) : null; - } - - /** - * This function is used in the execution of xsl:element - */ - private static int prefixIndex = 0; // not thread safe!! - private static Map nsMap = Collections.synchronizedMap(new HashMap()); - public static String generatePrefix() { - return ("ns" + prefixIndex++); - } - // This will record a new prefix used globally by XSLTC - // it *shouldn't be used anymore, but there might still be an edge case - public static String generatePrefix(String namespace) { - if(nsMap.containsKey(namespace)){ - return nsMap.get(namespace); - } - else{ - // Create a prefix, add to map and return it - String result = generatePrefix(); - nsMap.put(namespace,result); - return result; - } - } - // This will record a new prefix (if there isn't one already) - // and add it to the qname if it doesn't already have a prefix. - // This stores the new prefix in the map belonging to the translet - // so we don't leak prefix between separate translets. - public static String addPrefix(String qname, String namespace, Map prefixMap){ - // if it already has a prefix we don't need to do anything - if(qname.indexOf(':') == -1){ - if(prefixMap.containsKey(namespace)){ - return prefixMap.get(namespace)+":"+qname; - } - else{ - String prefix = "ns"+prefixMap.size(); - prefixMap.put(namespace,prefix); - return prefix+":"+qname; - } - } - else{ - return qname; - } - } - - public static final String RUN_TIME_INTERNAL_ERR = - "RUN_TIME_INTERNAL_ERR"; - public static final String RUN_TIME_COPY_ERR = - "RUN_TIME_COPY_ERR"; - public static final String DATA_CONVERSION_ERR = - "DATA_CONVERSION_ERR"; - public static final String EXTERNAL_FUNC_ERR = - "EXTERNAL_FUNC_ERR"; - public static final String EQUALITY_EXPR_ERR = - "EQUALITY_EXPR_ERR"; - public static final String INVALID_ARGUMENT_ERR = - "INVALID_ARGUMENT_ERR"; - public static final String FORMAT_NUMBER_ERR = - "FORMAT_NUMBER_ERR"; - public static final String ITERATOR_CLONE_ERR = - "ITERATOR_CLONE_ERR"; - public static final String AXIS_SUPPORT_ERR = - "AXIS_SUPPORT_ERR"; - public static final String TYPED_AXIS_SUPPORT_ERR = - "TYPED_AXIS_SUPPORT_ERR"; - public static final String STRAY_ATTRIBUTE_ERR = - "STRAY_ATTRIBUTE_ERR"; - public static final String STRAY_NAMESPACE_ERR = - "STRAY_NAMESPACE_ERR"; - public static final String NAMESPACE_PREFIX_ERR = - "NAMESPACE_PREFIX_ERR"; - public static final String DOM_ADAPTER_INIT_ERR = - "DOM_ADAPTER_INIT_ERR"; - public static final String PARSER_DTD_SUPPORT_ERR = - "PARSER_DTD_SUPPORT_ERR"; - public static final String NAMESPACES_SUPPORT_ERR = - "NAMESPACES_SUPPORT_ERR"; - public static final String CANT_RESOLVE_RELATIVE_URI_ERR = - "CANT_RESOLVE_RELATIVE_URI_ERR"; - public static final String UNSUPPORTED_XSL_ERR = - "UNSUPPORTED_XSL_ERR"; - public static final String UNSUPPORTED_EXT_ERR = - "UNSUPPORTED_EXT_ERR"; - public static final String UNKNOWN_TRANSLET_VERSION_ERR = - "UNKNOWN_TRANSLET_VERSION_ERR"; - public static final String INVALID_QNAME_ERR = "INVALID_QNAME_ERR"; - public static final String INVALID_NCNAME_ERR = "INVALID_NCNAME_ERR"; - public static final String UNALLOWED_EXTENSION_FUNCTION_ERR = "UNALLOWED_EXTENSION_FUNCTION_ERR"; - public static final String UNALLOWED_EXTENSION_ELEMENT_ERR = "UNALLOWED_EXTENSION_ELEMENT_ERR"; - - // All error messages are localized and are stored in resource bundles. - private static ResourceBundle m_bundle; + else{ + return qname; + } + } + + public static final String RUN_TIME_INTERNAL_ERR = + "RUN_TIME_INTERNAL_ERR"; + public static final String RUN_TIME_COPY_ERR = + "RUN_TIME_COPY_ERR"; + public static final String DATA_CONVERSION_ERR = + "DATA_CONVERSION_ERR"; + public static final String EXTERNAL_FUNC_ERR = + "EXTERNAL_FUNC_ERR"; + public static final String EQUALITY_EXPR_ERR = + "EQUALITY_EXPR_ERR"; + public static final String INVALID_ARGUMENT_ERR = + "INVALID_ARGUMENT_ERR"; + public static final String FORMAT_NUMBER_ERR = + "FORMAT_NUMBER_ERR"; + public static final String ITERATOR_CLONE_ERR = + "ITERATOR_CLONE_ERR"; + public static final String AXIS_SUPPORT_ERR = + "AXIS_SUPPORT_ERR"; + public static final String TYPED_AXIS_SUPPORT_ERR = + "TYPED_AXIS_SUPPORT_ERR"; + public static final String STRAY_ATTRIBUTE_ERR = + "STRAY_ATTRIBUTE_ERR"; + public static final String STRAY_NAMESPACE_ERR = + "STRAY_NAMESPACE_ERR"; + public static final String NAMESPACE_PREFIX_ERR = + "NAMESPACE_PREFIX_ERR"; + public static final String DOM_ADAPTER_INIT_ERR = + "DOM_ADAPTER_INIT_ERR"; + public static final String PARSER_DTD_SUPPORT_ERR = + "PARSER_DTD_SUPPORT_ERR"; + public static final String NAMESPACES_SUPPORT_ERR = + "NAMESPACES_SUPPORT_ERR"; + public static final String CANT_RESOLVE_RELATIVE_URI_ERR = + "CANT_RESOLVE_RELATIVE_URI_ERR"; + public static final String UNSUPPORTED_XSL_ERR = + "UNSUPPORTED_XSL_ERR"; + public static final String UNSUPPORTED_EXT_ERR = + "UNSUPPORTED_EXT_ERR"; + public static final String UNKNOWN_TRANSLET_VERSION_ERR = + "UNKNOWN_TRANSLET_VERSION_ERR"; + public static final String INVALID_QNAME_ERR = "INVALID_QNAME_ERR"; + public static final String INVALID_NCNAME_ERR = "INVALID_NCNAME_ERR"; + public static final String UNALLOWED_EXTENSION_FUNCTION_ERR = "UNALLOWED_EXTENSION_FUNCTION_ERR"; + public static final String UNALLOWED_EXTENSION_ELEMENT_ERR = "UNALLOWED_EXTENSION_ELEMENT_ERR"; + + // All error messages are localized and are stored in resource bundles. + private static ResourceBundle m_bundle; - public final static String ERROR_MESSAGES_KEY = "error-messages"; - - static { - String resource = "org.apache.xalan.xsltc.runtime.ErrorMessages"; - m_bundle = ResourceBundle.getBundle(resource); - } - - /** - * Print a run-time error message. - */ - public static void runTimeError(String code) { - throw new RuntimeException(m_bundle.getString(code)); - } - - public static void runTimeError(String code, Object[] args) { - final String message = MessageFormat.format(m_bundle.getString(code), - args); - throw new RuntimeException(message); - } - - public static void runTimeError(String code, Object arg0) { - runTimeError(code, new Object[]{ arg0 } ); - } - - public static void runTimeError(String code, Object arg0, Object arg1) { - runTimeError(code, new Object[]{ arg0, arg1 } ); - } - - public static void consoleOutput(String msg) { - System.out.println(msg); - } - - /** - * Replace a certain character in a string with a new substring. - */ - public static String replace(String base, char ch, String str) { - return (base.indexOf(ch) < 0) ? base : + public final static String ERROR_MESSAGES_KEY = "error-messages"; + + static { + String resource = "org.apache.xalan.xsltc.runtime.ErrorMessages"; + m_bundle = ResourceBundle.getBundle(resource); + } + + /** + * Print a run-time error message. + */ + public static void runTimeError(String code) { + throw new RuntimeException(m_bundle.getString(code)); + } + + public static void runTimeError(String code, Object[] args) { + final String message = MessageFormat.format(m_bundle.getString(code), + args); + throw new RuntimeException(message); + } + + public static void runTimeError(String code, Object arg0) { + runTimeError(code, new Object[]{ arg0 } ); + } + + public static void runTimeError(String code, Object arg0, Object arg1) { + runTimeError(code, new Object[]{ arg0, arg1 } ); + } + + public static void consoleOutput(String msg) { + System.out.println(msg); + } + + /** + * Replace a certain character in a string with a new substring. + */ + public static String replace(String base, char ch, String str) { + return (base.indexOf(ch) < 0) ? base : replace(base, String.valueOf(ch), new String[] { str }); - } + } - public static String replace(String base, String delim, String[] str) { - final int len = base.length(); - final StringBuffer result = new StringBuffer(); + public static String replace(String base, String delim, String[] str) { + final int len = base.length(); + final StringBuffer result = new StringBuffer(); - for (int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { final char ch = base.charAt(i); final int k = delim.indexOf(ch); if (k >= 0) { - result.append(str[k]); + result.append(str[k]); } else { - result.append(ch); + result.append(ch); } + } + return result.toString(); } - return result.toString(); - } - /** - * Utility method to allow setting parameters of the form - * {namespaceuri}localName - * which get mapped to an instance variable in the class - * Hence a parameter of the form "{http://foo.bar}xyz" - * will be replaced with the corresponding values - * by the BasisLibrary's utility method mapQNametoJavaName - * and thus get mapped to legal java variable names - */ - public static String mapQNameToJavaName (String base ) { - return replace(base, ".-:/{}?#%*", - new String[] { "$dot$", "$dash$" ,"$colon$", "$slash$", - "","$colon$","$ques$","$hash$","$per$", - "$aster$"}); + /** + * Utility method to allow setting parameters of the form + * {namespaceuri}localName + * which get mapped to an instance variable in the class + * Hence a parameter of the form "{http://foo.bar}xyz" + * will be replaced with the corresponding values + * by the BasisLibrary's utility method mapQNametoJavaName + * and thus get mapped to legal java variable names + */ + public static String mapQNameToJavaName (String base ) { + return replace(base, ".-:/{}?#%*", + new String[] { "$dot$", "$dash$" ,"$colon$", "$slash$", + "","$colon$","$ques$","$hash$","$per$", + "$aster$"}); - } + } - //-- End utility functions + //-- End utility functions }