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)
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)
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)