Main Page | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Namespace Members | Data Fields | Globals

persistable_object.hpp

Go to the documentation of this file.
00001 //
00002 // See license.txt for license information.
00003 //
00004 // persistable_object.hpp
00005 //
00006 // 17-Jul-2003  phamilton  Created
00007 //
00008 
00009 #ifndef incCOMMON_PERSISTABLE_OBJECT
00010 #define incCOMMON_PERSISTABLE_OBJECT
00011 
00012 // forwards
00013 #include <string>
00014 #include "object.hpp"
00015 #include "boost/filesystem/path.hpp"
00016 
00017 namespace ph {
00018 namespace common {
00019 
00020 // forwards
00021 class persistable_object_context;
00022 class object_writer;
00023 
00024 class persistable_object_base
00025 /**
00026         Abstract class representing the interface for an object to be persisted.
00027         
00028         NOTE: This class is completely independant of reflection, although it is
00029         obvious that reflection combined with persistance is the perfect solution
00030         for complex objects. It is kept separate for the purposes
00031         of reusability.
00032 */
00033 {
00034 public:
00035         virtual ~persistable_object_base() {}
00036                         
00037         virtual object_base *create(
00038                 const std::string &type, 
00039                 const std::string &name, 
00040                 persistable_object_context *context) = 0;
00041                 //!< Allow one object to create another. this is dependant
00042                 //! on the way you want to build new objects, but usually 
00043                 //! it involves the Abstract Factory pattern.
00044                 
00045         virtual object_base *get_composite_object(const std::string &name) = 0;
00046                 //!< return the object if it is a composite one.
00047                 //!
00048                 
00049         virtual bool has(const std::string &name) const = 0;
00050                 //!< Does this member name exist?
00051                 //!
00052                  
00053         virtual void set(const std::string &name, const std::string &value) = 0;
00054                 //!< Set the value of a member in the class with a particular name.
00055                 //!
00056         virtual std::string get(const std::string &name) const = 0;
00057                 //!< Get the value of a member in the class with a particular name.
00058                 //!
00059                 
00060         virtual bool write(object_writer *writer) const
00061                 { return true; }
00062                 //!< Write out the object using the writer passed in.
00063                 //!
00064                 
00065         virtual void set_file_path(const std::string &path) {}
00066                 //!< This object is coming as the root object from a file. 
00067                 //! Allow it to receive the path to this file.
00068 };
00069 
00070 class persistable_object_context
00071 /**
00072         Abstract class representing a context that is passed when objects
00073         are created.
00074 */
00075 {
00076 public:
00077         virtual ~persistable_object_context() {};
00078 
00079         virtual object_base *create(
00080                 const std::string &type, 
00081                 const std::string &name) = 0;
00082                 //!< Create an object of the appropriate type and name. Usually
00083                 //! implemented with an Abstract Factory pattern.
00084                 
00085         virtual object_base *find_object(
00086                 object_base *root, 
00087                 object_base *obj, 
00088                 const std::string &location) = 0;
00089                 //!< Find the object and return it if it's Composite.
00090                 //! "root" is the root object of the tree.
00091                 //! "obj" is the current object for relative locations.
00092                 //! "location" is the path location.
00093                 //!
00094 
00095         virtual object_base *find_composite_object(
00096                 object_base *root, 
00097                 object_base *obj, 
00098                 const std::string &location) = 0;
00099                 //!< Find the object and return it if it's Composite.
00100                 //! "root" is the root object of the tree.
00101                 //! "obj" is the current object for relative locations.
00102                 //! "location" is the path location.
00103                 //!
00104 
00105         virtual bool delayed_import() { return false; }
00106                 //!< The XML parser can do delayed importing. This means that instead of
00107                 //! actually importing an external file, a placeholder object is created and
00108                 //! then when this placeholder is referenced, the actual import is performed.
00109                 //! This speeds up extremely large object systems, and you can enable this
00110                 //! behaviour by returning true here. If your parser doesn't
00111                 //! handle this type of importing, then throw an error if this is set to
00112                 //! true (or something).
00113 
00114         virtual ph::common::object_base *create_delayed(
00115                 std::ostream *console,
00116                 const boost::filesystem::path &url, 
00117                 const std::string &name, 
00118                 unsigned int debug) { return 0 ; }
00119                 //!< Create an object to hold delayed import information.
00120 };
00121 
00122 class object_writer
00123 /**
00124         Abstract class used to write an object out.
00125 */
00126 {
00127 public:
00128         virtual ~object_writer() {};
00129         
00130         virtual bool start(const std::string &tagname) = 0;
00131                 //!< Start a new tag with the writer.
00132                 //!
00133         virtual bool attr(const std::string &name, const std::string &value) = 0;
00134                 //!< Write out name/value pairs for the tag.
00135                 //!
00136         virtual bool data(const std::string &d) = 0;
00137                 //!< Write out arbitrary data for the tag.
00138                 //!
00139         virtual bool end(const std::string &tagname) = 0;
00140                 //!< End the tag. Note that it is usually possible for the
00141                 //! implementation of the writer to save away the tag name,
00142                 //! but for keeping the writers simple, it is included again.
00143 };
00144 
00145 class object_writer_context
00146 /**
00147         A context used to start a tag, and then correctly end it
00148         upon destruction.
00149         
00150         This allows code such as:
00151         
00152         object_writer_context c(writer, "foo");
00153         c.attr("name", "foo_1");
00154         c.data("Hello World");
00155         
00156         To be used rather than explicitly starting and ending the tags.
00157 */
00158 {
00159 public:
00160         object_writer_context(object_writer *writer, const std::string &tagname) :
00161                 _writer(writer), _tagname(tagname)
00162                 { _writer->start(_tagname); }
00163         ~object_writer_context()
00164                 { _writer->end(_tagname); }
00165         void attr(const std::string &name, const std::string &value)
00166                 { _writer->attr(name, value); }
00167         void data(const std::string &d)
00168                 { _writer->data(d); }
00169         
00170 private:
00171         object_writer *_writer;
00172         std::string    _tagname;
00173 };
00174 
00175 inline bool get_persistable_obj_name(const object_base *obj, std::string *name)
00176 /**
00177         Function to return an objects name using the persistance scheme.
00178 */
00179 {
00180         if (!obj->persistable())
00181                 return false;
00182                 
00183         *name = obj->persistable()->get("name");
00184         return true;
00185 }
00186 
00187 inline bool get_persistable_obj_type(const object_base *obj, std::string *type)
00188 /**
00189         Function to return an objects type using the persistance scheme.
00190 */
00191 {
00192         if (!obj->persistable())
00193                 return false;
00194                 
00195         *type = obj->persistable()->get("type");
00196         return true;
00197 }
00198 
00199 inline bool set_persistable_obj_name(object_base *obj, const std::string &name)
00200 /**
00201         Function to set an objects name using the persistance scheme.
00202 */
00203 {
00204         if (!obj->persistable())
00205                 return false;
00206                 
00207         obj->persistable()->set("name", name);
00208         return true;
00209 }
00210 
00211 inline bool set_persistable_obj_type(object_base *obj, const std::string &type)
00212 /**
00213         Function to set an objects type using the persistance scheme.
00214 */
00215 {
00216         if (!obj->persistable())
00217                 return false;
00218                 
00219         obj->persistable()->set("type", type);
00220         return true;
00221 }
00222 
00223 }; // common
00224 }; // ph
00225 
00226 #endif // incCOMMON_PERSISTABLE_OBJECT

Generated on Wed Apr 5 22:03:26 2006 for cppxmlobj by  doxygen 1.4.3