001/*
002 *                  BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 * Created on Jan 18, 2008
021 *
022 */
023
024package org.biojava.nbio.ontology.obo;
025
026import org.biojava.nbio.ontology.AlreadyExistsException;
027import org.biojava.nbio.ontology.Ontology;
028import org.biojava.nbio.ontology.Synonym;
029import org.biojava.nbio.ontology.Term;
030import org.biojava.nbio.ontology.utils.Annotation;
031import org.slf4j.Logger;
032import org.slf4j.LoggerFactory;
033
034import java.util.ArrayList;
035import java.util.List;
036
037/** A  file handler for .obo files
038 *
039 * @author Andreas Prlic
040 *
041 */
042public class OboFileHandler implements OboFileEventListener {
043
044        private static final Logger logger = LoggerFactory.getLogger(OboFileEventListener.class);
045
046        Ontology ontology;
047        List<Term> termStack ;
048
049        public static final String TERM        = "Term";
050        public static final String TYPEDEF     = "Typedef";
051        public static final String ONTOLOGY    = "ontologys";
052        public static final String ID_KEY      = "id";
053        public static final String SYNONYM     = "synonym";
054        public static final String EXACT_SYNONYM  = "exact_synonym";
055        public static final String BROAD_SYNONYM  = "broad_synonym";
056        public static final String NARROW_SYNONYM = "narrow_synonym";
057        public static final String REL_SYNONYM = "related_synonym";
058        public static final String NAME        = "name";
059        public static final String DEF         = "def";
060        public static final String XREF_ANALOG = "xref_analog";
061        public static final String COMMENT     = "comment";
062        public static final String IS_A        = "is_a";
063        public static final String IS_OBSOLETE = "is_obsolete";
064        public static final String RELATIONSHIP = "relationship";
065        public static final String DISJOINT_FROM = "disjoint_from";
066        public static final String SUBSET       = "subset";
067        public static final String INTERSECTION_OF = "intersection_of";
068
069
070        public static final String ALT_ID      = "alt_id";
071
072        boolean isTerm ;
073
074        private Term currentTerm;
075
076        public OboFileHandler(Ontology ontology){
077                this.ontology = ontology ;
078
079                //Term isa = onto.importTerm(OntoTools.IS_A, null);
080                //Term partof = onto.importTerm(OntoTools.PART_OF, null);;
081
082        }
083
084        @Override
085        public void documentEnd() {
086                // TODO Auto-generated method stub
087
088        }
089
090        @Override
091        public void documentStart() {
092                termStack = new ArrayList<Term>();
093        }
094
095        @Override
096        public void newOboFileHeader() {
097                // TODO Auto-generated method stub
098        }
099
100        @Override
101        public void newStanza(String stanza) {
102                //logger.info("got a new stanza: {}", stanza);
103                if ( stanza.equals(TERM)){
104                        isTerm = true;
105                        currentTerm = null;
106                } else {
107                        isTerm = false;
108                }
109
110        }
111
112        @Override
113        public void newKey(String key, String value) {
114                if (isTerm) {
115
116                        if ( key.equals(ID_KEY)) {
117                                if ( ontology.containsTerm(key)){
118                                        currentTerm = ontology.getTerm(key);
119                                } else {
120                                        try {
121                                                if (  ontology.containsTerm(value)) {
122                                                        currentTerm = ontology.getTerm(value);
123                                                } else {
124                                                        currentTerm = ontology.createTerm(value);
125                                                }
126                                        } catch (AlreadyExistsException ex) {
127                                                logger.error("Exception: ", ex);
128                                        }
129
130                                }
131                                return;
132                        }
133                        if (currentTerm == null) {
134                                logger.warn("did not find ID for Term! ");
135                                return;
136                        }
137                        else if (key.equals(NAME)){
138                                currentTerm.setDescription(value);
139                        } else if (key.equals(DEF)){
140                                //TODO
141                                // set definition
142                                Annotation anno = currentTerm.getAnnotation();
143                                anno.setProperty(DEF, value);
144                        } else if (key.equals(XREF_ANALOG)){
145                                // set xref analog
146                                Annotation anno = currentTerm.getAnnotation();
147                                anno.setProperty(XREF_ANALOG, value);
148                        } else if (key.equals(IS_OBSOLETE)) {
149                                // ignore obsolete Terms...
150                                //logger.info("obsolete: {}", currentTerm);
151                                Annotation anno = currentTerm.getAnnotation();
152                                anno.setProperty(IS_OBSOLETE, new Boolean(true));
153
154                        } else if (key.equals(IS_A) ||
155                                        key.equals(RELATIONSHIP) ||
156                                        key.equals(DISJOINT_FROM) ||
157                                        key.equals(INTERSECTION_OF) ||
158                                        key.equals(SUBSET)) {
159                                try {
160                                        Term object = (ontology.containsTerm(value) ?
161                                                        ontology.getTerm(value): ontology.createTerm(value));
162                                        Term predicate = (ontology.containsTerm(key) ? ontology.getTerm(key) : ontology.createTerm(key));
163                                        ontology.createTriple(currentTerm, object, predicate, currentTerm + " " + predicate + " " + object, key+"-relationship");
164                                } catch (AlreadyExistsException ex) {
165                                }
166
167                        } else if (key.equals(COMMENT)){
168                                Annotation anno = currentTerm.getAnnotation();
169                                anno.setProperty(COMMENT, value);
170                        } else if (key.equals(ALT_ID)){
171                                Annotation anno = currentTerm.getAnnotation();
172                                anno.setProperty(ALT_ID, value);
173                        }
174
175                        else {
176                                //logger.info("unknown key {}", key);
177                        }
178
179
180                } else {
181                        //logger.info("not a term and ignoring: {}->{}", key, value);
182                }
183
184        }
185
186        @Override
187        public void newSynonym(Synonym synonym) {
188                if (isTerm) {
189                        currentTerm.addSynonym(synonym);
190                }
191        }
192
193}