📄 ruleparser.java
字号:
/* Sesame - Storage and Querying architecture for RDF and RDF Schema * Copyright (C) 2003 OntoText Lab, Sirma AI OOD * * Contact: * Sirma AI OOD, OntoText Lab. * 38A, Christo Botev Blvd. * 1000 Sofia, Bulgaria * tel. +359(2)981 00 18 * fax. +359(2)981 90 58 * info@ontotext.com * * http://www.ontotext.com/ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package org.openrdf.sesame.sailimpl.rdbms.rules;import java.io.BufferedInputStream;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import java.util.Iterator;import org.xml.sax.Attributes;import org.xml.sax.ContentHandler;import org.xml.sax.InputSource;import org.xml.sax.Locator;import org.xml.sax.SAXException;import org.xml.sax.XMLReader;import org.openrdf.util.xml.XMLReaderFactory;/** * Parser for custom inference rule files. * * @author Damyan Ognyanoff * @author Arjohn Kampman **/public class RuleParser implements ContentHandler {/*----------+| Constants |+----------*/ private static final String TAG_AXIOM = "axiom"; private static final String TAG_RULE = "rule"; private static final String TAG_PREMISE = "premise"; private static final String TAG_CONSEQUENT = "consequent"; private static final String TAG_SUBJECT = "subject"; private static final String TAG_PREDICATE = "predicate"; private static final String TAG_OBJECT = "object"; private static final String TAG_TRIGGERS_RULE = "triggers_rule"; private static final String ATTR_NAME = "name"; private static final String ATTR_VAR = "var"; private static final String ATTR_URI = "uri"; private static final String ATTR_PATTERN = "pattern"; private static final String ATTR_ESCAPE = "escape";/*-------------+| Constructors |+-------------*/ public RuleParser() { }/*--------+| Methods |+--------*/ public void load(String filename) throws IOException, SAXException { InputStream in = new FileInputStream(filename); in = new BufferedInputStream(in, 4096); try { parse(in); } finally { in.close(); } } public void parse(InputStream in) throws IOException, SAXException { XMLReader parser = XMLReaderFactory.createXMLReader(); parser.setContentHandler(this); parser.parse( new InputSource(in) ); }/*----------+| Variables |+----------*/ private ArrayList _rules = null; private ArrayList _axioms = null; private boolean _parsingTriggers; // indicates whether we're in a <triggers_rule> context private boolean _parsingAxiom; // indicates whether we're in a <axiom> context private Locator _locator = null; private Component _subjectComp = null; private Component _predicateComp = null; private Component _objectComp = null; private Rule _rule = null;/*------------------------------+| ContentHandler implementation |+------------------------------*/ // implements ContentHandler.setDocumentLocator(Locator) public void setDocumentLocator(Locator locator) { _locator = locator; } // implements ContentHandler.startDocument() public void startDocument() throws SAXException { _rules = new ArrayList(16); _axioms = new ArrayList(32); _parsingTriggers = false; _parsingAxiom = false; } // implements ContentHandler.endDocument() public void endDocument() throws SAXException { // ignore } // implements ContentHandler.startElement(...) public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { if (localName.equals(TAG_AXIOM)) { _parsingAxiom = true; } else if (localName.equals(TAG_RULE)) { String ruleName = atts.getValue(ATTR_NAME); if (_parsingTriggers) { _rule.triggersRule(ruleName); } else { _rule = new Rule(ruleName); } } else if (localName.equals(TAG_TRIGGERS_RULE)) { if (_rule == null) { _throwSAXException("Triggers can only be defined with the context of a rule"); } _parsingTriggers = true; _rule.initTriggersRuleCollection(); } else if (localName.equals(TAG_SUBJECT)) { _subjectComp = _createComponent(atts, _parsingAxiom); } else if (localName.equals(TAG_PREDICATE)) { _predicateComp = _createComponent(atts, _parsingAxiom); } else if (localName.equals(TAG_OBJECT)) { _objectComp = _createComponent(atts, _parsingAxiom); } } // implements ContentHandler.endElement(...) public void endElement(String namespaceURI, String localName, String qName) throws SAXException { if (localName.equals(TAG_AXIOM)) { if (_subjectComp == null) { _throwSAXException("Subject missing in axiom definition"); } if (_predicateComp == null) { _throwSAXException("Predicate missing in axiom definition"); } if (_objectComp == null) { _throwSAXException("Object missing in axiom definition"); } // add the used resources to the 'required' list so to be able to assign their respective id's later Rule.getId(_subjectComp); Rule.getId(_predicateComp); Rule.getId(_objectComp); _axioms.add( new TripleTemplate(_subjectComp, _predicateComp, _objectComp) ); _parsingAxiom = false; } else if (!_parsingTriggers && localName.equals(TAG_RULE)) { _rules.add(_rule); _rule = null; } else if (localName.equals(TAG_TRIGGERS_RULE)) { if (!_parsingTriggers) { _throwSAXException("Unexpected </" + TAG_TRIGGERS_RULE + ">"); } _parsingTriggers = false; } else if (localName.equals(TAG_PREMISE)) { if (_subjectComp == null) { _throwSAXException("Subject missing in premise definition"); } if (_predicateComp == null) { _throwSAXException("Predicate missing in premise definition"); } if (_objectComp == null) { _throwSAXException("Object missing in premise definition"); } _rule.addPremise( new TripleTemplate(_subjectComp, _predicateComp, _objectComp) ); } else if (localName.equals(TAG_CONSEQUENT)) { if (_subjectComp == null) { _throwSAXException("Subject missing in consequent definition"); } if (_predicateComp == null) { _throwSAXException("Predicate missing in consequent definition"); } if (_objectComp == null) { _throwSAXException("Object missing in consequent definition"); } if (_rule.getConsequent() != null) { _throwSAXException("A rule can only have one consequent"); } _rule.setConsequent( new TripleTemplate(_subjectComp, _predicateComp, _objectComp) ); } } // implements ContentHandler.characters(...) public void characters(char[] ch, int start, int length) throws SAXException { // ignore } // implements ContentHandler.startPrefixMapping(...) public void startPrefixMapping(String prefix, String uri) throws SAXException { // ignore } // implements ContentHandler.endPrefixMapping(...) public void endPrefixMapping(String prefix) throws SAXException { // ignore } // implements ContentHandler.ignorableWhitespace(...) public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { // ignore } // implements ContentHandler.processingInstruction(...) public void processingInstruction(String target, String data) throws SAXException { // ignore } // implements ContentHandler.skippedEntity(...) public void skippedEntity(String name) throws SAXException { // ignore } /** * create a new component instance from the attribute list * of 'subject' 'object' or 'predicate' tags. * @param attr - list of attributes of the tag * @param forceUriOnly - if the context forces only 'uri' attribute to appear in * the supplied list * @return new Component instance * @throws SAXException */ private Component _createComponent(Attributes attr, boolean forceUriOnly) throws SAXException { Component result = null; String attrUri = attr.getValue(ATTR_URI); if (forceUriOnly) { if (attrUri == null) { _throwSAXException("Missing '" + ATTR_URI + "' attribute"); } result = new Component(attrUri, Component.URI); } else if (attrUri != null) { result = new Component(attrUri, Component.URI); } else { // if there is no uri attribute - ensure that at least 'var' is present String var = attr.getValue(ATTR_VAR); if (var == null) { _throwSAXException("No '" + ATTR_URI + "' or '" + ATTR_VAR + "' attribute found"); } result = new Component(var, Component.VAR); String pattern = attr.getValue(ATTR_PATTERN); String escape = attr.getValue(ATTR_ESCAPE); if (pattern != null) { result.setRegExpTemplate(pattern, escape); } } return result; } private void _throwSAXException(String msg) throws SAXException { throw new SAXException( "Parse error (line " + _locator.getLineNumber() + ", column " + _locator.getColumnNumber() + "): " + msg); } /** * matchTriples - given a consequent and a premise it simply match them * and report that the consequent can be a premise for a rule * @param t1 * @param t2 * @return true if it is applicable. the arguments are compared by-component. * In case of a varible both componets of the triple can be unified. * In case of an explicit URIs they should be exactly the same. */ protected boolean matchTriples(TripleTemplate t1, TripleTemplate t2) { // special case on transitivity rules if (t1.predicate.isUri() && t2.predicate.isUri() && t1.predicate.value().equals(t2.predicate.value())) { if (t1.subject.isVar() && t1.object.isVar() && t1.subject.value().equals(t1.object.value())) { if (t2.subject.isVar() && t2.object.isVar() && !t2.subject.value().equals(t2.object.value())) { return false; } } } // end special case if (!t1.subject.isVar() && !t2.subject.isVar() && !t1.subject.value().equalsIgnoreCase(t2.subject.value())) { // Subjects don't match return false; } if (!t1.predicate.isVar() && !t2.predicate.isVar() && !t1.predicate.value().equalsIgnoreCase(t2.predicate.value())) { // Predicates don't match return false; } if (!t1.object.isVar() && !t2.object.isVar() && !t1.object.value().equalsIgnoreCase(t2.object.value())) { // Objects don't match return false; } return true; } /** * method buildTriggers - given a list of rules it builds the inter-rule dependancy table. * e.g. If a rule inferrs some new statemnents which rules should be applied on next iteration. * This method is implementation specific because it deals with several variants of a rule. * @param theRules ArrayList with the Rule instances * @return square array of boolean values. each row holds the flags that indicate which rules( * rule variants) are trigered by this rule(rule variant) */ protected boolean[][] buildTriggers(ArrayList theRules) { // total number of rules(variants) // it is equal to the sum of allpremises (implementation specific) int num_rule_variants = 0; for (int i=0; i < theRules.size(); i++) { Rule r = (Rule)theRules.get(i); num_rule_variants += r.getPremiseCount(); } // creates a square array of boolean values boolean[][] result = new boolean[num_rule_variants][num_rule_variants]; // each int rowIndex = 0; for (int i=0; i < theRules.size(); i++) { int colIndex = 0; Rule activator = (Rule)theRules.get(i); for (int j=0; j < theRules.size(); j++) { Rule activated = (Rule)theRules.get(j); String aName = activated.getName(); boolean inTrigersList = false; if (activator.getTriggersRule() != null) { Iterator trIter = activator.getTriggersRule().iterator(); while (trIter.hasNext()) { String toCheck = (String)trIter.next(); if (toCheck.equalsIgnoreCase(aName)) { inTrigersList = true; break; } } //while } // triggersList is not empty if (inTrigersList) { TripleTemplate consequent = activator.getConsequent(); for (int indexActivated = 0; indexActivated < activated.getPremiseCount(); indexActivated++) { TripleTemplate premiseToCheck = (TripleTemplate)activated.getPremiseCollection().get(indexActivated); boolean valueToSet = matchTriples(consequent, premiseToCheck); for (int activatorSize = 0; activatorSize < activator.getPremiseCount(); activatorSize++) { result[rowIndex+activatorSize][colIndex+indexActivated] = valueToSet; } }// for each premise of the rule } colIndex += activated.getPremiseCount(); }// for each activated rule rowIndex += activator.getPremiseCount(); } // for each activator return result; } // buildTriggers(); public ArrayList getRules() { return _rules; } public ArrayList getAxioms() { return _axioms; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -