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.util.ArrayList; 022import java.util.List; 023import java.util.SortedSet; 024import java.util.TreeSet; 025 026import org.apache.log4j.Logger; 027import org.dllearner.kb.aquisitors.RDFBlankNode; 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.OWLClassExpression; 036import org.semanticweb.owlapi.model.OWLDataFactory; 037 038/** 039 * Is a node in the graph, that is a class. 040 * 041 * @author Sebastian Hellmann 042 */ 043public class ClassNode extends Node { 044 045 private static Logger logger = Logger 046 .getLogger(ClassNode.class); 047 048 List<ObjectPropertyNode> classProperties = new ArrayList<>(); 049 List<DatatypePropertyNode> datatypeProperties = new ArrayList<>(); 050 List<BlankNode> blankNodes = new ArrayList<>(); 051 052 public ClassNode(String uri) { 053 super(uri); 054 } 055 056 // expands all directly connected nodes 057 @Override 058 public List<Node> expand(TupleAquisitor tupelAquisitor, Manipulator manipulator) { 059 060 SortedSet<RDFNodeTuple> newTuples = tupelAquisitor.getTupelForResource(this.uri); 061 // see manipulator 062 newTuples = manipulator.manipulate(this, newTuples); 063 064 List<Node> newNodes = new ArrayList<>(); 065 Node tmp; 066 for (RDFNodeTuple tuple : newTuples) { 067 if((tmp = processTuple(tuple,tupelAquisitor.isDissolveBlankNodes()))!= null) { 068 newNodes.add(tmp); 069 } 070 } 071 return newNodes; 072 } 073 074 private Node processTuple( RDFNodeTuple tuple, boolean dissolveBlankNodes) { 075 076 try { 077 String property = tuple.a.toString(); 078 if(tuple.b.isLiteral()) { 079 datatypeProperties.add(new DatatypePropertyNode(tuple.a.toString(), this, new LiteralNode(tuple.b) )); 080 return null; 081 }else if(tuple.b.isAnon()){ 082 if(dissolveBlankNodes){ 083 RDFBlankNode n = (RDFBlankNode) tuple.b; 084 BlankNode tmp = new BlankNode( n, tuple.a.toString()); 085 //add it to the graph 086 blankNodes.add(tmp); 087 //return tmp; 088 return tmp; 089 }else{ 090 //do nothing 091 return null; 092 } 093 // substitute rdf:type with owl:subclassof 094 }else if (property.equals(OWLVocabulary.RDF_TYPE) || 095 OWLVocabulary.isStringSubClassVocab(property)) { 096 ClassNode tmp = new ClassNode(tuple.b.toString()); 097 classProperties.add(new ObjectPropertyNode( OWLVocabulary.RDFS_SUBCLASS_OF, this, tmp)); 098 return tmp; 099 } else { 100 // further expansion stops here 101 ClassNode tmp = new ClassNode(tuple.b.toString()); 102 classProperties.add(new ObjectPropertyNode(tuple.a.toString(), this, tmp)); 103 return tmp; //is missing on purpose 104 } 105 } catch (Exception e) { 106 logger.warn("Problem with: " + this + " in tuple " + tuple); 107 e.printStackTrace(); 108 109 } 110 return null; 111 } 112 113 // gets the types for properties recursively 114 @Override 115 public List<BlankNode> expandProperties(TupleAquisitor tupelAquisitor, Manipulator manipulator, boolean dissolveBlankNodes) { 116 return new ArrayList<>(); 117 } 118 119 120 121 /* 122 * (non-Javadoc) 123 * 124 * @see org.dllearner.kb.sparql.datastructure.Node#toNTriple() 125 */ 126 @Override 127 public SortedSet<String> toNTriple() { 128 SortedSet<String> returnSet = new TreeSet<>(); 129 String subject = getNTripleForm(); 130 returnSet.add(subject+"<" + OWLVocabulary.RDF_TYPE + "><" + OWLVocabulary.OWL_CLASS + ">."); 131 132 for (ObjectPropertyNode one : classProperties) { 133 returnSet.add(subject + one.getNTripleForm() + 134 one.getBPart().getNTripleForm()+" ."); 135 returnSet.addAll(one.getBPart().toNTriple()); 136 } 137 for (DatatypePropertyNode one : datatypeProperties) { 138 returnSet.add(subject+ one.getNTripleForm() + one.getNTripleFormOfB() 139 + " ."); 140 } 141 142 return returnSet; 143 } 144 145 @Override 146 public void toOWLOntology( OWLAPIOntologyCollector owlAPIOntologyCollector){ 147 try{ 148 OWLDataFactory factory = owlAPIOntologyCollector.getFactory(); 149 150 OWLClass me =factory.getOWLClass(getIRI()); 151 for (ObjectPropertyNode one : classProperties) { 152 OWLClass c = factory.getOWLClass(one.getBPart().getIRI()); 153 if(OWLVocabulary.isStringSubClassVocab(one.getURIString())){ 154 owlAPIOntologyCollector.addAxiom(factory.getOWLSubClassOfAxiom(me, c)); 155 }else if(one.getURIString().equals(OWLVocabulary.OWL_DISJOINT_WITH)){ 156 owlAPIOntologyCollector.addAxiom(factory.getOWLDisjointClassesAxiom(me, c)); 157 }else if(one.getURIString().equals(OWLVocabulary.OWL_EQUIVALENT_CLASS)){ 158 owlAPIOntologyCollector.addAxiom(factory.getOWLEquivalentClassesAxiom(me, c)); 159 }else if(one.getURIString().equals(OWLVocabulary.RDFS_IS_DEFINED_BY)){ 160 logger.warn("IGNORING: "+OWLVocabulary.RDFS_IS_DEFINED_BY); 161 continue; 162 }else { 163 tail(true, "in ontology conversion"+" object property is: "+one.getURIString()+" connected with: "+one.getBPart().getURIString()); 164 continue; 165 } 166 one.getBPart().toOWLOntology(owlAPIOntologyCollector); 167 } 168 for (DatatypePropertyNode one : datatypeProperties) { 169 //FIXME add languages 170 // watch for tail 171 switch (one.getURIString()) { 172 case OWLVocabulary.RDFS_COMMENT: { 173 OWLAnnotation annoComment = factory.getOWLAnnotation(factory.getRDFSComment(), factory.getOWLLiteral(one.getBPart().getLiteral().getString())); 174 OWLAxiom ax = factory.getOWLAnnotationAssertionAxiom(me.getIRI(), annoComment); 175 owlAPIOntologyCollector.addAxiom(ax); 176 177 break; 178 } 179 case OWLVocabulary.RDFS_LABEL: { 180 OWLAnnotation annoLabel = factory.getOWLAnnotation(factory.getRDFSLabel(), factory.getOWLLiteral(one.getBPart().getLiteral().getString())); 181 OWLAxiom ax = factory.getOWLAnnotationAssertionAxiom(me.getIRI(), annoLabel); 182 owlAPIOntologyCollector.addAxiom(ax); 183 break; 184 } 185 default: 186 tail(true, "in ontology conversion: no other datatypes, but annotation is allowed for classes." + " data property is: " + one.getURIString() + " connected with: " + one.getBPart().getNTripleForm()); 187 188 break; 189 } 190 191 } 192 for (BlankNode bn : blankNodes) { 193 OWLClassExpression target = bn.getAnonymousClass(owlAPIOntologyCollector); 194 195 if(OWLVocabulary.isStringSubClassVocab(bn.getInBoundEdge())){ 196 owlAPIOntologyCollector.addAxiom(factory.getOWLSubClassOfAxiom(me, target)); 197 }else if(bn.getInBoundEdge().equals(OWLVocabulary.OWL_DISJOINT_WITH)){ 198 owlAPIOntologyCollector.addAxiom(factory.getOWLDisjointClassesAxiom(me, target)); 199 }else if(bn.getInBoundEdge().equals(OWLVocabulary.OWL_EQUIVALENT_CLASS)){ 200 owlAPIOntologyCollector.addAxiom(factory.getOWLEquivalentClassesAxiom(me, target)); 201 }else { 202 tail( "in ontology conversion"+" bnode is: "+bn.getInBoundEdge()+"||"+ bn ); 203 204 } 205 206 } 207 }catch (Exception e) { 208 System.out.println("aaa"+getURIString()); 209 e.printStackTrace(); 210 } 211 } 212 213 214}