def getResource(s, rxNSPrefix, nsMap, thisResource): typeName = None if matchName(s, rxNSPrefix, 'this-resource'): assert thisResource resource = thisResource elif matchName(s, rxNSPrefix, 'resource'): id = s.getAttributeNS(EMPTY_NAMESPACE, 'id') resource = id if not id: resource = RxPath.generateBnode() else: #deprecated if the element has an id element treat as the resource URI ref and the element name as the class type id = getAttributefromQName(s, rxNSPrefix, 'id') if id is not None: resource = id if not resource: resource = RxPath.generateBnode() typeName = getURIFromElementName(s, nsMap) else: resource = getURIFromElementName(s, nsMap) return resource, typeName
def addList2Model(model, subject, p, listID, scope, getObject=getObject): prevListID = None for child in p.childNodes: if child.nodeType == p.COMMENT_NODE: continue object, objectType = getObject(child) if prevListID: listID = RxPath.generateBnode() model.addStatement( Statement(prevListID, RDF_MS_BASE + 'type', RDF_MS_BASE + 'List', OBJECT_TYPE_RESOURCE, scope)) model.addStatement( Statement(prevListID, RDF_MS_BASE + 'rest', listID, OBJECT_TYPE_RESOURCE, scope)) model.addStatement( Statement(listID, RDF_MS_BASE + 'first', object, objectType, scope)) prevListID = listID model.addStatement( Statement(listID, RDF_MS_BASE + 'type', RDF_MS_BASE + 'List', OBJECT_TYPE_RESOURCE, scope)) model.addStatement( Statement(listID, RDF_MS_BASE + 'rest', RDF_MS_BASE + 'nil', OBJECT_TYPE_RESOURCE, scope))
def addResource(model, scope, resource, resourceElem, rxNSPrefix, nsMap, thisResource, noStmtIds=False): ''' add the children of a RXML resource element to the model ''' for p in resourceElem.childNodes: if p.nodeType != p.ELEMENT_NODE: continue if matchName(p, rxNSPrefix, 'resource'): predicate = p.getAttributeNS(EMPTY_NAMESPACE, 'id') elif matchName(p, rxNSPrefix, 'a'): #alias for rdf:type predicate = RDF_MS_BASE + 'type' else: predicate = getURIFromElementName(p, nsMap) id = getAttributefromQName(p, rxNSPrefix, RX_STMTID_ATTRIB) if not id: id = p.getAttributeNS(EMPTY_NAMESPACE, RX_STMTID_ATTRIB) if id and noStmtIds: raise RxMLError(RX_STMTID_ATTRIB + ' attribute found at illegal location') if id: raise RxMLError(RX_STMTID_ATTRIB + ' attribute not yet supported') object = getAttributefromQName(p, rxNSPrefix, 'res') #this is deprecated if object: objectType = OBJECT_TYPE_RESOURCE elif (getAttributefromQName(p, rxNSPrefix, 'list') is not None or getAttributefromQName(p, {'': EMPTY_NAMESPACE}, 'list') is not None or getAttributefromQName(p, rxNSPrefix, 'listType') is not None or getAttributefromQName( p, {'': EMPTY_NAMESPACE}, 'listType') is not None or len([ c for c in p.childNodes if c.nodeType != p.COMMENT_NODE and c.nodeValue and c.nodeValue.strip() ]) > 1): #the object of this predicate is a list listID = getAttributefromQName(p, rxNSPrefix, 'list') if not listID: listID = p.getAttributeNS(EMPTY_NAMESPACE, 'list') if not listID: listID = RxPath.generateBnode() model.addStatement( Statement(resource, predicate, listID, OBJECT_TYPE_RESOURCE, scope)) listType = getAttributefromQName(p, rxNSPrefix, 'listType') if not listID: listType = p.getAttributeNS(EMPTY_NAMESPACE, 'listType') getObjectFunc = lambda elem: getObject(elem, rxNSPrefix, nsMap, thisResource) if not listType or listType == 'rdf:List': addList2Model(model, resource, p, listID, scope, getObjectFunc) else: addContainer2Model(model, resource, p, listID, scope, getObjectFunc, listType) continue else: #object is a a literal or resource childNodes = [ child for child in p.childNodes if child.nodeType != child.COMMENT_NODE ] if not childNodes: #if predicate has no child we assume its an empty literal #this could be the result of the common error with ZML #where the ':' was missing after the predicate invalidAttrLocalNames = [ attName[1] for attName in p.attributes.keys() if attName[1] not in [RX_STMTID_ATTRIB, 'id'] ] if invalidAttrLocalNames: #there's an attribute that not either 'stmtid' or 'rdf:id' raise RxMLError('invalid attribute ' + invalidAttrLocalNames[0] + ' on predicate element ' + p.localName + ' -- did you forget a ":"?') object, objectType = "", OBJECT_TYPE_LITERAL else: assert len(childNodes) == 1, p object, objectType = getObject(childNodes[0], rxNSPrefix, nsMap, thisResource) #print >>sys.stderr, 'adding ', repr(resource), repr(predicate), object, model.addStatement( Statement(resource, predicate, object, objectType, scope))
def GenerateBnode(context, name=None): if name is not None: name = StringValue(name) return RxPath.generateBnode(name)
def _saveContents(self, filepath, contents, altfilename=None, indexURI=None, title='', previousRevisionDigest='', maxLiteral=None): ''' this is kind of ugly; XUpdate doesn't have an eval() function, so we build up a string of xml and then parse it and then return the doc as a nodeset and use xupdate:copy-of on the nodeset ''' if indexURI: self.addToIndex(indexURI, contents, title) if maxLiteral is None: maxLiteral = self.MAX_MODEL_LITERAL #print >>sys.stderr, 'sc', filepath, title, contents ns = '''xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:a="http://rx4rdf.sf.net/ns/archive#" xmlns:wiki="http://rx4rdf.sf.net/ns/wiki#"''' contentLength = len(contents) if filepath and maxLiteral > -1 and contentLength > maxLiteral: #save as file dir = os.path.split(filepath)[0] try: os.makedirs(dir) except OSError: pass #dir might already exist ff = TxnFileFactory(filepath) self.server.txnSvc.join(ff) f = ff.create('b') #f = file(filepath, 'wb') f.write(contents) f.close() digest = utils.shaDigestString(contents) if altfilename and self.ALTSAVE_DIR: #we save another copy of the last revision in a location that #that can be safely accessed and modified by external programs #without breaking diffs etc. altfilepath = os.path.join(self.ALTSAVE_DIR, altfilename) abspath = os.path.abspath(altfilepath) prefixlen = len( InputSource.DefaultFactory.resolver.getPrefix(abspath)) assert prefixlen, ("filepath %s must be on Raccoon's PATH" % abspath) altPathURI = raccoon.SiteUriResolver.OsPathToPathUri( abspath[prefixlen + 1:]) #if the altfilepath already exists compare its digest with the previous #revisions digest and don't overwrite this file if they don't match #-- instead add a wiki:save-conflict property to the new contentlocation. if os.path.exists(altfilepath): existingDigest = utils.shaDigest(altfilepath) if existingDigest == digest: #identical to the contents, so no need to write saveAltFile = False conflict = False else: conflict = True if previousRevisionDigest: #if these are equal, its ok to overwrite saveAltFile = previousRevisionDigest == existingDigest else: saveAltFile = False else: saveAltFile = True altContents = ("<wiki:alt-contents><a:ContentLocation " "rdf:about='%s' /></wiki:alt-contents>" % altPathURI) if saveAltFile: dir = os.path.split(altfilepath)[0] try: os.makedirs(dir) except OSError: pass #dir might already exist ff = TxnFileFactory(altfilepath) self.server.txnSvc.join(ff) f = ff.create('b') #f = file(altfilepath, 'wb') f.write(contents) f.close() elif conflict: self.log.warning( "conflict trying to save revision to ALTSAVE_DIR: " "unrecognized contents at %s" % altfilepath) altContents = ("<wiki:save-conflict><a:ContentLocation " "rdf:about='%s' /></wiki:save-conflict>" % altPathURI) else: altContents = '' contentProps = ("<a:content-length>%u</a:content-length>" "<a:sha1-digest>%s</a:sha1-digest>" % (contentLength, digest)) abspath = os.path.abspath(filepath) prefixlen = len( InputSource.DefaultFactory.resolver.getPrefix(abspath)) assert prefixlen, ("filepath %s must be on Raccoon's PATH" % abspath) filepathURI = raccoon.SiteUriResolver.OsPathToPathUri( abspath[prefixlen + 1:]) #print >>sys.stderr, abspath, abspath[prefixlen+1:], prefixlen, filepathURI xml = ("<a:ContentLocation %(ns)s rdf:about='%(filepathURI)s'>" "%(contentProps)s%(altContents)s</a:ContentLocation>" % locals()) else: #save the contents inside the model try: if isinstance(contents, str): #test to see if the string can be treated as utf8 contents.decode('utf8') return contents #contents = utils.htmlQuote(contents) #xml = '''<a:Content rdf:about='%(sha1urn)'>%(contentProps)s<a:contents>%(contents)s</a:contents></<a:Content>''' % locals() except UnicodeError: #could be binary, base64 encode encodedURI = RxPath.generateBnode() contents = base64.encodestring(contents) xml = ( "<a:ContentTransform %(ns)s rdf:about='%(encodedURI)s'>" "<a:transformed-by>" "<rdf:Description rdf:about='http://www.w3.org/2000/09/xmldsig#base64'/>" "</a:transformed-by>" "<a:contents>%(contents)s</a:contents>" "</a:ContentTransform>" % locals()) #print >>sys.stderr, 'sc', xml from Ft.Xml import Domlette #why can't InputSource accept unicode? lame (thus we don't support unicode filenames right now) isrc = InputSource.DefaultFactory.fromString(str(xml), 'file:') xmlDoc = Domlette.NonvalidatingReader.parse(isrc) #return a nodeset containing the root element of the doc #print >>sys.stderr, 'sc', xmlDoc.documentElement return [xmlDoc.documentElement]