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