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 org.apache.log4j.Logger; 022import org.dllearner.kb.aquisitors.RDFBlankNode; 023import org.dllearner.kb.aquisitors.TupleAquisitor; 024import org.dllearner.kb.manipulator.Manipulator; 025import org.dllearner.utilities.datastructures.RDFNodeTuple; 026import org.dllearner.utilities.datastructures.StringTuple; 027import org.dllearner.utilities.owl.OWLVocabulary; 028import org.semanticweb.owlapi.model.IRI; 029import org.semanticweb.owlapi.model.OWLClassExpression; 030import org.semanticweb.owlapi.model.OWLDataFactory; 031import org.semanticweb.owlapi.model.OWLObjectProperty; 032 033import java.util.*; 034 035public class BlankNode extends Node { 036 private static Logger logger = Logger 037 .getLogger(BlankNode.class); 038 039 RDFBlankNode bNode; 040 041 String inboundEdge; 042 043 044 private List<BlankNode> blankNodes = new ArrayList<>(); 045 private SortedSet<StringTuple> otherNodes = new TreeSet<>(); 046 private List<DatatypePropertyNode> datatypeProperties = new ArrayList<>(); 047 048 //private List<ObjectPropertyNode> objectProperties = new ArrayList<ObjectPropertyNode>(); 049 //private List<OWLDataPropertyNode> datatypeProperties = new ArrayList<OWLDataPropertyNode>(); 050 051 052 public BlankNode(RDFBlankNode bNode, String inboundEdge){ 053 super(""+bNode.getBNodeId()); 054 this.bNode=bNode; 055 this.inboundEdge = inboundEdge; 056 } 057 058 059 060 @Override 061 public List<Node> expand(TupleAquisitor tupleAquisitor, 062 Manipulator manipulator) { 063 List<Node> newNodes = new ArrayList<>(); 064 SortedSet<RDFNodeTuple> s = tupleAquisitor.getBlankNode(bNode.getBNodeId()); 065 //System.out.println("entering "+bNode.getBNodeId()); 066 067 068 for (RDFNodeTuple tuple : s) { 069 if(tuple.b.isLiteral()) { 070 //System.out.println("adding dtype: "+tuple); 071 datatypeProperties.add(new DatatypePropertyNode(tuple.a.toString(), this, new LiteralNode(tuple.b) )); 072 //connectedNodes.add(new DatatypePropertyNode(tuple.a.toString(), this, new LiteralNode(tuple.b) )); 073 }else if(tuple.b.isAnon()){ 074 //System.out.println("adding bnode: "+tuple); 075 BlankNode tmp = new BlankNode( (RDFBlankNode)tuple.b, tuple.a.toString()); 076 //objectProperties.add(new ObjectPropertyNode(tuple.a.toString(), this, tmp )); 077 //connectedNodes.add(new BlankNode( (RDFBlankNode)tuple.b, tuple.a.toString())); 078 blankNodes.add(tmp); 079 newNodes.add(tmp); 080 }else{ 081 //System.out.println("adding other: "+tuple); 082 otherNodes.add(new StringTuple(tuple.a.toString(), tuple.b.toString())); 083 //objectProperties.add(new ObjectPropertyNode(tuple.a.toString(), this, new ClassNode(tuple.b.toString()) )); 084 //connectedNodes.add(new ObjectPropertyNode(tuple.a.toString(), this, new ClassNode(tuple.b.toString()) )); 085 } 086 } 087 088 //System.out.println("finished"); 089 090 return newNodes; 091 } 092 093 @Override 094 public List<BlankNode> expandProperties(TupleAquisitor TupelAquisitor, 095 Manipulator manipulator, boolean dissolveBlankNodes) { 096 return new ArrayList<>(); 097 } 098 099 @Override 100 public SortedSet<String> toNTriple() { 101 SortedSet<String> returnSet = new TreeSet<>(); 102 //String subject = getNTripleForm(); 103 /*for (OWLObjectPropertyNode one : objectProperties) { 104 returnSet.add(subject + one.getNTripleForm() + one.getBPart().getNTripleForm()+" . "); 105 returnSet.addAll(one.getBPart().toNTriple()); 106 }*/ 107 return returnSet; 108 } 109 110 @Override 111 public String getNTripleForm(){ 112 return " "+uri+" "; 113 } 114 115 @Override 116 public String toString(){ 117 return "id: "+bNode.getBNodeId()+" inbound: "+getInBoundEdge(); 118 119 } 120 121 @Override 122 public IRI getIRI(){ 123 return IRI.create("http://www.empty.org/empty#empty"); 124 } 125 126 @Override 127 public void toOWLOntology( OWLAPIOntologyCollector owlAPIOntologyCollector){ 128 logger.error("toOWLOntology called in blanknodes "); 129 //FIXME robably not needed 130 } 131 132 public String getInBoundEdge(){ 133 return inboundEdge; 134 } 135 136 public OWLClassExpression getAnonymousClass(OWLAPIOntologyCollector owlAPIOntologyCollector){ 137 OWLDataFactory factory = owlAPIOntologyCollector.getFactory(); 138 OWLClassExpression ret = factory.getOWLClass(IRI.create("http://dummy.org/dummy")); 139 140 //System.out.println(inboundEdge); 141 142 if( 143 (inboundEdge.equals(OWLVocabulary.OWL_intersectionOf))|| 144 (inboundEdge.equals(OWLVocabulary.OWL_complementOf))|| 145 (inboundEdge.equals(OWLVocabulary.OWL_unionOf)) 146 ){ 147 Set<OWLClassExpression> target = new HashSet<>(); 148 List<BlankNode> tmp = new ArrayList<>(); 149 tmp.add(this); 150 while(!tmp.isEmpty()){ 151 BlankNode next = tmp.remove(0); 152 //next.printAll(); 153 154 if(next.otherNodes.contains(new StringTuple(OWLVocabulary.RDF_REST, OWLVocabulary.RDF_NIL))){ 155 for(StringTuple t : next.otherNodes){ 156 if(t.a.equals(OWLVocabulary.RDF_FIRST)){ 157 target.add(factory.getOWLClass(IRI.create(t.b))); 158 //System.out.println("added "+t.b); 159 } 160 } 161 //System.out.println("nil found"); 162 //do nothing 163 }else{ 164 StringTuple firstOtherNodes = null; 165 try{ 166 firstOtherNodes = next.otherNodes.first(); 167 if(firstOtherNodes.a.equals(OWLVocabulary.RDF_FIRST)){ 168 target.add(factory.getOWLClass(IRI.create(firstOtherNodes.b))); 169 tmp.add(next.blankNodes.get(0)); 170 //System.out.println("bnode added"); 171 }else{ 172 173 tail("double nesting not supported yet"); 174 175 } 176 177 178 }catch (NoSuchElementException e) { 179 logger.warn("something strange happened here: "+firstOtherNodes); 180 logger.warn("and here: "+next.otherNodes); 181 e.printStackTrace(); 182 } 183 184 } 185 }//end while 186 187 switch (inboundEdge) { 188 case OWLVocabulary.OWL_intersectionOf: 189 return factory.getOWLObjectIntersectionOf(target); 190 case OWLVocabulary.OWL_unionOf: 191 return factory.getOWLObjectUnionOf(target); 192 case OWLVocabulary.OWL_complementOf: 193 if (target.size() > 1) { 194 tail("more than one complement" + target); 195 196 } else { 197 return factory.getOWLObjectComplementOf(new ArrayList<>(target).remove(0)); 198 } 199 break; 200 default: 201 printAll(); 202 tail("bnode: wrong type: " + inboundEdge + this); 203 break; 204 } 205 } 206 207 // restriction 208 if(otherNodes.contains( 209 new StringTuple(OWLVocabulary.RDF_TYPE, OWLVocabulary.OWL_RESTRICTION))){ 210 return getRestriction( owlAPIOntologyCollector); 211 212 } 213 214 if(!blankNodes.isEmpty()){ 215 return blankNodes.get(0).getAnonymousClass(owlAPIOntologyCollector); 216 } 217 218 219 return ret; 220 221 } 222 223 public void printAll(){ 224 logger.debug(this); 225 226 logger.debug("otherNodes"); 227 for (StringTuple t : otherNodes) { 228 logger.debug(""+t); 229 } 230 logger.debug("***************"); 231 logger.debug("dtype "); 232 for (DatatypePropertyNode d : datatypeProperties) { 233 logger.debug(d.getURIString()+" "+d.getNTripleFormOfB()); 234 } 235 logger.debug("***************"); 236 logger.debug("other bnodes"); 237 for (BlankNode b : blankNodes) { 238 logger.debug(b); 239 } 240 logger.debug("***************"); 241 242 } 243 244 private OWLClassExpression getRestriction(OWLAPIOntologyCollector owlAPIOntologyCollector){ 245 OWLDataFactory factory = owlAPIOntologyCollector.getFactory(); 246 OWLObjectProperty property = null; 247 OWLClassExpression concept = null; 248 OWLClassExpression dummy = factory.getOWLClass(IRI.create("http://dummy.org/dummy")); 249 250 int total = otherNodes.size()+blankNodes.size()+datatypeProperties.size(); 251 if(total >=4 ){ 252 logger.info("qualified p restrictions not supported currently"); 253 } 254 255 // get Objectproperty 256 for(StringTuple n : otherNodes) { 257 if(n.a.equals(OWLVocabulary.OWL_ON_PROPERTY)){ 258 property = factory.getOWLObjectProperty(IRI.create(n.b)); 259 } 260 } 261 262 // has an Integer value 263 if(!datatypeProperties.isEmpty()){ 264 DatatypePropertyNode d = datatypeProperties.get(0); 265 String p = d.getURIString(); 266 switch (p) { 267 case OWLVocabulary.OWL_cardinality: 268 return factory.getOWLObjectExactCardinality(d.getBPart().getLiteral().getInt(), property); 269 case OWLVocabulary.OWL_maxCardinality: 270 return factory.getOWLObjectMaxCardinality(d.getBPart().getLiteral().getInt(), property); 271 case OWLVocabulary.OWL_minCardinality: 272 return factory.getOWLObjectMinCardinality(d.getBPart().getLiteral().getInt(), property); 273 default: 274 tail(p + d + " in " + this); 275 break; 276 } 277 } 278 279 if(!blankNodes.isEmpty()){ 280 concept = blankNodes.get(0).getAnonymousClass(owlAPIOntologyCollector); 281 }else{ 282 for(StringTuple n : otherNodes) { 283 String p = n.a; 284 String o = n.b; 285 if( 286 (p.equals(OWLVocabulary.OWL_ALL_VALUES_FROM)) || 287 (p.equals(OWLVocabulary.OWL_SOME_VALUES_FROM)) || 288 (p.equals(OWLVocabulary.OWL_HAS_VALUE)) 289 ){ 290 concept = factory.getOWLClass(IRI.create(o)); 291 } 292 } 293 } 294 295 for(StringTuple n : otherNodes) { 296 String p = n.a; 297 switch (p) { 298 case OWLVocabulary.OWL_ALL_VALUES_FROM: 299 return factory.getOWLObjectAllValuesFrom(property, concept); 300 case OWLVocabulary.OWL_SOME_VALUES_FROM: 301 return factory.getOWLObjectSomeValuesFrom(property, concept); 302 case OWLVocabulary.OWL_HAS_VALUE: 303 logger.warn("OWL_hasValue not implemented yet"); 304 return dummy; 305 } 306 } 307 return dummy; 308 } 309 310 311 312 313 /*private boolean isOfType(String type){ 314 for (Node n : connectedNodes) { 315 if((n instanceof BlankNode ) 316 && 317 ((BlankNode)n).getInBoundEdge().equals(type)) { 318 return true; 319 }else if((n instanceof ObjectPropertyNode ) 320 && 321 ((OWLObjectPropertyNode)n).getAPart().toString().equals(type)) { 322 return true; 323 } 324 } 325 return false; 326 } 327 328 private boolean containsDataTypeProperties(){ 329 for (Node n : connectedNodes) { 330 if(n instanceof DatatypePropertyNode) { 331 return true; 332 } 333 } 334 return false; 335 }*/ 336 337}