}
CloseableIteration<QueryResult, SQLException> bodyResult;
try {
KiWiReasoningConnection connection = persistence.getConnection();
SailConnection sail = store.getConnection();
KiWiSailConnection isail = getWrappedConnection(sail);
try {
// if there are further patterns, evaluate them; if the matched pattern was the only pattern, then
// simply take the match as binding
if(body.size() > 0) {
bodyResult = connection.query(body,match,null,null,true);
} else if(match != null) {
bodyResult = new SingletonIteration<QueryResult, SQLException>(match);
} else {
bodyResult = new EmptyIteration<QueryResult, SQLException>();
}
// construct triples out of the bindings and the rule heads
long counter = 0;
// initialise a new set of justifications
Set<Justification> justifications = new HashSet<Justification>();
sail.begin();
while(bodyResult.hasNext()) {
QueryResult row = bodyResult.next();
Map<VariableField,KiWiNode> binding = row.getBindings();
Resource subject = null;
URI property = null;
Value object;
if(rule.getHead().getSubject() != null && rule.getHead().getSubject().isVariableField()) {
if(!binding.get(rule.getHead().getSubject()).isUriResource() && !binding.get(rule.getHead().getSubject()).isAnonymousResource()) {
log.info("cannot use value {} as subject, because it is not a resource",binding.get(rule.getHead().getSubject()));
continue;
}
subject = (KiWiResource)binding.get(rule.getHead().getSubject());
} else if(rule.getHead().getSubject() != null && rule.getHead().getSubject().isResourceField()) {
subject = ((ResourceField)rule.getHead().getSubject()).getResource();
} else
throw new IllegalArgumentException("Subject of rule head may only be a variable or a resource; rule: "+rule);
if(rule.getHead().getProperty() != null && rule.getHead().getProperty().isVariableField()) {
if(!binding.get(rule.getHead().getProperty()).isUriResource()) {
log.info("cannot use value {} as property, because it is not a URI resource",binding.get(rule.getHead().getProperty()));
continue;
}
property = (KiWiUriResource)binding.get(rule.getHead().getProperty());
} else if(rule.getHead().getProperty() != null && rule.getHead().getProperty().isResourceField()) {
property = (KiWiUriResource)((ResourceField)rule.getHead().getProperty()).getResource();
} else
throw new IllegalArgumentException("Property of rule head may only be a variable or a resource; rule: "+rule);
if(rule.getHead().getObject() != null && rule.getHead().getObject().isVariableField()) {
object = binding.get(rule.getHead().getObject());
} else if(rule.getHead().getObject() != null && rule.getHead().getObject().isResourceField()) {
object = ((ResourceField)rule.getHead().getObject()).getResource();
} else if(rule.getHead().getObject() != null && rule.getHead().getObject().isLiteralField()) {
object = ((LiteralField)rule.getHead().getObject()).getLiteral();
} else
throw new IllegalArgumentException("Object of rule head may only be a variable, a literal, or a resource; rule: "+rule);
KiWiTriple triple = isail.addInferredStatement(subject, property, object);
Justification justification = new Justification();
justification.setTriple(triple);
justification.getSupportingRules().add(rule);
justification.getSupportingTriples().addAll(row.getJustifications());
justifications.add(justification);
// when the batch size is reached, commit the transaction, save the justifications, and start a new
// transaction and new justification set
if(++counter % config.getBatchSize() == 0) {
persistenceLock.lock();
try {
sail.commit();
log.debug("adding {} justifications",justifications.size());
updateTaskStatus("storing justifications ...");
Set<Justification> baseJustifications = getBaseJustifications(connection,justifications);
if(config.isRemoveDuplicateJustifications()) {
removeDuplicateJustifications(connection,baseJustifications);
}
log.debug("{} justifications added after resolving inferred triples", baseJustifications.size());
// persist the justifications that have been created in the rule processing
if(baseJustifications.size() > 0) {
connection.storeJustifications(baseJustifications);
}
connection.commit();
sail.begin();
} finally {
persistenceLock.unlock();
}
justifications.clear();
}
}
persistenceLock.lock();
try {
sail.commit();
log.debug("adding {} justifications",justifications.size());
updateTaskStatus("storing justifications ...");
Set<Justification> baseJustifications = getBaseJustifications(connection,justifications);
if(config.isRemoveDuplicateJustifications()) {
removeDuplicateJustifications(connection,baseJustifications);
}
// persist the justifications that have been created in the rule processing
if(baseJustifications.size() > 0) {
connection.storeJustifications(baseJustifications);
}
log.debug("{} justifications added after resolving inferred triples", baseJustifications.size());
Iterations.closeCloseable(bodyResult);
connection.commit();
} finally {
persistenceLock.unlock();
}
} catch(SailException ex) {
connection.rollback();
sail.rollback();
throw ex;
} catch(SQLException ex) {
sail.rollback();
connection.rollback();
throw ex;
} finally {
connection.close();
sail.close();
}
} catch(SQLException ex) {
log.error("DATABASE ERROR: could not process rule, database state will be inconsistent! Message: {}",ex.getMessage());