diff options
Diffstat (limited to 'ACE/ACEXML/common/NamespaceSupport.h')
-rw-r--r-- | ACE/ACEXML/common/NamespaceSupport.h | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/ACE/ACEXML/common/NamespaceSupport.h b/ACE/ACEXML/common/NamespaceSupport.h new file mode 100644 index 00000000000..d81f9303d70 --- /dev/null +++ b/ACE/ACEXML/common/NamespaceSupport.h @@ -0,0 +1,235 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file NamespaceSupport.h + * + * $Id$ + * $Id$ + * + * @author Nanbor Wang <nanbor@cs.wustl.edu> + */ +//============================================================================= + +#ifndef ACEXML_NAMESPACESUPPORT_H +#define ACEXML_NAMESPACESUPPORT_H + +#include /**/ "ace/pre.h" +#include "ACEXML/common/ACEXML_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ACEXML/common/XML_Types.h" +#include "ace/Functor.h" +#include "ace/Hash_Map_Manager.h" +#include "ace/Containers_T.h" +#include "ace/Null_Mutex.h" + + +typedef ACE_Hash_Map_Entry<ACEXML_String, + ACEXML_String> ACEXML_NS_CONTEXT_ENTRY; + +typedef ACE_Hash_Map_Manager_Ex<ACEXML_String, + ACEXML_String, + ACE_Hash<ACEXML_String>, + ACE_Equal_To<ACEXML_String>, + ACE_Null_Mutex> ACEXML_NS_CONTEXT; + +typedef ACE_Hash_Map_Iterator_Ex<ACEXML_String, + ACEXML_String, + ACE_Hash<ACEXML_String>, + ACE_Equal_To<ACEXML_String>, + ACE_Null_Mutex> ACEXML_NS_CONTEXT_ITER; + +typedef ACE_Hash_Map_Reverse_Iterator_Ex<ACEXML_String, + ACEXML_String, + ACE_Hash<ACEXML_String>, + ACE_Equal_To<ACEXML_String>, + ACE_Null_Mutex> ACEXML_NS_CONTEXT_REVERSE_ITER; + +typedef ACE_Unbounded_Queue<const ACEXML_Char *> ACEXML_STR_LIST; + +/** + * @class ACEXML_Namespace_Context_Stack NamespaceSupport.h "ACEXML/common/NamespaceSupport.h" + * + * @brief ACEXML_Namespace_Context_Stack implements a simple stack + * that ACEXML_NamespaceSupport uses to keep track of namespace scopes. + * + * @sa ACEXML_NamespaceSupport + */ +class ACEXML_Export ACEXML_Namespace_Context_Stack +{ +public: + /// Default constructor. + ACEXML_Namespace_Context_Stack (void); + + /// Destructor. + ~ACEXML_Namespace_Context_Stack (void); + + /// Push the old namespace before entering into a new namespace scope. + int push (ACEXML_NS_CONTEXT * old); + + /// Pop the old namespace when exiting a namespace scope. + ACEXML_NS_CONTEXT *pop (void); + +private: + /// Internal stack structure to hold namespace context. + ACE_Unbounded_Stack<ACEXML_NS_CONTEXT*> stack_; +}; + +/** + * @class ACEXML_NamespaceSupport NamespaceSupport.h "ACEXML/common/NamespaceSupport.h" + * + * @brief ACEXML_NamespaceSupport provides namespace management + * operation for an XML parser. + * + * This class encapsulates the logic of Namespace processing: it + * tracks the declarations currently in force for each context and + * automatically processes qualified XML 1.0 names into their + * Namespace parts; it can also be used in reverse for generating XML + * 1.0 from Namespaces. + * + * Namespace support objects are reusable, but the reset method must + * be invoked between each session. + * + * Here is a simple session (in Java :-p): + * @code + * String parts[] = new String[3]; + * NamespaceSupport support = new NamespaceSupport(); + * + * support.pushContext(); + * support.declarePrefix("", "http://www.w3.org/1999/xhtml"); + * support.declarePrefix("dc", "http://www.purl.org/dc#"); + * + * String parts[] = support.processName("p", parts, false); + * System.out.println("Namespace URI: " + parts[0]); + * System.out.println("Local name: " + parts[1]); + * System.out.println("Raw name: " + parts[2]); + * + * String parts[] = support.processName("dc:title", parts, false); + * System.out.println("Namespace URI: " + parts[0]); + * System.out.println("Local name: " + parts[1]); + * System.out.println("Raw name: " + parts[2]); + * + * support.popContext(); + * @endcode + * + * Note that this class is optimized for the use case where most + * elements do not contain Namespace declarations: if the same + * prefix/URI mapping is repeated for each context (for example), this + * class will be somewhat less efficient. + * + * @sa ACEXML_Exception + */ +class ACEXML_Export ACEXML_NamespaceSupport +{ +public: + /** + * Default constructor. + */ + ACEXML_NamespaceSupport (void); + + /** + * Default destructor. + */ + ~ACEXML_NamespaceSupport (void); + + /** + * Initialize the namespace support object + */ + int init(void); + + /** + * XMLNS default prefix and URI strings. + */ + static const ACEXML_Char *XMLNS_PREFIX; + static const ACEXML_Char *XMLNS; + + /** + * Declare a Namespace prefix. Return -1 if the prefix was illegal + * or an internal error occured. Return 0 if the prefix gets declared + * successfully, 1 if the prefix replaces an existing prefix definition. + */ + int declarePrefix (const ACEXML_Char *prefix, + const ACEXML_Char *uri); + + /** + * Return all prefixes declared in current context in + * the user-supplied list @a prefixes. It is user's reponsibility + * to ensure the list was empty originally. + */ + int getDeclaredPrefixes (ACEXML_STR_LIST &prefixes) const; + + /** + * Return one of the prefixes mapped to a Namespace URI. + */ + const ACEXML_Char *getPrefix (const ACEXML_Char *uri) const; + + /** + * Return all prefixes currently declared in the user-supplied list. + * @@ Known bug: This function should only return user-defined prefixes. + */ + int getPrefixes (ACEXML_STR_LIST &prefixes) const; + + /** + * Return all prefixes currently declared for a URI in the + * user-supplied list. + */ + int getPrefixes (const ACEXML_Char *uri, + ACEXML_STR_LIST &prefixes) const; + + /** + * Look up a prefix and get the currently-mapped Namespace URI. + */ + const ACEXML_Char *getURI (const ACEXML_Char *prefix) const; + + /** + * Revert to the previous namespace context. + */ + int popContext (void); + + /** + * Process a raw XML 1.0 name. + * @a qName is the raw XML name we want to parse, + * @a uri contains the URI string of the raw name. It points to a null + * string if the namespace is not valid or there's no namespace defined. + * @a name contains the original name without the prefix. + * @a is_attribute specifies whether the name is an attribute or not. + * Attributes have different scoping rules from elements. + */ + int processName (const ACEXML_Char *qName, + const ACEXML_Char *&uri, + const ACEXML_Char *&name, + int is_attribute) const; + + /** + * Start a new Namespace context. Prefixes defined in previous + * context are copied over to the new context. + */ + int pushContext (void); + + /** + * Reset this Namespace support object for reuse. + * + */ + int reset (void); + +private: + /** + * Namespace Context stack. When we entering a new namespace + * context, the old context is duplicated and pushed into + * this stack. + */ + ACEXML_Namespace_Context_Stack ns_stack_; + + /** + * The effective namespace context. + */ + ACEXML_NS_CONTEXT *effective_context_; +}; + +#include /**/ "ace/post.h" + +#endif /* ACEXML_NAMESPACESUPPORT_H */ |