示例#1
0
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
示例#2
0
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))
示例#3
0
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))
示例#4
0
def GenerateBnode(context, name=None):
    if name is not None:
        name = StringValue(name)
    return RxPath.generateBnode(name)
示例#5
0
    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]