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        @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        @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                        if (key.equals(NAMESPACE)){
138                                Annotation anno = currentTerm.getAnnotation();
139                                anno.setProperty(NAMESPACE, value);
140                        }
141                        else if (key.equals(NAME)){
142                                currentTerm.setDescription(value);
143                        } else if (key.equals(DEF)){
144                                //TODO
145                                // set definition
146                                Annotation anno = currentTerm.getAnnotation();
147                                anno.setProperty(DEF, value);
148                        } else if (key.equals(XREF_ANALOG)){
149                                // set xref analog
150                                Annotation anno = currentTerm.getAnnotation();
151                                anno.setProperty(XREF_ANALOG, value);
152                        } else if (key.equals(IS_OBSOLETE)) {
153                                // ignore obsolete Terms...
154                                //logger.info("obsolete: {}", currentTerm);
155                                Annotation anno = currentTerm.getAnnotation();
156                                anno.setProperty(IS_OBSOLETE, Boolean.TRUE);
157
158                        } else if (key.equals(IS_A) ||
159                                        key.equals(RELATIONSHIP) ||
160                                        key.equals(DISJOINT_FROM) ||
161                                        key.equals(INTERSECTION_OF) ||
162                                        key.equals(SUBSET)) {
163                                try {
164                                        Term object = (ontology.containsTerm(value) ?
165                                                        ontology.getTerm(value): ontology.createTerm(value));
166                                        Term predicate = (ontology.containsTerm(key) ? ontology.getTerm(key) : ontology.createTerm(key));
167                                        ontology.createTriple(currentTerm, object, predicate, currentTerm + " " + predicate + " " + object, key+"-relationship");
168                                } catch (AlreadyExistsException ex) {
169                                }
170
171                        } else if (key.equals(COMMENT)){
172                                Annotation anno = currentTerm.getAnnotation();
173                                anno.setProperty(COMMENT, value);
174                        } else if (key.equals(ALT_ID)){
175                                // #964
176                                Annotation anno = currentTerm.getAnnotation();
177                                if (anno.containsProperty(ALT_ID)) {
178                                        List<String> alts = (List<String>) anno.getProperty(ALT_ID);
179                                        alts.add(value);
180                                } else {
181                                        List<String> alts = new ArrayList<>();
182                                        alts.add(value);
183                                        anno.setProperty(ALT_ID, alts);
184                                }
185                        }
186                        else if (key.equals(REPLACED_BY)) {
187                                Annotation anno = currentTerm.getAnnotation();
188                                anno.setProperty(REPLACED_BY, value);
189                        }
190
191                        else {
192                                //logger.info("unknown key {}", key);
193                        }
194
195
196                } else {
197                        //logger.info("not a term and ignoring: {}->{}", key, value);
198                }
199
200        }
201
202        @Override
203        public void newSynonym(Synonym synonym) {
204                if (isTerm) {
205                        currentTerm.addSynonym(synonym);
206                }
207        }
208
209}