Viewing file: ResourceMetaDataClient.py (28.18 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
######################################################################## # $Header: /var/local/cvsroot/4Suite/Ft/Server/Client/Core/ResourceMetaDataClient.py,v 1.32 2005/03/28 11:27:38 mbrown Exp $ """ ResourceMetaData repository resource client class.
Copyright 2005 Fourthought, Inc. (USA). Detailed license and copyright information: http://4suite.org/COPYRIGHT Project home, documentation, distributions: http://4suite.org/ """
from Ft.Lib import Time as FtTime from Ft.Xml import XUpdate, InputSource from Ft.Server.Common import ResourceTypes, Schema from Ft.Server.Common import AclConstants, DocumentReference from Ft.Server.Client import FtServerClientException from Ft.Server.FtRpc import Commands
import ModelClient
class ResourceMetaDataClient: """ Every repository resource inherits from this class in order to store and provide access to information about its existence. """ def __init__(self, path, connection, resourceType, root): self._path = path self._connection = connection self.resourceType = resourceType self._root = root
#Cache some things self._basePath = None self._displayPath = None self._absolutePath = None self._absolutePathAsUri = None self._name = None self._creationDate = None return
############################################### #General interfaces for getting information about the object ############################################### def getPath(self): """ Get the path of this resource """ return self._path
def getBasePath(self): """ Get the base path of this object. The only difference between this and getPath is that for all non-container objects it will return the parent's path. For a container object it will return its path. """ if self._basePath is None: self._basePath = Commands.RemoteMethodCommand('getBasePath', self._path, () ).send(self._connection).results return self._basePath
def getDisplayPath(self): """ Get the path relative to the document root """ if self._displayPath is None: self._displayPath = Commands.RemoteMethodCommand('getDisplayPath', self._path, () ).send(self._connection).results return self._displayPath
def getAbsolutePath(self): """ Get the full path into the system """ if self._absolutePath is None: self._absolutePath = Commands.RemoteMethodCommand('getAbsolutePath', self._path, () ).send(self._connection).results return self._absolutePath
def getAbsolutePathAsUri(self): """ Get the full path into the system, as an absolute URI string. """ if self._absolutePathAsUri is None: self._absolutePathAsUri = Commands.RemoteMethodCommand('getAbsolutePathAsUri', self._path, () ).send(self._connection).results return self._absolutePathAsUri
def getName(self): """ Get the name of the resource. """ if self._name is None: self._name = Commands.RemoteMethodCommand('getName', self._path, () ).send(self._connection).results return self._name
def getCreationDate(self): """ Get the date that this resource was created. The date will be an ISO 8601 string like u'2002-08-16T22:49:56Z'. """ if self._creationDate is None: self._creationDate = Commands.RemoteMethodCommand('getCreationDate', self._path, () ).send(self._connection).results return self._creationDate
def getLastModifiedDate(self): """ Get the date that this resource was last modified. The date will be an ISO 8601 string like u'2002-08-16T22:49:56Z'. """ return Commands.RemoteMethodCommand('getLastModifiedDate', self._path, () ).send(self._connection).results
def getSize(self): """ Get the size of the content """ return Commands.RemoteMethodCommand('getSize', self._path, () ).send(self._connection).results
def getResourceType(self): """ Get the type of this resource. Types are defined in Ft.Server.Common.ResourceTypes.ResourceType. """ return self.resourceType
def isResourceType(self, testType): """ Determine if this resource is of a certain type """ return ResourceTypes._IsResourceType(self.getResourceType(), testType)
def getContent(self): """ Get the string content of this resource """ return Commands.RemoteMethodCommand('getContent', self._path, () ).send(self._connection).results
def getContentSlice(self, start=None, end=None): """ Get a piece of our content. Really only makes sense for large raw files """ return Commands.RemoteMethodCommand('getContentSlice', self._path, (start, end) ).send(self._connection).results
def getMetaDataResource(self): """ Get the string meta data of this resource """ return self
def getContentResource(self): """ Get the resource the represents the content of this object """ return self.fetchResource('.;content')
def getImt(self): """ Returns the Internet Media Type of the raw file resource """ return Commands.RemoteMethodCommand('getImt', self._path, () ).send(self._connection).results
def getValidationInfo(self): """ Get the validation information associated with this resource. """ return Commands.RemoteMethodCommand('getValidationInfo', self._path, () ).send(self._connection).results
def getParent(self): """ Get the parent container of this resource """ path = Commands.RemoteMethodCommand('getParent', self._path, () ).send(self._connection).results if path: return self.fetchResource(path) else: return path
def getRoot(self): """ Get a reference to the system repository """ return self._root
def getAliases(self): """ Get a list of alias objects that reference this object """ return Commands.RemoteMethodCommand('getAliases', self._path, () ).send(self._connection).results
##################################### #ACL Interfaces ##################################### def addAcl(self, aclKey, aclIdent, allowed=1): """ Add an acl identifier to the acl key. If the specified key does not exist on the resource this function has the same functionality of setAcl. """ acl = self.getAcl(aclKey).items() acl.append((aclIdent, allowed and AclConstants.ALLOWED or AclConstants.DENIED)) Commands.RemoteMethodCommand('addAcl', self._path, (aclKey, aclIdent, allowed) ).send(self._connection).results
def getAcl(self, aclKey=None): """ Get a list of users and groups specified by the aclKey. If an aclKey is specified, then the results will be a list of dictionaries keyed by acl identifiers and with values of ALLOWED or DISALLOWED (from AclConstants). The values in the list of dictionaries could be inherited from the parent object. If no aclKey is specified, then the results will be a nested dictionary. The outer dictionary is keyed by all of the defined acl keys on this resource. Each value of the outer dictionary will be a dictionary identical to when this method is called with a aclKey. These results will not return any inherited values. """ return Commands.RemoteMethodCommand('getAcl', self._path, (aclKey,) ).send(self._connection).results
def getAclIdentifiers(self): """ Get a list of all acl identifiers for the current users. This is equivalent to performing an "expandGroups" of the current user. It will also add things such as "WORLD-GROUP" or "USER-GROUP" if they exist. """ return Commands.RemoteMethodCommand('getAclIdentifiers', self._path, () ).send(self._connection).results
def getAclIdent(self): """ Get the ACL identifier for the current user (without expansion). """ return Commands.RemoteMethodCommand('getAclIdent', self._path, () ).send(self._connection).results
def inheritAcl(self, aclKey): """ Remove the entire key from the ACL entry so that it is inherited again from its parent """ Commands.RemoteMethodCommand('inheritAcl', self._path, (aclKey,) ).send(self._connection).results
def removeAcl(self, aclKey, aclIdent): """ Remove the acl identifier from the acl key. If the specified aclKey is not present on the resource or the specified aclIdent is not in the key, then do nothing. Remember that entries inherited from the parent are *not* included in the acl on the actual resurce. In order to override inherited permissions, set to no access rather than trying to remove. """ Commands.RemoteMethodCommand('removeAcl', self._path, (aclKey, aclIdent) ).send(self._connection).results
def setAcl(self,aclKey,aclIdent,allowed=1): """ Replace the aclKey with a single entry of aclIdent. """ Commands.RemoteMethodCommand('setAcl', self._path, (aclKey, aclIdent, allowed) ).send(self._connection).results
def verifyAcl(self, aclKey, verifyTraverse=1): """ Test to see whether the current user (and the current users set of acl identifiers) is allowed to perform the specified action, aclKey, on the current object. If verifyTraverse is specified, then execute premissions are tested on all of the parents of this resource as well. """ return Commands.RemoteMethodCommand('verifyAcl', self._path, (aclKey, verifyTraverse) ).send(self._connection).results def getOwner(self): """ Get the owner of this resource """ path = Commands.RemoteMethodCommand('getOwner', self._path, () ).send(self._connection).results if path: return self.fetchResource(path) else: return path
def setOwner(self, newOwner): """ Change the owner of this resource """ return Commands.RemoteMethodCommand('setOwner', self._path, ((None,newOwner.getAbsolutePath()),) ).send(self._connection).results
########################################## #XML Interfaces ##########################################
def applyXslt(self, chain, params=None, ignorePis=1, extParams=None, extModules=None): """ applies the specified chain of stylesheets (with the specified transformation parameters) using the "self" object as source chain - can be a list of transforms, in which case only one transform run will execute, with the list of transforms all used such that [a.xsl, b.xsl] is equivalent to adding an import of b.xsl to a.xsl and applying a.xsl can also be a list of lists of transforms, in which case a chain of transforms is run, one pass for each inner list. The output of each step in the chain is fed as the input to the next params - a dictionary giving the overridden top-level parameters for the transforms ignorePis - whether or not to ignore <xml-stylesheet processing instructions in the source document extParams - a special dictionary of parameters that allows the processor to communicate special values back to the caller extModules - a list of modules containing extension function and element implementations """ if chain and isinstance(chain[0], (list, tuple)): chain = [ [ DocumentReference.InternalDocumentReference(j.getPath()) for j in i ] for i in chain ] else: chain = [ DocumentReference.InternalDocumentReference(i.getPath()) for i in chain ] return Commands.RemoteMethodCommand( 'applyXslt', self._path, (chain, params, ignorePis, extParams, extModules) ).send(self._connection).results
def asDom(self, stripElements=None): """ Return this object as a non-live DOM instance. This means that any mutations to the returned DOM object will not affect the content of this resource. """ from Ft.Xml import ReaderException, Domlette try: reader = Domlette.NonvalidatingReader comp = reader.parseString(self.getContent(), self._path) return comp except ReaderException, e: raise raise FtServerClientException(Error.XML_PARSE_EXCEPTION, message = e.params[0], lineNum = e.params[1], colNum = e.params[2])
def toXPathContext(self, nss=None): """ Create an XPath Context with the src of this RawFile. nss is a dictionary of namespace definitions to include in the context. """ reader, dom = self.asReadonlyDom() processorNss = {'ftss':FTSERVER_NAMESPACE, 'xlink':XLINK_NAMESPACE} if nss: processorNss.update(nss) return reader, dom, Context.Context(dom, processorNss=processorNss)
def xUpdate(self, updateSrc): """ Allows XML content to be updated with the XUpdate protocol """ return Commands.RemoteMethodCommand('xUpdate', self._path, (updateSrc,) ).send(self._connection).results
##################################### #Query Interfaces ##################################### def hasResource(self, path): """ Query if the system has a resource specified by the path. No exception will be raised by this function. If the current user cannot access the resource or the resource does not exist in the repository, then the results will be 0. If the resource does exist, then the results will be the integer resource type of the resource (see Ft.Server.Common.ResourceTypes.ResourceTypes). """ return Commands.RemoteMethodCommand('hasResource', self._path, (path,) ).send(self._connection).results
##################################### #Retrieval Interfaces ##################################### def fetchResource(self, path): """ Fetch a resource from the system. path is a string. The traverseAliases parameter is deprecated and the new ";traverse" path arguments should be used. As an example, where before you could call: resource.fetchResource('path', 1) now you would call resource.fetchResource('path;traverse') """ rsp = Commands.ResourceTypeCommand( path=path, baseObject=self._path).send(self._connection) path = rsp.path rt = rsp.resourceType
#Very few specializations client side if rt == ResourceTypes.ResourceType.CONTAINER: if path == '/': return self._root import ContainerClient obj = ContainerClient.ContainerClient(path, self._connection, rt, self._root) elif rt == ResourceTypes.ResourceType.XSLT_DOCUMENT_DEFINITION: import XsltDocumentDefinitionClient obj = XsltDocumentDefinitionClient.XsltDocumentDefinitionClient( path, self._connection, rt, self._root ) elif rt == ResourceTypes.ResourceType.XPATH_DOCUMENT_DEFINITION: import XPathDocumentDefinitionClient obj = XPathDocumentDefinitionClient.XPathDocumentDefinitionClient( path, self._connection, rt, self._root ) elif rt == ResourceTypes.ResourceType.USER: import UserClient obj = UserClient.UserClient(path, self._connection, rt, self._root) elif rt == ResourceTypes.ResourceType.META_DATA: import ResourceMetaDataClient obj = ResourceMetaDataClient.ResourceMetaDataClient( path, self._connection, rt, self._root ) elif rt == ResourceTypes.ResourceType.GROUP: import GroupClient obj = GroupClient.GroupClient( path, self._connection, rt, self._root ) elif rt == ResourceTypes.ResourceType.ALIAS: import AliasClient obj = AliasClient.AliasClient( path, self._connection, rt, self._root ) elif rt == ResourceTypes.ResourceType.COMMAND: import CommandClient obj = CommandClient.CommandClient( path, self._connection, rt, self._root ) elif rt == ResourceTypes.ResourceType.XSLT_DOCUMENT: import XsltDocumentClient obj = XsltDocumentClient.XsltDocumentClient( path, self._connection, rt, self._root ) elif rt == ResourceTypes.ResourceType.XML_DOCUMENT: import XmlDocumentClient obj = XmlDocumentClient.XmlDocumentClient( path, self._connection, rt, self._root ) elif rt == ResourceTypes.ResourceType.RAW_FILE: import RawFileClient obj = RawFileClient.RawFileClient( path, self._connection, rt, self._root ) elif rt == ResourceTypes.ResourceType.URI_REFERENCE_FILE: import UriReferenceFileClient obj = UriReferenceFileClient.UriReferenceFileClient( path, self._connection, rt, self._root ) elif rt == ResourceTypes.ResourceType.RDF_DOCUMENT: import RdfDocumentClient obj = RdfDocumentClient.RdfDocumentClient( path, self._connection, rt, self._root ) elif rt == ResourceTypes.ResourceType.SERVER: import ServerClient obj = ServerClient.ServerClient( path, self._connection, rt, self._root ) else: raise FtServerClientException(Error.UNKNOWN_RESOURCE_TYPE, type=rt) return obj
########################################## #Mutation Interfaces ########################################## def setContent(self, src): """ Set the string content of this resource """ return Commands.RemoteMethodCommand('setContent', self._path, (src,) ).send(self._connection).results
def delete(self): """ Delete this object from the repository """ return Commands.RemoteMethodCommand('delete', self._path, () ).send(self._connection).results
################################### #Creation Interfaces ################################### def addAlias(self, path, docDef = None): """ Adds an alias for this resource to the repository. """ path = Commands.RemoteMethodCommand('addAlias', self._path, (path, docDef) ).send(self._connection).results return self.fetchResource(path)
###################################### #Delete Interface ###################################### def removeAlias(self, path): """ Removes the specified alias for this resource """ raise NotImplementedError("removeAlias")
######################################## #RDF Interfaces ########################################
def getModel(self): """ Retrieves the common model associated w/ the repository """ return ModelClient.ModelClient(self._connection, self._path)
def addLiteralProperty(self, predicate, object, scope='', statementUri = ''): """ Adds a statement about this repository object, with a literal property, to the model """ raise NotImplementedError("addLiteralProperty")
def addResourceProperty(self, predicate, object, scope='', statementUri=''): """ Adds a statement about this repository object, with a resource property, to the model """
raise NotImplementedError("addResourceProperty")
def removeResourceProperty(self, predicate, object): """ Remove a statement about this repository object, with a resource preoperty, from the model """ raise NotImplementedError("removeResourceProperty")
def removeLiteralProperty(self, predicate, object): """ Removes a statement about this repository object, with a literal property, from the model """ raise NotImplementedError("rmeoveLiteralProperty")
def getStatementsAbout(self): """ Returns all statements about this object in the model """ raise NotImplementedError("getStatementsAbout")
def getStatementsGeneratedBy(self): """ Returns all statements in the model generated by this object """ raise NotImplementedError("getStatementsGeneratedBy")
######################################## #Temporary file Interfaces ######################################## def markTemporary(self, timeToLive): """ Mark this resource as temporary. Temporary objects will be removed from the repository when thier timeToLive has expired and purgeTemporaryResources is called the repository. Time to live is seconds from now. """ raise NotImplementedError("markTemporary")
########################################## #String interfaces ########################################## def __str__(self): return "<%s at %x path='%s'>" % (ResourceTypes.g_resourceTypeMap[self.getResourceType()], id(self), self.getAbsolutePath()) def __cmp__(self, other): if isinstance(other, self.__class__): return cmp(other.getPath(), self.getPath()) return -1
def __hash__(self): return id(self)
def pprint(self): print "Resource: %s" % self.getPath() print "Resource Type: %s" % Schema.g_rdfResourceTypes[self.resourceType] print "Creation Date: %s" % FtTime.FromISO8601(self.getCreationDate()).asRFC822DateTime(local=1) print "Modified Date: %s" % FtTime.FromISO8601(self.getLastModifiedDate()).asRFC822DateTime(local=1) print "Internet Media Type: %s" % self.getImt() print "Size: %s" % self.getSize() owner = self.getOwner() if owner: print "Owner: %s" % owner.getAbsolutePath() else: print "Owner: Error retrieving owner" print
from Ft.Server.Common.Util import RepoPathToUri temp_stmts = self.getModel().complete( #RepoPathToUri(self.getAbsolutePath()), self.getAbsolutePath(), Schema.TIME_TO_LIVE, None) if temp_stmts: #now = Time.FromPythonTime().asISO8601DateTime() #if temp_stmts[0].object <= cur: print "This is a temporary resource scheduled to be deleted after ", temp_stmts[0].object print
acl = self.getAcl()
for name, key in (('Read', AclConstants.READ_ACCESS), ('Write', AclConstants.WRITE_ACCESS), ('Execute', AclConstants.EXECUTE_ACCESS), ('Delete', AclConstants.DELETE_ACCESS), ('Change Permissions', AclConstants.CHANGE_PERMISSIONS_ACCESS), ('Change Owner', AclConstants.CHANGE_OWNER_ACCESS), ('Write User Model', AclConstants.WRITE_USER_MODEL_ACCESS), ):
if key in acl: print "%s ACL" % name else: print "%s ACL (inherited)" % name
for ident, allowed in self.getAcl(key).items(): if ident[0] == ':': ident = ident[1:] print " %s --> %s" % (ident, allowed == AclConstants.ALLOWED and 'allowed' or 'denied')
|