001/** 002 * Copyright (C) 2007 - 2016, Jens Lehmann 003 * <p> 004 * This file is part of DL-Learner. 005 * <p> 006 * DL-Learner is free software; you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation; either version 3 of the License, or 009 * (at your option) any later version. 010 * <p> 011 * DL-Learner is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * <p> 016 * You should have received a copy of the GNU General Public License 017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package org.dllearner.kb.sparql; 020 021import java.io.StringReader; 022import java.util.Set; 023 024import org.aksw.jena_sparql_api.model.QueryExecutionFactoryModel; 025import org.apache.jena.query.ParameterizedSparqlString; 026import org.apache.jena.query.QueryExecution; 027import org.apache.jena.rdf.model.Model; 028import org.apache.jena.rdf.model.ModelFactory; 029import org.slf4j.Logger; 030import org.slf4j.LoggerFactory; 031 032/** 033 * A CBD generator that resolves blank nodes. 034 * 035 * @author Lorenz Buehmann 036 */ 037public class BlanknodeResolvingCBDGenerator implements ConciseBoundedDescriptionGenerator { 038 039 private static final Logger log = LoggerFactory.getLogger(BlanknodeResolvingCBDGenerator.class); 040 041 private QueryExecutionFactoryModel qef; 042 043 public BlanknodeResolvingCBDGenerator(Model model) { 044 String query = "prefix : <http://dl-learner.org/ontology/> " 045 + "construct { ?s ?p ?o ; ?type ?s .} " 046 + "where { ?s ?p ?o . bind( if(isIRI(?s),:sameIri,:sameBlank) as ?type )}"; 047 qef = new QueryExecutionFactoryModel(model); 048 QueryExecution qe = qef.createQueryExecution(query); 049 Model extendedModel = qe.execConstruct(); 050 qe.close(); 051 052 qef = new QueryExecutionFactoryModel(extendedModel); 053 } 054 055 /* (non-Javadoc) 056 * @see org.dllearner.kb.sparql.ConciseBoundedDescriptionGenerator#getConciseBoundedDescription(java.lang.String) 057 */ 058 @Override 059 public Model getConciseBoundedDescription(String resourceURI) { 060 return getConciseBoundedDescription(resourceURI, 0); 061 } 062 063 /* (non-Javadoc) 064 * @see org.dllearner.kb.sparql.ConciseBoundedDescriptionGenerator#getConciseBoundedDescription(java.lang.String, int) 065 */ 066 @Override 067 public Model getConciseBoundedDescription(String resource, int depth) { 068 return getConciseBoundedDescription(resource, depth, false); 069 } 070 071 /* (non-Javadoc) 072 * @see org.dllearner.kb.sparql.ConciseBoundedDescriptionGenerator#getConciseBoundedDescription(java.lang.String, int, boolean) 073 */ 074 @Override 075 public Model getConciseBoundedDescription(String resource, int depth, boolean withTypesForLeafs) { 076 StringBuilder constructTemplate = new StringBuilder("?s0 ?p0 ?o0 .\n"); 077 for (int i = 1; i < depth; i++) { 078 constructTemplate.append("?s").append(i).append(" ?p").append(i).append(" ?o").append(i).append(" .\n"); 079 } 080 081 StringBuilder triplesTemplate = new StringBuilder("?x ((!<x>|!<y>)/:sameBlank)* ?s0 . ?s0 ?p0 ?o0 . filter(!(?p0 in (:sameIri, :sameBlank)))\n"); 082 for (int i = 1; i < depth; i++) { 083 triplesTemplate.append("OPTIONAL {").append("?o").append(i - 1).append(" ((!<x>|!<y>)/:sameBlank)* ?s").append(i).append(" .") 084 .append("?s").append(i).append(" ?p").append(i).append(" ?o").append(i).append(" filter(!(?p").append(i).append(" in (:sameIri, :sameBlank)))"); 085 } 086 087 088 for (int i = 1; i < depth; i++) { 089 triplesTemplate.append("}"); 090 } 091 092 ParameterizedSparqlString query = new ParameterizedSparqlString("prefix : <http://dl-learner.org/ontology/> " + 093 "\nCONSTRUCT {\n" + constructTemplate + "} WHERE {\n" + triplesTemplate + "\n}"); 094 query.setIri("x", resource); 095 096 log.debug("CBD query:\n" + query.toString()); 097 098 try (QueryExecution qe = qef.createQueryExecution(query.toString())) { 099 return qe.execConstruct(); 100 } 101 } 102 103 @Override 104 public void setIgnoredProperties(Set<String> properties) { 105 throw new UnsupportedOperationException("not supported yet!"); 106 } 107 108 /* (non-Javadoc) 109 * @see org.dllearner.kb.sparql.ConciseBoundedDescriptionGenerator#setRestrictToNamespaces(java.util.List) 110 */ 111 @Override 112 public void setAllowedPropertyNamespaces(Set<String> namespaces) { 113 throw new UnsupportedOperationException("not supported yet!"); 114 } 115 116 /* (non-Javadoc) 117 * @see org.dllearner.kb.sparql.ConciseBoundedDescriptionGenerator#setAllowedObjectNamespaces(java.util.Set) 118 */ 119 @Override 120 public void setAllowedObjectNamespaces(Set<String> namespaces) { 121 throw new UnsupportedOperationException("not supported yet!"); 122 } 123 124 public static void main(String[] args) { 125 String data = "@prefix : <http://dl-learner.org/test/> .\n" + 126 "\n" + 127 ":A :p :B ;\n" + 128 " :q [ :r :C , :D ] .\n" + 129 ":B :q :D, :E .\n" + 130 ":C :r :F .\n" + 131 ":D :r :F , :G ;\n" + 132 " :s :A , :B ."; 133 134 printCBD(data, 1); 135 136 data = "@prefix : <http://dl-learner.org/test/> .\n" + 137 "\n" + 138 ":A :p :B . :B :q [ :r :C , :D ] . \n" + 139 ":B :q :D, :E .\n" + 140 ":C :r :F .\n" + 141 ":D :r :F , :G ;\n" + 142 " :s :A , :B ."; 143 144 printCBD(data, 2); 145 } 146 147 private static void printCBD(String data, int depth) { 148 Model m = ModelFactory.createDefaultModel(); 149 m.read(new StringReader(data), null, "Turtle"); 150 151 BlanknodeResolvingCBDGenerator cbdGen = new BlanknodeResolvingCBDGenerator(m); 152 153 Model cbd = cbdGen.getConciseBoundedDescription("http://dl-learner.org/test/A", 2); 154 cbd.setNsPrefix("", "http://dl-learner.org/test/"); 155 cbd.write(System.out, "Turtle"); 156 } 157}