/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !defined(XALANQNAME_HEADER_GUARD_1357924680) #define XALANQNAME_HEADER_GUARD_1357924680 // Base header file. Must be first. #include #include #include #include #include #include #include #include #include namespace XALAN_CPP_NAMESPACE { class XalanElement; class XPathEnvSupport; /** * Class to represent a qualified name. The name of an internal XSLT object, * specifically a named template (see [7 Named Templates]), a mode (see [6.7 Modes]), * an attribute set (see [8.1.4 Named Attribute Sets]), a key (see [14.2 Keys]), * a locale (see [14.3 Number Formatting]), a variable or a parameter (see * [12 Variables and Parameters]) is specified as a QName. If it has a prefix, * then the prefix is expanded into a URI reference using the namespace declarations * in effect on the attribute in which the name occurs. The expanded name * consisting of the local part of the name and the possibly null URI reference * is used as the name of the object. The default namespace is not used for * unprefixed names. */ class XALAN_XPATH_EXPORT XalanQName { public: typedef XalanDeque > NamespaceVectorType; typedef XalanDeque > NamespacesStackType; /** * Construct an empty XalanQName. * */ explicit XalanQName() { } virtual ~XalanQName() { } XalanQName(const XalanQName&) { } /** * Retrieve the local part of qualified name. * * @return local part string */ virtual const XalanDOMString& getLocalPart() const = 0; /** * Retrieve the namespace of qualified name. * * @return namespace string */ virtual const XalanDOMString& getNamespace() const = 0; /** * Determine if the qualified name is valid. * * @return true if the instance is a valid QName, false if not. */ bool isValid() const { return isValidNCName(getLocalPart()); } /** * Whether the qualified name is empty. * * @return true if namespace and local part are both empty */ bool isEmpty() const { return getNamespace().empty() && getLocalPart().empty(); } /** * Override equals and agree that we're equal if the passed object is a * string and it matches the name of the arg. * * @param theRHS namespace to compare * @return true if namespace and local part are both empty */ bool equals(const XalanQName& theRHS) const { // Note that we do not use our member variables here. See // class QNameReference for details... return getLocalPart() == theRHS.getLocalPart() && getNamespace() == theRHS.getNamespace(); } /** * Format the QName using the notation "{namespace-uri}local-part" or * "local-part" if the namespace URI is empty. The result is appended * to the provided string. * * @param theString The string to format with the * @return A reference to the parameter. */ XalanDOMString& format(XalanDOMString& theString) const; size_t hash() const { return getLocalPart().hash() % (getNamespace().hash() + 1); } class XALAN_XPATH_EXPORT PrefixResolverProxy : public PrefixResolver { public: /** * Construct a PrefixResolver from a NamespacesStackType * instance. * * @param theStack The stack to use for prefix resolution * @param theURI The namespace URI of the resolver, if any. Only a reference is kept, so this cannot be a temporary * @return pointer to the string value if found, otherwise 0. */ PrefixResolverProxy( const NamespacesStackType& theStack, const XalanDOMString& theURI); virtual ~PrefixResolverProxy(); virtual const XalanDOMString* getNamespaceForPrefix(const XalanDOMString& prefix) const; virtual const XalanDOMString& getURI() const; private: const NamespacesStackType& m_stack; const XalanDOMString& m_uri; }; /** * Get the namespace for a prefix by searching a vector of namespaces. * * @param namespaces vector of namespaces to search * @param prefix namespace prefix to find * @return pointer to the string value if found, otherwise null. */ static const XalanDOMString* getNamespaceForPrefix( const NamespaceVectorType& namespaces, const XalanDOMString& prefix); /** * Get the namespace for a prefix by searching a stack of namespace * vectors. * * @param nsStack stack of namespace vectors to search * @param prefix namespace prefix to find * @return pointer to the string value if found, otherwise null. */ static const XalanDOMString* getNamespaceForPrefix( const NamespacesStackType& nsStack, const XalanDOMString& prefix); static const XalanDOMString* getNamespaceForPrefix( const NamespacesStackType& nsStack, const XalanDOMChar* prefix); /** * Get the namespace for a prefix by searching a range of iterators. * The search is done in reverse, from the end of the range to the * beginning. * * @param theBegin The beginning iterator for the range * @param theBegin The ending iterator for the range * @param prefix namespace prefix to find * @return pointer to the string value if found, otherwise null. */ static const XalanDOMString* getNamespaceForPrefix( NamespacesStackType::const_iterator theBegin, NamespacesStackType::const_iterator theEnd, const XalanDOMString& prefix); /** * Get the prefix for a namespace by searching a vector of namespaces. * * @param namespaces vector of namespaces to search * @param uri URI string for namespace to find * @param reverse true to search vector from last to first, default true * @return pointer to the string value if found, otherwise null. */ static const XalanDOMString* getPrefixForNamespace( const NamespaceVectorType& namespaces, const XalanDOMString& uri); static const XalanDOMString* getNamespaceForPrefix( const NamespaceVectorType& namespaces, const XalanDOMChar* prefix); /** * Get the prefix for a namespace by searching a stack of namespace * vectors. * * @param nsStack stack of namespace vectors to search * @param uri URI string for namespace to find * @return pointer to the string value if found, otherwise null. */ static const XalanDOMString* getPrefixForNamespace( const NamespacesStackType& nsStack, const XalanDOMString& uri); /** * Get the prefix for a namespace by searching a range of iterators. * The search is done in reverse, from the end of the range to the * beginning. * * @param theBegin The beginning iterator for the range to search * @param theBegin The ending iterator for the range to search * @param uri URI string for namespace to find * @return pointer to the string value if found, otherwise null. */ static const XalanDOMString* getPrefixForNamespace( NamespacesStackType::const_iterator theBegin, NamespacesStackType::const_iterator theEnd, const XalanDOMString& uri); static const XalanDOMString* getNamespaceForPrefix( NamespacesStackType::const_iterator theBegin, NamespacesStackType::const_iterator theEnd, const XalanDOMChar* prefix); /** * Determine if the string supplied satisfies the grammar for * an XML NCName. * * @param theNCName The string to check * @return bool true if the string is a valid NCName, false if not. */ static bool isValidNCName(const XalanDOMString& theNCName); /** * Determine if the string supplied satisfies the grammar for * an XML NCName. * * @param theNCName The string to check * @param theLength The length of the string * @return bool true if the string is a valid NCName, false if not */ static bool isValidNCName( const XalanDOMChar* theNCName, XalanDOMString::size_type theLength = XalanDOMString::npos); /** * Determine if the string supplied satisfies the grammar for * an XML QName. Note that this function does not determine * if any supplied prefix is bound to a namespace URI * * @param theQName The string to check * @return bool true if the string is a valid QName, false if not */ static bool isValidQName(const XalanDOMString& theQName); /** * Determine if the string supplied satisfies the grammar for * an XML QName. Note that this function does not determine * if any supplied prefix is bound to a namespace URI * * @param theQName The string to check * @param theLength The length of the string * @return bool true if the string is a valid QName, false if not */ static bool isValidQName( const XalanDOMChar* theQName, XalanDOMString::size_type theLength = XalanDOMString::npos); class InvalidQNameException : public XalanXPathException { public: /** * Constructor * * @param theQName The QName string that is not valid. * @param theQNameLength The length of the string. * @param theResult A temporary string for loading the error message. */ InvalidQNameException( const XalanDOMChar* theQName, XalanDOMString::size_type theQNameLength, XalanDOMString& theResult, const Locator* theLocator); /** * Constructor * * @param theMessage The message for the exception * @param theManager The MemoryManager instance to use when constructing the exception */ InvalidQNameException( const XalanDOMString& theMessage, MemoryManager& theManager, const Locator* theLocator); InvalidQNameException(const InvalidQNameException& other); virtual ~InvalidQNameException(); virtual const XalanDOMChar* getType() const; private: static const XalanDOMString& format( const XalanDOMChar* theQName, XalanDOMString::size_type theQNameLength, XalanDOMString& theResult); }; protected: static const XalanDOMString s_emptyString; }; inline bool operator==( const XalanQName& theLHS, const XalanQName& theRHS) { return theLHS.equals(theRHS); } inline bool operator!=( const XalanQName& theLHS, const XalanQName& theRHS) { return !(theLHS == theRHS); } inline bool operator<( const XalanQName& theLHS, const XalanQName& theRHS) { if (theLHS.getNamespace() < theRHS.getNamespace()) { return true; } else if (equals(theLHS.getNamespace(), theRHS.getNamespace())) { return theLHS.getLocalPart() < theRHS.getLocalPart(); } else { return false; } } template<> struct XalanMapKeyTraits { typedef XalanHashMemberReference Hasher; typedef std::equal_to Comparator; }; template<> struct XalanMapKeyTraits { typedef XalanHashMemberPointer Hasher; typedef pointer_equal Comparator; }; } #endif // XALANQNAME_HEADER_GUARD_1357924680