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 2014/05/19 18:24:46 UTC

svn commit: r1595949 - in /chemistry/cmislib/trunk/src/cmislib: atompub/binding.py browser/binding.py cmis_services.py exceptions.py messages.py model.py net.py util.py

Author: jpotts
Date: Mon May 19 16:24:46 2014
New Revision: 1595949

URL: http://svn.apache.org/r1595949
Log:
cmislib pylint cleanup

Modified:
    chemistry/cmislib/trunk/src/cmislib/atompub/binding.py
    chemistry/cmislib/trunk/src/cmislib/browser/binding.py
    chemistry/cmislib/trunk/src/cmislib/cmis_services.py
    chemistry/cmislib/trunk/src/cmislib/exceptions.py
    chemistry/cmislib/trunk/src/cmislib/messages.py
    chemistry/cmislib/trunk/src/cmislib/model.py
    chemistry/cmislib/trunk/src/cmislib/net.py
    chemistry/cmislib/trunk/src/cmislib/util.py

Modified: chemistry/cmislib/trunk/src/cmislib/atompub/binding.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/trunk/src/cmislib/atompub/binding.py?rev=1595949&r1=1595948&r2=1595949&view=diff
==============================================================================
--- chemistry/cmislib/trunk/src/cmislib/atompub/binding.py (original)
+++ chemistry/cmislib/trunk/src/cmislib/atompub/binding.py Mon May 19 16:24:46 2014
@@ -22,12 +22,12 @@ provider.
 """
 from cmislib.cmis_services import Binding, RepositoryServiceIfc
 from cmislib.domain import CmisId, CmisObject, ObjectType, Property, ACL, ACE, ChangeEntry, ResultSet, Rendition
+from cmislib import messages
 from cmislib.net import RESTService as Rest
 from cmislib.exceptions import CmisException, \
     ObjectNotFoundException, InvalidArgumentException, \
     NotSupportedException
 from cmislib.util import multiple_replace, parsePropValue, parseBoolValue, toCMISValue, parseDateTimeValue
-import cmislib.messages
 
 from urllib import quote
 from urlparse import urlparse, urlunparse
@@ -86,6 +86,12 @@ ROOT_COLL = 'root'
 
 
 class AtomPubBinding(Binding):
+
+    """
+    The binding responsible for talking to the CMIS server via the AtomPub
+    Publishing Protocol.
+    """
+
     def __init__(self, **kwargs):
         self.extArgs = kwargs
 
@@ -214,11 +220,19 @@ class AtomPubBinding(Binding):
 
 
 class RepositoryService(RepositoryServiceIfc):
+
+    """
+    The repository service for the AtomPub binding.
+    """
+
     def __init__(self):
         self._uriTemplates = {}
         self.logger = logging.getLogger('cmislib.atompub_binding.RepositoryService')
 
     def reload(self, obj):
+
+        """ Reloads the state of the repository object."""
+
         self.logger.debug('Reload called on object')
         obj.xmlDoc = obj._cmisClient.binding.get(obj._cmisClient.repositoryUrl.encode('utf-8'),
                                                  obj._cmisClient.username,
@@ -226,6 +240,11 @@ class RepositoryService(RepositoryServic
         obj._initData()
 
     def getRepository(self, client, repositoryId):
+
+        """
+        Get the repository for the specified repositoryId.
+        """
+
         doc = client.binding.get(client.repositoryUrl, client.username, client.password, **client.extArgs)
         workspaceElements = doc.getElementsByTagNameNS(APP_NS, 'workspace')
 
@@ -237,6 +256,11 @@ class RepositoryService(RepositoryServic
         raise ObjectNotFoundException(url=client.repositoryUrl)
 
     def getRepositories(self, client):
+
+        """
+        Get all of the repositories provided by the server.
+        """
+
         result = client.binding.get(client.repositoryUrl, client.username, client.password, **client.extArgs)
 
         workspaceElements = result.getElementsByTagNameNS(APP_NS, 'workspace')
@@ -252,6 +276,11 @@ class RepositoryService(RepositoryServic
         return repositories
 
     def getDefaultRepository(self, client):
+
+        """
+        Returns the default repository for the server via the AtomPub binding.
+        """
+
         doc = client.binding.get(client.repositoryUrl, client.username, client.password, **client.extArgs)
         workspaceElements = doc.getElementsByTagNameNS(APP_NS, 'workspace')
         # instantiate a Repository object with the first workspace
@@ -605,15 +634,15 @@ class AtomPubCmisObject(CmisObject):
 
         # if we have a change token, we must pass it back, per the spec
         args = {}
-        if (self.properties.has_key('cmis:changeToken') and self.properties['cmis:changeToken'] is not None):
+        if self.properties.has_key('cmis:changeToken') and self.properties['cmis:changeToken'] is not None:
             self.logger.debug('Change token present, adding it to args')
             args = {"changeToken": self.properties['cmis:changeToken']}
 
         # the getEntryXmlDoc function may need the object type
         objectTypeId = None
-        if (self.properties.has_key('cmis:objectTypeId') and not properties.has_key('cmis:objectTypeId')):
+        if self.properties.has_key('cmis:objectTypeId') and not properties.has_key('cmis:objectTypeId'):
             objectTypeId = self.properties['cmis:objectTypeId']
-            self.logger.debug('This object type is:%s' % objectTypeId)
+            self.logger.debug('This object type is:%s', objectTypeId)
 
         # build the entry based on the properties provided
         xmlEntryDoc = getEntryXmlDoc(self._repository, objectTypeId, properties)
@@ -2520,7 +2549,7 @@ class AtomPubDocument(AtomPubCmisObject)
 
         # if we have a change token, we must pass it back, per the spec
         args = {}
-        if (self.properties.has_key('cmis:changeToken') and self.properties['cmis:changeToken'] is not None):
+        if self.properties.has_key('cmis:changeToken') and self.properties['cmis:changeToken'] is not None:
             self.logger.debug('Change token present, adding it to args')
             args = {"changeToken": self.properties['cmis:changeToken']}
 
@@ -2559,7 +2588,7 @@ class AtomPubDocument(AtomPubCmisObject)
 
         # if we have a change token, we must pass it back, per the spec
         args = {}
-        if (self.properties.has_key('cmis:changeToken') and self.properties['cmis:changeToken'] is not None):
+        if self.properties.has_key('cmis:changeToken') and self.properties['cmis:changeToken'] is not None:
             self.logger.debug('Change token present, adding it to args')
             args = {"changeToken": self.properties['cmis:changeToken']}
 
@@ -3432,7 +3461,7 @@ class AtomPubACL(ACL):
         """
 
         if self._entries.has_key(principalId):
-            del(self._entries[principalId])
+            del self._entries[principalId]
 
     def clearEntries(self):
 
@@ -3565,160 +3594,15 @@ class AtomPubACL(ACL):
 
 class AtomPubACE(ACE):
 
-    pass
-
-
-class AtomPubChangeEntry(ChangeEntry):
-
     """
-    Represents a change log entry. Retrieve a list of change entries via
-    :meth:`Repository.getContentChanges`.
-
-    >>> for changeEntry in rs:
-    ...     changeEntry.objectId
-    ...     changeEntry.id
-    ...     changeEntry.changeType
-    ...     changeEntry.changeTime
-    ...
-    'workspace://SpacesStore/0e2dc775-16b7-4634-9e54-2417a196829b'
-    u'urn:uuid:0e2dc775-16b7-4634-9e54-2417a196829b'
-    u'created'
-    datetime.datetime(2010, 2, 11, 12, 55, 14)
-    'workspace://SpacesStore/bd768f9f-99a7-4033-828d-5b13f96c6923'
-    u'urn:uuid:bd768f9f-99a7-4033-828d-5b13f96c6923'
-    u'updated'
-    datetime.datetime(2010, 2, 11, 12, 55, 13)
-    'workspace://SpacesStore/572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
-    u'urn:uuid:572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
-    u'updated'
+    Represents an ACE for the AtomPub binding.
     """
 
-    def __init__(self, cmisClient, repository, xmlDoc):
-        """Constructor"""
-        self._cmisClient = cmisClient
-        self._repository = repository
-        self._xmlDoc = xmlDoc
-        self._properties = {}
-        self._objectId = None
-        self._changeEntryId = None
-        self._changeType = None
-        self._changeTime = None
-        self.logger = logging.getLogger('cmislib.model.ChangeEntry')
-        self.logger.info('Creating an instance of ChangeEntry')
-
-    def getId(self):
-        """
-        Returns the unique ID of the change entry.
-        """
-        if self._changeEntryId is None:
-            self._changeEntryId = self._xmlDoc.getElementsByTagNameNS(ATOM_NS, 'id')[0].firstChild.data
-        return self._changeEntryId
-
-    def getObjectId(self):
-        """
-        Returns the object ID of the object that changed.
-        """
-        if self._objectId is None:
-            props = self.getProperties()
-            self._objectId = CmisId(props['cmis:objectId'])
-        return self._objectId
-
-    def getChangeType(self):
-
-        """
-        Returns the type of change that occurred. The resulting value must be
-        one of:
-
-         - created
-         - updated
-         - deleted
-         - security
-        """
-
-        if self._changeType is None:
-            self._changeType = self._xmlDoc.getElementsByTagNameNS(CMIS_NS, 'changeType')[0].firstChild.data
-        return self._changeType
-
-    def getACL(self):
-
-        """
-        Gets the :class:`ACL` object that is included with this Change Entry.
-        """
-
-        # if you call getContentChanges with includeACL=true, you will get a
-        # cmis:ACL entry. change entries don't appear to have a self URL so
-        # instead of doing a reload with includeACL set to true, we'll either
-        # see if the XML already has an ACL element and instantiate an ACL with
-        # it, or we'll get the ACL_REL link, invoke that, and return the result
-        if not self._repository.getCapabilities()['ACL']:
-            return
-        aclEls = self._xmlDoc.getElementsByTagNameNS(CMIS_NS, 'acl')
-        aclUrl = self._getLink(ACL_REL)
-        if len(aclEls) == 1:
-            return AtomPubACL(aceList=aclEls[0])
-        elif aclUrl:
-            result = self._cmisClient.binding.get(aclUrl.encode('utf-8'),
-                                                  self._cmisClient.username,
-                                                  self._cmisClient.password)
-            return AtomPubACL(xmlDoc=result)
-
-    def getChangeTime(self):
-
-        """
-        Returns a datetime object representing the time the change occurred.
-        """
-
-        if self._changeTime is None:
-            self._changeTime = self._xmlDoc.getElementsByTagNameNS(CMIS_NS, 'changeTime')[0].firstChild.data
-        return parseDateTimeValue(self._changeTime)
-
-    def getProperties(self):
-
-        """
-        Returns the properties of the change entry. Note that depending on the
-        capabilities of the repository ("capabilityChanges") the list may not
-        include the actual property values that changed.
-        """
-
-        if self._properties == {}:
-            propertiesElement = self._xmlDoc.getElementsByTagNameNS(CMIS_NS, 'properties')[0]
-            for node in [e for e in propertiesElement.childNodes if e.nodeType == e.ELEMENT_NODE]:
-                propertyName = node.attributes['propertyDefinitionId'].value
-                if node.childNodes and \
-                   node.getElementsByTagNameNS(CMIS_NS, 'value')[0] and \
-                   node.getElementsByTagNameNS(CMIS_NS, 'value')[0].childNodes:
-                    propertyValue = parsePropValue(
-                        node.getElementsByTagNameNS(CMIS_NS, 'value')[0].childNodes[0].data,
-                        node.localName)
-                else:
-                    propertyValue = None
-                self._properties[propertyName] = propertyValue
-        return self._properties
-
-    def _getLink(self, rel):
-
-        """
-        Returns the HREF attribute of an Atom link element for the
-        specified rel.
-        """
-
-        linkElements = self._xmlDoc.getElementsByTagNameNS(ATOM_NS, 'link')
-
-        for linkElement in linkElements:
-            if linkElement.attributes.has_key('rel'):
-                relAttr = linkElement.attributes['rel'].value
-
-                if relAttr == rel:
-                    return linkElement.attributes['href'].value
+    pass
 
-    id = property(getId)
-    objectId = property(getObjectId)
-    changeTime = property(getChangeTime)
-    changeType = property(getChangeType)
-    properties = property(getProperties)
 
+class AtomPubChangeEntry(ChangeEntry):
 
-class AtomPubChangeEntry(object):
     """
     Represents a change log entry. Retrieve a list of change entries via
     :meth:`Repository.getContentChanges`.
@@ -4099,18 +3983,18 @@ def getEntryXmlDoc(repo=None, objectType
 
         typeDef = None
         for propName, propValue in properties.items():
-            """
+            '''
             the name of the element here is significant: it includes the
             data type. I should be able to figure out the right type based
             on the actual type of the object passed in.
 
             I could do a lookup to the type definition, but that doesn't
             seem worth the performance hit
-            """
+            '''
             if propValue is None or (type(propValue) == list and propValue[0] is None):
                 # grab the prop type from the typeDef
                 if typeDef is None:
-                    moduleLogger.debug('Looking up type def for: %s' % objectTypeId)
+                    moduleLogger.debug('Looking up type def for: %s', objectTypeId)
                     typeDef = repo.getTypeDefinition(objectTypeId)
                     # TODO what to do if type not found
                 propType = typeDef.properties[propName].propertyType
@@ -4143,7 +4027,7 @@ def getElementNameAndValues(propType, pr
     """
 
     moduleLogger.debug('Inside getElementNameAndValues')
-    moduleLogger.debug('propType:%s propName:%s isList:%s' % (propType, propName, isList))
+    moduleLogger.debug('propType:%s propName:%s isList:%s', propType, propName, isList)
     if propType == 'id' or propType == CmisId:
         propElementName = 'cmis:propertyId'
         if isList:
@@ -4246,4 +4130,4 @@ def getEmptyXmlDoc():
     entryElement = entryXmlDoc.createElementNS(ATOM_NS, "entry")
     entryElement.setAttribute('xmlns', ATOM_NS)
     entryXmlDoc.appendChild(entryElement)
-    return entryXmlDoc
\ No newline at end of file
+    return entryXmlDoc

Modified: chemistry/cmislib/trunk/src/cmislib/browser/binding.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/trunk/src/cmislib/browser/binding.py?rev=1595949&r1=1595948&r2=1595949&view=diff
==============================================================================
--- chemistry/cmislib/trunk/src/cmislib/browser/binding.py (original)
+++ chemistry/cmislib/trunk/src/cmislib/browser/binding.py Mon May 19 16:24:46 2014
@@ -21,10 +21,11 @@ Module containing the browser binding-sp
 provider.
 """
 from cmislib.cmis_services import Binding, RepositoryServiceIfc
-from cmislib.domain import CmisId, CmisObject, Repository, Relationship, Policy, ObjectType, Property, Folder, Document, ACL, ACE, ChangeEntry, ResultSet, ChangeEntryResultSet, Rendition
-from cmislib.exceptions import CmisException, NotSupportedException, ObjectNotFoundException, RuntimeException
+from cmislib.domain import CmisId, CmisObject, ObjectType, ACL, ACE, ChangeEntry
+from cmislib.exceptions import CmisException, InvalidArgumentException,\
+                               NotSupportedException, ObjectNotFoundException
 from cmislib.net import RESTService as Rest
-from cmislib.util import parsePropValueByType, parseBoolValue
+from cmislib.util import parsePropValueByType
 import json
 import logging
 import StringIO
@@ -37,6 +38,13 @@ moduleLogger = logging.getLogger('cmisli
 
 
 class BrowserBinding(Binding):
+
+    """
+    Implements the Browser Binding to communicate with the CMIS server. The
+    Browser Binding uses only GET and POST. It sends JSON and HTML forms and
+    gets back JSON.
+    """
+
     def __init__(self, **kwargs):
         self.extArgs = kwargs
 
@@ -101,6 +109,11 @@ class BrowserBinding(Binding):
 
 
 class RepositoryService(RepositoryServiceIfc):
+
+    """
+    Defines the repository service for the Browser Binding.
+    """
+
     def getRepository(self, client, repositoryId):
         result = client.binding.get(client.repositoryUrl, client.username, client.password, **client.extArgs)
 
@@ -119,6 +132,13 @@ class RepositoryService(RepositoryServic
         return repositories
 
     def getDefaultRepository(self, client):
+
+        """
+        Gets the default repository for this server. The spec doesn't include
+        the notion of a default, so this just returns the first one in the
+        list.
+        """
+
         result = client.binding.get(client.repositoryUrl, client.username, client.password, **client.extArgs)
         # instantiate a Repository object with the first workspace
         # element we find
@@ -360,11 +380,7 @@ 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,
@@ -373,11 +389,11 @@ class BrowserCmisObject(object):
                  "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)
+        self._cmisClient.binding.post(moveUrl.encode('utf-8'),
+                                      urlencode(props),
+                                      'application/x-www-form-urlencoded',
+                                      self._cmisClient.username,
+                                      self._cmisClient.password)
 
         return
 
@@ -401,12 +417,12 @@ class BrowserCmisObject(object):
                  "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)
+        self._cmisClient.binding.post(delUrl.encode('utf-8'),
+                                      urlencode(props),
+                                      'application/x-www-form-urlencoded',
+                                      self._cmisClient.username,
+                                      self._cmisClient.password,
+                                      **kwargs)
 
         return
 
@@ -579,7 +595,6 @@ class BrowserRepository(object):
         self._repositoryName = None
         self._repositoryInfo = {}
         self._capabilities = {}
-        self._uriTemplates = {}
         self._permDefs = {}
         self._permMap = {}
         self._permissions = None
@@ -667,11 +682,17 @@ class BrowserRepository(object):
         return self._repositoryInfo
 
     def getRootFolderUrl(self):
+
+        """ Gets the repository's root folder URL """
+
         if self.data is None:
             self.reload()
         return self.data['rootFolderUrl']
 
     def getRepositoryUrl(self):
+
+        """ Gets the repository's URL """
+
         if self.data is None:
             self.reload()
         return self.data['repositoryUrl']
@@ -690,16 +711,6 @@ class BrowserRepository(object):
          - includeAllowableActions
         """
 
-        '''
-        if kwargs:
-            if self._extArgs:
-                self._extArgs.update(kwargs)
-            else:
-                self._extArgs = kwargs
-        '''
-        # 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,
@@ -926,8 +937,7 @@ class BrowserRepository(object):
         # return the result
         return types
 
-    def getTypeDescendants(self, typeId=None, **kwargs):
-
+    def getTypeDescendants(self, typeId=None, depth=None, **kwargs):
         """
         Returns a list of :class:`ObjectType` objects corresponding to the
         descendant types of the type specified by the typeId.
@@ -952,8 +962,10 @@ class BrowserRepository(object):
         F:app:glossary
         F:fm:topic
 
-        These optional arguments are supported:
+        This optional argument is supported:
          - depth
+
+        These optional arguments are supported:
          - includePropertyDefinitions
 
         >>> types = alfRepo.getTypeDescendants('cmis:folder')
@@ -967,7 +979,21 @@ class BrowserRepository(object):
         17
         """
 
-        pass
+        typesUrl = self.getRepositoryUrl() + "?cmisselector=typeDescendants"
+
+        if typeId is not None:
+            typesUrl += "&typeId=%s" % (quote(typeId))
+        if depth is not None:
+            typesUrl += "&depth=%s" % (depth)
+        print typesUrl
+
+        result = self._cmisClient.binding.get(typesUrl,
+                                              self._cmisClient.username,
+                                              self._cmisClient.password,
+                                              **kwargs)
+        serializer = TreeSerializer(treeType='type')
+        types = serializer.getEntries(self._cmisClient, self, result)
+        return types
 
     def getTypeDefinitions(self, **kwargs):
 
@@ -1654,11 +1680,11 @@ class BrowserDocument(BrowserCmisObject)
                  "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)
+        self._cmisClient.binding.post(coUrl.encode('utf-8'),
+                                      urlencode(props),
+                                      'application/x-www-form-urlencoded',
+                                      self._cmisClient.username,
+                                      self._cmisClient.password)
 
         return
 
@@ -1905,11 +1931,11 @@ class BrowserDocument(BrowserCmisObject)
             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)
+        self._cmisClient.binding.post(delUrl.encode('utf-8'),
+                                      urlencode(props),
+                                      'application/x-www-form-urlencoded',
+                                      self._cmisClient.username,
+                                      self._cmisClient.password)
 
         return
 
@@ -1962,8 +1988,7 @@ class BrowserDocument(BrowserCmisObject)
                                               self._cmisClient.password)
 
         paths = []
-        rs = self.getObjectParents()
-        # TODO why is the call to getObjectParents() made if it isn't used?
+
         for res in result:
             path = res['object']['properties']['cmis:path']['value']
             logging.debug(path)
@@ -2245,12 +2270,12 @@ class BrowserFolder(BrowserCmisObject):
                  "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)
+        self._cmisClient.binding.post(delUrl.encode('utf-8'),
+                                      urlencode(props),
+                                      'application/x-www-form-urlencoded',
+                                      self._cmisClient.username,
+                                      self._cmisClient.password,
+                                      **kwargs)
 
         return
 
@@ -2289,7 +2314,8 @@ class BrowserFolder(BrowserCmisObject):
                                                urlencode(props),
                                                'application/x-www-form-urlencoded',
                                                self._cmisClient.username,
-                                               self._cmisClient.password)
+                                               self._cmisClient.password,
+                                               **kwargs)
 
         return getSpecializedObject(BrowserCmisObject(self._cmisClient, self._repository, data=result))
 
@@ -2381,7 +2407,7 @@ class BrowserPolicy(CmisObject):
     pass
 
 
-class BrowserObjectType(object):
+class BrowserObjectType(ObjectType):
 
     """
     Represents the CMIS object type such as 'cmis:document' or 'cmis:folder'.
@@ -2684,6 +2710,11 @@ class BrowserACL(ACL):
         self.logger.info('Creating an instance of ACL')
 
     def _getEntriesFromData(self):
+
+        """
+        Internal method used to get the ACL entries from the fetched data.
+        """
+
         if not self._data:
             return
         result = {}
@@ -2726,7 +2757,7 @@ class BrowserACL(ACL):
         """
 
         if self._entries.has_key(principalId):
-            del(self._entries[principalId])
+            del self._entries[principalId]
 
     def clearEntries(self):
 
@@ -2747,7 +2778,7 @@ class BrowserACL(ACL):
         """
 
         self._entries.clear()
-        self.results = None
+        self._data = None
 
     def getEntries(self):
 
@@ -2783,10 +2814,14 @@ class BrowserACL(ACL):
 
 class BrowserACE(ACE):
 
+    """
+    Represents an ACE retrieved with the Browser Binding.
+    """
+
     pass
 
 
-class BrowserChangeEntry(object):
+class BrowserChangeEntry(ChangeEntry):
 
     """
     Represents a change log entry. Retrieve a list of change entries via
@@ -2872,7 +2907,7 @@ class BrowserChangeEntry(object):
     properties = property(getProperties)
 
 
-class BrowserChangeEntryResultSet(ResultSet):
+class BrowserChangeEntryResultSet(BrowserResultSet):
 
     """
     A specialized type of :class:`ResultSet` that knows how to instantiate
@@ -3015,7 +3050,7 @@ def getSpecializedObject(obj, **kwargs):
     return obj
 
 
-def encode_multipart_formdata(fields, file, contentType):
+def encode_multipart_formdata(fields, contentFile, contentType):
     """
     fields is a sequence of (name, value) elements for regular form fields.
     files is a sequence of (name, filename, value) elements for data to be uploaded as files
@@ -3027,7 +3062,7 @@ def encode_multipart_formdata(fields, fi
     fileName = None
     if fields:
         for (key, value) in fields.iteritems():
-            if (key == 'cmis:name'):
+            if key == 'cmis:name':
                 fileName = value
             L.append('--' + boundary)
             L.append('Content-Disposition: form-data; name="%s"' % key)
@@ -3035,13 +3070,13 @@ def encode_multipart_formdata(fields, fi
             L.append('')
             L.append(value.encode('utf-8'))
 
-    if file:
+    if contentFile:
         L.append('--' + boundary)
         L.append('Content-Disposition: form-data; name="%s"; filename=%s' % ('content', fileName))
         L.append('Content-Type: %s' % contentType)
         L.append('Content-Transfer-Encoding: binary')
         L.append('')
-        L.append(file.read())
+        L.append(contentFile.read())
 
     L.append('--' + boundary + '--')
     L.append('')
@@ -3051,7 +3086,13 @@ def encode_multipart_formdata(fields, fi
 
 
 class ResultsSerializer(object):
+
+    """
+    Responsible for serializing :class:`BrowserResultSet` objects.
+    """
+
     def fromJSON(self, client, repo, jsonObj):
+        """Transforms from JSON to the object."""
         entries = []
         for obj in jsonObj['results']:
             cmisObject = getSpecializedObject(BrowserCmisObject(client,
@@ -3063,7 +3104,13 @@ class ResultsSerializer(object):
 
 
 class ChildrenSerializer(object):
+
+    """
+    Responsible for serializing lists of children.
+    """
+
     def fromJSON(self, client, repo, jsonObj):
+        """Transforms from JSON to the object."""
         entries = []
         for obj in jsonObj['objects']:
             dataObj = obj['object']
@@ -3076,7 +3123,13 @@ class ChildrenSerializer(object):
 
 
 class VersionsSerializer(object):
+
+    """
+    Responsible for serializing a list of versions.
+    """
+
     def fromJSON(self, client, repo, jsonObj):
+        """Transforms from JSON to the object."""
         entries = []
         for obj in jsonObj['objects']:
             cmisObject = getSpecializedObject(BrowserCmisObject(client,
@@ -3087,25 +3140,39 @@ class VersionsSerializer(object):
         return entries
 
 
+# TODO Preserve tree hierarchy
 class TreeSerializer(object):
-    '''
+
+    """
     The AtomPubBinding may be returning descendants and trees as a flat list of results.
     We should probably implement a Tree result set and return that here instead.
-    '''
+    """
+
+    def __init__(self, treeType='object'):
+        self.treeType = treeType
+
     def fromJSON(self, client, repo, jsonObj):
+        """Transforms from JSON to the object."""
         entries = self.getEntries(client, repo, jsonObj)
 
         return entries
 
     def getEntries(self, client, repo, jsonObj):
+        '''obj is the list of items in the tree'''
         entries = []
         for obj in jsonObj:
-            dataObj = obj['object']['object']
-            cmisObject = getSpecializedObject(BrowserCmisObject(client,
-                                                                repo,
-                                                                data=dataObj))
-            entries.append(cmisObject)
+            if self.treeType == 'object':
+                dataObj = obj['object']['object']
+                cmisThing = getSpecializedObject(BrowserCmisObject(client,
+                                                                   repo,
+                                                                   data=dataObj))
+            elif self.treeType == 'type':
+                dataObj = obj['type']
+                cmisThing = BrowserObjectType(client, repo, data=dataObj)
+            else:
+                raise CmisException("Invalid tree type")
 
+            entries.append(cmisThing)
             try:
                 dataObj = obj['children']
                 # if obj['object'].has_key('children'):
@@ -3119,7 +3186,13 @@ class TreeSerializer(object):
 
 
 class FolderSerializer(object):
+
+    """
+    Responsible for serializing :class:`Folder` objects.
+    """
+
     def fromJSON(self, client, repo, jsonString):
+        """Transforms the folder from JSON to an object."""
         obj = json.loads(jsonString)
         objectId = obj['succinctProperties']['cmis:objectId']
         folder = BrowserFolder(client, repo, objectId, properties=obj['succinctProperties'])
@@ -3127,7 +3200,13 @@ class FolderSerializer(object):
 
 
 class ACLSerializer(object):
+
+    """
+    Responsible for serializing :class:`BrowserACL` objects.
+    """
+
     def toJSON(self, acl):
+        """ Transforms the ACL to JSON. """
         entries = acl.getEntries()
         aces = []
         for key in entries:
@@ -3137,4 +3216,4 @@ class ACLSerializer(object):
             entryJSON['permissions'] = entries[key].permissions
             aces.append(entryJSON)
 
-        return json.dumps(aces)
\ No newline at end of file
+        return json.dumps(aces)

Modified: chemistry/cmislib/trunk/src/cmislib/cmis_services.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/trunk/src/cmislib/cmis_services.py?rev=1595949&r1=1595948&r2=1595949&view=diff
==============================================================================
--- chemistry/cmislib/trunk/src/cmislib/cmis_services.py (original)
+++ chemistry/cmislib/trunk/src/cmislib/cmis_services.py Mon May 19 16:24:46 2014
@@ -16,6 +16,7 @@
 #      specific language governing permissions and limitations
 #      under the License.
 #
+
 """
 Module containing the base Binding class and other service objects.
 """
@@ -26,7 +27,17 @@ from cmislib.exceptions import CmisExcep
 
 
 class Binding(object):
+
+    """
+    Represents the binding used to communicate with the CMIS server.
+    """
+
     def getRepositoryService(self):
+
+        """
+        Returns the repository service specific to this binding.
+        """
+
         pass
 
     def _processCommonErrors(self, error, url):
@@ -56,8 +67,23 @@ class Binding(object):
 
 
 class RepositoryServiceIfc(object):
+
+    """
+    Defines the interface for the repository service.
+    """
+
     def getRepositories(self, client):
+
+        """
+        Returns a list of repositories for this server.
+        """
+
         pass
 
     def getRepositoryInfo(self):
+
+        """
+        Returns the repository information for this server.
+        """
+
         pass

Modified: chemistry/cmislib/trunk/src/cmislib/exceptions.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/trunk/src/cmislib/exceptions.py?rev=1595949&r1=1595948&r2=1595949&view=diff
==============================================================================
--- chemistry/cmislib/trunk/src/cmislib/exceptions.py (original)
+++ chemistry/cmislib/trunk/src/cmislib/exceptions.py Mon May 19 16:24:46 2014
@@ -17,7 +17,9 @@
 #      under the License.
 #
 
-
+"""
+Module containing exceptions.
+"""
 class CmisException(Exception):
 
     """

Modified: chemistry/cmislib/trunk/src/cmislib/messages.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/trunk/src/cmislib/messages.py?rev=1595949&r1=1595948&r2=1595949&view=diff
==============================================================================
--- chemistry/cmislib/trunk/src/cmislib/messages.py (original)
+++ chemistry/cmislib/trunk/src/cmislib/messages.py Mon May 19 16:24:46 2014
@@ -17,5 +17,8 @@
 #      under the License.
 #
 
+"""
+Common strings.
+"""
 NO_ACL_SUPPORT = 'This repository does not support ACLs'
 NO_CHANGE_LOG_SUPPORT = 'This repository does not support change logs'

Modified: chemistry/cmislib/trunk/src/cmislib/model.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/trunk/src/cmislib/model.py?rev=1595949&r1=1595948&r2=1595949&view=diff
==============================================================================
--- chemistry/cmislib/trunk/src/cmislib/model.py (original)
+++ chemistry/cmislib/trunk/src/cmislib/model.py Mon May 19 16:24:46 2014
@@ -23,8 +23,8 @@ really appropriate, but it is kept for b
 """
 import logging
 
-from atompub.binding import AtomPubBinding
-from cmis_services import Binding
+from cmislib.atompub.binding import AtomPubBinding
+from cmislib.cmis_services import Binding
 
 
 moduleLogger = logging.getLogger('cmislib.model')
@@ -101,4 +101,4 @@ class CmisClient(object):
         return self.binding.getRepositoryService().getDefaultRepository(self)
 
     defaultRepository = property(getDefaultRepository)
-    repositories = property(getRepositories)
\ No newline at end of file
+    repositories = property(getRepositories)

Modified: chemistry/cmislib/trunk/src/cmislib/net.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/trunk/src/cmislib/net.py?rev=1595949&r1=1595948&r2=1595949&view=diff
==============================================================================
--- chemistry/cmislib/trunk/src/cmislib/net.py (original)
+++ chemistry/cmislib/trunk/src/cmislib/net.py Mon May 19 16:24:46 2014
@@ -50,8 +50,8 @@ class RESTService(object):
         if kwargs:
             if 'headers' in kwargs:
                 headers = kwargs['headers']
-                del(kwargs['headers'])
-                self.logger.debug('Headers passed in:%s' % headers)
+                del kwargs['headers']
+                self.logger.debug('Headers passed in:' + headers)
             if url.find('?') >= 0:
                 url = url + '&' + urlencode(kwargs)
             else:
@@ -73,8 +73,8 @@ class RESTService(object):
         if kwargs:
             if 'headers' in kwargs:
                 headers = kwargs['headers']
-                del(kwargs['headers'])
-                self.logger.debug('Headers passed in:%s' % headers)
+                del kwargs['headers']
+                self.logger.debug('Headers passed in:' + headers)
             if url.find('?') >= 0:
                 url = url + '&' + urlencode(kwargs)
             else:
@@ -106,8 +106,8 @@ class RESTService(object):
         if kwargs:
             if 'headers' in kwargs:
                 headers = kwargs['headers']
-                del(kwargs['headers'])
-                self.logger.debug('Headers passed in:%s' % headers)
+                del kwargs['headers']
+                self.logger.debug('Headers passed in:' + headers)
             if url.find('?') >= 0:
                 url = url + '&' + urlencode(kwargs)
             else:
@@ -140,8 +140,8 @@ class RESTService(object):
         if kwargs:
             if 'headers' in kwargs:
                 headers = kwargs['headers']
-                del(kwargs['headers'])
-                self.logger.debug('Headers passed in:%s' % headers)
+                del kwargs['headers']
+                self.logger.debug('Headers passed in:' + headers)
             if url.find('?') >= 0:
                 url = url + '&' + urlencode(kwargs)
             else:

Modified: chemistry/cmislib/trunk/src/cmislib/util.py
URL: http://svn.apache.org/viewvc/chemistry/cmislib/trunk/src/cmislib/util.py?rev=1595949&r1=1595948&r2=1595949&view=diff
==============================================================================
--- chemistry/cmislib/trunk/src/cmislib/util.py (original)
+++ chemistry/cmislib/trunk/src/cmislib/util.py Mon May 19 16:24:46 2014
@@ -23,7 +23,7 @@ import re
 import iso8601
 import logging
 import datetime
-from cmislib.domain import CmisId, Document, Folder
+from cmislib.domain import CmisId
 
 moduleLogger = logging.getLogger('cmislib.util')
 
@@ -79,7 +79,7 @@ def parsePropValueByType(value, typeName
     node's property definition.
     """
 
-    moduleLogger.debug('Inside parsePropValueByType: %s: %s' % (typeName, value))
+    moduleLogger.debug('Inside parsePropValueByType: %s: %s', typeName, value)
 
     if typeName == 'id':
         if value:
@@ -161,4 +161,4 @@ def toCMISValue(value):
     elif value is None:
         return 'none'
     else:
-        return value
\ No newline at end of file
+        return value