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        public static final String NAMESPACE = "namespace";
069        public static final String REPLACED_BY = "replaced_by";
070
071
072        public static final String ALT_ID      = "alt_id";
073
074        boolean isTerm ;
075
076        private Term currentTerm;
077
078        public OboFileHandler(Ontology ontology){
079                this.ontology = ontology ;
080
081                //Term isa = onto.importTerm(OntoTools.IS_A, null);
082                //Term partof = onto.importTerm(OntoTools.PART_OF, null);;
083
084        }
085
086        @Override
087        public void documentEnd() {
088                // TODO Auto-generated method stub
089
090        }
091
092        @Override
093        public void documentStart() {
094                termStack = new ArrayList<Term>();
095        }
096
097        @Override
098        public void newOboFileHeader() {
099                // TODO Auto-generated method stub
100        }
101
102        @Override
103        public void newStanza(String stanza) {
104                //logger.info("got a new stanza: {}", stanza);
105                if ( stanza.equals(TERM)){
106                        isTerm = true;
107                        currentTerm = null;
108                } else {
109                        isTerm = false;
110                }
111
112        }
113
114        @Override
115        public void newKey(String key, String value) {
116                if (isTerm) {
117
118                        if ( key.equals(ID_KEY)) {
119                                if ( ontology.containsTerm(key)){
120                                        currentTerm = ontology.getTerm(key);
121                                } else {
122                                        try {
123                                                if (  ontology.containsTerm(value)) {
124                                                        currentTerm = ontology.getTerm(value);
125                                                } else {
126                                                        currentTerm = ontology.createTerm(value);
127                                                }
128                                        } catch (AlreadyExistsException ex) {
129                                                logger.error("Exception: ", ex);
130                                        }
131
132                                }
133                                return;
134                        }
135                        if (currentTerm == null) {
136                                logger.warn("did not find ID for Term! ");
137                                return;
138                        }
139                        if (key.equals(NAMESPACE)){
140                                Annotation anno = currentTerm.getAnnotation();
141                                anno.setProperty(NAMESPACE, value);
142                        }
143                        else if (key.equals(NAME)){
144                                currentTerm.setDescription(value);
145                        } else if (key.equals(DEF)){
146                                //TODO
147                                // set definition
148                                Annotation anno = currentTerm.getAnnotation();
149                                anno.setProperty(DEF, value);
150                        } else if (key.equals(XREF_ANALOG)){
151                                // set xref analog
152                                Annotation anno = currentTerm.getAnnotation();
153                                anno.setProperty(XREF_ANALOG, value);
154                        } else if (key.equals(IS_OBSOLETE)) {
155                                // ignore obsolete Terms...
156                                //logger.info("obsolete: {}", currentTerm);
157                                Annotation anno = currentTerm.getAnnotation();
158                                anno.setProperty(IS_OBSOLETE, new Boolean(true));
159
160                        } else if (key.equals(IS_A) ||
161                                        key.equals(RELATIONSHIP) ||
162                                        key.equals(DISJOINT_FROM) ||
163                                        key.equals(INTERSECTION_OF) ||
164                                        key.equals(SUBSET)) {
165                                try {
166                                        Term object = (ontology.containsTerm(value) ?
167                                                        ontology.getTerm(value): ontology.createTerm(value));
168                                        Term predicate = (ontology.containsTerm(key) ? ontology.getTerm(key) : ontology.createTerm(key));
169                                        ontology.createTriple(currentTerm, object, predicate, currentTerm + " " + predicate + " " + object, key+"-relationship");
170                                } catch (AlreadyExistsException ex) {
171                                }
172
173                        } else if (key.equals(COMMENT)){
174                                Annotation anno = currentTerm.getAnnotation();
175                                anno.setProperty(COMMENT, value);
176                        } else if (key.equals(ALT_ID)){
177                                Annotation anno = currentTerm.getAnnotation();
178                                anno.setProperty(ALT_ID, value);
179                        }
180                        else if (key.equals(REPLACED_BY)) {
181                                Annotation anno = currentTerm.getAnnotation();
182                                anno.setProperty(REPLACED_BY, value);
183                        }
184
185                        else {
186                                //logger.info("unknown key {}", key);
187                        }
188
189
190                } else {
191                        //logger.info("not a term and ignoring: {}->{}", key, value);
192                }
193
194        }
195
196        @Override
197        public void newSynonym(Synonym synonym) {
198                if (isTerm) {
199                        currentTerm.addSynonym(synonym);
200                }
201        }
202
203}