コード例 #1
0
    def DELETE(self, REQUEST, RESPONSE):
        """Delete a collection resource. For collection resources, DELETE
        may return either 200 (OK) or 204 (No Content) to indicate total
        success, or may return 207 (Multistatus) to indicate partial
        success. Note that in Zope a DELETE currently never returns 207."""

        from webdav.davcmds import DeleteCollection

        self.dav__init(REQUEST, RESPONSE)
        ifhdr = REQUEST.get_header('If', '')
        url = urlfix(REQUEST['URL'], 'DELETE')
        name = unquote(filter(None, url.split( '/'))[-1])
        parent = self.aq_parent
        sm = getSecurityManager()
        token = None

#        if re.match("/Control_Panel",REQUEST['PATH_INFO']):
#            RESPONSE.setStatus(403)
#            RESPONSE.setHeader('Content-Type', 'text/xml; charset="utf-8"')
#            return RESPONSE

        # Level 1 of lock checking (is the collection or its parent locked?)
        if wl_isLocked(self):
            if ifhdr:
                self.dav__simpleifhandler(REQUEST, RESPONSE, 'DELETE', col=1)
            else:
                raise Locked
        elif wl_isLocked(parent):
            if ifhdr:
                parent.dav__simpleifhandler(REQUEST, RESPONSE, 'DELETE', col=1)
            else:
                raise PreconditionFailed
        # Second level of lock\conflict checking (are any descendants locked,
        # or is the user not permitted to delete?).  This results in a
        # multistatus response
        if ifhdr:
            tokens = self.wl_lockTokens()
            for tok in tokens:
                # We already know that the simple if handler succeeded,
                # we just want to get the right token out of the header now
                if ifhdr.find(tok) > -1:
                    token = tok
        cmd = DeleteCollection()
        result = cmd.apply(self, token, sm, REQUEST['URL'])

        if result:
            # There were conflicts, so we need to report them
            RESPONSE.setStatus(207)
            RESPONSE.setHeader('Content-Type', 'text/xml; charset="utf-8"')
            RESPONSE.setBody(result)
        else:
            # There were no conflicts, so we can go ahead and delete
            # ajung: additional check if we really could delete the collection
            # (Collector #2196)
            if parent.manage_delObjects([name],REQUEST=None)  is None:
                RESPONSE.setStatus(204)
            else:
                RESPONSE.setStatus(403)

        return RESPONSE
コード例 #2
0
 def test_wl_isLocked(self):
     from webdav.Lockable import wl_isLocked
     unlockable = UnlockableResource()
     self.assertFalse(wl_isLocked(unlockable))
     lockable_unlocked = LockableResource(locked=False)
     self.assertFalse(wl_isLocked(lockable_unlocked))
     lockable_locked = LockableResource(locked=True)
     self.assertTrue(wl_isLocked(lockable_locked))
コード例 #3
0
 def test_wl_isLocked(self):
     from webdav.Lockable import wl_isLocked
     unlockable = UnlockableResource()
     self.assertFalse(wl_isLocked(unlockable))
     lockable_unlocked = LockableResource(locked=False)
     self.assertFalse(wl_isLocked(lockable_unlocked))
     lockable_locked = LockableResource(locked=True)
     self.assertTrue(wl_isLocked(lockable_locked))
コード例 #4
0
ファイル: consolehelpers.py プロジェクト: isotoma/zkaffold
def __findapply(obj, result=None, path=''):   
    # recursive function to actually dig through and find the locked
    # objects.

    if result is None:
        result = []
    base = aq_base(obj)
    if not hasattr(base, 'objectItems'):
        return result
    try: items = obj.objectItems()
    except: return result

    addresult = result.append
    for id, ob in items:
        if path: p = '%s/%s' % (path, id)
        else: p = id

        dflag = hasattr(ob, '_p_changed') and (ob._p_changed == None)
        bs = aq_base(ob)
        if wl_isLocked(ob):
            li = []
            addlockinfo = li.append
            for token, lock in ob.wl_lockItems():
                addlockinfo({'owner':lock.getCreatorPath(),
                             'token':token})
            addresult((ob, p, li))
            dflag = 0
        if hasattr(bs, 'objectItems'):
            __findapply(ob, result, p)
        if dflag: ob._p_deactivate()

    return result

################################################################################
コード例 #5
0
    def DELETE(self, REQUEST, RESPONSE):
        """Delete a resource. For non-collection resources, DELETE may
        return either 200 or 204 (No Content) to indicate success."""
        self.dav__init(REQUEST, RESPONSE)
        ifhdr = REQUEST.get_header('If', '')
        url = urlfix(REQUEST['URL'], 'DELETE')
        name = unquote(filter(None, url.split('/')[-1]))
        parent = aq_parent(aq_inner(self))
        # Lock checking
        if wl_isLocked(self):
            if ifhdr:
                self.dav__simpleifhandler(REQUEST, RESPONSE, 'DELETE')
            else:
                # We're locked, and no if header was passed in, so
                # the client doesn't own a lock.
                raise Locked, 'Resource is locked.'
        elif IWriteLock.providedBy(parent) and parent.wl_isLocked():
            if ifhdr:
                parent.dav__simpleifhandler(REQUEST, RESPONSE, 'DELETE', col=1)
            else:
                # Our parent is locked, and no If header was passed in.
                # When a parent is locked, members cannot be removed
                raise PreconditionFailed, 'Resource is locked, and no '\
                      'condition was passed in.'
        # Either we're not locked, or a succesful lock token was submitted
        # so we can delete the lock now.
        # ajung: Fix for Collector # 2196

        if parent.manage_delObjects([name], REQUEST=None) is None:
            RESPONSE.setStatus(204)
        else:

            RESPONSE.setStatus(403)

        return RESPONSE
コード例 #6
0
ファイル: Resource.py プロジェクト: nacho22martin/tesis
    def DELETE(self, REQUEST, RESPONSE):
        """Delete a resource. For non-collection resources, DELETE may
        return either 200 or 204 (No Content) to indicate success."""
        self.dav__init(REQUEST, RESPONSE)
        ifhdr = REQUEST.get_header('If', '')
        url = urlfix(REQUEST['URL'], 'DELETE')
        name = unquote(filter(None, url.split( '/')[-1]))
        parent = aq_parent(aq_inner(self))
        # Lock checking
        if wl_isLocked(self):
            if ifhdr:
                self.dav__simpleifhandler(REQUEST, RESPONSE, 'DELETE')
            else:
                # We're locked, and no if header was passed in, so
                # the client doesn't own a lock.
                raise Locked, 'Resource is locked.'
        elif IWriteLock.providedBy(parent) and parent.wl_isLocked():
            if ifhdr:
                parent.dav__simpleifhandler(REQUEST, RESPONSE, 'DELETE', col=1)
            else:
                # Our parent is locked, and no If header was passed in.
                # When a parent is locked, members cannot be removed
                raise PreconditionFailed, 'Resource is locked, and no '\
                      'condition was passed in.'
        # Either we're not locked, or a succesful lock token was submitted
        # so we can delete the lock now.
        # ajung: Fix for Collector # 2196

        if parent.manage_delObjects([name],REQUEST=None)  is None:
            RESPONSE.setStatus(204)
        else:

            RESPONSE.setStatus(403)

        return RESPONSE
コード例 #7
0
ファイル: design.py プロジェクト: sudhan77/Plomino
    def importElementFromJSON(self, container, id, element):
        """
        """
        element_type = element['type']
        if id in container.objectIds():
            ob = getattr(container, id)
            if wl_isLocked(ob):
                ob.wl_clearLocks()
            container.manage_delObjects([id])
        params = element['params']
        container.invokeFactory(element_type, id=id, **params)
        obj = getattr(container, id)
        obj.title = element['title']
        if element_type == 'PlominoForm':
            obj.form_layout = RichTextValue(params.get('form_layout', ''),
                                            'text/plain', 'text/html')
        obj.reindexObject()

        if element_type == "PlominoField":
            # some params comes from the type-specific schema
            # they must be re-set
            for param in params:
                setattr(obj, param, params[param])
        if 'elements' in element:
            for (child_id, child) in element['elements'].items():
                self.importElementFromJSON(obj, child_id, child)
コード例 #8
0
ファイル: design.py プロジェクト: plomino/Plomino
    def importElementFromJSON(self, container, id, element):
        """
        """
        element_type = element['type']
        if id in container.objectIds():
            ob = getattr(container, id)
            if wl_isLocked(ob):
                ob.wl_clearLocks()
            container.manage_delObjects([id])
        params = element['params']
        container.invokeFactory(element_type, id=id, **params)
        obj = getattr(container, id)
        obj.title = element['title']
        if element_type == 'PlominoForm':
            obj.form_layout = RichTextValue(
                params.get('form_layout', ''), 'text/plain', 'text/html')
        obj.reindexObject()

        if element_type == "PlominoField":
            # some params comes from the type-specific schema
            # they must be re-set
            for param in params:
                setattr(obj, param, params[param])
        if 'elements' in element:
            for (child_id, child) in element['elements'].items():
                self.importElementFromJSON(obj, child_id, child)
コード例 #9
0
ファイル: Resource.py プロジェクト: nacho22martin/tesis
    def LOCK(self, REQUEST, RESPONSE):
        """Lock a resource"""
        from webdav.davcmds import Lock
        self.dav__init(REQUEST, RESPONSE)
        security = getSecurityManager()
        creator = security.getUser()
        body = REQUEST.get('BODY', '')
        ifhdr = REQUEST.get_header('If', None)
        depth = REQUEST.get_header('Depth', 'infinity')
        alreadylocked = wl_isLocked(self)

        if body and alreadylocked:
            # This is a full LOCK request, and the Resource is
            # already locked, so we need to raise the alreadylocked
            # exception.
            RESPONSE.setStatus(423)
        elif body:
            # This is a normal lock request with an XML payload
            cmd = Lock(REQUEST)
            token, result = cmd.apply(self, creator, depth=depth)
            if result:
                # Return the multistatus result (there were multiple
                # errors.  Note that davcmds.Lock.apply aborted the
                # transaction already.
                RESPONSE.setStatus(207)
                RESPONSE.setHeader('Content-Type', 'text/xml; charset="utf-8"')
                RESPONSE.setBody(result)
            else:
                # Success
                lock = self.wl_getLock(token)
                RESPONSE.setStatus(200)
                RESPONSE.setHeader('Content-Type', 'text/xml; charset="utf-8"')
                RESPONSE.setHeader('Lock-Token', 'opaquelocktoken:' + token)
                RESPONSE.setBody(lock.asXML())
        else:
            # There's no body, so this likely to be a refresh request
            if not ifhdr:
                raise PreconditionFailed, 'If Header Missing'
            taglist = IfParser(ifhdr)
            found = 0
            for tag in taglist:
                for listitem in tag.list:
                    token = tokenFinder(listitem)
                    if token and self.wl_hasLock(token):
                        lock = self.wl_getLock(token)
                        timeout = REQUEST.get_header('Timeout', 'Infinite')
                        lock.setTimeout(timeout) # automatically refreshes
                        found = 1

                        RESPONSE.setStatus(200)
                        RESPONSE.setHeader('Content-Type',
                                           'text/xml; charset="utf-8"')
                        RESPONSE.setBody(lock.asXML())
                        break
                if found: break
            if not found:
                RESPONSE.setStatus(412) # Precondition failed

        return RESPONSE
コード例 #10
0
    def LOCK(self, REQUEST, RESPONSE):
        """Lock a resource"""
        from webdav.davcmds import Lock
        self.dav__init(REQUEST, RESPONSE)
        security = getSecurityManager()
        creator = security.getUser()
        body = REQUEST.get('BODY', '')
        ifhdr = REQUEST.get_header('If', None)
        depth = REQUEST.get_header('Depth', 'infinity')
        alreadylocked = wl_isLocked(self)

        if body and alreadylocked:
            # This is a full LOCK request, and the Resource is
            # already locked, so we need to raise the alreadylocked
            # exception.
            RESPONSE.setStatus(423)
        elif body:
            # This is a normal lock request with an XML payload
            cmd = Lock(REQUEST)
            token, result = cmd.apply(self, creator, depth=depth)
            if result:
                # Return the multistatus result (there were multiple
                # errors.  Note that davcmds.Lock.apply aborted the
                # transaction already.
                RESPONSE.setStatus(207)
                RESPONSE.setHeader('Content-Type', 'text/xml; charset="utf-8"')
                RESPONSE.setBody(result)
            else:
                # Success
                lock = self.wl_getLock(token)
                RESPONSE.setStatus(200)
                RESPONSE.setHeader('Content-Type', 'text/xml; charset="utf-8"')
                RESPONSE.setHeader('Lock-Token', 'opaquelocktoken:' + token)
                RESPONSE.setBody(lock.asXML())
        else:
            # There's no body, so this likely to be a refresh request
            if not ifhdr:
                raise PreconditionFailed, 'If Header Missing'
            taglist = IfParser(ifhdr)
            found = 0
            for tag in taglist:
                for listitem in tag.list:
                    token = tokenFinder(listitem)
                    if token and self.wl_hasLock(token):
                        lock = self.wl_getLock(token)
                        timeout = REQUEST.get_header('Timeout', 'Infinite')
                        lock.setTimeout(timeout)  # automatically refreshes
                        found = 1

                        RESPONSE.setStatus(200)
                        RESPONSE.setHeader('Content-Type',
                                           'text/xml; charset="utf-8"')
                        RESPONSE.setBody(lock.asXML())
                        break
                if found: break
            if not found:
                RESPONSE.setStatus(412)  # Precondition failed

        return RESPONSE
コード例 #11
0
    def storybrain2dict(self, brain, locked_status=False):
        """Get a dict with info from this story brain.
        """
        context = aq_inner(self.context)
        review_state_id = brain.review_state

        # compute progress percentage
        is_completed = (review_state_id == 'completed')
        if is_completed:
            progress = 100
        else:
            estimated = brain.estimate
            actual = brain.actual_time
            progress = self.get_progress_perc(actual, estimated)

        # Extract locked status if requested
        locked = False
        if locked_status:
            locked = wl_isLocked(brain.getObject())

        # compute open task count
        searchpath = brain.getPath()
        filter = dict(portal_type=['Task', 'PoiTask'], path=searchpath)
        unfinished_states = (
            'open',
            'to-do',
        )
        filter['review_state'] = unfinished_states
        open_tasks = len(self.catalog.searchResults(**filter))

        # compute completed task count
        finished_states = ('completed', )
        filter['review_state'] = finished_states
        completed_tasks = len(self.catalog.searchResults(**filter))

        estimate = brain.estimate
        actual = brain.actual_time
        returnvalue = dict(
            story_id=brain.getId,
            uid=brain.UID,
            url=brain.getURL(),
            title=brain.Title,
            description=brain.Description,
            raw_estimate=estimate,
            estimate=formatTime(estimate),
            size_estimate=brain.size_estimate,
            actual=formatTime(actual),
            difference=formatTime(estimate - actual),
            progress=progress,
            review_state=review_state_id,
            review_state_title=self.workflow.getTitleForStateOnType(
                review_state_id, 'Story'),
            is_completed=is_completed,
            open_tasks=open_tasks,
            completed_tasks=completed_tasks,
            locked=locked,
        )
        return returnvalue
コード例 #12
0
 def storybrain2dict(self, brain):
     obj = brain.getObject()
     info = dict(title=brain.Title,
                 uid=brain.UID,
                 url=brain.getURL(),
                 estimate=brain.size_estimate,
                 locked=wl_isLocked(obj),
                 review_state=brain.review_state)
     return info
コード例 #13
0
 def storybrain2dict(self, brain):
     obj = brain.getObject()
     info = dict(title=brain.Title,
                 uid=brain.UID,
                 url=brain.getURL(),
                 estimate=brain.size_estimate,
                 locked=wl_isLocked(obj),
                 review_state=brain.review_state)
     return info
コード例 #14
0
    def storybrain2dict(self, brain, locked_status=False):
        """Get a dict with info from this story brain.
        """
        context = aq_inner(self.context)
        review_state_id = brain.review_state

        # compute progress percentage
        is_completed = (review_state_id == 'completed')
        if is_completed:
            progress = 100
        else:
            estimated = brain.estimate
            actual = brain.actual_time
            progress = self.get_progress_perc(actual, estimated)

        # Extract locked status if requested
        locked = False
        if locked_status:
            locked = wl_isLocked(brain.getObject())

        # compute open task count
        searchpath = brain.getPath()
        filter = dict(portal_type=['Task', 'PoiTask'],
                      path=searchpath)
        unfinished_states = ('open', 'to-do', )
        filter['review_state'] = unfinished_states
        open_tasks = len(self.catalog.searchResults(**filter))

        # compute completed task count
        finished_states = ('completed', )
        filter['review_state'] = finished_states
        completed_tasks = len(self.catalog.searchResults(**filter))

        estimate = brain.estimate
        actual = brain.actual_time
        returnvalue = dict(
            story_id=brain.getId,
            uid=brain.UID,
            url=brain.getURL(),
            title=brain.Title,
            description=brain.Description,
            raw_estimate=estimate,
            estimate=formatTime(estimate),
            size_estimate=brain.size_estimate,
            actual=formatTime(actual),
            difference=formatTime(estimate - actual),
            progress=progress,
            review_state=review_state_id,
            review_state_title=self.workflow.getTitleForStateOnType(
                review_state_id, 'Story'),
            is_completed=is_completed,
            open_tasks=open_tasks,
            completed_tasks=completed_tasks,
            locked=locked,
        )
        return returnvalue
コード例 #15
0
    def PROPPATCH(self, REQUEST, RESPONSE):
        """Set and/or remove properties defined on the resource."""
        from webdav.davcmds import PropPatch
        self.dav__init(REQUEST, RESPONSE)
        if not hasattr(aq_base(self), 'propertysheets'):
            raise MethodNotAllowed, ('Method not supported for this resource.')
        # Lock checking
        ifhdr = REQUEST.get_header('If', '')
        if wl_isLocked(self):
            if ifhdr:
                self.dav__simpleifhandler(REQUEST, RESPONSE, 'PROPPATCH')
            else:
                raise Locked, 'Resource is locked.'

        cmd = PropPatch(REQUEST)
        result = cmd.apply(self)
        RESPONSE.setStatus(207)
        RESPONSE.setHeader('Content-Type', 'text/xml; charset="utf-8"')
        RESPONSE.setBody(result)
        return RESPONSE
コード例 #16
0
    def iterationbrain2dict(self, brain):
        """Get a dict with info from this iteration brain.

        This one gets used by current_iterations() and open_iterations().
        """
        iteration = brain.getObject()
        iteration_view = getMultiAdapter((iteration, self.request),
                                         name='iteration')
        stories = iteration_view.stories(sort_by_state=False,
                                         locked_status=True)
        stories = self.update_stories(stories)
        returnvalue = dict(
            url=brain.getURL(),
            title=brain.Title,
            description=brain.Description,
            brain=brain,
            stories=stories,
            uid=brain.UID,
            locked=wl_isLocked(iteration),
        )
        return returnvalue
コード例 #17
0
    def iterationbrain2dict(self, brain):
        """Get a dict with info from this iteration brain.

        This one gets used by current_iterations() and open_iterations().
        """
        iteration = brain.getObject()
        iteration_view = getMultiAdapter((iteration, self.request),
                                         name='iteration')
        stories = iteration_view.stories(sort_by_state=False,
                                         locked_status=True)
        stories = self.update_stories(stories)
        returnvalue = dict(
            url=brain.getURL(),
            title=brain.Title,
            description=brain.Description,
            brain=brain,
            stories=stories,
            uid=brain.UID,
            locked=wl_isLocked(iteration),
        )
        return returnvalue
コード例 #18
0
ファイル: Resource.py プロジェクト: nacho22martin/tesis
    def PROPPATCH(self, REQUEST, RESPONSE):
        """Set and/or remove properties defined on the resource."""
        from webdav.davcmds import PropPatch
        self.dav__init(REQUEST, RESPONSE)
        if not hasattr(aq_base(self), 'propertysheets'):
            raise MethodNotAllowed, (
                  'Method not supported for this resource.')
        # Lock checking
        ifhdr = REQUEST.get_header('If', '')
        if wl_isLocked(self):
            if ifhdr:
                self.dav__simpleifhandler(REQUEST, RESPONSE, 'PROPPATCH')
            else:
                raise Locked, 'Resource is locked.'

        cmd = PropPatch(REQUEST)
        result = cmd.apply(self)
        RESPONSE.setStatus(207)
        RESPONSE.setHeader('Content-Type', 'text/xml; charset="utf-8"')
        RESPONSE.setBody(result)
        return RESPONSE
コード例 #19
0
    def _findapply(self, obj, result=None, path=''):
        # recursive function to actually dig through and find the locked
        # objects.

        if result is None:
            result = []
        base = aq_base(obj)
        if not hasattr(base, 'objectItems'):
            return result
        try:
            items = obj.objectItems()
        except Exception:
            return result

        addresult = result.append
        for id, ob in items:
            if path:
                p = '%s/%s' % (path, id)
            else:
                p = id

            dflag = hasattr(ob, '_p_changed') and (ob._p_changed == None)
            bs = aq_base(ob)
            if wl_isLocked(ob):
                li = []
                addlockinfo = li.append
                for token, lock in ob.wl_lockItems():
                    addlockinfo({
                        'owner': lock.getCreatorPath(),
                        'token': token
                    })
                addresult((p, li))
                dflag = 0
            if hasattr(bs, 'objectItems'):
                self._findapply(ob, result, p)
            if dflag:
                ob._p_deactivate()

        return result
コード例 #20
0
ファイル: DavLockManager.py プロジェクト: pigaov10/plone4.3
    def _findapply(self, obj, result=None, path=""):
        # recursive function to actually dig through and find the locked
        # objects.

        if result is None:
            result = []
        base = aq_base(obj)
        if not hasattr(base, "objectItems"):
            return result
        try:
            items = obj.objectItems()
        except Exception:
            return result

        addresult = result.append
        for id, ob in items:
            if path:
                p = "%s/%s" % (path, id)
            else:
                p = id

            dflag = hasattr(ob, "_p_changed") and (ob._p_changed == None)
            bs = aq_base(ob)
            if wl_isLocked(ob):
                li = []
                addlockinfo = li.append
                for token, lock in ob.wl_lockItems():
                    addlockinfo({"owner": lock.getCreatorPath(), "token": token})
                addresult((p, li))
                dflag = 0
            if hasattr(bs, "objectItems"):
                self._findapply(ob, result, p)
            if dflag:
                ob._p_deactivate()

        return result
コード例 #21
0
    def MOVE(self, REQUEST, RESPONSE):
        """Move a resource to a new location. Though we may later try to
        make a move appear seamless across namespaces (e.g. from Zope
        to Apache), MOVE is currently only supported within the Zope
        namespace."""
        self.dav__init(REQUEST, RESPONSE)
        self.dav__validate(self, 'DELETE', REQUEST)
        if not hasattr(aq_base(self), 'cb_isMoveable') or \
           not self.cb_isMoveable():
            raise MethodNotAllowed, 'This object may not be moved.'

        dest = REQUEST.get_header('Destination', '')

        try:
            path = REQUEST.physicalPathFromURL(dest)
        except ValueError:
            raise BadRequest, 'No destination given'

        flag = REQUEST.get_header('Overwrite', 'F')
        flag = flag.upper()

        name = path.pop()
        parent_path = '/'.join(path)

        try:
            parent = self.restrictedTraverse(path)
        except ValueError:
            raise Conflict, 'Attempt to move to an unknown namespace.'
        except 'Not Found':
            raise Conflict, 'The resource %s must exist.' % parent_path
        except:
            raise
        if hasattr(parent, '__null_resource__'):
            raise Conflict, 'The resource %s must exist.' % parent_path
        existing = hasattr(aq_base(parent), name)
        if existing and flag == 'F':
            raise PreconditionFailed, 'Resource %s exists.' % dest
        try:
            parent._checkId(name, allow_dup=1)
        except:
            raise Forbidden, sys.exc_info()[1]
        try:
            parent._verifyObjectPaste(self)
        except Unauthorized:
            raise
        except:
            raise Forbidden, sys.exc_info()[1]

        # Now check locks.  Since we're affecting the resource that we're
        # moving as well as the destination, we have to check both.
        ifhdr = REQUEST.get_header('If', '')
        if existing:
            # The destination itself exists, so we need to check its locks
            destob = aq_base(parent)._getOb(name)
            if IWriteLock.providedBy(destob) and destob.wl_isLocked():
                if ifhdr:
                    itrue = destob.dav__simpleifhandler(REQUEST,
                                                        RESPONSE,
                                                        'MOVE',
                                                        url=dest,
                                                        refresh=1)
                    if not itrue:
                        raise PreconditionFailed
                else:
                    raise Locked, 'Destination is locked.'
        elif IWriteLock.providedBy(parent) and parent.wl_isLocked():
            # There's no existing object in the destination folder, so
            # we need to check the folders locks since we're changing its
            # member list
            if ifhdr:
                itrue = parent.dav__simpleifhandler(REQUEST,
                                                    RESPONSE,
                                                    'MOVE',
                                                    col=1,
                                                    url=dest,
                                                    refresh=1)
                if not itrue:
                    raise PreconditionFailed, 'Condition failed.'
            else:
                raise Locked, 'Destination is locked.'
        if wl_isLocked(self):
            # Lastly, we check ourselves
            if ifhdr:
                itrue = self.dav__simpleifhandler(REQUEST,
                                                  RESPONSE,
                                                  'MOVE',
                                                  refresh=1)
                if not itrue:
                    raise PreconditionFailed, 'Condition failed.'
            else:
                raise Locked('Source is locked and no condition was passed in')

        orig_container = aq_parent(aq_inner(self))
        orig_id = self.getId()

        self._notifyOfCopyTo(parent, op=1)

        notify(
            ObjectWillBeMovedEvent(self, orig_container, orig_id, parent,
                                   name))

        # try to make ownership explicit so that it gets carried
        # along to the new location if needed.
        self.manage_changeOwnershipType(explicit=1)

        ob = self._getCopy(parent)
        ob._setId(name)

        orig_container._delObject(orig_id, suppress_events=True)

        if existing:
            object = getattr(parent, name)
            self.dav__validate(object, 'DELETE', REQUEST)
            parent._delObject(name)

        parent._setObject(name, ob, set_owner=0, suppress_events=True)
        ob = parent._getOb(name)

        notify(ObjectMovedEvent(ob, orig_container, orig_id, parent, name))
        notifyContainerModified(orig_container)
        if aq_base(orig_container) is not aq_base(parent):
            notifyContainerModified(parent)

        ob._postCopy(parent, op=1)

        # try to make ownership implicit if possible
        ob.manage_changeOwnershipType(explicit=0)

        RESPONSE.setStatus(existing and 204 or 201)
        if not existing:
            RESPONSE.setHeader('Location', dest)
        RESPONSE.setBody('')
        return RESPONSE
コード例 #22
0
ファイル: Resource.py プロジェクト: nacho22martin/tesis
    def MOVE(self, REQUEST, RESPONSE):
        """Move a resource to a new location. Though we may later try to
        make a move appear seamless across namespaces (e.g. from Zope
        to Apache), MOVE is currently only supported within the Zope
        namespace."""
        self.dav__init(REQUEST, RESPONSE)
        self.dav__validate(self, 'DELETE', REQUEST)
        if not hasattr(aq_base(self), 'cb_isMoveable') or \
           not self.cb_isMoveable():
            raise MethodNotAllowed, 'This object may not be moved.'

        dest=REQUEST.get_header('Destination', '')

        try: path = REQUEST.physicalPathFromURL(dest)
        except ValueError:
            raise BadRequest, 'No destination given'

        flag=REQUEST.get_header('Overwrite', 'F')
        flag=flag.upper()

        name = path.pop()
        parent_path = '/'.join(path)

        try: parent = self.restrictedTraverse(path)
        except ValueError:
            raise Conflict, 'Attempt to move to an unknown namespace.'
        except 'Not Found':
            raise Conflict, 'The resource %s must exist.' % parent_path
        except:
            raise
        if hasattr(parent, '__null_resource__'):
            raise Conflict, 'The resource %s must exist.' % parent_path
        existing=hasattr(aq_base(parent), name)
        if existing and flag=='F':
            raise PreconditionFailed, 'Resource %s exists.' % dest
        try:
            parent._checkId(name, allow_dup=1)
        except:
            raise Forbidden, sys.exc_info()[1]
        try:
            parent._verifyObjectPaste(self)
        except Unauthorized:
            raise
        except:
            raise Forbidden, sys.exc_info()[1]

        # Now check locks.  Since we're affecting the resource that we're
        # moving as well as the destination, we have to check both.
        ifhdr = REQUEST.get_header('If', '')
        if existing:
            # The destination itself exists, so we need to check its locks
            destob = aq_base(parent)._getOb(name)
            if IWriteLock.providedBy(destob) and destob.wl_isLocked():
                if ifhdr:
                    itrue = destob.dav__simpleifhandler(
                        REQUEST, RESPONSE, 'MOVE', url=dest, refresh=1)
                    if not itrue:
                        raise PreconditionFailed
                else:
                    raise Locked, 'Destination is locked.'
        elif IWriteLock.providedBy(parent) and parent.wl_isLocked():
            # There's no existing object in the destination folder, so
            # we need to check the folders locks since we're changing its
            # member list
            if ifhdr:
                itrue = parent.dav__simpleifhandler(REQUEST, RESPONSE, 'MOVE',
                                                    col=1, url=dest, refresh=1)
                if not itrue:
                    raise PreconditionFailed, 'Condition failed.'
            else:
                raise Locked, 'Destination is locked.'
        if wl_isLocked(self):
            # Lastly, we check ourselves
            if ifhdr:
                itrue = self.dav__simpleifhandler(REQUEST, RESPONSE, 'MOVE',
                                                  refresh=1)
                if not itrue:
                    raise PreconditionFailed, 'Condition failed.'
            else:
                raise Locked('Source is locked and no condition was passed in')

        orig_container = aq_parent(aq_inner(self))
        orig_id = self.getId()

        self._notifyOfCopyTo(parent, op=1)

        notify(ObjectWillBeMovedEvent(self, orig_container, orig_id,
                                      parent, name))

        # try to make ownership explicit so that it gets carried
        # along to the new location if needed.
        self.manage_changeOwnershipType(explicit=1)

        ob = self._getCopy(parent)
        ob._setId(name)

        orig_container._delObject(orig_id, suppress_events=True)

        if existing:
            object=getattr(parent, name)
            self.dav__validate(object, 'DELETE', REQUEST)
            parent._delObject(name)

        parent._setObject(name, ob, set_owner=0, suppress_events=True)
        ob = parent._getOb(name)

        notify(ObjectMovedEvent(ob, orig_container, orig_id, parent, name))
        notifyContainerModified(orig_container)
        if aq_base(orig_container) is not aq_base(parent):
            notifyContainerModified(parent)

        ob._postCopy(parent, op=1)

        # try to make ownership implicit if possible
        ob.manage_changeOwnershipType(explicit=0)

        RESPONSE.setStatus(existing and 204 or 201)
        if not existing:
            RESPONSE.setHeader('Location', dest)
        RESPONSE.setBody('')
        return RESPONSE
コード例 #23
0
ファイル: ExternalEditor.py プロジェクト: bendavis78/zope
 def index_html(self, REQUEST, RESPONSE, path=None):
     """Publish the object to the external editor helper app"""
     
     security = getSecurityManager()
     if path is None:
         parent = self.aq_parent
         try:
             ob = parent[REQUEST['target']] # Try getitem
         except KeyError:
             ob = getattr(parent, REQUEST['target']) # Try getattr
         except AttributeError:
             # Handle objects that are methods in ZClasses
             ob = parent.propertysheets.methods[REQUEST['target']]
     else:
         ob = self.restrictedTraverse( path )
     
     r = []
     r.append('url:%s' % ob.absolute_url())
     r.append('meta_type:%s' % ob.meta_type)
     
     if hasattr(Acquisition.aq_base(ob), 'content_type'):
         if callable(ob.content_type):
             r.append('content_type:%s' % ob.content_type())
         else:
             r.append('content_type:%s' % ob.content_type)
             
     if REQUEST._auth:
         if REQUEST._auth[-1] == '\n':
             auth = REQUEST._auth[:-1]
         else:
             auth = REQUEST._auth
             
         r.append('auth:%s' % auth)
         
     r.append('cookie:%s' % REQUEST.environ.get('HTTP_COOKIE',''))
     
     if wl_isLocked(ob):
         # Object is locked, send down the lock token 
         # owned by this user (if any)
         user_id = security.getUser().getId()
         for lock in ob.wl_lockValues():
             if not lock.isValid():
                 continue # Skip invalid/expired locks
             creator = lock.getCreator()
             if creator and creator[1] == user_id:
                 # Found a lock for this user, so send it
                 r.append('lock-token:%s' % lock.getLockToken())
                 break       
           
     r.append('')
     
     RESPONSE.setHeader('Pragma', 'no-cache')
     
     if hasattr(Acquisition.aq_base(ob), 'data') \
        and hasattr(ob.data, '__class__') \
        and ob.data.__class__ is Image.Pdata:
         # We have a File instance with chunked data, lets stream it
         metadata = join(r, '\n')
         RESPONSE.setHeader('Content-Type', 'application/x-zope-edit')
         RESPONSE.setHeader('Content-Length', 
                            len(metadata) + ob.get_size() + 1)
         RESPONSE.write(metadata)
         RESPONSE.write('\n')
         data = ob.data
         while data is not None:
             RESPONSE.write(data.data)
             data = data.next         
         return ''
     if hasattr(ob, 'manage_FTPget'):
         try:
             r.append(ob.manage_FTPget())
         except TypeError: # some need the R/R pair!
             r.append(ob.manage_FTPget(REQUEST, RESPONSE))
     elif hasattr(ob, 'EditableBody'):
         r.append(ob.EditableBody())
     elif hasattr(ob, 'document_src'):
         r.append(ob.document_src(REQUEST, RESPONSE))
     elif hasattr(ob, 'read'):
         r.append(ob.read())
     else:
         # can't read it!
         raise 'BadRequest', 'Object does not support external editing'
     
     RESPONSE.setHeader('Content-Type', 'application/x-zope-edit')    
     return join(r, '\n')
コード例 #24
0
    def index_html(self, REQUEST, RESPONSE, path=None):
        """Publish the object to the external editor helper app"""

        security = getSecurityManager()
        if path is None:
            parent = self.aq_parent
            try:
                ob = parent[REQUEST['target']]  # Try getitem
            except KeyError:
                ob = getattr(parent, REQUEST['target'])  # Try getattr
            except AttributeError:
                # Handle objects that are methods in ZClasses
                ob = parent.propertysheets.methods[REQUEST['target']]
        else:
            ob = self.restrictedTraverse(path)

        r = []
        r.append('url:%s' % ob.absolute_url())
        r.append('meta_type:%s' % ob.meta_type)

        title = getattr(aq_base(ob), 'title', None)
        if title is not None:
            if callable(title):
                title = title()
            if isinstance(title, types.UnicodeType):
                title = unicode.encode(title, 'utf-8')
            r.append('title:%s' % title)

        if hasattr(aq_base(ob), 'content_type'):
            if callable(ob.content_type):
                r.append('content_type:%s' % ob.content_type())
            else:
                r.append('content_type:%s' % ob.content_type)

        if REQUEST._auth:
            if REQUEST._auth[-1] == '\n':
                auth = REQUEST._auth[:-1]
            else:
                auth = REQUEST._auth

            r.append('auth:%s' % auth)

        r.append('cookie:%s' % REQUEST.environ.get('HTTP_COOKIE', ''))

        if wl_isLocked(ob):
            # Object is locked, send down the lock token
            # owned by this user (if any)
            user_id = security.getUser().getId()
            for lock in ob.wl_lockValues():
                if not lock.isValid():
                    continue  # Skip invalid/expired locks
                creator = lock.getCreator()
                if creator and creator[1] == user_id:
                    # Found a lock for this user, so send it
                    r.append('lock-token:%s' % lock.getLockToken())
                    if REQUEST.get('borrow_lock'):
                        r.append('borrow_lock:1')
                    break

        # Apply any extra callbacks that might have been registered.
        applyCallbacks(ob, r, REQUEST, RESPONSE)

        # Finish metadata with an empty line.
        r.append('')
        metadata = join(r, '\n')
        metadata_len = len(metadata)

        # Check if we should send the file's data down the response.
        if REQUEST.get('skip_data'):
            # We've been requested to send only the metadata. The
            # client will presumably fetch the data itself.
            self._write_metadata(RESPONSE, metadata, metadata_len)
            return ''

        ob_data = getattr(aq_base(ob), 'data', None)
        if (ob_data is not None and isinstance(ob_data, Image.Pdata)):
            # We have a File instance with chunked data, lets stream it.
            #
            # Note we are setting the content-length header here. This
            # is a simplification. Read comment below.
            #
            # We assume that ob.get_size() will return the exact size
            # of the PData chain. If that assumption is broken we
            # might have problems. This is mainly an optimization. If
            # we read the whole PData chain just to compute the
            # correct size that could cause the whole file to be read
            # into memory.
            RESPONSE.setHeader('Content-Length', ob.get_size())
            # It is safe to use this PDataStreamIterator here because
            # it is consumed right below. This is only used to
            # simplify the code below so it only has to deal with
            # stream iterators or plain strings.
            body = PDataStreamIterator(ob.data)
        elif hasattr(ob, 'manage_FTPget'):
            # Calling manage_FTPget *might* have side-effects. For
            # example, in Archetypes it does set the 'content-type'
            # response header, which would end up overriding our own
            # content-type header because we've set it 'too
            # early'. We've moved setting the content-type header to
            # the '_write_metadata' method since, and any manipulation
            # of response headers should happen there, if possible.
            try:
                body = ob.manage_FTPget()
            except TypeError:  # some need the R/R pair!
                body = ob.manage_FTPget(REQUEST, RESPONSE)
        elif hasattr(ob, 'EditableBody'):
            body = ob.EditableBody()
        elif hasattr(ob, 'document_src'):
            body = ob.document_src(REQUEST, RESPONSE)
        elif hasattr(ob, 'read'):
            body = ob.read()
        else:
            # can't read it!
            raise 'BadRequest', 'Object does not support external editing'

        if (HAVE_Z3_IFACE and IStreamIterator.providedBy(body) or
                (not HAVE_Z3_IFACE) and IStreamIterator.isImplementedBy(body)):
            # We need to manage our content-length because we're streaming.
            # The content-length should have been set in the response by
            # the method that returns the iterator, but we need to fix it up
            # here because we insert metadata before the body.
            clen = RESPONSE.headers.get('content-length', None)
            assert clen is not None
            self._write_metadata(RESPONSE, metadata, metadata_len + int(clen))
            for data in body:
                RESPONSE.write(data)
            return ''

        # If we reached this point, body *must* be a string. We *must*
        # set the headers ourselves since _write_metadata won't get
        # called.
        self._set_headers(RESPONSE)
        return join((metadata, body), '\n')
コード例 #25
0
    def importElementFromXML(self, container, node):
        """
        """
        id = node.getAttribute('id')
        element_type = node.getAttribute('type')
        if id in container.objectIds():
            ob = getattr(container, id)
            if wl_isLocked(ob):
                ob.wl_clearLocks()
            container.manage_delObjects([id])
        container.invokeFactory(element_type, id=id)
        #        if not(hasattr(container, id)):
        #            container.invokeFactory(element_type, id=id)
        obj = getattr(container, id)
        if obj.Type() == element_type:
            # note: there might be an existing object with the same id but with a
            # different type, in this case, we do not import
            title = node.getAttribute('title')
            obj.setTitle(title)
            child = node.firstChild
            at_values = {}
            settings_values = {}
            while child is not None:
                name = child.nodeName
                if name == 'id':
                    pass
                elif name == 'elements':
                    # current object is a form or a view, it contains sub-objects
                    # (fields, actions, columns, hide-when)
                    subchild = child.firstChild
                    while subchild is not None:
                        if subchild.nodeType == subchild.ELEMENT_NODE:
                            self.importElementFromXML(obj, subchild)
                        subchild = subchild.nextSibling
                elif name == 'params':
                    # current object is a field, the params tag contains the
                    # specific settings
                    result, method = xmlrpclib.loads(
                        node.toxml().encode('utf-8'))
                    parameters = result[0]
                    for key in parameters.keys():
                        v = parameters[key]
                        if v is not None:
                            if hasattr(v, 'encode'):
                                v = unicode(v)
                            else:
                                if hasattr(v, 'append'):
                                    uv = []
                                    for e in v:
                                        if hasattr(e, 'encode'):
                                            uv.append(unicode(e))
                                        else:
                                            uv.append(e)
                                    v = uv
                            settings_values[key] = v
                elif name == "CustomData":
                    # Only one non.text child is expected
                    customnode = [
                        el for el in child.childNodes if el.nodeName != '#text'
                    ][0]
                    classname = customnode.getAttribute('ExportImportClass')
                    importer = resolve(classname)(obj)
                    importer.import_xml(customnode.toxml())
                else:
                    if child.hasChildNodes():
                        # Get cdata content if available, else get text node
                        cdatas = [
                            n for n in child.childNodes
                            if n.nodeType == n.CDATA_SECTION_NODE
                        ]
                        if len(cdatas) > 0:
                            v = cdatas[0].data
                        else:
                            v = child.firstChild.data
                        v = v.strip()
                        at_values[name] = v
                child = child.nextSibling

            if element_type == "PlominoForm":
                at_values['FormLayout_text_format'] = "text/html"

            if len(at_values) > 0:
                obj.processForm(REQUEST=None, values=at_values)

            if len(settings_values) > 0:
                adapt = obj.getSettings()
                for key in settings_values.keys():
                    getattr(adapt, 'parameters')[key] = settings_values[key]
コード例 #26
0
ファイル: ExternalEditor.py プロジェクト: goschtl/zope
 def index_html(self, REQUEST, RESPONSE, path=None):
     """Publish the object to the external editor helper app"""
     
     security = getSecurityManager()
     if path is None:
         parent = self.aq_parent
         try:
             ob = parent[REQUEST['target']] # Try getitem
         except KeyError:
             ob = getattr(parent, REQUEST['target']) # Try getattr
         except AttributeError:
             # Handle objects that are methods in ZClasses
             ob = parent.propertysheets.methods[REQUEST['target']]
     else:
         ob = self.restrictedTraverse( path )
     
     r = []
     r.append('url:%s' % ob.absolute_url())
     r.append('meta_type:%s' % ob.meta_type)
     
     if hasattr(Acquisition.aq_base(ob), 'content_type'):
         if callable(ob.content_type):
             r.append('content_type:%s' % ob.content_type())
         else:
             r.append('content_type:%s' % ob.content_type)
             
     if REQUEST._auth:
         if REQUEST._auth[-1] == '\n':
             auth = REQUEST._auth[:-1]
         else:
             auth = REQUEST._auth
             
         r.append('auth:%s' % auth)
         
     r.append('cookie:%s' % REQUEST.environ.get('HTTP_COOKIE',''))
     
     if wl_isLocked(ob):
         # Object is locked, send down the lock token 
         # owned by this user (if any)
         user_id = security.getUser().getId()
         for lock in ob.wl_lockValues():
             if not lock.isValid():
                 continue # Skip invalid/expired locks
             creator = lock.getCreator()
             if creator and creator[1] == user_id:
                 # Found a lock for this user, so send it
                 r.append('lock-token:%s' % lock.getLockToken())
                 if REQUEST.get('borrow_lock'):
                     r.append('borrow_lock:1')
                 break       
           
     r.append('')
     
     # Using RESPONSE.setHeader('Pragma', 'no-cache') would be better, but
     # this chokes crappy most MSIE versions when downloads happen on SSL.
     # cf. http://support.microsoft.com/support/kb/articles/q316/4/31.asp
     RESPONSE.setHeader('Last-Modified', rfc1123_date())
     
     if hasattr(Acquisition.aq_base(ob), 'data') \
        and hasattr(ob.data, '__class__') \
        and ob.data.__class__ is Image.Pdata:
         # We have a File instance with chunked data, lets stream it
         metadata = join(r, '\n')
         RESPONSE.setHeader('Content-Type', 'application/x-zope-edit')
         RESPONSE.setHeader('Content-Length', 
                            len(metadata) + ob.get_size() + 1)
         RESPONSE.write(metadata)
         RESPONSE.write('\n')
         data = ob.data
         while data is not None:
             RESPONSE.write(data.data)
             data = data.next         
         return ''
     if hasattr(ob, 'manage_FTPget'):
         try:
             r.append(ob.manage_FTPget())
         except TypeError: # some need the R/R pair!
             r.append(ob.manage_FTPget(REQUEST, RESPONSE))
     elif hasattr(ob, 'EditableBody'):
         r.append(ob.EditableBody())
     elif hasattr(ob, 'document_src'):
         r.append(ob.document_src(REQUEST, RESPONSE))
     elif hasattr(ob, 'read'):
         r.append(ob.read())
     else:
         # can't read it!
         raise 'BadRequest', 'Object does not support external editing'
     
     RESPONSE.setHeader('Content-Type', 'application/x-zope-edit')    
     return join(r, '\n')
コード例 #27
0
    def index_html(self, REQUEST, RESPONSE, path=None):
        """Publish the object to the external editor helper app"""

        security = getSecurityManager()
        if path is None:
            parent = self.aq_parent
            try:
                ob = parent[REQUEST['target']]  # Try getitem
            except KeyError:
                ob = getattr(parent, REQUEST['target'])  # Try getattr
            except AttributeError:
                # Handle objects that are methods in ZClasses
                ob = parent.propertysheets.methods[REQUEST['target']]
        else:
            ob = self.restrictedTraverse(path)

        r = []
        r.append('url:%s' % ob.absolute_url())
        r.append('meta_type:%s' % ob.meta_type)

        title = getattr(Acquisition.aq_base(ob), 'title', None)
        if title is not None:
            if callable(title):
                title = title()
            if isinstance(title, types.UnicodeType):
                title = unicode.encode(title, 'utf-8')
            r.append('title:%s' % title)

        if hasattr(Acquisition.aq_base(ob), 'content_type'):
            if callable(ob.content_type):
                r.append('content_type:%s' % ob.content_type())
            else:
                r.append('content_type:%s' % ob.content_type)

        if REQUEST._auth:
            if REQUEST._auth[-1] == '\n':
                auth = REQUEST._auth[:-1]
            else:
                auth = REQUEST._auth

            r.append('auth:%s' % auth)

        r.append('cookie:%s' % REQUEST.environ.get('HTTP_COOKIE', ''))

        if wl_isLocked(ob):
            # Object is locked, send down the lock token
            # owned by this user (if any)
            user_id = security.getUser().getId()
            for lock in ob.wl_lockValues():
                if not lock.isValid():
                    continue  # Skip invalid/expired locks
                creator = lock.getCreator()
                if creator and creator[1] == user_id:
                    # Found a lock for this user, so send it
                    r.append('lock-token:%s' % lock.getLockToken())
                    if REQUEST.get('borrow_lock'):
                        r.append('borrow_lock:1')
                    break

        r.append('')
        streamiterator = None

        # Using RESPONSE.setHeader('Pragma', 'no-cache') would be better, but
        # this chokes crappy most MSIE versions when downloads happen on SSL.
        # cf. http://support.microsoft.com/support/kb/articles/q316/4/31.asp
        RESPONSE.setHeader('Last-Modified', rfc1123_date())

        if hasattr(Acquisition.aq_base(ob), 'data') \
           and hasattr(ob.data, '__class__') \
           and ob.data.__class__ is Image.Pdata:
            # We have a File instance with chunked data, lets stream it
            metadata = join(r, '\n')
            RESPONSE.setHeader('Content-Type', 'application/x-zope-edit')
            RESPONSE.setHeader('Content-Length',
                               len(metadata) + ob.get_size() + 1)
            RESPONSE.write(metadata)
            RESPONSE.write('\n')
            data = ob.data
            while data is not None:
                RESPONSE.write(data.data)
                data = data.next
            return ''
        if hasattr(ob, 'manage_FTPget'):
            try:
                body = ob.manage_FTPget()
            except TypeError:  # some need the R/R pair!
                body = ob.manage_FTPget(REQUEST, RESPONSE)
        elif hasattr(ob, 'EditableBody'):
            body = ob.EditableBody()
        elif hasattr(ob, 'document_src'):
            body = ob.document_src(REQUEST, RESPONSE)
        elif hasattr(ob, 'read'):
            body = ob.read()
        else:
            # can't read it!
            raise 'BadRequest', 'Object does not support external editing'

        RESPONSE.setHeader('Content-Type', 'application/x-zope-edit')

        if (IStreamIterator is not None
                and IStreamIterator.isImplementedBy(body)):
            # We need to manage our content-length because we're streaming.
            # The content-length should have been set in the response by
            # the method that returns the iterator, but we need to fix it up
            # here because we insert metadata before the body.
            clen = RESPONSE.headers.get('content-length', None)
            assert clen is not None
            metadata = join(r, '\n')
            RESPONSE.setHeader('Content-Length', len(metadata) + int(clen) + 1)
            RESPONSE.write(metadata)
            RESPONSE.write('\n')
            for data in body:
                RESPONSE.write(data)
        else:
            r.append(body)
            return join(r, '\n')
コード例 #28
0
    def index_html(self, REQUEST, RESPONSE, path=None):
        """Publish the object to the external editor helper app"""

        security = getSecurityManager()
        if path is None:
            parent = self.aq_parent
            try:
                ob = parent[REQUEST['target']]  # Try getitem
            except KeyError:
                ob = getattr(parent, REQUEST['target'])  # Try getattr
            except AttributeError:
                # Handle objects that are methods in ZClasses
                ob = parent.propertysheets.methods[REQUEST['target']]
        else:
            ob = self.restrictedTraverse(path)

        r = []
        r.append('url:%s' % ob.absolute_url())
        r.append('meta_type:%s' % ob.meta_type)

        title = getattr(aq_base(ob), 'title', None)
        if title is not None:
            if callable(title):
                title = title()
            if isinstance(title, types.UnicodeType):
                title = unicode.encode(title, 'utf-8')
            r.append('title:%s' % title)

        if hasattr(aq_base(ob), 'content_type'):
            if callable(ob.content_type):
                r.append('content_type:%s' % ob.content_type())
            else:
                r.append('content_type:%s' % ob.content_type)

        if REQUEST._auth:
            if REQUEST._auth[-1] == '\n':
                auth = REQUEST._auth[:-1]
            else:
                auth = REQUEST._auth

            r.append('auth:%s' % auth)

        r.append('cookie:%s' % REQUEST.environ.get('HTTP_COOKIE', ''))

        if wl_isLocked(ob):
            # Object is locked, send down the lock token
            # owned by this user (if any)
            user_id = security.getUser().getId()
            for lock in ob.wl_lockValues():
                if not lock.isValid():
                    continue  # Skip invalid/expired locks
                creator = lock.getCreator()
                if creator and creator[1] == user_id:
                    # Found a lock for this user, so send it
                    r.append('lock-token:%s' % lock.getLockToken())
                    if REQUEST.get('borrow_lock'):
                        r.append('borrow_lock:1')
                    break

        # Apply any extra callbacks that might have been registered.
        applyCallbacks(ob, r, REQUEST, RESPONSE)

        # Finish metadata with an empty line.
        r.append('')
        metadata = join(r, '\n')
        metadata_len = len(metadata)

        # Check if we should send the file's data down the response.
        if REQUEST.get('skip_data'):
            # We've been requested to send only the metadata. The
            # client will presumably fetch the data itself.
            self._write_metadata(RESPONSE, metadata, metadata_len)
            return ''

        ob_data = getattr(aq_base(ob), 'data', None)
        if (ob_data is not None and isinstance(ob_data, Image.Pdata)):
            # We have a File instance with chunked data, lets stream it.
            #
            # Note we are setting the content-length header here. This
            # is a simplification. Read comment below.
            #
            # We assume that ob.get_size() will return the exact size
            # of the PData chain. If that assumption is broken we
            # might have problems. This is mainly an optimization. If
            # we read the whole PData chain just to compute the
            # correct size that could cause the whole file to be read
            # into memory.
            RESPONSE.setHeader('Content-Length', ob.get_size())
            # It is safe to use this PDataStreamIterator here because
            # it is consumed right below. This is only used to
            # simplify the code below so it only has to deal with
            # stream iterators or plain strings.
            body = PDataStreamIterator(ob.data)
        elif hasattr(ob, 'manage_FTPget'):
            # Calling manage_FTPget *might* have side-effects. For
            # example, in Archetypes it does set the 'content-type'
            # response header, which would end up overriding our own
            # content-type header because we've set it 'too
            # early'. We've moved setting the content-type header to
            # the '_write_metadata' method since, and any manipulation
            # of response headers should happen there, if possible.
            try:
                body = ob.manage_FTPget()
            except TypeError:  # some need the R/R pair!
                body = ob.manage_FTPget(REQUEST, RESPONSE)
        elif hasattr(ob, 'EditableBody'):
            body = ob.EditableBody()
        elif hasattr(ob, 'document_src'):
            body = ob.document_src(REQUEST, RESPONSE)
        elif hasattr(ob, 'read'):
            body = ob.read()
        else:
            # can't read it!
            raise 'BadRequest', 'Object does not support external editing'

        if (HAVE_Z3_IFACE and IStreamIterator.providedBy(body) or
            (not HAVE_Z3_IFACE) and IStreamIterator.isImplementedBy(body)):
            # We need to manage our content-length because we're streaming.
            # The content-length should have been set in the response by
            # the method that returns the iterator, but we need to fix it up
            # here because we insert metadata before the body.
            clen = RESPONSE.headers.get('content-length', None)
            assert clen is not None
            self._write_metadata(RESPONSE, metadata, metadata_len + int(clen))
            for data in body:
                RESPONSE.write(data)
            return ''

        # If we reached this point, body *must* be a string. We *must*
        # set the headers ourselves since _write_metadata won't get
        # called.
        self._set_headers(RESPONSE)
        return join((metadata, body), '\n')