Example #1
0
def getConstraint(minimgraph, rouri, target_ref, purpose_regex_string):
    """
    Find constraint matching supplied RO, target and purpose regex
    
    Constraint is returned with:
    targetro_actual  -> URI of resource
    targetres_actual -> URI of target if supplied, else subject of minium:hasConstraint
    """
    def mkstr(u):
        return u and str(u)
    log.debug("getConstraint: rouri %s, target_ref %s"%(rouri, target_ref))
    target       = target_ref and ro_manifest.getComponentUri(rouri, target_ref)
    log.debug("               target_uri %s"%(target))
    purpose      = purpose_regex_string and re.compile(purpose_regex_string)
    templatedict = {'targetro': urllib.unquote(str(rouri))}
    if target:
        # Allow use of {+targetres} in checklist target template:
        templatedict['targetres'] = urllib.unquote(str(target))
    for c in getConstraints(minimgraph):
        log.debug("- test: target %s purpose %s"%(c['target'],c['purpose']))
        log.debug("- purpose %s, c['purpose'] %s"%(purpose_regex_string, c['purpose']))
        if not purpose or purpose.match(c['purpose']):
            c['targetro_actual']   = rouri
            c['targetres_actual']  = target or c['target']
            if not target:
                # No target specified in request, match any (first) constraint
                return c
            if c['target'] == target:
                # Match explicit target specification (subject of minim:hasConstraint)
                return c
            log.debug("- target: %s, c['target_t']: %s"%(target, repr(c['target_t'])))
            if c['target_t'] and c['target_t'].value == "*":
                # Special case: wilcard ("*") template matches any target
                return c
            if target and c['target_t']:
                log.debug("- expand %s"%(uritemplate.expand(c['target_t'], templatedict)))
                if str(target) == uritemplate.expand(c['target_t'], templatedict):
                    # Target matches expanded template from constraint description
                    return c
    return None
def expand_uri_template(request):
    tp = request.json_body
    uri = uritemplate.expand(tp['template'], tp['params'])
    return Response(uri+"\n", content_type="text/plain")
def evalContentMatch(rometa, rule, constraintbinding):
    """
    rometa      ro_metadata for RO to test
    rule        requirement rule to evaluate
    constraintbinding
                value bindings generated by constraint matching:
                'targetro', 'targetres' and 'onresource'
    """
    querytemplate = """
        PREFIX rdf:        <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
        PREFIX rdfs:       <http://www.w3.org/2000/01/rdf-schema#>
        PREFIX owl:        <http://www.w3.org/2002/07/owl#>
        PREFIX xsd:        <http://www.w3.org/2001/XMLSchema#>
        PREFIX xml:        <http://www.w3.org/XML/1998/namespace>
        PREFIX ro:         <http://purl.org/wf4ever/ro#>
        PREFIX wfprov:     <http://purl.org/wf4ever/wfprov#>
        PREFIX wfdesc:     <http://purl.org/wf4ever/wfdesc#>
        PREFIX rdfg:       <http://www.w3.org/2004/03/trix/rdfg-1/>
        PREFIX ore:        <http://www.openarchives.org/ore/terms/>
        PREFIX ao:         <http://purl.org/ao/>
        PREFIX dcterms:    <http://purl.org/dc/terms/>
        PREFIX foaf:       <http://xmlns.com/foaf/0.1/>

        %(queryverb)s
        {
          %(querypattern)s
        }
        """
    satisfied     = True
    simplebinding = constraintbinding
    if rule['forall']:
        exists   = rule['exists']
        template = rule['template']
        islive   = rule['islive']
        assert (exists or template or islive), (
            "minim:forall construct requires "+
            "minim:aggregatesTemplate, minim:isLiveTemplate and/or minim:exists value")
        queryparams = (
            { 'queryverb': "SELECT * WHERE"
            , 'querypattern': rule['forall']
            })
        query = querytemplate%queryparams
        resp  = rometa.queryAnnotations(query, initBindings=constraintbinding)
        for binding in resp:
            satisfied = False
            # Extract keys and values from query result to return with result
            simplebinding = constraintbinding
            for k in binding:
                ###print "key: "+repr(k) 
                if not isinstance(k,rdflib.BNode):
                    simplebinding[str(k)] = str(binding[k])
                    # @@TODO remove this when rdflib bug resolved 
                    if str(k) in ['if', 'of'] and str(binding[k])[:5] not in ["file:","http:"]:
                        # Houston, we have a problem...
                        agraph = rometa.roannotations
                        print "--------------------"
                        print "Graph: "+agraph.serialize(format="xml")
                        print "Query: "+query
                        print "Response bindings: "+repr(resp)
                        print "--------------------"
                        assert False, "Aborted"
            if exists:
                # existence query against forall results
                existsparams = (
                    { 'queryverb': "ASK"
                    , 'querypattern': exists
                    })
                query = querytemplate%existsparams
                log.debug("***** evalContentMatch RO test exists: \nquery: %s \nbinding: %s)"%(query, repr(binding)))
                satisfied = rometa.queryAnnotations(query,initBindings=binding)
            if template:
                # Construct URI for file from template
                # Uses code copied from http://code.google.com/p/uri-templates
                fileref = uritemplate.expand(template, simplebinding)
                fileuri = rometa.getComponentUri(fileref)
                # Test if URI is aggregated
                log.debug("evalContentMatch RO aggregates %s (%s)"%(fileref, str(fileuri)))
                satisfied = rometa.roManifestContains( (rometa.getRoUri(), ORE.aggregates, fileuri) )
            if islive:
                # Construct URI for file from template
                # Uses code copied from http://code.google.com/p/uri-templates
                fileref = uritemplate.expand(islive, simplebinding)
                fileuri = rometa.getComponentUri(fileref)
                # Test if URI is live (accessible)
                log.debug("evalContentMatch RO islive %s (%s)"%(fileref, str(fileuri)))
                satisfied = isLiveUri(fileuri)
            log.debug("evalContentMatch (forall) RO satisfied %s"%(satisfied))
            if not satisfied: break
    elif rule['exists']:
        queryparams = (
            { 'queryverb': "ASK"
            , 'querypattern': rule['exists']
            })
        query = querytemplate%queryparams
        log.debug("- query %s"%(query))
        satisfied = rometa.queryAnnotations(query)
        log.debug("- satisfied %s"%(satisfied))
    else:
        raise ValueError("Unrecognized content match rule: %s"%repr(rule))
    return (satisfied,simplebinding)
Example #4
0
def evalQueryTest(rometa, rule, constraintbinding):
    """
    rometa      ro_metadata for RO to test
    rule        requirement rule to evaluate
    constraintbinding
                value bindings generated by constraint matching:
                'targetro' and 'targetres', and maybe others

    Returns (satisfied, binding, msg)
    """
    log.debug("evalQueryTest: rule: \n----\n  %s, \n----\nconstraintbinding:\n  %s\n----"%(repr(rule), repr(constraintbinding)))
    querytemplate = (make_sparql_prefixes(rule['prefixes'])+
        """
        BASE <%(querybase)s>

        %(queryverb)s
        {
          %(querypattern)s
        } %(resultmod)s
        """)
    satisfied     = True
    simplebinding = constraintbinding.copy()
    if rule['exists'] and not rule['query']:
        # Bare "exists" is syntactic sugar for "query" with "min=1"
        rule['query']  = rule['exists']
        rule['exists'] = None
        rule['min']    = rule['min'] or 1
    # print >>sys.stderr, "@@@@@@"
    # print >>sys.stderr, repr(rule)
    # print >>sys.stderr, "@@@@@@"
    if rule['query']:
        count_min  = rule['min']
        count_max  = rule['max']
        aggregates = rule['aggregates_t']
        islive     = rule['islive_t']
        exists     = rule['exists']
        assert (count_min or count_max or aggregates or islive or exists), (
            "minim:QueryTestRule requires "+
            "minim:min, minim:max, minim:aggregatesTemplate, minim:isLiveTemplate and/or minim:exists value")
        if aggregates:  aggregates = str(aggregates).strip()
        if islive:      islive   = str(islive).strip()
        queryparams = (
            { 'querybase':    str(rometa.getRoUri())
            , 'queryverb':    "SELECT DISTINCT * WHERE"
            , 'querypattern': rule['query']
            , 'resultmod':    rule['resultmod'] or ""
            })
        query = querytemplate%queryparams
        log.debug(" - QueryTest: "+query)
        resp  = rometa.queryAnnotations(query, initBindings=constraintbinding)
        log.debug(" - QueryTest resp: "+repr(resp))
        simplebinding['_count'] = len(resp)
        satisfied_count  = 0
        total_count      = len(resp)
        result_list      = []
        failure_message_template = rule['showfail'] or rule['show']
        for binding in resp:
            satisfied = True
            failmsg   = failure_message_template
            simplebinding = constraintbinding.copy()
            for k in binding:
                if not isinstance(k,rdflib.BNode):
                    simplebinding[str(k)]   = unicode(binding[k])
                    simplebinding['_count'] = len(resp)
            # Do the required test
            if aggregates:
                fileref   = uritemplate.expand(aggregates, simplebinding)
                fileuri   = rometa.getComponentUri(fileref)
                simplebinding.update({'_fileref': fileref, '_fileuri': fileuri})
                log.debug("evalQueryTest RO aggregates %s (%s)"%(fileref, str(fileuri)))
                satisfied = rometa.roManifestContains( (rometa.getRoUri(), ORE.aggregates, fileuri) )
                failmsg   = failmsg or "Aggregates %(_fileref)s"
            if islive:
                fileref   = uritemplate.expand(islive, simplebinding)
                fileuri   = rometa.getComponentUri(fileref)
                simplebinding.update({'_fileref': fileref, '_fileuri': fileuri})
                log.debug("evalQueryTest RO isLive %s (%s)"%(fileref, str(fileuri)))
                satisfied = isLiveUri(fileuri)
                failmsg   = failmsg or "Accessible %(_fileref)s"
            if exists:
                existsparams = (
                    { 'querybase':    str(rometa.getRoUri())
                    , 'queryverb':    "ASK"
                    , 'querypattern': exists
                    , 'resultmod':    ""
                    })
                query = querytemplate%existsparams
                simplebinding.update({'_pattern': exists, '_query': query})
                log.debug("evalContentMatch RO test exists: \nquery: %s \nbinding: %s"%
                          (query, repr(binding)))
                satisfied = rometa.queryAnnotations(query,initBindings=binding)
                failmsg   = failmsg or "Exists %(_fileref)s"
            # Test done, defines: satisfied, failmsg, simplebinding 
            log.debug("Satisfied: %s"%(repr(satisfied)))
            if satisfied:
                satisfied_count += 1
            result_list.append((satisfied, failmsg, simplebinding))
        # All responses tested
    else:
        raise ValueError("Query test rule has no query: %s"%repr(rule))
    # Sort out final response
    log.debug("evalQueryTest RO satisfied_count %d"%(satisfied_count))
    if count_min or count_max:
        satisfied = ( (not count_min or (satisfied_count >= count_min)) and
                      (not count_max or (satisfied_count <= count_max)) )
        binding = constraintbinding.copy()
        binding['_count'] = satisfied_count
        msg = (rule['showpass'] if satisfied else rule['showfail'])
        msh = msg or rule['show'] or "Cardinality requirement failed"
    elif total_count == 0:
        binding   = simplebinding
        satisfied = False if rule['showmiss'] else True
        msg       = rule['showmiss'] or rule['showpass'] or rule['show'] or "No matches"
    elif (satisfied_count < total_count):
        satisfied = False
        # Pick out first failure (for now):
        (msg, binding) = ((failmsg,binding) for (satisfied, failmsg, binding) in result_list if not satisfied).next()
    else:
        satisfied = True
        binding   = simplebinding     # last result tested
        msg       = rule['showpass']
    # Add collected values to binding returned
    addCollectedVariables(rule['list'], [True, False], result_list, binding)
    addCollectedVariables(rule['listfail'], [False], result_list, binding)
    addCollectedVariables(rule['listpass'], [True], result_list, binding)
    return (satisfied, binding, msg)
Example #5
0
def evalContentMatch(rometa, rule, constraintbinding):
    """
    rometa      ro_metadata for RO to test
    rule        requirement rule to evaluate
    constraintbinding
                value bindings generated by constraint matching:
                'targetro' and 'targetres'
    """
    log.debug("evalContentMatch: rule: \n  %s, \nconstraintbinding:\n  %s"%(repr(rule), repr(constraintbinding)))
    querytemplate = (make_sparql_prefixes()+
        """
        %(queryverb)s
        {
          %(querypattern)s
        } %(queryorder)s
        """)
    satisfied     = True
    simplebinding = constraintbinding.copy()
    if rule['forall']:
        log.debug("forall rule: "+repr(rule))
        exists   = rule['exists']
        template = rule['template']
        islive   = rule['islive']
        assert (exists or template or islive), (
            "minim:forall construct (%(forall)s) requires "%(rule)+
            "minim:aggregatesTemplate, minim:isLiveTemplate and/or minim:exists value"+
            "")
        if template:  template = str(template).strip()
        if islive:    islive   = str(islive).strip()
        queryparams = (
            { 'queryverb':    "SELECT * WHERE"
            , 'querypattern': rule['forall']
            , 'queryorder':   rule['orderby'] or ""
            })
        query = querytemplate%queryparams
        log.debug(" - forall query: "+query)
        ### @@TODO: Why is this failing?
        # resp  = rometa.queryAnnotations(query, initBindings=constraintbinding)
        resp  = rometa.queryAnnotations(query)
        log.debug(" - forall resp: "+repr(resp))
        simplebinding['_count'] = len(resp)
        if len(resp) == 0 and rule['showmiss']:
            satisfied = False
        for binding in resp:
            satisfied = False
            # Extract keys and values from query result to return with result
            simplebinding = constraintbinding.copy()
            for k in binding:
                if not isinstance(k,rdflib.BNode):
                    simplebinding[str(k)] = str(binding[k])
                    simplebinding['_count'] = len(resp)
                    # @@TODO remove this when rdflib bug resolved 
                    if str(k) in ['if', 'of'] and str(binding[k])[:5] not in ["file:","http:"]:
                        # Houston, we have a problem...
                        agraph = rometa.roannotations
                        log.warning( "--------------------" )
                        log.debug( "Graph: "+agraph.serialize(format="xml") )
                        log.warning( "Query: "+query )
                        log.warning( "Response bindings: "+repr(resp) )
                        log.warning( "--------------------" )
                        ### assert False, "Aborted"
            if exists:
                # existence query against forall results
                existsparams = (
                    { 'queryverb': "ASK"
                    , 'querypattern': exists
                    , 'queryorder':   ""
                    })
                query = querytemplate%existsparams
                log.debug("evalContentMatch RO test exists: \nquery: %s \nbinding: %s"%
                          (query, repr(binding)))
                satisfied = rometa.queryAnnotations(query,initBindings=binding)
            if template:
                # Construct URI for file from template
                # Uses code copied from http://code.google.com/p/uri-templates
                fileref = uritemplate.expand(template, simplebinding)
                fileuri = rometa.getComponentUri(fileref)
                # Test if URI is aggregated
                log.debug("evalContentMatch RO aggregates %s (%s)"%(fileref, str(fileuri)))
                satisfied = rometa.roManifestContains( (rometa.getRoUri(), ORE.aggregates, fileuri) )
            if islive:
                # Construct URI for file from template
                # Uses code copied from http://code.google.com/p/uri-templates
                fileref = uritemplate.expand(islive, simplebinding)
                fileuri = rometa.getComponentUri(fileref)
                # Test if URI is live (accessible)
                log.debug("evalContentMatch RO islive %s (%s)"%(fileref, str(fileuri)))
                satisfied = isLiveUri(fileuri)
            log.debug("evalContentMatch (forall) RO satisfied %s"%(satisfied))
            if not satisfied: break
    elif rule['exists']:
        queryparams = (
            { 'queryverb': "ASK"
            , 'querypattern': rule['exists']
            , 'queryorder':   ""
            })
        query = querytemplate%queryparams
        log.debug("- query %s"%(query))
        satisfied = rometa.queryAnnotations(query)
        log.debug("- satisfied %s"%(satisfied))
    else:
        raise ValueError("Unrecognized content match rule: %s"%repr(rule))
    return (satisfied,simplebinding)