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    }