001/** 002 * Copyright (C) 2007 - 2016, Jens Lehmann 003 * 004 * This file is part of DL-Learner. 005 * 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 * 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 * 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.extraction; 020 021import java.net.URI; 022import java.util.ArrayList; 023import java.util.List; 024import java.util.SortedSet; 025import java.util.TreeSet; 026 027import org.apache.log4j.Logger; 028import org.dllearner.kb.aquisitors.TupleAquisitor; 029import org.dllearner.kb.manipulator.Manipulator; 030import org.dllearner.utilities.datastructures.RDFNodeTuple; 031import org.dllearner.utilities.owl.OWLVocabulary; 032import org.semanticweb.owlapi.model.OWLAnnotation; 033import org.semanticweb.owlapi.model.OWLAxiom; 034import org.semanticweb.owlapi.model.OWLClass; 035import org.semanticweb.owlapi.model.OWLDataFactory; 036import org.semanticweb.owlapi.model.OWLDataProperty; 037import org.semanticweb.owlapi.model.OWLIndividual; 038import org.semanticweb.owlapi.model.OWLNamedIndividual; 039import org.semanticweb.owlapi.model.OWLObjectProperty; 040 041import org.apache.jena.rdf.model.Literal; 042 043/** 044 * A node in the graph that is an instance. 045 * 046 * @author Sebastian Hellmann 047 * 048 */ 049public class InstanceNode extends Node { 050 051 private static Logger logger = Logger 052 .getLogger(InstanceNode.class); 053 054 private List<ClassNode> classes = new ArrayList<>(); 055 //SortedSet<StringTuple> datatypes = new TreeSet<StringTuple>(); 056 private List<ObjectPropertyNode> objectProperties = new ArrayList<>(); 057 private List<DatatypePropertyNode> datatypeProperties = new ArrayList<>(); 058 059 public InstanceNode(String uri) { 060 super(uri); 061 } 062 063 // expands all directly connected nodes 064 @Override 065 public List<Node> expand(TupleAquisitor tupelAquisitor, Manipulator manipulator) { 066 067 SortedSet<RDFNodeTuple> newTuples = tupelAquisitor.getTupelForResource(uri); 068 // see Manipulator 069 newTuples = manipulator.manipulate(this, newTuples); 070 071 List<Node> newNodes = new ArrayList<>(); 072 073 Node tmp; 074 for (RDFNodeTuple tuple : newTuples) { 075 076 if((tmp = processTuple(tuple))!= null) { 077 newNodes.add(tmp); 078 } 079 }//endfor 080 expanded = true; 081 return newNodes; 082 } 083 084 /** 085 * estimates the type of the retrieved tuple 086 * @param tuple 087 * @return 088 */ 089 public Node processTuple( RDFNodeTuple tuple) { 090 091 try { 092 093 //Literal nodes 094 if(tuple.b.isLiteral()) { 095 datatypeProperties.add(new DatatypePropertyNode(tuple.a.toString(), this, new LiteralNode(tuple.b) )); 096 return null; 097 //Blank nodes 098 }else if(tuple.b.isAnon()){ 099// @SuppressWarnings("unused") 100// RDFBlankNode n = (RDFBlankNode) tuple.b; 101 if(tuple.a.toString().equals(OWLVocabulary.RDF_TYPE)){ 102 logger.warn("blanknodes for instances not implemented yet (rare frequency). e.g. (instance rdf:type (A and B)"+" " + this+ " in tuple "+tuple); 103 } 104 else{ 105 logger.warn("encountered Bnode in InstanceNode "+ this +" in tuple " + tuple); 106 logger.warn("In OWL-DL the subject of an object property assertion must be an instance (not a class). Triple will be ignored."); 107 } 108 return null; 109 110 // basically : if p is rdf:type then o is a class 111 // else it is an instance 112 // Class Node 113 }else if (tuple.a.toString().equals(OWLVocabulary.RDF_TYPE)) { 114 try{ 115 URI.create(tuple.b.toString()); 116 }catch (Exception e) { 117 logger.warn("uri "+tuple.b.toString()+" is not a valid uri for a class, ignoring"); 118 return null; 119 } 120 121 ClassNode tmp = new ClassNode(tuple.b.toString()); 122 classes.add(tmp); 123 return tmp; 124 // instance node 125 } else { 126 127 try{ 128 URI.create(tuple.b.toString()); 129 }catch (Exception e) { 130 logger.warn("uri "+tuple.b.toString()+" for objectproperty: "+tuple.a.toString() +" is not valid, ignoring"); 131 return null; 132 } 133 InstanceNode tmp = new InstanceNode(tuple.b.toString()); 134 objectProperties.add(new ObjectPropertyNode(tuple.a.toString(), this, tmp)); 135 return tmp; 136 } 137 } catch (Exception e) { 138 tail("process tuple: problem with: " + tuple); 139 e.printStackTrace(); 140 return null; 141 } 142 } 143 144 // gets the types for properties recursively 145 @Override 146 public List<BlankNode> expandProperties(TupleAquisitor tupelAquisitor, Manipulator manipulator, boolean dissolveBlankNodes) { 147 List<BlankNode> ret = new ArrayList<>(); 148 for (ObjectPropertyNode one : objectProperties) { 149 ret.addAll(one.expandProperties(tupelAquisitor, manipulator, dissolveBlankNodes)); 150 } 151 152 for (DatatypePropertyNode one : datatypeProperties) { 153 ret.addAll(one.expandProperties(tupelAquisitor, manipulator, dissolveBlankNodes)); 154 } 155 return ret; 156 157 } 158 159 @Override 160 public SortedSet<String> toNTriple() { 161 SortedSet<String> returnSet = new TreeSet<>(); 162 returnSet.add("<" + uri + "><" + OWLVocabulary.RDF_TYPE + "><" + OWLVocabulary.OWL_THING + ">."); 163 for (ClassNode one : classes) { 164 returnSet.add("<" + uri + "><" + OWLVocabulary.RDF_TYPE + "><" + one.getURIString() + ">."); 165 returnSet.addAll(one.toNTriple()); 166 } 167 for (ObjectPropertyNode one : objectProperties) { 168 returnSet.add("<" + uri + "><" + one.getURIString() + "><" + one.getBPart().getURIString() 169 + ">."); 170 returnSet.addAll(one.toNTriple()); 171 returnSet.addAll(one.getBPart().toNTriple()); 172 } 173 174 for (DatatypePropertyNode one : datatypeProperties) { 175 returnSet.add("<" + uri + "><" + one.getURIString() + "> " + one.getNTripleFormOfB() 176 + " ."); 177 } 178 179 return returnSet; 180 } 181 182 @Override 183 public void toOWLOntology( OWLAPIOntologyCollector owlAPIOntologyCollector){ 184 OWLDataFactory factory = owlAPIOntologyCollector.getFactory(); 185 186 187 OWLNamedIndividual me = factory.getOWLNamedIndividual(getIRI()); 188 189 for (ClassNode one : classes) { 190 //create Axiom 191 OWLClass c = factory.getOWLClass(one.getIRI()); 192 OWLAxiom ax = factory.getOWLClassAssertionAxiom(c, me); 193 //collect 194 owlAPIOntologyCollector.addAxiom(ax); 195 //handover 196 one.toOWLOntology(owlAPIOntologyCollector); 197 } 198 for (ObjectPropertyNode one : objectProperties) { 199 OWLAxiom ax = null; 200 if(one.getURIString().equals(OWLVocabulary.OWL_DIFFERENT_FROM)){ 201 OWLIndividual o = factory.getOWLNamedIndividual(one.getBPart().getIRI()); 202 203 ax = factory.getOWLDifferentIndividualsAxiom(me, o); 204 }else{ 205 206 //create axiom 207 OWLIndividual o = factory.getOWLNamedIndividual(one.getBPart().getIRI()); 208 OWLObjectProperty p = factory.getOWLObjectProperty(one.getIRI()); 209 ax = factory.getOWLObjectPropertyAssertionAxiom(p, me, o); 210 } 211 //collect 212 owlAPIOntologyCollector.addAxiom(ax); 213 214 //handover 215 one.toOWLOntology(owlAPIOntologyCollector); 216 one.getBPart().toOWLOntology(owlAPIOntologyCollector); 217 } 218 219 for (DatatypePropertyNode one : datatypeProperties) { 220 OWLDataProperty p = factory.getOWLDataProperty(one.getIRI()); 221 Literal ln = one.getBPart().getLiteral(); 222 223 switch (one.getURIString()) { 224 case OWLVocabulary.RDFS_COMMENT: 225 //skip 226 //OWLCommentAnnotation comment = factory.getOWL(one.b.toString()); 227 //owlAPIOntologyCollector.addAxiom(factory.getOWLEntityAnnotationAxiom(me, label)); 228 break; 229 case OWLVocabulary.RDFS_LABEL: 230 OWLAnnotation annoLabel = factory.getOWLAnnotation(factory.getRDFSLabel(), factory.getOWLLiteral(ln.getString())); 231 OWLAxiom ax = factory.getOWLAnnotationAssertionAxiom(me.getIRI(), annoLabel); 232 owlAPIOntologyCollector.addAxiom(ax); 233 break; 234 default: 235 236 try { 237 238 if (one.getBPart().isFloat()) { 239 owlAPIOntologyCollector.addAxiom( 240 factory.getOWLDataPropertyAssertionAxiom(p, me, ln.getFloat())); 241 } else if (one.getBPart().isDouble()) { 242 owlAPIOntologyCollector.addAxiom( 243 factory.getOWLDataPropertyAssertionAxiom(p, me, ln.getDouble())); 244 } else if (one.getBPart().isInt()) { 245 owlAPIOntologyCollector.addAxiom( 246 factory.getOWLDataPropertyAssertionAxiom(p, me, ln.getInt())); 247 } else if (one.getBPart().isBoolean()) { 248 owlAPIOntologyCollector.addAxiom( 249 factory.getOWLDataPropertyAssertionAxiom(p, me, ln.getBoolean())); 250 } else if (one.getBPart().isString()) { 251 //System.out.println(ln.getString()+" "+one.getBPart().isBoolean()); 252 owlAPIOntologyCollector.addAxiom( 253 factory.getOWLDataPropertyAssertionAxiom(p, me, ln.getString())); 254 255 } else { 256 tail("strange dataytype in ontology conversion" + one.getURIString() + " datatype: " + one.getBPart().getNTripleForm()); 257 } 258 259 //handover 260 one.toOWLOntology(owlAPIOntologyCollector); 261 262 } catch (Exception e) { 263 e.printStackTrace(); 264 tail("strange dataytype in ontology conversion" + one.getURIString() + " datatype: " + one.getBPart().getNTripleForm()); 265 } 266 break; 267 } 268 //factory.getOWLDataPropertyAssertionAxiom() 269 //returnSet.add("<" + uri + "><" + one.getURI() + "> " + one.getNTripleFormOfB() 270 // + " ."); 271 } 272 } 273 274 275 public List<ObjectPropertyNode> getObjectProperties() { 276 return objectProperties; 277 } 278 279 public List<DatatypePropertyNode> getDatatypePropertyNode() { 280 return datatypeProperties; 281 } 282 283 284 285}