def update(self, trans):
        """
        Updates the item.
        
        @param trans: A valid transaction handle
        @return: None
        """
        old_item = _db.get_item(self._id, trans)
        parent = _db.get_item(self._parentid, trans)
        
        user = currentThread().context.user
        user_role = permsresolver.get_access(old_item, user)
        
        if user_role > permsresolver.READER:
            # set security
            if user_role == permsresolver.COORDINATOR:
                # user is COORDINATOR
                if (self.inheritRoles != old_item.inheritRoles) or \
                        (not self.inheritRoles and \
                         self.security != old_item.security):
                    self._applySecurity(parent, trans)
            else:
                # restore previous ACL
                self.security = old_item.security
                self.inheritRoles = old_item.inheritRoles

            _db.handle_update(self, old_item, trans)
            self.modifiedBy = user.displayName.value
            self.modified = time.time()
            parent.modified = self.modified
            _db.put_item(self, trans)
            _db.put_item(parent, trans)
        else:
            raise exceptions.PermissionDenied, \
                    'The user does not have update permissions.'
 def on_update(cls, item, new_attr, old_attr, trans):
     from porcupine.systemObjects import Composite
     # load objects
     dctObjects = {}
     for i, obj in enumerate(new_attr.value):
         if isinstance(obj, Composite):
             obj._containerid = item._id
         elif isinstance(obj, str):
             obj = _db.getItem(obj, trans)
             new_attr.value[i] = obj
         else:
             raise exceptions.ContainmentError, \
                 'Invalid object type "%s" in composition.' % \
                 obj.__class__.__name__
         dctObjects[obj._id] = obj
     
     # check containment
     compositeClass = misc.getCallableByName(new_attr.compositeClass)
     
     if [obj for obj in dctObjects.values()
             if not isinstance(obj, compositeClass)]:
         raise exceptions.ContainmentError, \
             'Invalid content class "%s" in composition.' % \
             obj.getContentclass()
     
     # get previous value
     if old_attr != None:
         old_ids = set(old_attr.value)
     else:
         old_ids = set()
     
     new_ids = set([obj._id for obj in new_attr.value])
     
     # calculate added composites
     lstAdded = list(new_ids - old_ids)
     for obj_id in lstAdded:
         _db.handle_update(dctObjects[obj_id], None, trans)
         dctObjects[obj_id]._isDeleted = False
         _db.putItem(dctObjects[obj_id], trans)
     
     # calculate constant composites
     lstConstant = list(new_ids & old_ids)
     for obj_id in lstConstant:
         _db.handle_update(dctObjects[obj_id],
                              _db.getItem(obj_id, trans),
                              trans)
         _db.putItem(dctObjects[obj_id], trans)
     
     # calculate removed composites
     lstRemoved = list(old_ids - new_ids)
     for obj_id in lstRemoved:
         composite4removal = _db.getItem(obj_id, trans)
         cls.removeComposite(composite4removal, trans)
     
     new_attr.value = list(new_ids)
    def appendTo(self, parent, trans):
        """
        Adds the item to the specified container.

        @param parent: The id of the destination container or the container
            itself
        @type parent: str OR L{Container}
        
        @param trans: A valid transaction handle
        
        @return: None
        """
        if type(parent) == str:
            oParent = _db.getItem(parent, trans)
        else:
            oParent = parent
        
        if isinstance(self, Shortcut):
            contentclass = self.target.getItem(trans).getContentclass()
        else:
            contentclass = self.contentclass
        
        oUser = currentThread().context.user
        iUserRole = objectAccess.getAccess(oParent, oUser)
        if iUserRole == objectAccess.READER:
            raise exceptions.PermissionDenied, \
                'The user does not have write permissions ' + \
                'on the parent folder.'
        if not(contentclass in oParent.containment):
            raise exceptions.ContainmentError, \
                'The target container does not accept ' + \
                'objects of type "%s".' % contentclass

        # set security to new item
        if iUserRole == objectAccess.COORDINATOR:
            # user is COORDINATOR
            self._applySecurity(oParent, trans)
        else:
            # user is not COORDINATOR
            self.inheritRoles = True
            self.security = oParent.security
            #if trans._retries == 0:
            #   raise exceptions.DBTransactionIncomplete    
        self._owner = oUser._id
        self._created = time.time()
        self.modifiedBy = oUser.displayName.value
        self.modified = time.time()
        self._parentid = oParent._id
        _db.handle_update(self, None, trans)
        _db.putItem(self, trans)
        # update container
        oParent._addItemReference(self)
        _db.putItem(oParent, trans)
 def recycle(self, rbID, trans):
     """
     Moves the item to the specified recycle bin.
     
     The item then becomes inaccesible.
     
     @param rbID: The id of the destination container, which must be
                  a L{RecycleBin} instance
     @type rbID: str
     
     @param trans: A valid transaction handle 
     
     @return: None
     """
     oUser = currentThread().context.session.user
     self = _db.getItem(self._id, trans)
     
     iUserRole = objectAccess.getAccess(self, oUser)
     bCanDelete = (iUserRole > objectAccess.AUTHOR) or \
         (iUserRole == objectAccess.AUTHOR and self._owner == oUser._id)
     
     if (not(self._isSystem) and bCanDelete):
         oDeleted = DeletedItem(self)
         
         oDeleted._owner = oUser._id
         oDeleted._created = time.time()
         oDeleted.modifiedBy = oUser.displayName.value
         oDeleted.modified = time.time()
         oDeleted._parentid = rbID
         _db.handle_update(oDeleted, None, trans)
         _db.putItem(oDeleted, trans)
         
         # delete item logically
         self._recycle(trans)
         
         # save container
         oParent = _db.getItem(self._parentid, trans)
         oParent._removeItemReference(self)
         _db.putItem(oParent, trans)
         
         #update recycle bin
         oRecycleBin = _db.getItem(rbID, trans)
         if not(oDeleted.getContentclass() in oRecycleBin.containment):
             raise exceptions.ContainmentError, \
                 'The target container does not accept ' + \
                 'objects of type "%s".' % oDeleted.getContentclass()
         oRecycleBin._addItemReference(oDeleted)
         _db.putItem(oRecycleBin, trans)
     else:
         raise exceptions.PermissionDenied, \
             'The object was not deleted.\n' + \
             'The user has insufficient permissions.'
 def recycle(self, rb_id, trans):
     """
     Moves the item to the specified recycle bin.
     The item then becomes inaccessible.
     
     @param rb_id: The id of the destination container, which must be
                   a L{RecycleBin} instance
     @type rb_id: str
     @param trans: A valid transaction handle
     @return: None
     """
     user = currentThread().context.user
     self = _db.get_item(self._id, trans)
     
     user_role = permsresolver.get_access(self, user)
     can_delete = (user_role > permsresolver.AUTHOR) or \
                  (user_role == permsresolver.AUTHOR and
                   self._owner == user._id)
     
     if (not(self._isSystem) and can_delete):
         deleted = DeletedItem(self, trans)
         deleted._owner = user._id
         deleted._created = time.time()
         deleted.modifiedBy = user.displayName.value
         deleted.modified = time.time()
         deleted._parentid = rb_id
         
         # check recycle bin's containment
         recycle_bin = _db.get_item(rb_id, trans)
         if not(deleted.get_contentclass() in recycle_bin.containment):
             raise exceptions.ContainmentError, \
                 'The target container does not accept ' + \
                 'objects of type\n"%s".' % deleted.get_contentclass()
         
         _db.handle_update(deleted, None, trans)
         _db.put_item(deleted, trans)
         
         # delete item logically
         self._recycle(trans)
         
         # update container
         parent = _db.get_item(self._parentid, trans)
         parent.modified = time.time()
         _db.put_item(parent, trans)
     else:
         raise exceptions.PermissionDenied, \
             'The object was not deleted.\n' + \
             'The user has insufficient permissions.'
    def _undelete(self, deletedItem, trans):
        """
        Undeletes a logically deleted item.
        
        Returns: None
        """
        _db.handle_update(deletedItem, None, trans)
        deletedItem._isDeleted = False
        
        if deletedItem.isCollection:
            lstChildren = deletedItem._items.values() + deletedItem._subfolders.values()
            for sID in lstChildren:
                oChild = _db.getDeletedItem(sID, trans)
                self._undelete(oChild, trans)

        _db.putItem(deletedItem, trans)
    def append_to(self, parent, trans):
        """
        Adds the item to the specified container.

        @param parent: The id of the destination container or the container
                       itself
        @type parent: str OR L{Container}
        @param trans: A valid transaction handle
        @return: None
        """
        if type(parent) == str:
            parent = _db.get_item(parent, trans)
        
        if isinstance(self, Shortcut):
            contentclass = self.get_target_contentclass(trans)
        else:
            contentclass = self.get_contentclass()
        
        user = currentThread().context.user
        user_role = permsresolver.get_access(parent, user)
        if user_role == permsresolver.READER:
            raise exceptions.PermissionDenied, \
                'The user does not have write permissions ' + \
                'on the parent folder.'
        if not(contentclass in parent.containment):
            raise exceptions.ContainmentError, \
                'The target container does not accept ' + \
                'objects of type\n"%s".' % contentclass

        # set security to new item
        if user_role == permsresolver.COORDINATOR:
            # user is COORDINATOR
            self._applySecurity(parent, trans)
        else:
            # user is not COORDINATOR
            self.inheritRoles = True
            self.security = parent.security
        
        self._owner = user._id
        self._created = time.time()
        self.modifiedBy = user.displayName.value
        self.modified = time.time()
        self._parentid = parent._id
        _db.handle_update(self, None, trans)
        parent.modified = self.modified
        _db.put_item(self, trans)
        _db.put_item(parent, trans)
    def _copy(self, target, trans, clear_inherited=False):
        clone = self.clone()
        if clear_inherited:
            clone.inheritRoles = False
        
        user = currentThread().context.user
        clone._owner = user._id
        clone._created = time.time()
        clone.modifiedBy = user.displayName.value
        clone.modified = time.time()
        clone._parentid = target._id
        
        _db.handle_update(clone, None, trans)
        _db.put_item(clone, trans)

        if self.isCollection:
            [child._copy(clone, trans) for child in self.get_children(trans)]
    def update(self, trans):
        """
        Updates the item.
        
        @param trans: A valid transaction handle
            
        @return: None
        """
        oOldItem = _db.getItem(self._id, trans)
        
        oUser = currentThread().context.session.user
        iUserRole = objectAccess.getAccess(oOldItem, oUser)
        
        if iUserRole > objectAccess.READER:
            # set security
            if iUserRole == objectAccess.COORDINATOR:
                # user is COORDINATOR
                if (self.inheritRoles != oOldItem.inheritRoles) or \
                (not self.inheritRoles and self.security != oOldItem.security):
                    oParent = _db.getItem(self._parentid, trans)
                    self._applySecurity(oParent, trans)
            else:
                # restore previous ACL
                self.security = oOldItem.security
                self.inheritRoles = oOldItem.inheritRoles

            _db.handle_update(self, oOldItem, trans)
            self.modifiedBy = oUser.displayName.value
            self.modified = time.time()
            _db.putItem(self, trans)
            
            if self.displayName.value != oOldItem.displayName.value:
                oParent = _db.getItem(self._parentid, trans)
                oParent._removeItemReference(oOldItem)
                oParent._addItemReference(self)
                _db.putItem(oParent, trans)
        else:
            raise exceptions.PermissionDenied, \
                    'The user does not have update permissions.'
    def _copy(self, target, trans, clearRolesInherited=False):
        oCopy = self.clone()
        if clearRolesInherited:
            oCopy.inheritRoles = False

        oUser = currentThread().context.session.user
        oCopy._owner = oUser._id
        oCopy._created = time.time()
        oCopy.modifiedBy = oUser.displayName.value
        oCopy.modified = time.time()
        oCopy._parentid = target._id
        
        _db.handle_update(oCopy, None, trans)
        _db.putItem(oCopy, trans)

        if self.isCollection:
            lstChildrentIds = self._items.values() + self._subfolders.values()
            for sId in lstChildrentIds:
                child = _db.getItem(sId, trans)
                if child and objectAccess.getAccess(child, oUser):
                    child._copy(oCopy, trans)

        target._addItemReference(oCopy)
        _db.putItem(target, trans)