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