You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by jp...@apache.org on 2013/07/29 02:23:19 UTC

svn commit: r1507877 - /chemistry/cmislib/trunk/src/cmislib/browser_binding.py

Author: jpotts
Date: Mon Jul 29 00:23:19 2013
New Revision: 1507877

URL: http://svn.apache.org/r1507877
Log:
Continued work in progress on the browser binding implementation.

Modified:
    chemistry/cmislib/trunk/src/cmislib/browser_binding.py

Modified: chemistry/cmislib/trunk/src/cmislib/browser_binding.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/trunk/src/cmislib/browser_binding.py?rev=1507877&r1=1507876&r2=1507877&view=diff
==============================================================================
--- chemistry/cmislib/trunk/src/cmislib/browser_binding.py (original)
+++ chemistry/cmislib/trunk/src/cmislib/browser_binding.py Mon Jul 29 00:23:19 2013
@@ -29,7 +29,7 @@ from util import parsePropValueByType, p
 import json
 import StringIO
 import logging
-from urllib import urlencode
+from urllib import urlencode, quote
 
 CMIS_FORM_TYPE = 'application/x-www-form-urlencoded;charset=utf-8'
 
@@ -94,7 +94,7 @@ class BrowserBinding(Binding):
                              **kwargs)
         if resp['status'] != '200' and resp['status'] != '201':
             self._processCommonErrors(resp, url)
-        else:
+        elif content is not None and content != "":
             result = json.loads(content)
         return result
 
@@ -338,8 +338,27 @@ class BrowserCmisObject(object):
         >>> doc = repo.getObjectByPath('/cmislib/sub1/testdoc1')
         >>> doc.move(sub1, sub2)
         """
+        '''
+        cmisaction=move
+        <input name="targetFolderId" type="hidden" value="1234-abcd-5678" />
+        <input name="sourceFolderId" type="hidden" value="1234-abcd-5678" />
+        '''
+        moveUrl = self._repository.getRootFolderUrl()
+
+        props = {"objectId" : self.id,
+                 "cmisaction" : "move",
+                 "sourceFolderId" : sourceFolder.id,
+                 "targetFolderId" : targetFolder.id}
+
+        # invoke the URL
+        result = self._cmisClient.binding.post(moveUrl.encode('utf-8'),
+                                               urlencode(props),
+                                               'application/x-www-form-urlencoded',
+                                               self._cmisClient.username,
+                                               self._cmisClient.password)
+
+        return
 
-        pass
 
     def delete(self, **kwargs):
 
@@ -355,7 +374,21 @@ class BrowserCmisObject(object):
         The optional allVersions argument is supported.
         """
 
-        pass
+        delUrl = self._repository.getRootFolderUrl()
+
+        props = {"objectId" : self.id,
+                 "cmisaction" : "delete"}
+
+        # invoke the URL
+        result = self._cmisClient.binding.post(delUrl.encode('utf-8'),
+                                               urlencode(props),
+                                               'application/x-www-form-urlencoded',
+                                               self._cmisClient.username,
+                                               self._cmisClient.password,
+                                               **kwargs)
+
+        return
+
 
     def applyPolicy(self, policyId):
 
@@ -575,7 +608,7 @@ class BrowserRepository(object):
             if self.data is None:
                 self.reload()
             repoInfo = {'repositoryId': self.data['repositoryId'], 'repositoryName': self.data['repositoryName'],
-                        'resositoryDescription': self.data['repositoryDescription'],
+                        'repositoryDescription': self.data['repositoryDescription'],
                         'vendorName': self.data['vendorName'], 'productName': self.data['productName'],
                         'productVersion': self.data['productVersion'], 'rootFolderId': self.data['rootFolderId'],
                         'latestChangeLogToken': self.data['latestChangeLogToken'],
@@ -620,7 +653,10 @@ class BrowserRepository(object):
             else:
                 self._kwargs = kwargs
 
-        byPathUrl = self.getRootFolderUrl() + path + "?cmisselector=object"
+        #TODO why is quoting the path required for the browser binding and not for atom pub
+        #on inmemory 0.9?
+        #TODO maybe we should quote all urls in the net library instead of here
+        byPathUrl = self.getRootFolderUrl() + quote(path) + "?cmisselector=object"
         result = self._cmisClient.binding.get(byPathUrl.encode('utf-8'),
                                                    self._cmisClient.username,
                                                    self._cmisClient.password,
@@ -873,6 +909,7 @@ class BrowserRepository(object):
         """
 
         typesUrl = self.getRepositoryUrl() + "?cmisselector=typeChildren"
+
         result = self._cmisClient.binding.get(typesUrl,
                                                    self._cmisClient.username,
                                                    self._cmisClient.password,
@@ -893,8 +930,16 @@ class BrowserRepository(object):
 
         >>> folderType = repo.getTypeDefinition('cmis:folder')
         """
+        #localhost:8080/chemistry/browser/A1?cmisselector=typeDefinition&typeId=cmis:folder
+        typesUrl = self.getRepositoryUrl() + "?cmisselector=typeDefinition" + \
+                    "&typeId=" + typeId
+        result = self._cmisClient.binding.get(typesUrl,
+                                                   self._cmisClient.username,
+                                                   self._cmisClient.password)
 
-        pass
+        return BrowserObjectType(self._cmisClient,
+                                    self,
+                                    data=result)
 
     def getCheckedOutDocs(self, **kwargs):
 
@@ -922,7 +967,16 @@ class BrowserRepository(object):
          - includeAllowableActions
         """
 
-        pass
+        typesUrl = self.getRepositoryUrl() + "?cmisselector=checkedOut"
+
+        result = self._cmisClient.binding.get(typesUrl,
+                                                   self._cmisClient.username,
+                                                   self._cmisClient.password,
+                                                   **kwargs)
+
+        return BrowserResultSet(self._cmisClient,
+                                    self,
+                                    data=result)
 
     def getUnfiledDocs(self, **kwargs):
 
@@ -1273,9 +1327,15 @@ class BrowserResultSet(object):
         if self._data:
             entries = []
             for obj in self._data['objects']:
+                #some result sets have an enclosing object and some don't
+                dataObj = None
+                if isinstance(obj, dict) and obj.has_key('object'):
+                    dataObj = obj['object']
+                else:
+                    dataObj = obj
                 cmisObject = getSpecializedObject(BrowserCmisObject(self._cmisClient,
                                                                     self._repository,
-                                                                    data=obj['object']))
+                                                                    data=dataObj))
                 entries.append(cmisObject)
 
             self._results = entries
@@ -1430,7 +1490,20 @@ class BrowserDocument(BrowserCmisObject)
         True
         """
 
-        pass
+        coUrl = self._repository.getRootFolderUrl()
+
+        props = {"objectId" : self.id,
+                 "cmisaction" : "checkOut"}
+
+        # invoke the URL
+        result = self._cmisClient.binding.post(coUrl.encode('utf-8'),
+                                               urlencode(props),
+                                               'application/x-www-form-urlencoded',
+                                               self._cmisClient.username,
+                                               self._cmisClient.password)
+
+        return getSpecializedObject(BrowserCmisObject(self._cmisClient, self._repository, data=result))
+
 
     def cancelCheckout(self):
         """
@@ -1445,7 +1518,19 @@ class BrowserDocument(BrowserCmisObject)
         False
         """
 
-        pass
+        coUrl = self._repository.getRootFolderUrl()
+
+        props = {"objectId" : self.id,
+                 "cmisaction" : "cancelCheckOut"}
+
+        # invoke the URL
+        result = self._cmisClient.binding.post(coUrl.encode('utf-8'),
+                                               urlencode(props),
+                                               'application/x-www-form-urlencoded',
+                                               self._cmisClient.username,
+                                               self._cmisClient.password)
+
+        return
 
     def getPrivateWorkingCopy(self):
 
@@ -1517,7 +1602,7 @@ class BrowserDocument(BrowserCmisObject)
         >>> doc.isCheckedOut()
         False
 
-        The following optional arguments are supported:
+        The following optional arguments are NOT supported:
          - major
          - properties
          - contentStream
@@ -1525,8 +1610,28 @@ class BrowserDocument(BrowserCmisObject)
          - addACEs
          - removeACEs
         """
+        #TODO implement optional arguments
+        # major = true is supposed to be the default but inmemory 0.9 is throwing an error 500 without it
+        if not kwargs.has_key('major'):
+            kwargs['major'] = 'true'
 
-        pass
+        kwargs['checkinComment'] = checkinComment
+
+        ciUrl = self._repository.getRootFolderUrl()
+
+        #TODO don't hardcode major flag
+        props = {"objectId" : self.id,
+                 "cmisaction" : "checkIn"}
+
+        # invoke the URL
+        result = self._cmisClient.binding.post(ciUrl.encode('utf-8'),
+                                               urlencode(props),
+                                               'application/x-www-form-urlencoded',
+                                               self._cmisClient.username,
+                                               self._cmisClient.password,
+                                               **kwargs)
+
+        return getSpecializedObject(BrowserCmisObject(self._cmisClient, self._repository, data=result))
 
     def getLatestVersion(self, **kwargs):
 
@@ -1587,7 +1692,7 @@ class BrowserDocument(BrowserCmisObject)
                                               **kwargs)
 
         # return the result set
-        return BrowserResultSet(self._cmisClient, self._repository, {'objects': result})
+        return BrowserResultSet(self._cmisClient, self._repository, data={'objects': result})
 
     def getContentStream(self):
 
@@ -1637,7 +1742,22 @@ class BrowserDocument(BrowserCmisObject)
         Delete's the content stream associated with this object.
         """
 
-        pass
+        delUrl = self._repository.getRootFolderUrl()
+
+        props = {"objectId" : self.id,
+                 "cmisaction" : "deleteContent"}
+
+        if self.properties.has_key('cmis:changeToken'):
+            props["changeToken"] = self.properties['cmis:changeToken']
+
+        # invoke the URL
+        result = self._cmisClient.binding.post(delUrl.encode('utf-8'),
+                                               urlencode(props),
+                                               'application/x-www-form-urlencoded',
+                                               self._cmisClient.username,
+                                               self._cmisClient.password)
+
+        return
 
     def getRenditions(self):
 
@@ -1651,6 +1771,7 @@ class BrowserDocument(BrowserCmisObject)
          - skipCount
         """
 
+        #TODO to be implemented
         pass
 
     checkedOut = property(isCheckedOut)
@@ -1760,7 +1881,39 @@ class BrowserFolder(BrowserCmisObject):
         >>> testFolder.createDocumentFromString('testdoc3', contentString='hello, world', contentType='text/plain')
         """
 
-        pass
+        # get the root folder URL
+        createDocUrl = self._repository.getRootFolderUrl()
+
+        props = {"objectId" : self.id,
+                 "cmisaction" : "createDocument",
+                 "propertyId[0]" : "cmis:name",
+                 "propertyValue[0]" : name}
+
+        props["propertyId[1]"] = "cmis:objectTypeId"
+        if properties.has_key('cmis:objectTypeId'):
+            props["propertyValue[1]"] = properties['cmis:objectTypeId']
+        else:
+            props["propertyValue[1]"] = "cmis:document"
+
+        propCount = 2
+        for prop in properties:
+            props["propertyId[%s]" % propCount] = prop.key
+            props["propertyValue[%s]" % propCount] = prop
+            propCount += 1
+
+        #TODO this isn't working at the moment
+        props["content"] = contentString
+
+        # invoke the URL
+        result = self._cmisClient.binding.post(createDocUrl.encode('utf-8'),
+                                               urlencode(props),
+                                               'application/x-www-form-urlencoded',
+                                               self._cmisClient.username,
+                                               self._cmisClient.password)
+
+        # return the result set
+        return BrowserDocument(self._cmisClient, self._repository, data=result)
+
 
     def createDocument(self, name, properties={}, contentFile=None,
             contentType=None, contentEncoding=None):
@@ -1803,7 +1956,40 @@ class BrowserFolder(BrowserCmisObject):
          - removeACEs
         """
 
-        pass
+        #TODO work in progress
+
+        # get the root folder URL
+        createDocUrl = self._repository.getRootFolderUrl()
+
+        props = {"objectId" : self.id,
+                 "cmisaction" : "createDocument",
+                 "propertyId[0]" : "cmis:name",
+                 "propertyValue[0]" : name}
+
+        props["propertyId[1]"] = "cmis:objectTypeId"
+        if properties.has_key('cmis:objectTypeId'):
+            pass
+        else:
+            props["propertyValue[1]"] = "cmis:document"
+
+        propCount = 2
+        for prop in properties:
+            props["propertyId[%s]" % propCount] = prop
+            props["propertyValue[%s]" % propCount] = properties[prop]
+            propCount += 1
+
+        #TODO this isn't working at the moment
+        props["content"] = 'this is a test'
+
+        # invoke the URL
+        result = self._cmisClient.binding.post(createDocUrl.encode('utf-8'),
+                                               urlencode(props),
+                                               'application/x-www-form-urlencoded',
+                                               self._cmisClient.username,
+                                               self._cmisClient.password)
+
+        # return the result set
+        return BrowserDocument(self._cmisClient, self._repository, data=result)
 
     def getChildren(self, **kwargs):
 
@@ -1868,7 +2054,14 @@ class BrowserFolder(BrowserCmisObject):
 
         """
 
-        pass
+        byObjectIdUrl = self._repository.getRootFolderUrl() + "?objectId=" + self.getObjectId() + "&cmisselector=descendants"
+        result = self._cmisClient.binding.get(byObjectIdUrl.encode('utf-8'),
+                                                   self._cmisClient.username,
+                                                   self._cmisClient.password,
+                                                   **kwargs)
+        # return the result set
+        return BrowserResultSet(self._cmisClient, self._repository, result)
+
 
     def getTree(self, **kwargs):
 
@@ -1922,7 +2115,20 @@ class BrowserFolder(BrowserCmisObject):
          - continueOnFailure
         """
 
-        pass
+        delUrl = self._repository.getRootFolderUrl()
+
+        props = {"objectId" : self.id,
+                 "cmisaction" : "deleteTree"}
+
+        # invoke the URL
+        result = self._cmisClient.binding.post(delUrl.encode('utf-8'),
+                                               urlencode(props),
+                                               'application/x-www-form-urlencoded',
+                                               self._cmisClient.username,
+                                               self._cmisClient.password,
+                                               **kwargs)
+
+        return
 
     def addObject(self, cmisObject, **kwargs):
 
@@ -1943,11 +2149,25 @@ class BrowserFolder(BrowserCmisObject):
         >>> sub2.getChildren()[0].name
         u'testdoc1'
 
-        The following optional arguments are supported:
+        The following optional arguments are NOT supported:
          - allVersions
         """
+        #TODO need to add support (and unit test) for allVersions
 
-        pass
+        addUrl = self._repository.getRootFolderUrl()
+
+        props = {"folderId" : self.id,
+                 "cmisaction" : "addObjectToFolder",
+                 "objectId" : cmisObject.id}
+
+        # invoke the URL
+        result = self._cmisClient.binding.post(addUrl.encode('utf-8'),
+                                               urlencode(props),
+                                               'application/x-www-form-urlencoded',
+                                               self._cmisClient.username,
+                                               self._cmisClient.password)
+
+        return getSpecializedObject(BrowserCmisObject(self._cmisClient, self._repository, data=result))
 
     def removeObject(self, cmisObject):
 
@@ -1956,8 +2176,21 @@ class BrowserFolder(BrowserCmisObject):
         support unfiling for this to work.
         """
 
-        pass
-    
+        remUrl = self._repository.getRootFolderUrl()
+
+        props = {"folderId" : self.id,
+                 "cmisaction" : "removeObjectFromFolder",
+                 "objectId" : cmisObject.id}
+
+        # invoke the URL
+        result = self._cmisClient.binding.post(remUrl.encode('utf-8'),
+                                               urlencode(props),
+                                               'application/x-www-form-urlencoded',
+                                               self._cmisClient.username,
+                                               self._cmisClient.password)
+
+        return getSpecializedObject(BrowserCmisObject(self._cmisClient, self._repository, data=result))
+
     def getPaths(self):
         """
         Returns the paths as a list of strings. The spec says folders cannot