// DtdRegistry.h #ifndef dset_DtdRegistry_H #define dset_DtdRegistry_H // David Adams // April 2003 // // Provides central registration for XML data type definitions (DTD's). // Each instance of DtdRegistry correponds to an XML system and returns // a name (e.g. dataset) and a DTD filename (e.g. dataset.dtd). // // An XML type is added to a system with the method add_dtd(..) or with // the static method register_dtd(..). The latter requires that the type // provide the standard DTD interface. The method write(...) can be used // write the DTD to a file. Each registry is labeled with a string and // the file name is obtained by appending ".dtd" to this label. // // The static method system(type) returns the system associated with a // given type name. It can be used by parsers to find the DTD for a type: // DtdRegistry::system(mytype)->name() is the system name // DtdRegistry::system(mytype)->filename() is the DTD filename // DtdRegistry::system(mytype)->text() is the DTD text for the system // // Sub-DTD's can also be registered. These are either copied into the parent // DTD or are included with an entity declaration. // // Example registering two types and then writing: // Text dtd1; // //... // int i1 = DtdRegistry::instance("MySystem").add_dtd("MyClass1",mydtd1); // int i2 = DtdRegistry.register_dtd("MySystem"); // DtdRegistry::instance("MySystem").write(); // // The second registration makes use of the static methods // MyClass2::xml_name() and MyClass2::dtd(). #include #include #include #include #include "dataset_util/Text.h" class DtdRegistry { public: // Typedefs. typedef std::string Name; typedef Text Dtd; typedef unsigned int Status; typedef std::vector NameList; typedef std::vector BoolList; typedef std::map DtdMap; private: // Data // Name for this registry. Name m_name; // Ordered list of types. NameList m_types; // DTD's indexed by type name. DtdMap m_dtds; // Sub-DTD's NameList m_subs; // Copy status for each sub-DTD. BoolList m_copy; // DTD mutable Text m_dtd; public: // Static methods // Return a registry. // Created if it does not already exist. static DtdRegistry& instance(Name rname); // Templated registration. // Subclass must provide xml_name() and dtd(). template static Status register_dtd(Name sys) { return instance(sys).add_type(T::xml_name(), T::dtd()); } // Display all known registries. static std::ostream& display(std::ostream& str); // Return whether a type has been registered in any registry. static bool is_registered(Name type); // Return the registry for the given type. // The DTD for type should be in DtdRegistry::system(type).filename(). // Zero is returned if the type is not registered. static DtdRegistry* system(Name type); private: // Hide standard constructors from users. // Constructor. DtdRegistry(Name name =""); // Copy constructor. // Not implemented. DtdRegistry(const DtdRegistry& rhs); // Assignment. // Not implemented. DtdRegistry& operator=(const DtdRegistry& rhs); private: // for internal use only // Clear the DTD. void clear_dtd() const; // Build the DTD. void build_dtd() const; public: // non-const functions // Add the DTD for a new type. // The text from the give DTD will be added to global DTD. // Any given type may only be registered once. // type = XML type name // dtd = DTD for that type // deps = Names of the types on which this type depends // Returns 0 for success. Status add_type(Name type, const Dtd& dtd); // Add another DTD registry. // The new registry is created if it does not exist. // IF copy is true, then the sub-DTD is copied into this one. // Otherwise it is referenced with an XML entity declaration. // Returns 0 for success. Status add_dtd(const Name rname, bool copy =false); public: // const functions // Return the name of this registry. Name name() const; // Return the DTD file name. Name filename() const; // Return the list of types in this DTD. const NameList& types() const; // Return if a type name is included in this registry. bool has_type(Name type) const; // Return the list of registries used by this registry. const NameList& dtds() const; // Return if another DTD registry is included in this registry. bool has_dtd(Name reg) const; // Return the DTD text. const Text& text() const; // Write the DTD to a file. // Returns the file name. Name write() const; }; // Output stream. std::ostream& operator<<(std::ostream& lhs, const DtdRegistry& rhs); #endif