/home/tetron/hack/vos/libs/vos/vos/vobject.hh
Go to the documentation of this file.00001 /* 00002 00003 This file is part of the Virtual Object System of 00004 the Interreality project (http://interreality.org). 00005 00006 Copyright (C) 2001-2003 Peter Amstutz 00007 00008 This library is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU Lesser General Public 00010 License as published by the Free Software Foundation; either 00011 version 2 of the License, or (at your option) any later version. 00012 00013 This library is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 Lesser General Public License for more details. 00017 00018 You should have received a copy of the GNU Lesser General Public 00019 License along with this library; if not, write to the Free Software 00020 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00021 00022 Peter Amstutz <http://www.interreality.org> 00023 */ 00024 00025 #ifndef _VOBJECT_HH_ 00026 #define _VOBJECT_HH_ 00027 00028 #include <vos/vos/vosdefs.hh> 00029 #include <vos/vutil/refcount.hh> 00030 #include <vos/vutil/url.hh> 00031 #include <vos/vutil/log.hh> 00032 00033 #include <deque> 00034 #include <stdexcept> 00035 #include <vector> 00036 00037 00038 namespace VOS 00039 { 00040 class Site; 00041 class Message; 00042 class MessageBlock; 00043 class TypeChangeListener; 00044 class ParentChangeListener; 00045 class ChildChangeListener; 00046 class ParentChildRelation; 00047 class MetaObject; 00048 class VobjectBase; 00049 class Identity; 00050 class Group; 00051 class ACLIterator; 00052 00053 class PCRIterator; 00054 typedef PCRIterator ChildListIterator; 00055 typedef PCRIterator ParentSetIterator; 00056 class StringIterator; 00057 typedef StringIterator TypeSetIterator; 00058 00059 /** @class NoSuchSiteError vobject.hh vos/vos/vobject.hh 00060 @ingroup libvos 00061 An exception class thrown when a remote site cannot be contacted. 00062 */ 00063 class VOS_API NoSuchSiteError : public std::runtime_error { 00064 public: 00065 NoSuchSiteError(const std::string& s) : runtime_error(s) { }; 00066 static const char* errorCode() { return "404"; } 00067 }; 00068 00069 /** @class NoSuchObjectError vobject.hh vos/vos/vobject.hh 00070 @ingroup libvos 00071 An exception class thrown when an object lookup fails. 00072 */ 00073 class VOS_API NoSuchObjectError : public std::runtime_error { 00074 public: 00075 NoSuchObjectError(const std::string& s) : runtime_error(s) { }; 00076 static const char* errorCode() { return "404"; } 00077 }; 00078 00079 /** @class AccessControlError vobject.hh vos/vos/vobject.hh 00080 @ingroup libvos 00081 */ 00082 class VOS_API AccessControlError : public std::runtime_error { 00083 public: 00084 AccessControlError(const std::string& s) : runtime_error(s) { }; 00085 static const char* errorCode() { return "403"; } 00086 }; 00087 00088 /** @class RemoteError vobject.hh vos/vos/vobject.hh 00089 @ingroup libvos 00090 An exception class thrown when a remote action fails. */ 00091 class VOS_API RemoteError : public std::runtime_error { 00092 public: 00093 RemoteError(const std::string& s) : runtime_error(s) { }; 00094 }; 00095 00096 /** @class TimeoutError vobject.hh vos/vos/vobject.hh 00097 @ingroup libvos 00098 00099 An exception class thrown when an expected reply didn't arrive 00100 in the alloted time. 00101 */ 00102 class VOS_API TimeoutError : public RemoteError { 00103 public: 00104 TimeoutError(const std::string& s) : RemoteError(s) { }; 00105 }; 00106 00107 /** Used by metaobject and vobject extension classes to all them to accept message dispatch (directing 00108 messages with a given method string to a specific method). 00109 */ 00110 class VOS_API Dispatchable 00111 { 00112 public: 00113 virtual ~Dispatchable() { } 00114 }; 00115 00116 /** @class Vobject vobject.hh vos/vos/vobject.hh 00117 @ingroup libvos 00118 00119 This is the abstract class that defines the basic API common to 00120 all virtual objects. Whether the object is local or remote, you 00121 should be able to use all the methods in this API (provided you 00122 have proper permissions). 00123 */ 00124 class VOS_API Vobject : public VUtil::RefCounted 00125 { 00126 public: 00127 /** @return the site name of this object. */ 00128 virtual const std::string& getSiteName() const = 0; 00129 00130 /** @return the site this object resides on. */ 00131 virtual VUtil::vRef<VOS::Site> getSite() const = 0; 00132 00133 /** @return the URL path as a URL object */ 00134 virtual const VUtil::URL& getURL() const = 0; 00135 00136 /** @return the URL path (in the form "proto://site/name") */ 00137 virtual std::string getURLstr() { return getURL().getString(); } 00138 00139 /** @return true if this object is local, false if not */ 00140 virtual bool isLocal() = 0; 00141 00142 /** @return true if this object is remote, false if not */ 00143 virtual bool isRemote() = 0; 00144 00145 /** @return a set of type names for the types supported by this object. */ 00146 virtual TypeSetIterator getTypes() = 0; 00147 00148 /** Adds a new type to this object's type set. This only changes 00149 the stored set of type name std::strings and does not necessarily 00150 affect the actual code behind the object. See the Local Site 00151 class for information about extending the actual functionality 00152 of an existing meta objects. 00153 @param s the type std::string 00154 */ 00155 virtual void addType(const std::string& s) = 0; 00156 00157 /** Remove a type from the type set. 00158 @param s the type std::string 00159 */ 00160 virtual void removeType(const std::string& s) = 0; 00161 00162 /** Get the set of parent-child relationships in which this object is the child. 00163 @return a set of parent-child relations 00164 */ 00165 virtual ParentSetIterator getParents() = 0; 00166 00167 /** Get the children of this Vobject. Permits fetching a "slice" 00168 of a child list by specifying starting and ending positions. 00169 00170 @param start the position of the first child to return (inclusive) 00171 @param end the position of th elast child to return (inclusive) 00172 @return an Iterator over a list of parent-child relations 00173 */ 00174 virtual ChildListIterator getChildren(int start = 0, int end = -1) = 0; 00175 00176 /** @return the number of children that this Vobject has. This is 00177 more efficient than calling getChildren().size() because if 00178 this is a remote object it does not actually fetch the 00179 children. 00180 */ 00181 virtual int numChildren() = 0; 00182 00183 /** Delivers a message to the object. This may trigger immediate 00184 processing of the message if the object is local. 00185 @param m A pointer to the message which is being sent. 00186 */ 00187 virtual void sendMessage(Message* m) = 0; 00188 00189 /** Delivers a block of messages to the object. This may trigger immediate 00190 processing of the message if the object is local. 00191 @param m A pointer to the message which is being sent. 00192 */ 00193 virtual void sendMessage(MessageBlock* m) = 0; 00194 00195 /** Delivers an update message to this object -- only meaningful if 00196 this is a remote object. Update messages are special in that 00197 they are sent by the remote site to update our local cache. 00198 00199 @param m A pointer to the message which is being sent. 00200 */ 00201 virtual void sendUpdateMessage(Message* m) = 0; 00202 00203 /** Searchs and returns some object, given a rooted path (that is, 00204 in the form "vop://site:port/child1/child2/etc"). See 00205 findObject() for more information about paths. 00206 00207 @param path the path to the object we want to find 00208 @return the object, if found. 00209 @throws NoSuchSiteError The DNS lookup for the site failed, 00210 the site is not listening on the expected port, site peering 00211 failed, for whatever other reason the site could not be contacted. 00212 @throws NoSuchObjectError if that object path does not exist on the site 00213 @throws BadURLError if there is a syntax error in the supplied URL 00214 @throws AccessControlError if a remote site reported that the user 00215 is not allowed that information 00216 */ 00217 static VUtil::vRef<VOS::Vobject> findObjectFromRoot(const std::string& path); 00218 00219 /** Follows some path to find the Vobject. Unlike 00220 findObjectFromRoot(), if the path does not start with "vop://" 00221 the path will be intepreted relative to this object. For 00222 example, "foo/bar" will find the first child object named 00223 "foo" of this object, then the first child named "bar" of 00224 "foo" object and return that. If there is a leading slash, 00225 the path is relative to the object's site, so "/foo/bar" means 00226 to find the Vobject with site name "foo", then find the first 00227 child of that object "bar" and return that. Instead of using 00228 child names, one may use the position by prefixing a hash mark 00229 to the numerical position. So "\#0" refers to the first child 00230 of this object, "\#1" to the second etc. If this is larger 00231 than the number of children, an exception will be raised. See 00232 setChild() for more information about the possible numerical 00233 values of positions. 00234 00235 @param path the path to the object we want to find 00236 @return the object, if found. 00237 @throws NoSuchSiteError The DNS lookup for the site failed, 00238 the site is not listening on the expected port, site peering 00239 failed, for whatever other reason the site could not be 00240 contacted. Only thrown if there is a site specified in the 00241 path.) 00242 @throws NoSuchObjectError if that object path does not exist on the site 00243 @throws BadURLError if there is a syntax error in the supplied URL 00244 @throws AccessControlError if a remote site reported that the user 00245 is not allowed that information 00246 */ 00247 virtual VUtil::vRef<VOS::Vobject> findObject(const std::string& path) = 0; 00248 00249 /** Fetch a child. This searchs for a single parent-child 00250 relation in the immediate child list of this object. It is 00251 distinguished from findObject in that it returns the full 00252 parent-child relation structure, and that it only accepts two 00253 forms of input: the child name, or the position in the child 00254 list. See setChild() for more information about the possible 00255 numerical values of positions. If there are multiple children 00256 with the same name, the one with the lowest position is 00257 returned. 00258 00259 @param path either the child name or the position as a string 00260 @return the ParentChildRelation structure representing the 00261 relation of this parent and the requested child. 00262 @throws NoSuchObjectError if the path is illegal 00263 @throws AccessControlError if a remote site reported the user 00264 is not allowed that information 00265 */ 00266 virtual VUtil::vRef<VOS::ParentChildRelation> findChild(const std::string& path) = 0; 00267 00268 /** Get the child at a certain position. This searchs for a 00269 single parent-child relation in the immediate child list of 00270 this object. See setChild() for more information about the 00271 possible numerical values of positions. 00272 00273 @param pos the child position 00274 @return the ParentChildRelation structure representing the 00275 relation of this parent and the requested child. 00276 @throws NoSuchObjectError if the path is illegal 00277 @throws AccessControlError if a remote site reported the user 00278 is not allowed that information 00279 */ 00280 virtual VUtil::vRef<VOS::ParentChildRelation> findChild(int pos) = 0; 00281 00282 /** Find a parent. This tests to see if the supplied Vobject is 00283 a parent of this Vobject. 00284 @param parent the parent object 00285 @returns the parent-child relation. 00286 @throws NoSuchObjectError if the object is NOT a parent 00287 @throws AccessControlError if a remote site reported the user 00288 is not allowed that information 00289 */ 00290 00291 virtual VUtil::vRef<VOS::ParentChildRelation> findParent(Vobject* parent) = 0; 00292 00293 /** Replace an entry in the child list with a new entry. This can 00294 be used to change the child, the contextual name, or both. 00295 00296 @note On positions: if a position is zero or positive, its 00297 meaning is as you would expect, expressing the offset into an 00298 array of children. However, if the position is negative, it 00299 expresses the offset from the end of the list. This means for 00300 a list of length n, -1 is the last item in the list (equal to 00301 position n - 1) and -n is the first item (equal to positive 00302 position 0). This position notation is used in setChild() 00303 findObject(), findObjectFromRoot(), insertChild(), and 00304 removeChild(); it should also be available with any methods 00305 who make use of the previously-mentioned methods. 00306 00307 @param position the position 00308 @param contextual_name This is the name, specific to this 00309 parent-child relation, used for refering to this object by 00310 path. 00311 @param child the child object, in question 00312 @throws AccessControl if this is a remote object and the 00313 remote site has denied the requsted action 00314 */ 00315 virtual void setChild(int position, const std::string& contextual_name, 00316 Vobject* child) = 0; 00317 00318 /** Insert a child at some position with a new object. If the 00319 position is positive, the object is inserted such that it now 00320 occupies that position, and all objects starting from the 00321 previous occupant of that position onward are moved up one. 00322 If the position in negative, the object is similarly inserted 00323 so that it now occupies that position. For example, position 00324 -1 will append the object to the end of the list, position -2 00325 will insert the object in the second-to-last position, etc. See 00326 setChild() for more discussion on positions. 00327 @param position the position 00328 @param contextual_name This is the name, specific to this 00329 parent-child relation, used for refering to this object by 00330 path. 00331 @param child the child object, in question 00332 @throws AccessControl if this is a remote object and the 00333 remote site has denied the requsted action 00334 */ 00335 virtual void insertChild(int position, const std::string& contextual_name, 00336 Vobject* child) = 0; 00337 00338 /** Remove the child at some position. See setChild() for more 00339 information on positions. 00340 00341 @param pcr ParentChildRelation object describing the child 00342 entry to remove. 00343 @param strict Should the position in the supplied parent child 00344 relation be strictly followed? If strict is false, then if 00345 the parent-child entry at the supplied position does NOT match 00346 the contextual name and/or child object, but there is exactly 00347 one other entry in the child list which does match the 00348 contextual name and child we want to remove, then that entry 00349 will be removed instead. If strict is true, an 00350 AccessControlError is raised in this situation. 00351 00352 @throws AccessControl if this is a remote object and the 00353 remote site has denied the requsted action 00354 */ 00355 virtual void removeChild(ParentChildRelation* pcr, bool strict = true) = 0; 00356 00357 /** Adds some object callback to be notified when the type set changes. 00358 @param tl the listener object. 00359 @param refresh if true, will queue up notification callbacks 00360 on the listener fully describing the current state. 00361 */ 00362 virtual void addTypeListener(TypeChangeListener* tl, bool refresh = true) = 0; 00363 00364 /** Adds some object callback to be notified when the parent set changes. 00365 @param pl the listener object 00366 @param refresh if true, will queue up notification callbacks 00367 on the listener fully describing the current state. 00368 */ 00369 virtual void addParentListener(ParentChangeListener* pl, bool refresh = true) = 0; 00370 00371 /** Adds some object callback to be notified when the child list 00372 changes. The 00373 @param cl The listener object. 00374 @param refresh if true, will queue up notification callbacks 00375 on the listener fully describing the current state. 00376 */ 00377 virtual void addChildListener(ChildChangeListener* cl, bool refresh = true) = 0; 00378 00379 /** Removes an object callback, previously added with addTypeListener(). 00380 @param tl the listener object 00381 */ 00382 virtual void removeTypeListener(TypeChangeListener* tl) = 0; 00383 00384 /** Removes an object callback, previously added with addParentListener(). 00385 @param pl the listener object 00386 */ 00387 virtual void removeParentListener(ParentChangeListener* pl) = 0; 00388 00389 /** Removes an object callback, previously added with addChildListener(). 00390 @param cl the listener object 00391 */ 00392 virtual void removeChildListener(ChildChangeListener* cl) = 0; 00393 00394 /** Provide our own comparison function for objects which are logically 00395 equivilent in terms of the Vobject system. 00396 @param v the object to compare this to 00397 @return true if these objects are equivalent, else false. 00398 */ 00399 bool operator==(Vobject& v) const; 00400 00401 /** Provide our own comparison function for objects which are logically 00402 equivilent in terms of the Vobject system. 00403 @param v the object to compare with this object 00404 @return false if these objects are equivalent, otherwise true. 00405 */ 00406 bool operator!=(Vobject& v) const; 00407 00408 /** Create a message block which, when run, will recreate any 00409 non-VOS state related to this vobject (such as property 00410 values). In other words, it should not emit anything related 00411 to parent-child relationships, but is rather is a hook for 00412 other arbitrary state information, encoded as messages. @note 00413 Save-state routines ought to work for saving remote objects as 00414 well, based on available state. Also, only the method and the 00415 message fields themselves should be used. "To", "from", 00416 "nonce" and others will be ignored. 00417 @param output messages should be appended to this message block 00418 @param types the type set that should be output for this vobject 00419 @param portable If true, generate a "portable" state. This 00420 means that all the data required to restore state should be 00421 embedded in the message. If false, fully recreating the state 00422 may rely on external resources such as files or databases. 00423 */ 00424 virtual void saveState(MessageBlock& output, std::set<std::string>& types, bool portable) = 0; 00425 00426 /** Add a flag string. Useful when doing recursive tree walks, to 00427 avoid cycles. This is local-only, it is not shared with other 00428 sites in any way. 00429 00430 @param flag the flag string 00431 */ 00432 virtual void addFlag(const std::string& flag) = 0; 00433 00434 /** Remove a flag string. 00435 @param flag the flag string 00436 */ 00437 virtual void removeFlag(const std::string& flag) = 0; 00438 00439 /** Check the flag std::string. 00440 @param flag the flag std::string 00441 @return whether the flag std::string is set 00442 */ 00443 virtual bool checkFlag(const std::string& flag) = 0; 00444 00445 /** @return the VobjectBase object that actually implements this Vobject */ 00446 virtual VUtil::vRef<VobjectBase> getVobjectBase() = 0; 00447 00448 /** @copydoc VOS::AccessControlState::getPolicy */ 00449 virtual StringIterator getPolicy(const std::string& domain, Identity* id) = 0; 00450 00451 /** @copydoc VOS::AccessControlState::getAvailablePolicies */ 00452 virtual StringIterator getAvailablePolicies(const std::string& domain) = 0; 00453 00454 /** @copydoc VOS::AccessControlState::addToACL(const std::string& ACLname, Identity* id) */ 00455 virtual void addToACL(const std::string& ACLname, Identity* id) = 0; 00456 00457 /** @copydoc VOS::AccessControlState::addToACL(const std::string& ACLname, Group* grp) */ 00458 virtual void addToACL(const std::string& ACLname, Group* grp) = 0; 00459 00460 /** @copydoc VOS::AccessControlState::removeFromACL(const std::string& ACLname, Identity* id) */ 00461 virtual void removeFromACL(const std::string& ACLname, Identity* id) = 0; 00462 00463 /** @copydoc VOS::AccessControlState::removeFromACL(const std::string& ACLname, Group* grp) */ 00464 virtual void removeFromACL(const std::string& ACLname, Group* grp) = 0; 00465 00466 /** @copydoc VOS::AccessControlState::deleteACL */ 00467 virtual void deleteACL(const std::string& policies) = 0; 00468 00469 /** @copydoc VOS::AccessControlState::getDefaultPolicy */ 00470 virtual std::string getDefaultPolicy(const std::string& domain = "") = 0; 00471 00472 /** @copydoc VOS::AccessControlState::setDefaultPolicy */ 00473 virtual void setDefaultPolicy(const std::string& policy) = 0; 00474 00475 /** @copydoc VOS::AccessControlState::getAllACLs */ 00476 virtual ACLIterator getAllACLs() = 0; 00477 }; 00478 00479 } 00480 00481 #endif