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

/home/tetron/hack/vos/libs/vos/vos/vobjectbase.hh

Go to the documentation of this file.
00001 /*
00002     This file is part of the Virtual Object System of
00003     the Interreality project (http://interreality.org).
00004 
00005     Copyright (C) 2001-2003 Peter Amstutz
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00020 
00021     Peter Amstutz <http://www.interreality.org>
00022 */
00023 
00024 #ifndef _VOBJECTBASE_HH_
00025 #define _VOBJECTBASE_HH_
00026 
00027 /** @file
00028     Defines VobjectBase.
00029 */
00030 
00031 #include <vos/vutil/refcount.hh>
00032 #include <vos/vutil/url.hh>
00033 #include <vos/vutil/log.hh>
00034 #include <vos/vos/vobject.hh>
00035 #include <vos/vutil/readwritemutex.hh>
00036 #include <vos/vos/listener.hh>
00037 #include <vos/vos/vobjectextension.hh>
00038 #include <vos/vos/vobjectstate.hh>
00039 #include <vos/vos/accesscontrolstate.hh>
00040 #include <vos/vos/accesscontrol.hh>
00041 #include <vos/vos/iterator.hh>
00042 #include <vos/vos/policies.hh>
00043 
00044 #include <deque>
00045 #include <stdexcept>
00046 
00047 
00048 namespace VOS
00049 {
00050     class Site;
00051     class Message;
00052     class MessageBlock;
00053     class TypeChangeListener;
00054     class ParentChangeListener;
00055     class ChildChangeListener;
00056     class ParentChildRelation;
00057     class AccessControlList;
00058     class AccessControlState;
00059     class MetaObjectIterator;
00060 
00061     /** @class MessageDispatch vobjectbase.hh vos/vos/vobjectbase.hh
00062         @ingroup libvos
00063     */
00064     class VOS_API MessageDispatch
00065     {
00066     public:
00067         virtual ~MessageDispatch() {};
00068         virtual void sendMessage(Dispatchable* handler, Message* m) = 0;
00069     };
00070 
00071     template<class T> class MessageDispatchTemplate : public MessageDispatch
00072     {
00073     private:
00074         typedef void (T::* MessageHandler)(Message*);
00075         MessageHandler thismethod;
00076 
00077     public:
00078         MessageDispatchTemplate(MessageHandler themethod) : thismethod(themethod)
00079             { }
00080 
00081         virtual ~MessageDispatchTemplate() { }
00082 
00083         virtual void sendMessage(Dispatchable* mob, Message* m) {
00084             ((dynamic_cast<T*>(mob))->*thismethod)(m);
00085         }
00086     };
00087 
00088 /** @class VobjectBase vobjectbase.hh vos/vos/vobjectbase.hh
00089     @ingroup libvos
00090 
00091     A base implementation class for virtual objects.  Except for a few
00092     implementation-specific added methods, the API is the same as
00093     Vobject.
00094 */
00095 class VOS_API VobjectBase : public Vobject
00096 {
00097 private:
00098     bool islocal;
00099     bool exciseCalled;
00100     Site* site;
00101 
00102     std::string name;
00103     VUtil::URL url;
00104 
00105     boost::mutex flagstrings_mutex;
00106     std::set<std::string> flagstrings;
00107 
00108     VobjectState vobjectstate;
00109 
00110     typedef std::map<std::string, std::map<std::string, MessageDispatch*> > HandlerMap;
00111 
00112     static boost::mutex msghandlers_mutex;
00113     static HandlerMap msghandlers;
00114 
00115     static boost::mutex updatehandlers_mutex;
00116     static HandlerMap updatehandlers;
00117 
00118     VUtil::read_write_mutex metaobject_extensions_mutex;
00119     std::vector< std::pair<std::string, MetaObject*> > metaobject_extensions;
00120 
00121     VUtil::read_write_mutex vobject_extensions_mutex;
00122     std::vector< std::pair<std::string, VobjectExtension*> > vobject_extensions;
00123 
00124     AccessControlState* accesscontrolstate;
00125 
00126     VobjectBase(const std::string& name, Site* site, bool islocalobj);
00127 
00128 protected:
00129 
00130     virtual void setURL(const VUtil::URL& u) { url = u; }
00131 
00132     virtual void msgSendImpl(boost::mutex& usehandlers_mutex, HandlerMap& usehandlers, Message* msg);
00133 
00134 public:
00135     virtual ~VobjectBase();
00136 
00137     VobjectState& getVobjectState() { return vobjectstate; }
00138 
00139     virtual const std::string& getSiteName() const { return name; };
00140     virtual VUtil::vRef<Site> getSite() const;
00141     virtual const VUtil::URL& getURL() const { return url; }
00142     virtual bool isLocal() { return islocal; };
00143     virtual bool isRemote() { return (!islocal); };
00144 
00145 #ifndef SWIG
00146     template<class T> static void addMessageHandler(const std::string& method,
00147                                                     void (T::* messageHandler)(Message*))
00148         {
00149             boost::mutex::scoped_lock lk(msghandlers_mutex);
00150             if (msghandlers[typeid(T).name()][method] != 0) {
00151                 delete msghandlers[typeid(T).name()][method];
00152             }
00153             msghandlers[typeid(T).name()][method] = new MessageDispatchTemplate<T>(messageHandler);
00154         };
00155 
00156     template<class T> static void addUpdateHandler(const std::string& method,
00157                                                    void (T::* messageHandler)(Message*))
00158         {
00159             boost::mutex::scoped_lock lk(updatehandlers_mutex);
00160             if (updatehandlers[typeid(T).name()][method] != 0) {
00161                 delete updatehandlers[typeid(T).name()][method];
00162             }
00163             updatehandlers[typeid(T).name()][method] = new MessageDispatchTemplate<T>(messageHandler);
00164         };
00165 
00166     template<class T> static void removeMessageHandler(const std::string& method)
00167         {
00168             boost::mutex::scoped_lock lk(msghandlers_mutex);
00169 
00170             HandlerMap::iterator i = msghandlers.find(typeid(T).name());
00171 
00172             if (i != msghandlers.end()) {
00173                 std::map<std::string, MessageDispatch*>::iterator j = (*i).second.find(method);
00174 
00175                 if (j != (*i).second.end()) {
00176                     delete (*j).second;
00177                     (*i).second.erase(j);
00178                 }
00179             }
00180         };
00181 
00182     template<class T> static void removeUpdateHandler(const std::string& method)
00183         {
00184             boost::mutex::scoped_lock lk(updatehandlers_mutex);
00185 
00186             HandlerMap::iterator i = msghandlers.find(typeid(T).name());
00187 
00188             if (i != msghandlers.end()) {
00189                 std::map<std::string, MessageDispatch*>::iterator j = (*i).second.find(method);
00190 
00191                 if (j != (*i).second.end()) {
00192                     delete (*j).second;
00193                     (*i).second.erase(j);
00194                 }
00195             }
00196         };
00197 #endif
00198 
00199     /** Specify if this vobject's child list should be cached locally.
00200         Only meaningful for remote vobjects.  This means that we
00201         become a listener of the remote vobject child list and receive
00202         updates.  Calls to getChildren(), findChild() and findObject()
00203         will be serviced using the cached list and will not go out to
00204         the network.
00205         @param b If true, use cache.  If false, the list will not be
00206         cached (unless it is being listened to by another part of the
00207         program.)
00208      */
00209     virtual void cacheChildren(bool b);
00210 
00211     /** Specify if this vobject's parent set should be cached locally.
00212         Only meaningful for remote vobjects.  This means that we
00213         become a listener of the remote vobject parent set and receive
00214         updates.  Calls to getParents() and findParent() will be
00215         serviced using the cached set and will not go out to the
00216         network.
00217         @param b If true, use cache.  If false, the set will not be
00218         cached (unless it is being listened to by another part of the
00219         program.)
00220      */
00221     virtual void cacheParents(bool b);
00222 
00223     virtual TypeSetIterator getTypes(Vobject* requester);
00224     virtual TypeSetIterator getTypes()
00225         { return getTypes(0); }
00226 
00227     virtual void addType(Vobject* requester, const std::string& s);
00228     virtual void addType(const std::string& s)
00229         { addType(0, s); }
00230 
00231     virtual void removeType(Vobject* requester, const std::string& s);
00232     virtual void removeType(const std::string& s)
00233         { removeType(0, s); }
00234 
00235     virtual ParentSetIterator getParents(Vobject* requester);
00236     virtual ParentSetIterator getParents()
00237         { return getParents(0); }
00238 
00239         virtual ChildListIterator getChildren(Vobject* requester, int start = 0, int end = -1);
00240     virtual ChildListIterator getChildren(int start = 0, int end = -1)
00241         { return getChildren(0, start, end); }
00242 
00243         virtual int numChildren(Vobject* requester);
00244     virtual int numChildren()
00245         { return numChildren(0); }
00246 
00247     virtual VUtil::vRef<Vobject> findObject(Vobject* requester, const std::string& path);
00248     virtual VUtil::vRef<Vobject> findObject(const std::string& path)
00249                 { return findObject(0, path); }
00250 
00251     virtual VUtil::vRef<ParentChildRelation> findChild(Vobject* requester, const std::string& path);
00252     virtual VUtil::vRef<ParentChildRelation> findChild(const std::string& path)
00253         { return findChild(0, path); }
00254 
00255     virtual VUtil::vRef<ParentChildRelation> findChild(Vobject* requester, int pos);
00256     virtual VUtil::vRef<ParentChildRelation> findChild(int pos)
00257         { return findChild(0, pos); }
00258 
00259     virtual VUtil::vRef<ParentChildRelation> findParent(Vobject* requester, Vobject& parent);
00260     virtual VUtil::vRef<ParentChildRelation> findParent(Vobject& parent)
00261         { return findParent(0, parent); }
00262 
00263     virtual VUtil::vRef<ParentChildRelation> findParent(Vobject* parent)
00264         { return findParent(0, *parent); }
00265 
00266     virtual void setChild(Vobject* requester,
00267                           int position, const std::string& contextual_name, Vobject* child);
00268     virtual void setChild(int position, const std::string& contextual_name, Vobject* child)
00269         { setChild(0, position, contextual_name, child); }
00270 
00271     virtual void insertChild(Vobject* requester,
00272                              int position, const std::string& contextual_name, Vobject* child);
00273     virtual void insertChild(int position, const std::string& contextual_name, Vobject* child)
00274         { insertChild(0, position, contextual_name, child); }
00275 
00276     virtual void removeChild(Vobject* requester, ParentChildRelation* pcr, bool strict = true);
00277     virtual void removeChild(ParentChildRelation* pcr, bool strict = true)
00278         { removeChild(0, pcr, strict); }
00279 
00280     virtual void sendMessage(Message* m);
00281     virtual void sendMessage(MessageBlock* m);
00282     virtual void sendUpdateMessage(Message* m);
00283 #if 0
00284     virtual void initialize();
00285 #endif
00286 
00287     virtual void addTypeListener(Vobject* requester, TypeChangeListener* tl, bool refresh = true);
00288     virtual void addTypeListener(TypeChangeListener* tl, bool refresh = true)
00289         { addTypeListener(0, tl, refresh); }
00290 
00291     virtual void addParentListener(Vobject* requester, ParentChangeListener* pl, bool refresh = true);
00292     virtual void addParentListener(ParentChangeListener* pl, bool refresh = true)
00293         { addParentListener(0, pl, refresh); }
00294 
00295     virtual void addChildListener(Vobject* requester, ChildChangeListener* cl, bool refresh = true);
00296     virtual void addChildListener(ChildChangeListener* cl, bool refresh = true)
00297         { addChildListener(0, cl, refresh); }
00298 
00299     virtual void removeTypeListener(Vobject* requester, TypeChangeListener* tl);
00300     virtual void removeTypeListener(TypeChangeListener* tl)
00301         { removeTypeListener(0, tl); }
00302 
00303     virtual void removeParentListener(Vobject* requester, ParentChangeListener* pl);
00304     virtual void removeParentListener(ParentChangeListener* pl)
00305         { removeParentListener(0, pl); }
00306 
00307     virtual void removeChildListener(Vobject* requester, ChildChangeListener* cl);
00308     virtual void removeChildListener(ChildChangeListener* cl)
00309         { removeChildListener(0, cl); }
00310 
00311     virtual void excise();
00312 
00313     virtual void saveState(MessageBlock& output, std::set<std::string>& types, bool portable);
00314 
00315     virtual void addFlag(const std::string& flag);
00316     virtual void removeFlag(const std::string& flag);
00317     virtual bool checkFlag(const std::string& flag);
00318 
00319     virtual void addVobjectExtension(VobjectExtension* vx);
00320     virtual void addMetaObjectExtension(MetaObject* m);
00321 
00322     virtual MetaObjectIterator getMetaObjectExtensions();
00323 
00324     virtual StringIterator getPolicy(Vobject* requester, const std::string& domain, Identity* id);
00325     virtual StringIterator getPolicy(const std::string& domain, Identity* id)
00326         { return getPolicy(0, domain, id); }
00327 
00328     virtual StringIterator getAvailablePolicies(Vobject* requester, const std::string& domain);
00329     virtual StringIterator getAvailablePolicies(const std::string& domain)
00330         { return getAvailablePolicies(0, domain); }
00331 
00332     virtual void addToACL(Vobject* requester, const std::string& ACLname, Identity* id);
00333     virtual void addToACL(const std::string& ACLname, Identity* id)
00334         { addToACL(0, ACLname, id); }
00335 
00336     virtual void addToACL(Vobject* requester, const std::string& ACLname, Group* grp);
00337     virtual void addToACL(const std::string& ACLname, Group* grp)
00338         { addToACL(0, ACLname, grp); }
00339 
00340     virtual void removeFromACL(Vobject* requester, const std::string& ACLname, Identity* id);
00341     virtual void removeFromACL(const std::string& ACLname, Identity* id)
00342         { removeFromACL(0, ACLname, id); }
00343 
00344     virtual void removeFromACL(Vobject* requester, const std::string& ACLname, Group* grp);
00345     virtual void removeFromACL(const std::string& ACLname, Group* grp)
00346         { removeFromACL(0, ACLname, grp); }
00347 
00348     virtual void deleteACL(Vobject* requester, const std::string& policies);
00349     virtual void deleteACL(const std::string& policies)
00350         { deleteACL(0, policies); }
00351 
00352     virtual std::string getDefaultPolicy(Vobject* requester, const std::string& domain);
00353     virtual std::string getDefaultPolicy(const std::string& domain = "")
00354         { return getDefaultPolicy(0, domain); }
00355 
00356     virtual void setDefaultPolicy(Vobject* requester, const std::string& policy);
00357     virtual void setDefaultPolicy(const std::string& policy)
00358         { setDefaultPolicy(0, policy); }
00359 
00360     virtual ACLIterator getAllACLs(Vobject* requester);
00361     virtual ACLIterator getAllACLs();
00362 
00363 
00364     void doAccessControlCheck(VobjectEvent& ve);
00365 
00366     template<class AccessControlType> inline std::vector<AccessControlType*>
00367                 getAccessControlsFor(Vobject* requester,
00368                                 PolicyDomain<AccessControlType>& accessControlPolicies);
00369 
00370     virtual VUtil::vRef<VobjectBase> getVobjectBase() { return VUtil::vRef<VobjectBase>(this, true); }
00371 
00372 #ifndef SWIG
00373     template<class C> VUtil::vRef<C> queryInterface()
00374         {
00375             VUtil::scoped_read_lock lk(metaobject_extensions_mutex);
00376             for(std::vector< std::pair<std::string, MetaObject*> >::iterator i = metaobject_extensions.begin();
00377                 i != metaobject_extensions.end();
00378                 i++)
00379             {
00380                 if(C* ret = dynamic_cast<C*>((*i).second)) return VUtil::vRef<C>(ret, true);
00381             }
00382             return VUtil::vRef<C>();
00383         }
00384     template<class C> C* queryExtension()
00385         {
00386             VUtil::scoped_read_lock lk(vobject_extensions_mutex);
00387 
00388             for(std::vector< std::pair<std::string, VobjectExtension*> >::iterator i = vobject_extensions.begin();
00389                 i != vobject_extensions.end();
00390                 i++)
00391             {
00392                 if(C* ret = dynamic_cast<C*>((*i).second)) return ret;
00393             }
00394             return 0;
00395         }
00396 
00397     friend class Site;
00398 #endif
00399 };
00400 
00401     /** Copies the access control policies (default policy + access
00402         control lists) from one Vobject to another
00403     */
00404     VOS_API void copyAccessControlPolicies(Vobject* to, Vobject* from);
00405 
00406     /** @return true if the the supplied have the same access control
00407         lists (comparison does NOT include default policies).
00408     */
00409     VOS_API bool sameAccessControlLists(Vobject* a, Vobject* b);
00410 }
00411 
00412 #endif
00413