NamespaceSupport.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    NamespaceSupport.h
00006  *
00007  *  NamespaceSupport.h,v 1.10 2006/02/09 22:53:20 kitty Exp
00008  *  NamespaceSupport.h,v 1.10 2006/02/09 22:53:20 kitty Exp
00009  *
00010  *  @author Nanbor Wang <nanbor@cs.wustl.edu>
00011  */
00012 //=============================================================================
00013 
00014 #ifndef ACEXML_NAMESPACESUPPORT_H
00015 #define ACEXML_NAMESPACESUPPORT_H
00016 
00017 #include /**/ "ace/pre.h"
00018 #include "ACEXML/common/ACEXML_Export.h"
00019 
00020 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00021 #pragma once
00022 #endif /* ACE_LACKS_PRAGMA_ONCE */
00023 
00024 #include "ACEXML/common/XML_Types.h"
00025 #include "ace/Functor.h"
00026 #include "ace/Hash_Map_Manager.h"
00027 #include "ace/Containers_T.h"
00028 #include "ace/Null_Mutex.h"
00029 
00030 
00031 typedef ACE_Hash_Map_Entry<ACEXML_String,
00032                            ACEXML_String> ACEXML_NS_CONTEXT_ENTRY;
00033 
00034 typedef ACE_Hash_Map_Manager_Ex<ACEXML_String,
00035                                 ACEXML_String,
00036                                 ACE_Hash<ACEXML_String>,
00037                                 ACE_Equal_To<ACEXML_String>,
00038                                 ACE_Null_Mutex> ACEXML_NS_CONTEXT;
00039 
00040 typedef ACE_Hash_Map_Iterator_Ex<ACEXML_String,
00041                                  ACEXML_String,
00042                                  ACE_Hash<ACEXML_String>,
00043                                  ACE_Equal_To<ACEXML_String>,
00044                                  ACE_Null_Mutex> ACEXML_NS_CONTEXT_ITER;
00045 
00046 typedef ACE_Hash_Map_Reverse_Iterator_Ex<ACEXML_String,
00047                                          ACEXML_String,
00048                                          ACE_Hash<ACEXML_String>,
00049                                          ACE_Equal_To<ACEXML_String>,
00050                                          ACE_Null_Mutex> ACEXML_NS_CONTEXT_REVERSE_ITER;
00051 
00052 typedef ACE_Unbounded_Queue<const ACEXML_Char *> ACEXML_STR_LIST;
00053 
00054 /**
00055  * @class ACEXML_Namespace_Context_Stack NamespaceSupport.h "ACEXML/common/NamespaceSupport.h"
00056  *
00057  * @brief ACEXML_Namespace_Context_Stack implements a simple stack
00058  * that ACEXML_NamespaceSupport uses to keep track of namespace scopes.
00059  *
00060  * @sa ACEXML_NamespaceSupport
00061  */
00062 class ACEXML_Export ACEXML_Namespace_Context_Stack
00063 {
00064 public:
00065   /// Default constructor.
00066   ACEXML_Namespace_Context_Stack (void);
00067 
00068   /// Destructor.
00069   ~ACEXML_Namespace_Context_Stack (void);
00070 
00071   /// Push the old namespace before entering into a new namespace scope.
00072   int push (ACEXML_NS_CONTEXT * old);
00073 
00074   /// Pop the old namespace when exiting a namespace scope.
00075   ACEXML_NS_CONTEXT *pop (void);
00076 
00077 private:
00078   /// Internal stack structure to hold namespace context.
00079   ACE_Unbounded_Stack<ACEXML_NS_CONTEXT*> stack_;
00080 };
00081 
00082 /**
00083  * @class ACEXML_NamespaceSupport NamespaceSupport.h "ACEXML/common/NamespaceSupport.h"
00084  *
00085  * @brief ACEXML_NamespaceSupport provides namespace management
00086  * operation for an XML parser.
00087  *
00088  * This class encapsulates the logic of Namespace processing: it
00089  * tracks the declarations currently in force for each context and
00090  * automatically processes qualified XML 1.0 names into their
00091  * Namespace parts; it can also be used in reverse for generating XML
00092  * 1.0 from Namespaces.
00093  *
00094  * Namespace support objects are reusable, but the reset method must
00095  * be invoked between each session.
00096  *
00097  * Here is a simple session (in Java :-p):
00098  * @code
00099  *  String parts[] = new String[3];
00100  *  NamespaceSupport support = new NamespaceSupport();
00101  *
00102  *  support.pushContext();
00103  *  support.declarePrefix("", "http://www.w3.org/1999/xhtml");
00104  *  support.declarePrefix("dc", "http://www.purl.org/dc#");
00105  *
00106  *  String parts[] = support.processName("p", parts, false);
00107  *  System.out.println("Namespace URI: " + parts[0]);
00108  *  System.out.println("Local name: " + parts[1]);
00109  *  System.out.println("Raw name: " + parts[2]);
00110  *
00111  *  String parts[] = support.processName("dc:title", parts, false);
00112  *  System.out.println("Namespace URI: " + parts[0]);
00113  *  System.out.println("Local name: " + parts[1]);
00114  *  System.out.println("Raw name: " + parts[2]);
00115  *
00116  *  support.popContext();
00117  * @endcode
00118  *
00119  * Note that this class is optimized for the use case where most
00120  * elements do not contain Namespace declarations: if the same
00121  * prefix/URI mapping is repeated for each context (for example), this
00122  * class will be somewhat less efficient.
00123  *
00124  * @sa ACEXML_Exception
00125  */
00126 class ACEXML_Export ACEXML_NamespaceSupport
00127 {
00128 public:
00129   /**
00130    * Default constructor.
00131    */
00132   ACEXML_NamespaceSupport (void);
00133 
00134   /**
00135    * Default destructor.
00136    */
00137   ~ACEXML_NamespaceSupport (void);
00138 
00139   /**
00140    *  Initialize the namespace support object
00141    */
00142   int init(void);
00143 
00144   /**
00145    * XMLNS default prefix and URI strings.
00146    */
00147   static const ACEXML_Char *XMLNS_PREFIX;
00148   static const ACEXML_Char *XMLNS;
00149 
00150   /**
00151    * Declare a Namespace prefix.  Return -1 if the prefix was illegal
00152    * or an internal error occured.  Return 0 if the prefix gets declared
00153    * successfully, 1 if the prefix replaces an existing prefix definition.
00154    */
00155   int declarePrefix (const ACEXML_Char *prefix,
00156                      const ACEXML_Char *uri);
00157 
00158   /**
00159    * Return all prefixes declared in current context in
00160    * the user-supplied list @a prefixes.  It is user's reponsibility
00161    * to ensure the list was empty originally.
00162    */
00163   int getDeclaredPrefixes (ACEXML_STR_LIST &prefixes) const;
00164 
00165   /**
00166    * Return one of the prefixes mapped to a Namespace URI.
00167    */
00168   const ACEXML_Char *getPrefix (const ACEXML_Char *uri) const;
00169 
00170   /**
00171    * Return all prefixes currently declared in the user-supplied list.
00172    * @@ Known bug: This function should only return user-defined prefixes.
00173    */
00174   int getPrefixes (ACEXML_STR_LIST &prefixes) const;
00175 
00176   /**
00177    * Return all prefixes currently declared for a URI in the
00178    * user-supplied list.
00179    */
00180   int getPrefixes (const ACEXML_Char *uri,
00181                    ACEXML_STR_LIST &prefixes) const;
00182 
00183   /**
00184    * Look up a prefix and get the currently-mapped Namespace URI.
00185    */
00186   const ACEXML_Char *getURI (const ACEXML_Char *prefix) const;
00187 
00188   /**
00189    * Revert to the previous namespace context.
00190    */
00191   int popContext (void);
00192 
00193   /**
00194    * Process a raw XML 1.0 name.
00195    * @a qName is the raw XML name we want to parse,
00196    * @a uri contains the URI string of the raw name.  It points to a null
00197    *    string if the namespace is not valid or there's no namespace defined.
00198    * @a name contains the original name without the prefix.
00199    * @a is_attribute specifies whether the name is an attribute or not.
00200    *    Attributes have different scoping rules from elements.
00201    */
00202   int processName (const ACEXML_Char *qName,
00203                    const ACEXML_Char *&uri,
00204                    const ACEXML_Char *&name,
00205                    int is_attribute) const;
00206 
00207   /**
00208    * Start a new Namespace context.  Prefixes defined in previous
00209    * context are copied over to the new context.
00210    */
00211   int pushContext (void);
00212 
00213   /**
00214    * Reset this Namespace support object for reuse.
00215    *
00216    */
00217   int reset (void);
00218 
00219 private:
00220   /**
00221    * Namespace Context stack.  When we entering a new namespace
00222    * context, the old context is duplicated and pushed into
00223    * this stack.
00224    */
00225   ACEXML_Namespace_Context_Stack ns_stack_;
00226 
00227   /**
00228    * The effective namespace context.
00229    */
00230   ACEXML_NS_CONTEXT *effective_context_;
00231 };
00232 
00233 #include /**/ "ace/post.h"
00234 
00235 #endif /* ACEXML_NAMESPACESUPPORT_H */

Generated on Thu Nov 9 11:45:37 2006 for ACEXML by doxygen 1.3.6