00001 // 00002 // See license.txt for license information. 00003 // 00004 // visitable_object.hpp 00005 // 00006 // 17-Jul-2003 phamilton Created 00007 // 00008 00009 #ifndef incCOMMON_VISITABLE_OBJECT 00010 #define incCOMMON_VISITABLE_OBJECT 00011 00012 // forwards 00013 #include <string> 00014 #include "object.hpp" 00015 00016 namespace ph { 00017 namespace common { 00018 00019 class member_base 00020 /** 00021 Abstract class representing a member variable for visiting purposes. 00022 */ 00023 { 00024 public: 00025 virtual ~member_base() {}; 00026 00027 virtual std::string get() const = 0; 00028 //!< get the member value as a string. 00029 //! 00030 virtual void set(const std::string &s) = 0; 00031 //!< set the member value as a string. 00032 //! 00033 }; 00034 00035 class object_visitor 00036 /** 00037 Abstract class representing a visitor for objects. 00038 00039 This class represents the "Visitor" in the "Visitor" pattern. 00040 */ 00041 { 00042 public: 00043 virtual ~object_visitor() {}; 00044 00045 virtual bool recurse() { return false; } 00046 //!< Return true if the visitor should recurse through composite objects. 00047 //! it is up to the individual composite objects to implement this correctly. 00048 //! 00049 virtual bool visit(object_base *obj) = 0; 00050 //!< Visit an object. 00051 //! 00052 virtual bool visit_composite(object_base *obj) = 0; 00053 //!< Visit a composite object. 00054 //! 00055 }; 00056 00057 class const_object_visitor 00058 /** 00059 Abstract class representing a visitor for objects, where 00060 the visitor does not modify the objects that it visits. 00061 00062 This class represents the "Visitor" in the "Visitor" pattern. 00063 */ 00064 { 00065 public: 00066 virtual ~const_object_visitor() {}; 00067 00068 virtual bool recurse() { return false; } 00069 //!< Return true if the visitor should recurse through composite objects. 00070 //! it is up to the individual composite objects to implement this correctly. 00071 //! 00072 virtual bool visit(const object_base *obj) = 0; 00073 //!< Visit an object. 00074 //! 00075 virtual bool visit_composite(const object_base *obj) = 0; 00076 //!< Visit a composite object. 00077 //! 00078 }; 00079 00080 class member_visitor 00081 /** 00082 Abstract class representing a visitor for members of a descriptor. 00083 00084 This class represents the "Visitor" in the "Visitor" pattern. 00085 */ 00086 { 00087 public: 00088 virtual ~member_visitor() {}; 00089 00090 virtual bool visit(object_base *obj, 00091 const std::string &name, member_base *member) = 0; 00092 //!< Visit the member passing the name of it, a member base class which 00093 //! can be used to convert to/from a string, and the actual 00094 //! parent object. 00095 }; 00096 00097 class const_member_visitor 00098 /** 00099 Abstract class representing a visitor for members, where 00100 the visitor does not modify the objects or members that it visits. 00101 00102 This class represents the "Visitor" in the "Visitor" pattern. 00103 */ 00104 { 00105 public: 00106 virtual ~const_member_visitor() {}; 00107 00108 virtual bool visit(const object_base *obj, 00109 const std::string &name, const member_base *member) = 0; 00110 //!< Visit the member passing the name of it, a member base class which 00111 //! can be used to convert to/from a string, and the actual 00112 //! parent object. 00113 }; 00114 00115 class object_name_visitor 00116 /** 00117 Abstract class representing a visitor for an object's nameable interface. 00118 00119 This class represents the "Visitor" in the "Visitor" pattern. 00120 */ 00121 { 00122 public: 00123 virtual ~object_name_visitor() {}; 00124 00125 virtual bool recurse() { return false; } 00126 //!< Return true if the visitor should recurse through composite objects. 00127 //! it is up to the individual composite objects to implement this correctly. 00128 //! 00129 virtual bool visit(const object_base *obj, const nameable_object_base *nameable) = 0; 00130 //!< Visit an object's nameable interface. 00131 virtual bool visit_composite(const object_base *obj, const nameable_object_base *obj) = 0; 00132 //!< Visit a composite object's nameable interface. 00133 //! 00134 }; 00135 00136 class visitable_object_base 00137 /** 00138 Abstract class representing the interface for an object to be visited. 00139 00140 This class represents the "Element" in the "Visitor" pattern. 00141 */ 00142 { 00143 public: 00144 virtual ~visitable_object_base() {}; 00145 00146 virtual bool accept(object_name_visitor *v) const = 0; 00147 //!< Visit the name and type of the object (only). 00148 00149 virtual bool accept(member_visitor *v) = 0; 00150 //!< Visit each of the members in the object. 00151 //! 00152 virtual bool accept(const_member_visitor *v) const = 0; 00153 //!< Visit each of the members in the object. But 00154 //! they won't be modified. 00155 00156 virtual bool accept(object_visitor *v) = 0; 00157 //!< Visit each of the objects within this object. 00158 //! 00159 virtual bool accept(const_object_visitor *v) const = 0; 00160 //!< Visit each of the objects within this object. But 00161 //! they won't be modified. 00162 00163 }; 00164 00165 class get_member_value_visitor : public const_member_visitor 00166 /** 00167 Concrete subclass of const_member_visitor used to get the value of a member. 00168 */ 00169 { 00170 public: 00171 get_member_value_visitor(const std::string &name) : 00172 _name(name), _value(""), _found(false) 00173 {}; 00174 00175 std::string get() { return _value; } 00176 bool found() { return _found; } 00177 00178 virtual bool visit(const object_base *obj, const std::string &name, const member_base *member) 00179 { 00180 if (name == _name) 00181 { 00182 _value = member->get(); 00183 _found = true; 00184 return false; 00185 } 00186 return true; 00187 } 00188 00189 private: 00190 std::string _name; 00191 std::string _value; 00192 bool _found; 00193 }; 00194 00195 inline bool get_visitable_obj_member(const object_base *obj, const std::string &name, std::string *value) 00196 /** 00197 Function which implements returning the value of a mebmber using the visitor pattern. 00198 */ 00199 { 00200 if (!obj->visitable()) 00201 return false; 00202 00203 get_member_value_visitor v(name); 00204 obj->visitable()->accept(&v); 00205 if (v.found()) 00206 { 00207 *value = v.get(); 00208 return true; 00209 } 00210 else 00211 return false; 00212 } 00213 00214 }; // common 00215 }; // ph 00216 00217 #endif // incCOMMON_VISITABLE_OBJECT