Exemple #1
0
 def __init__(self, env):
     self.env = env
     self.xmldb = XmlDbManager(env.db)
     self.index_catalog = XmlIndexCatalog(env.db, self.xmldb)
     self.index_catalog.env = env
Exemple #2
0
class XmlCatalog(object):
    """
    The catalog object.
    
    Use this class to manage all indexes and resources.
    """
    def __init__(self, env):
        self.env = env
        self.xmldb = XmlDbManager(env.db)
        self.index_catalog = XmlIndexCatalog(env.db, self.xmldb)
        self.index_catalog.env = env

    def addResource(self, package_id, resourcetype_id, xml_data, uid=None,
                    name=None):
        """
        Add a new resource to the database.
        
        @param package_id: package id
        @param resourcetype_id: resourcetype id
        @param xml_data: xml data
        @param uid: user id of creator
        @param name: optional resource name, defaults to unique integer id
        @return: Resource object
        """
        _, resourcetype = self.env.registry.objects_from_id(package_id,
                                                            resourcetype_id)
        res = Resource(resourcetype,
                       document=newXMLDocument(xml_data, uid=uid),
                       name=name)
        # get xml_doc to ensure the document is parsed
        res.document.xml_doc
        self.validateResource(res)
        self.xmldb.addResource(res)
        self.index_catalog.indexResource(res)
        return res

    def renameResource(self, resource, new_name):
        """
        Rename a given Resource object.
        """
        self.xmldb.renameResource(resource, new_name)

    def modifyResource(self, resource, xml_data, uid=None):
        """
        Modify the XML document of an already existing resource.
        
        In case of a version controlled resource a new revision is created.
        """
        new_resource = Resource(resourcetype=resource.resourcetype,
                                document=newXMLDocument(xml_data),
                                name=resource.name)
        self.validateResource(new_resource)
        self.xmldb.modifyResource(resource, new_resource, uid)
        # we only keep indexes for the newest revision
        self.index_catalog.flushResource(resource)
        self.index_catalog.indexResource(new_resource)

    def deleteResource(self, resource=None, resource_id=None):
        """
        Remove a resource from the database.
        """
        if resource_id:
            resource = self.xmldb.getResource(id=resource_id)
        # create backup entry into the global trash folder
        if self.env.config.getbool('seishub', 'use_trash_folder', False):
            data = resource.document.data
            # ensure we return a UTF-8 encoded string not an Unicode object 
            if isinstance(data, unicode):
                data = data.encode('utf-8')
            # set XML declaration inclusive UTF-8 encoding string 
            if not data.startswith('<xml'):
                data = addXMLDeclaration(data, 'utf-8')
            path = os.path.join(self.env.getInstancePath(), 'data', 'trash',
                                resource.package.package_id,
                                resource.resourcetype.resourcetype_id)
            if not os.path.exists(path):
                os.makedirs(path)
            # add current datetime to filename to prevent overwriting resources
            # with the same filename (e.g. resource deleted/created several
            # times)
            filename = resource.name
            filename += datetime.datetime.now().strftime('__%Y%m%d%H%M%S')
            file = os.path.join(path, filename)
            try:
                fp = open(file, 'wb')
                fp.write(data)
                fp.close()
            except:
                pass
        # remove indexed data:
        self.index_catalog.flushResource(resource)
        res = self.xmldb.deleteResource(resource)
        if not res:
            msg = "Error deleting a resource: No resource was found with " + \
                  "the given parameters."
            raise NotFoundError(msg)
        return res

    def deleteAllResources(self, package_id, resourcetype_id=None):
        """
        Remove all resources of specified package_id and resourcetype_id.
        """
        return self.xmldb.deleteAllResources(package_id, resourcetype_id)

    def getResource(self, package_id=None, resourcetype_id=None,
                    name=None, revision=None, document_id=None,
                    id=None):
        """
        Get a specific resource from the database.
        
        @param package_id: resourcetype id
        @param: resourcetype_id: package id
        @param name: Name of the resource
        @param revision: revision of related document (if no revision is given,
            newest revision is used, to retrieve all revisions of a document  
            use getRevisions()
        """
        return self.xmldb.getResource(package_id=package_id,
                                      resourcetype_id=resourcetype_id,
                                      name=name,
                                      revision=revision,
                                      document_id=document_id,
                                      id=id)

    def getRevisions(self, package_id, resourcetype_id, name):
        """
        Get all revisions of the specified resource.
        
        The Resource instance returned will contain a list of documents sorted 
        by revision (accessible as usual via Resource.document).
        Note: In case a resource does not provide multiple revisions, this is 
        the same as a call to XmlCatalog.getResource(...).
        
        @param package_id: package id
        @param resourcetype_id: resourcetype id
        @param name: name of the resource
        @return: Resource object
        """
        return self.xmldb.getRevisions(package_id, resourcetype_id, name)

    def getAllResources(self, package_id=None, resourcetype_id=None):
        """
        Get a list of resources for specified package and resourcetype.
        """
        return self.xmldb.getAllResources(package_id, resourcetype_id)
#    
#    def revertResource(self, package_id, resourcetype_id, name, revision):
#        """
#        Reverts the specified revision for the given resource.
#        
#        All revisions newer than the specified one will be removed.
#        """
#        return self.xmldb.revertResource(package_id, resourcetype_id, name, 
#                                         revision)

    def validateResource(self, resource):
        """
        Do a schema validation of a given resource.
        
        This validates against all schemas of the corresponding resourcetype.
        """
        pid = resource.package.package_id
        rid = resource.resourcetype.resourcetype_id
        schemas = self.env.registry.schemas.get(pid, rid)
        for schema in schemas:
            try:
                schema.validate(resource)
            except Exception, e:
                msg = "Resource-validation against schema '%s' failed. (%s)"
                raise InvalidObjectError(msg % (str(schema.getResource().name),
                                                str(e)))