interreality.org [VOS]
[Home] [About]
[Screenshots]
[Download]
[News]
[Community]
[Documentation] [Manual]
[Bugs & Requests] [Wiki]

/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