Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages | Examples

vos/corelibs/vos/localvobject.cc

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 <tetron@interreality.org>
00022 */
00023 
00024 #include "localvobject.hh"
00025 #include "localsite.hh"
00026 #include "listener.hh"
00027 #include "message.hh"
00028 #include "messageblock.hh"
00029 #include "remotesite.hh"
00030 #include "timer.hh"
00031 #include "accesscontrol.hh"
00032 
00033 using namespace VOS;
00034 
00035 #include <stdio.h>
00036 #include <math.h>
00037 
00038 #include <string>
00039 #include <algorithm>
00040 
00041 /** @file
00042     Implements LocalVobject.
00043  */
00044 
00045 LocalVobject::LocalVobject(const string& n, LocalSite* s, VobjectAccessControl* ac)
00046     :  VobjectImplementation(n, s, true)
00047 {
00048     insertAccessControl(0, ac);
00049 
00050     addMessageHandler<LocalVobject>("core:find-child", this, &LocalVobject::findObjectHandler);
00051     addMessageHandler<LocalVobject>("core:get-types", this, &LocalVobject::getTypesHandler);
00052     addMessageHandler<LocalVobject>("core:get-parents", this, &LocalVobject::getParentsHandler);
00053     addMessageHandler<LocalVobject>("core:set-child", this, &LocalVobject::addChildHandler);
00054     addMessageHandler<LocalVobject>("core:insert-child", this, &LocalVobject::addChildHandler);
00055     addMessageHandler<LocalVobject>("core:remove-child", this, &LocalVobject::removeChildHandler);
00056     addMessageHandler<LocalVobject>("core:start-listening", this, &LocalVobject::startListeningHandler);
00057     addMessageHandler<LocalVobject>("core:stop-listening", this, &LocalVobject::stopListeningHandler);
00058     addMessageHandler<LocalVobject>("core:type-add", this, &LocalVobject::typeAddHandler);
00059 }
00060 
00061 void LocalVobject::initReply(Vobject* v, Message* reply, Message* m, const string& method)
00062 {
00063     reply->setType("update");
00064     reply->setMethod(method);
00065     reply->setTo(m->getFrom());
00066     reply->setFrom(v->getURL().getString());
00067     reply->setNonce(m->getNonce());
00068 }
00069 
00070 void LocalVobject::sendMessage(MessageBlock* mb)
00071 {
00072     pREF(MessageContext*, mc, new MessageContext(),
00073          for(int i = 0; i < mb->numMessages(); i++) {
00074              pREF(Message*, msg, mb->getMessage(i),
00075                   msg->setMessageContext(mc);
00076                   sendMessage(msg);
00077                  );
00078          }
00079         );
00080 }
00081 
00082 void LocalVobject::findObjectHandler(Message* m)
00083 {
00084     vRef<Message> reply = new Message();
00085     initReply(this, &reply, m, "core:set-child-update");
00086     vRef<Site> mysite = getSite();
00087     bool thisIsSite = ((*mysite) == (*this));
00088     try {
00089         vRef<Vobject> from = Vobject::findObjectFromRoot(m->getFrom());
00090         const ChildList& childrenX = getChildren();
00091         for(int i=0; i < m->getNumFields(); i++) {
00092             const Message::Field& f=m->getField(i);
00093             LOG("localvobject", 5, "path is " << f.value);
00094             if(f.key == "path") {
00095                 if((i + 2) < m->getNumFields()
00096                    && m->getField(i+1).key == "to"
00097                    && m->getField(i+2).key == "path") {
00098                     try {
00099                         int pos1;
00100                         int pos2;
00101                         rREF(ParentChildRelation&, p, findChild(f.value), pos1 = p.position;);
00102                         rREF(ParentChildRelation&, p, findChild(m->getField(i+2).value), pos2 = p.position;);
00103                         if(pos1 > pos2) {
00104                             int tmp=pos2;
00105                             pos2=pos1;
00106                             pos1=tmp;
00107                         }
00108                         for(int n=pos1; n <= pos2; n++) {
00109                             vRef<VobjectEvent> event = new VobjectEvent(VobjectEvent::ReadChild, *from, *this, n,
00110                                                                         childrenX[n]->contextual_name,
00111                                                                         *(childrenX[n]->child));
00112                             string errmessage;
00113                             if(validateAccess(*event, errmessage)) {
00114                                 reply->insertField(-1, "pos", n);
00115                                 reply->insertField(-1, "name", childrenX[n]->contextual_name);
00116                                 reply->insertField(-1, "path", childrenX[n]->child->getURL().getString());
00117                                 if(thisIsSite) {
00118                                     const TypeSet& ts = childrenX[n]->child->getTypes();
00119                                     if(ts.size()) {
00120                                         for(TypeSet::const_iterator ti = ts.begin(); ti != ts.end(); ti++) {
00121                                             reply->insertField(-1, "type", *ti);
00122                                         }
00123                                     } else {
00124                                         reply->insertField(-1, "type", "");
00125                                     }
00126                                 }
00127                             } else {
00128                                 reply->insertField(-1, "error", "Permission denied: " + errmessage);
00129                             }
00130                         }
00131                         i+=2;
00132                     } catch(NoSuchObjectError) {
00133                         reply->insertField(-1, "error", f.value);
00134                     }
00135                 } else if(f.value.find("/") != string::npos) {
00136                 } else {
00137                     try {
00138                         vRef<ParentChildRelation> c = findChild(f.value);
00139 
00140                         vRef<VobjectEvent> event = new VobjectEvent(VobjectEvent::ReadChild, *from, *this,
00141                                                                     c->position, c->contextual_name, *(c->child));
00142 
00143                         string errmessage;
00144                         if(validateAccess(*event, errmessage)) {
00145                             reply->insertField(-1, "pos", c->position);
00146                             reply->insertField(-1, "name", c->contextual_name);
00147                             reply->insertField(-1, "path", c->child->getURL().getString());
00148                             if(thisIsSite) {
00149                                 const TypeSet& ts = c->child->getTypes();
00150                                 if(ts.size()) {
00151                                     for(TypeSet::const_iterator ti = ts.begin(); ti != ts.end(); ti++) {
00152                                         reply->insertField(-1, "type", *ti);
00153                                     }
00154                                 } else {
00155                                     reply->insertField(-1, "type", "");
00156                                 }
00157                             }
00158                         } else {
00159                             reply->insertField(-1, "error", "Permission denied: " + errmessage);
00160                         }
00161                     } catch(NoSuchObjectError) {
00162                         reply->insertField(-1, "error", f.value);
00163                     }
00164                 }
00165             }
00166         }
00167         from->sendMessage(&reply);
00168     } catch(Message::NoSuchFieldError) {
00169     }
00170 }
00171 
00172 void LocalVobject::getTypesHandler(Message* m)
00173 {
00174     try {
00175         vRef<Message> reply = new Message();
00176         initReply(this, &reply, m, "core:type-add-update");
00177 
00178         for(set<string>::iterator i=types.begin(); i != types.end(); i++) {
00179             reply->insertField(-1, "type", *i);
00180         }
00181 
00182         vRef<Vobject> from = Vobject::findObjectFromRoot(m->getFrom());
00183         from->sendMessage(&reply);
00184     } catch(NoSuchObjectError) {
00185     }
00186 }
00187 
00188 void LocalVobject::getParentsHandler(Message* m)
00189 {
00190     try {
00191         vRef<Message> reply = new Message();
00192         initReply(this, &reply, m, "core:insert-parent-update");
00193 
00194         for(ParentSet::iterator i=parents.begin(); i != parents.end(); i++) {
00195             char pos[16];
00196             snprintf(pos, sizeof(pos), "%i", (*i)->position);
00197             reply->insertField(-1, "pos", string(pos));
00198             reply->insertField(-1, "name", (*i)->contextual_name);
00199             reply->insertField(-1, "path", (*i)->parent->getURL().getString());
00200         }
00201 
00202         vRef<Vobject> from = Vobject::findObjectFromRoot(m->getFrom());
00203         from->sendMessage(&reply);
00204     } catch(NoSuchObjectError) {
00205     }
00206 }
00207 
00208 void LocalVobject::addChildHandler(Message* m)
00209 {
00210     vRef<Message> reply = new Message();
00211     try {
00212         vRef<Vobject> from = Vobject::findObjectFromRoot(m->getFrom());
00213         initReply(this, &reply, m, m->getMethod() + "-update");
00214         LOG("localvobject", 5, "setting up reply (0)");
00215         vRef<Site> st = m->getSourceSite();
00216         RemoteSite* fromsite = dynamic_cast<RemoteSite*>(&st);
00217         bool isListener = (childListeners.count(fromsite) != 0);
00218         if(isListener) childListeners.erase(fromsite);
00219 
00220         LOG("localvobject", 5, "set/insert-child creating reply " << m->getNumFields());
00221 
00222         for(int i=0; i < m->getNumFields(); i++) {
00223             if((i + 2) < m->getNumFields()) {
00224                 const Message::Field& pos = m->getField(i);
00225                 const Message::Field& name = m->getField(++i);
00226                 const Message::Field& path = m->getField(++i);
00227                 if(pos.key == "pos"
00228                    && name.key == "name"
00229                    && path.key == "path") {
00230                     int ipos=atoi(pos.value.c_str());
00231                     if(ipos < 0) ipos = ipos + (int)children.size() + 1;
00232                     ipos = ipos % ((int)children.size() + 1);
00233 
00234                     vRef<Vobject> newobj = findObject(path.value);
00235                     if(m->getMethod() == "core:set-child") {
00236 
00237                         if(children.size() == 0) {
00238                             reply->insertField(-1, "error", "permission to set " + path.value + " denied");
00239                             continue;
00240                         }
00241 
00242                         vRef<VobjectEvent> event = new VobjectEvent(VobjectEvent::ChildReplace, *from, *this, ipos,
00243                                                                     name.value, *newobj, *(children[ipos]->child));
00244 
00245                         string errmessage;
00246                         if(validateAccess(*event, errmessage)) {
00247                             try {
00248                                 VobjectImplementation::setChild(&from, ipos, name.value, &newobj);
00249                             } catch(...) {
00250                                 reply->insertField(-1, "error", "permission to set " + path.value + " denied");
00251                                 continue;
00252                             }
00253                         } else {
00254                             reply->insertField(-1, "error", "Permission to set '" + path.value + "' denied: " + errmessage);
00255                             continue;
00256                         }
00257                     } else {
00258                         vRef<VobjectEvent> event = new VobjectEvent(VobjectEvent::ChildInsert, *from,
00259                                                                     *this, ipos, name.value, *newobj);
00260                         string errmessage;
00261                         if(validateAccess(*event, errmessage)) {
00262                             try {
00263                                 VobjectImplementation::insertChild(&from, ipos, name.value, &newobj);
00264                             } catch(...) {
00265                                 reply->insertField(-1, "error", "permission to set " + path.value + " denied");
00266                                 continue;
00267                             }
00268                         } else {
00269                             reply->insertField(-1, "error", "Permission to add '" + path.value + "' denied: " + errmessage);
00270                             continue;
00271                         }
00272                     }
00273                     vRef<ParentChildRelation> r = findChild("#" + pos.value);
00274                     char x[16];
00275                     snprintf(x, sizeof(x), "%i", r->position);
00276                     reply->insertField(-1, "pos", string(x));
00277                     reply->insertField(-1, "name", r->contextual_name);
00278                     reply->insertField(-1, "path", r->child->getURL().getString());
00279                 }
00280             }
00281         }
00282 
00283         if(isListener) childListeners.insert(fromsite);
00284         LOG("localvobject", 5, "about to send reply");
00285         from->sendMessage(&reply);
00286         LOG("localvobject", 5, "sent reply");
00287     } catch(NoSuchObjectError) {
00288     }
00289 }
00290 
00291 void LocalVobject::removeChildHandler(Message* m)
00292 {
00293     vRef<Message> reply = new Message();
00294     try {
00295         vRef<Vobject> from = Vobject::findObjectFromRoot(m->getFrom());
00296         initReply(this, &reply, m, "core:remove-child-update");
00297         vRef<Site> st = m->getSourceSite();
00298         RemoteSite* fromsite = dynamic_cast<RemoteSite*>(&st);
00299         bool isListener = (childListeners.count(fromsite) != 0);
00300         if(isListener) childListeners.erase(fromsite);
00301 
00302         for(int i=0; i < m->getNumFields(); i++) {
00303             const Message::Field& pos=m->getField(i);
00304             if(pos.key != "pos") break;
00305             const Message::Field& name=m->getField(++i);
00306             if(name.key != "name") break;
00307             const Message::Field& path=m->getField(++i);
00308             if(path.key != "path") break;
00309 
00310             try {
00311                 int ipos=atoi(pos.value.c_str());
00312                 vRef<Vobject> pathobj = findObjectFromRoot(path.value);
00313 
00314                 const string& ctxname = children[ipos]->contextual_name;
00315                 Vobject* target = children[ipos]->child;
00316 
00317                 vRef<VobjectEvent> event = new VobjectEvent(VobjectEvent::ChildRemove, *from,
00318                                                             *this, ipos, ctxname, *target);
00319 
00320                 string errmessage;
00321                 if(ctxname == name.value
00322                    && *target == *pathobj
00323                    && validateAccess(*event, errmessage))
00324                 {
00325                     VobjectImplementation::removeChild(&from, ipos);
00326                     reply->insertField(-1, "pos", pos.value);
00327                     reply->insertField(-1, "name", name.value);
00328                     reply->insertField(-1, "path", path.value);
00329                 } else {
00330                     reply->insertField(-1, "error", "Permission to remove " + pos.value + " denied: " + errmessage);
00331                 }
00332             } catch(NoSuchObjectError) {
00333                 reply->insertField(-1, "error", "No such object path " + path.value);
00334             }
00335         }
00336         from->sendMessage(&reply);
00337         if(isListener) childListeners.insert(fromsite);
00338     } catch(NoSuchObjectError) {
00339     } catch(Message::NoSuchFieldError) {
00340     }
00341 }
00342 
00343 void LocalVobject::startListeningHandler(Message* m)
00344 {
00345     try {
00346         vRef<Vobject> from = Vobject::findObjectFromRoot(m->getFrom());
00347         vRef<Site> st = m->getSourceSite();
00348         RemoteSite* rs = dynamic_cast<RemoteSite*>(&st);
00349 
00350         if(rs) {
00351             for(int i = 0; i < m->getNumFields(); i++) {
00352                 const Message::Field& f = m->getField(i);
00353                 if(f.key == "listen") {
00354                     if(f.value == "types" || f.value == "children" || f.value == "parents"){
00355                         vRef<Message> reply = new Message();
00356                         initReply(this, &reply, m, "core:start-listening-reply");
00357                         reply->setNonce(m->getNonce() + string("-1"));
00358                         reply->insertField(-1, "listen", f.value);
00359                         from->sendMessage(&reply);
00360                     }
00361 
00362                     if(f.value == "types") {
00363                         vRef<VobjectEvent> event = new VobjectEvent(VobjectEvent::ReadType, *from, *this);
00364                         string errmessage;
00365                         if(validateAccess(*event, errmessage)) {
00366                             rs->lockTypeNotifyOutgoing(this);
00367                             addTypeListener(rs);
00368                             rs->unlockTypeNotifyOutgoing(this, m->getNonce());
00369                         }
00370                     } else if(f.value == "children") {
00371                         vRef<VobjectEvent> event = new VobjectEvent(VobjectEvent::ChildrenListen, *from, *this);
00372                         string errmessage;
00373                         if(validateAccess(*event, errmessage)) {
00374                             rs->lockChildNotifyOutgoing(this);
00375                             addChildListener(rs);
00376                             rs->unlockChildNotifyOutgoing(this, m->getNonce());
00377                         }
00378                     } else if(f.value == "parents") {
00379                         vRef<VobjectEvent> event = new VobjectEvent(VobjectEvent::ParentListen, *from, *this);
00380 
00381                         string errmessage;
00382                         if(validateAccess(*event, errmessage)) {
00383                             rs->lockParentNotifyOutgoing(this);
00384                             addParentListener(rs);
00385                             rs->unlockParentNotifyOutgoing(this, m->getNonce());
00386                         }
00387                     }
00388                 }
00389             }
00390         }
00391     } catch(Message::NoSuchFieldError) { }
00392 }
00393 
00394 void LocalVobject::stopListeningHandler(Message* m)
00395 {
00396     try {
00397         for(int i=0; i < m->getNumFields(); i++) {
00398             const Message::Field& f = m->getField(i);
00399             if(f.key == "listen") {
00400                 vRef<Site> st = m->getSourceSite();
00401                 RemoteSite* rs = dynamic_cast<RemoteSite*>(&st);
00402                 if(rs) {
00403                     if(f.value == "types") {
00404                         removeTypeListener(rs);
00405                     } else if(f.value == "children") {
00406                         removeChildListener(rs);
00407                     } else if(f.value == "parents") {
00408                         removeParentListener(rs);
00409                     }
00410                 }
00411             }
00412         }
00413     } catch(Message::NoSuchFieldError) { }
00414 }
00415 
00416 void LocalVobject::typeAddHandler(Message* m)
00417 {
00418     try {
00419         vRef<Vobject> from = Vobject::findObjectFromRoot(m->getFrom());
00420         for(int i=0; i < m->getNumFields(); i++) {
00421             const Message::Field& f = m->getField(i);
00422             if(f.key == "type") {
00423                 vRef<VobjectEvent> event = new VobjectEvent(VobjectEvent::TypeInsert, *from, *this, f.value);
00424 
00425                 string errmessage;
00426                 if(validateAccess(*event, errmessage)) {
00427                     VobjectImplementation::addType(&from, f.value);
00428 
00429                     vRef<Message> reply = new Message();
00430                     initReply(this, &reply, m, "core:type-add-update");
00431 
00432                     reply->insertField(-1, "type", f.value);
00433 
00434                     vRef<Vobject> from = Vobject::findObjectFromRoot(m->getFrom());
00435                     from->sendMessage(&reply);
00436                 }
00437             }
00438         }
00439     } catch(Message::NoSuchFieldError) { }
00440 }
00441 
00442 
00443 void LocalVobject::sendMessage(Message* m)
00444 {
00445     LOG("LocalVobject::sendMessage", 5, "<<<(incoming)<<< sending to " << getURL().getString() << " ["
00446         << m->refcount_debug << "/" << m->getCount() << "]\n" << m->getFormattedString());
00447 
00448     LOG("localvobject", 5, "getting from (1) " << queueMsgs);
00449 
00450     // are we waiting for this nonce?
00451     /*if(waitForNonces.count(m->getNonce())) {
00452         m->acquire(); // released by: whoever calls LocalVobject::waitFor()
00453         waitForNonces[m->getNonce()]=m;
00454         }*/
00455     if(queueMsgs) {
00456         m->acquire(); // released by: whoever calls VobjectImplementation::receiveMessage()
00457         incomingMessageQueue.push_back(m);
00458     }
00459 
00460     if(m->getType() != "message") return;
00461 
00462     vRef<Vobject> to = findObjectFromRoot(m->getTo());
00463     if(&to != this) return;
00464 
00465     pair<HandlerMap::iterator, HandlerMap::iterator> hndls = msghandlers.equal_range(m->getMethod());
00466     for(HandlerMap::iterator i = hndls.first; i !=  hndls.second; i++) {
00467         (*i).second->sendMessage(m);
00468     }
00469 }
00470 
00471 Message* LocalVobject::waitFor(const string& nonce, RemoteSite* from, double timeout)
00472 {
00473     bool prioritize=true;
00474 
00475     if(! from->isConnected()) {
00476         throw TimeoutError("remote site is not connected");
00477     }
00478 
00479     from->catchIncomingMessage(nonce);
00480 
00481     double now = getTimer();
00482     double timeoutAt = now + timeout;
00483     vRef<LocalSite> ls = dynamic_cast<LocalSite&>(getSite());
00484     double dmaxwait = ls->getTimeoutOnSelect();
00485 
00486     if(prioritize) ls->addPrioritizedNonce(nonce, from);
00487     try {
00488         while(true) {
00489             now = getTimer();
00490             if(now >= timeoutAt && !from->messageInProgress(nonce)) {
00491                 from->clearCaughtMessage(nonce);
00492                 ls->setTimeoutOnSelect(dmaxwait);
00493                 LOG("localvobject", 3, "Timed out waiting for " << nonce);
00494                 throw TimeoutError("waitFor timed out");
00495             }
00496             double waitLeft = timeoutAt - now;
00497             if(dmaxwait > 0.0) {
00498                 if(dmaxwait < waitLeft) {
00499                     ls->setTimeoutOnSelect(dmaxwait);
00500                 } else {
00501                     ls->setTimeoutOnSelect(waitLeft);
00502                 }
00503             } else {
00504                 ls->setTimeoutOnSelect(waitLeft);
00505             }
00506 
00507             try {
00508                 ls->flushIncomingBuffers();
00509                 if(from->messageReady(nonce)) {
00510                     if(Message* m = from->retrieveCaughtMessage(nonce)) {
00511                         vRef<Vobject> to = findObjectFromRoot(m->getTo());
00512                         if(&to == this) {
00513                             from->clearCaughtMessage(nonce);
00514                             ls->setTimeoutOnSelect(dmaxwait);
00515                             if(prioritize) ls->removePrioritizedNonce(nonce, from);
00516                             // pass reference through
00517                             return m;
00518                         }
00519                     }
00520                 }
00521             } catch(MessageQueueEmptyError) {}
00522             if(! from->isConnected()) {
00523                 ls->setTimeoutOnSelect(dmaxwait);
00524                 LOG("localvobject", 3, "Timed out waiting for " << nonce);
00525                 throw TimeoutError("remote site we were waiting on disconnected");
00526             }
00527         }
00528     } catch(...) {
00529         if(prioritize) ls->removePrioritizedNonce(nonce, from);
00530         throw;
00531     }
00532 }
00533 
00534 void LocalVobject::addType(const string& s)
00535 {
00536     VobjectImplementation::addType(this, s);
00537 }
00538 
00539 void LocalVobject::setChild(int position, const string& contextual_name, Vobject* child)
00540     throw (AccessControlError, RemoteError)
00541 {
00542     VobjectImplementation::setChild(this, position, contextual_name, child);
00543 }
00544 
00545 void LocalVobject::insertChild(int position, const string& contextual_name, Vobject* child)
00546     throw (AccessControlError, RemoteError)
00547 {
00548     VobjectImplementation::insertChild(this, position, contextual_name, child);
00549 }
00550 
00551 void LocalVobject::removeChild(int position)
00552     throw (AccessControlError, RemoteError)
00553 {
00554     VobjectImplementation::removeChild(this, position);
00555 }
00556 
00557 
00558 
00559 void LocalVobject::insertAccessControl(int pos, VobjectAccessControl* ac)
00560 {
00561     if(pos < 0) pos += (int)accesscontrols.size() + 1;
00562     accesscontrols.insert(accesscontrols.begin() + pos, ac);
00563 }
00564 
00565 void LocalVobject::insertAccessControl(int pos, const string& policyname)
00566 {
00567     if(pos < 0) pos += (int)accesscontrols.size() + 1;
00568 
00569     VobjectAccessControl* ac = VobjectAccessControl::getPolicy(policyname, this);
00570     if(ac) accesscontrols.insert(accesscontrols.begin() + pos, ac);
00571 }
00572 
00573 void LocalVobject::removeAccessControl(int pos)
00574 {
00575     if(pos < 0) pos += (int)accesscontrols.size() + 1;
00576     accesscontrols.erase(accesscontrols.begin() + pos);
00577 }
00578 
00579 void LocalVobject::removeAccessControl(VobjectAccessControl* ac)
00580 {
00581     for(unsigned int i = 0; i < accesscontrols.size(); i++) {
00582         if(accesscontrols[i] == ac) {
00583             accesscontrols.erase(accesscontrols.begin() + i);
00584             i--;
00585         }
00586     }
00587 }
00588 
00589 void LocalVobject::removeAccessControl(const string& policyname)
00590 {
00591     for(unsigned int i = 0; i < accesscontrols.size(); i++) {
00592         if(accesscontrols[i]->getPolicyName() == policyname) {
00593             accesscontrols.erase(accesscontrols.begin() + i);
00594             i--;
00595         }
00596     }
00597 }
00598 
00599 const deque<VobjectAccessControl*>& LocalVobject::getAccessControls()
00600 {
00601     return accesscontrols;
00602 }
00603 
00604 bool LocalVobject::validateAccess(VobjectEvent& e, string& message)
00605 {
00606     if(accesscontrols.size() == 0) {
00607         message = "Error in access policy list.  Permission denied by default.";
00608         LOG("localvobject", 1, "Access policy list for "
00609             << e.getAffectedObject()->getURL().getString() << " is empty!");
00610         return false;
00611     }
00612 
00613     for(unsigned int i = 0; i < accesscontrols.size(); i++) {
00614         if(! accesscontrols[i]) {
00615             message = "Error in access policy list.  Permission denied by default.";
00616             LOG("localvobject", 1, "Access policy list "
00617                 << e.getAffectedObject()->getURL().getString() << " contains an invalid (null) policy!");
00618             return false;
00619         }
00620         switch(e.getEvent()) {
00621         case VobjectEvent::TypeInsert:
00622             if(! accesscontrols[i]->checkAddTypePermission(e, message)) return false;
00623             break;
00624         case VobjectEvent::ChildInsert:
00625             if(! accesscontrols[i]->checkInsertChildPermission(e, message)) return false;
00626             break;
00627         case VobjectEvent::ChildReplace:
00628             if(! accesscontrols[i]->checkSetChildPermission(e, message)) return false;
00629             break;
00630         case VobjectEvent::ChildRemove:
00631             if(! accesscontrols[i]->checkRemoveChildPermission(e, message)) return false;
00632             break;
00633         case VobjectEvent::ReadChild:
00634             if(! accesscontrols[i]->checkReadChildPermission(e, message)) return false;
00635             break;
00636         case VobjectEvent::ReadParent:
00637             if(! accesscontrols[i]->checkReadParentPermission(e, message)) return false;
00638             break;
00639         case VobjectEvent::ReadType:
00640             if(! accesscontrols[i]->checkReadTypePermission(e, message)) return false;
00641             break;
00642         case VobjectEvent::ChildrenListen:
00643             if(! accesscontrols[i]->checkChildListenPermission(e, message)) return false;
00644             break;
00645         case VobjectEvent::ParentListen:
00646             if(! accesscontrols[i]->checkParentListenPermission(e, message)) return false;
00647             break;
00648         default:
00649             message = "Supplied validateAccess with an unsupported event type!";
00650             LOG("localvobject", 1, "Supplied validateAccess with an unsupported event type " << e.getEvent());
00651             return false;
00652         }
00653     }
00654     return true;
00655 }

Generated on Tue Aug 12 03:55:40 2003 for Interreality Project - VOS by doxygen 1.3.2