/*
* This software is Copyright 2005,2006,2007,2008 Langdale Consultants.
* Langdale Consultants can be contacted at: http://www.langdale.com.au
*/
package au.com.langdale.validation;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import au.com.langdale.inference.LOG;
import au.com.langdale.inference.Reporting;
import au.com.langdale.inference.RuleParser;
import au.com.langdale.inference.SimpleInfGraph;
import au.com.langdale.inference.SimpleReasoner;
import au.com.langdale.inference.RuleParser.ParserException;
import au.com.langdale.kena.OntModel;
import au.com.langdale.kena.OntResource;
import au.com.langdale.kena.ResIterator;
import au.com.langdale.util.Logger;
import au.com.langdale.util.Profiler.TimeSpan;
import com.hp.hpl.jena.graph.Graph;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.Triple;
import com.hp.hpl.jena.reasoner.rulesys.BuiltinRegistry;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
public abstract class ValidatorUtil extends Reporting {
public interface ValidatorProtocol {
/**
* Execute validation for the given inputs and output. This method can
* be called more than once to apply a given set of rules to more than
* one input.
*
* @param source: the pathname of the model to validate
* @param base: the pathname of a base model when the source represents an incremental model
* @param namespace: not used for split models
* @param errors: the destination for errors reports (not validation reports)
* @return a diagnostic model
* @throws IOException
*/
public abstract OntModel run(String source, String base, String namespace, Logger errors) throws IOException;
}
public static InputStream openStandardRules(String name) {
return ValidatorUtil.class.getResourceAsStream(name + ".rules");
}
public static List expandRules(OntModel schema, InputStream ruleText, BuiltinRegistry registry) throws ParserException, IOException {
TimeSpan span = new TimeSpan("Parse Rules");
RuleParser parser = new RuleParser(ruleText, registry);
parser.registerPrefix("topol", guessTopolNameSpace(schema));
List rules = parser.parse();
span = span.start("Expand Rules");
SimpleReasoner stage1 = new SimpleReasoner(rules);
Graph graph = schema.getGraph();
SimpleInfGraph deductions = (SimpleInfGraph) stage1.bind(graph);
List brules = deductions.getBRules();
debug(graph, rules, brules);
span.stop();
return brules;
}
private static String guessTopolNameSpace(OntModel schema) {
String ns = "http://langdale.com.au/2008/default_electrical_topology#";
ResIterator it = schema.listSubjectsWithProperty(RDF.type, OWL.ObjectProperty);
while( it.hasNext()) {
OntResource prop = it.nextResource();
if(prop.getLocalName().equals("Terminal.ConnectivityNode")) {
ns = prop.getNameSpace();
break;
}
}
return ns;
}
private static void debug(Graph graph, List rules, List brules) {
// System.out.println("---funny triples---");
// ExtendedIterator it = graph.find(Node.ANY, RDFS.subClassOf.asNode(), Node.ANY);
// while (it.hasNext()) {
// Triple t = (Triple) it.next();
// if( t.getObject().isBlank())
// System.out.println(t);
// }
// System.out.println("---initial rules---");
// PrintUtil.printOut(rules.iterator());
//
// System.out.println("---expanded rules---");
// PrintUtil.printOut(brules.iterator());
}
public static void logProblems(Logger log, Graph deductions) {
TimeSpan span = new TimeSpan("Generate Report");
Iterator it = deductions.find(Node.ANY, RDF.type.asNode(), LOG.Problem.asNode());
while (it.hasNext()) {
Triple t = (Triple) it.next();
logProblem(log, deductions, t.getSubject());
}
span.stop();
}
public static void logProblem(Logger log, Graph deductions, Node problem) {
Node subject = getSubject(deductions, LOG.hasProblems.asNode(), problem, null);
String key = subject != null && subject.isURI()? subject.getURI(): "";
String phrase = getString(deductions, problem, RDFS.comment.asNode(), "");
String detail = getString(deductions, problem, LOG.problemDetail.asNode(), "");
log.log(phrase + ":\t" + key + "\t" + detail);
}
public static String getString(Graph graph, Node subject, Node prop,
String alt) {
ExtendedIterator it = graph.find(subject, prop, Node.ANY);
while (it.hasNext()) {
Triple t = (Triple) it.next();
Node n = t.getObject();
if( n.isLiteral()) {
it.close();
return n.getLiteralLexicalForm();
}
}
return alt;
}
public static Node getSubject(Graph graph, Node prop, Node object, Node alt) {
ExtendedIterator it = graph.find(Node.ANY, prop, object);
while (it.hasNext()) {
Triple t = (Triple) it.next();
Node n = t.getSubject();
it.close();
return n;
}
return alt;
}
public static Node cons(Graph graph, Node first, Node rest) {
Node head = Node.createAnon();
graph.add(new Triple(head, RDF.first.asNode(), first));
graph.add(new Triple(head, RDF.rest.asNode(), rest));
return head;
}
}