001    /**
002     * Copyright (C) 2010 The Roslin Institute <contact andy.law@roslin.ed.ac.uk>
003     *
004     * This file is part of the Ensembl Java API demonstration project developed by the
005     * Bioinformatics Group at The Roslin Institute, The Royal (Dick) School of
006     * Veterinary Studies, University of Edinburgh.
007     *
008     * This is free software: you can redistribute it and/or modify
009     * it under the terms of the GNU General Public License (version 3) as published by
010     * the Free Software Foundation.
011     *
012     * This software is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015     * GNU General Public License for more details.
016     *
017     * You should have received a copy of the GNU General Public License
018     * in this software distribution. If not, see <http://www.gnu.org/licenses/gpl-3.0.html/>.
019     */
020    
021    package uk.ac.roslin.ensembl.datasourceaware.core;
022    
023    import java.util.ArrayList;
024    import java.util.Collection;
025    import java.util.HashMap;
026    import java.util.List;
027    import java.util.TreeMap;
028    import java.util.TreeSet;
029    import org.apache.log4j.Logger;
030    import uk.ac.roslin.ensembl.config.EnsemblComparaDivision;
031    import uk.ac.roslin.ensembl.dao.factory.DAOCoreFactory;
032    import uk.ac.roslin.ensembl.exception.DAOException;
033    import uk.ac.roslin.ensembl.model.ObjectType;
034    import uk.ac.roslin.ensembl.model.core.Analysis;
035    import uk.ac.roslin.ensembl.model.core.Gene;
036    import uk.ac.roslin.ensembl.model.core.Transcript;
037    import uk.ac.roslin.ensembl.config.FeatureType;
038    import uk.ac.roslin.ensembl.datasourceaware.compara.DAHomologyPairRelationship;
039    import uk.ac.roslin.ensembl.model.core.Species;
040    
041    public class DAGene extends DAFeature implements Gene {
042    
043    
044        private String biotype = null;
045        private DAAnalysis analysis = null;
046        private Integer canonicalTranscriptID = null;
047        private String stableID = null;
048        private TreeMap<Integer, DATranscript> transcriptHash = null;
049        private HashMap<EnsemblComparaDivision, List<DAHomologyPairRelationship>> homologies =
050                new HashMap<EnsemblComparaDivision, List<DAHomologyPairRelationship>>();
051        private TreeSet<EnsemblComparaDivision> homologySearchesPerformed = new TreeSet<EnsemblComparaDivision>();
052    
053        final static Logger LOGGER = Logger.getLogger(DAGene.class);
054    
055        public DAGene() {
056            super();
057        }
058    
059        public DAGene(DAOCoreFactory factory) {
060            super(factory);
061         }
062    
063        @Override
064        public ObjectType getType() {
065            return FeatureType.gene;
066        }
067    
068        public DAAnalysis getAnalysis() {
069            return this.analysis;
070        }
071    
072        public void setAnalysis(Analysis analysis) {
073            this.analysis = (DAAnalysis) analysis;
074        }
075    
076        public String getBiotype() {
077            return this.biotype;
078        }
079    
080        public void setBiotype(String biotype) {
081            this.biotype = biotype;
082        }
083    
084        public Collection<DATranscript> getTranscripts() {
085            if (transcriptHash == null) {
086    
087                try {
088                    transcriptHash = new TreeMap<Integer, DATranscript>();
089                    return (Collection<DATranscript>) this.getDaoFactory().getTranscriptDAO().getTranscriptsForGene(this);
090                } catch (Exception e) {
091                    transcriptHash = new TreeMap<Integer, DATranscript>();
092                    LOGGER.info("Threw DAOException on tryiong to populate transcripts for a Gene", e);
093                }
094    
095            }
096            return this.transcriptHash.values();
097        }
098    
099        public void addTranscript(Transcript transcript) {
100            if (transcriptHash==null) {
101                transcriptHash = new TreeMap<Integer, DATranscript>();
102            }
103            try {
104                DATranscript t = (DATranscript) transcript;
105                this.transcriptHash.put(t.getId(), t);
106            } catch (Exception e) {
107                LOGGER.info("failed to add atranscript to the Gene", e);
108            }
109        }
110    
111        public DATranscript getCanonicalTranscript() {
112            if (this.canonicalTranscriptID==null || this.canonicalTranscriptID == 0) {
113                return null;
114            }
115            this.getTranscripts();   
116            if (this.transcriptHash.containsKey(this.canonicalTranscriptID)) {
117                return this.transcriptHash.get(this.canonicalTranscriptID);
118            } else {
119                return null;
120            }
121           
122        }
123    
124        public String getStableID() {
125            return stableID;
126        }
127    
128        public void setStableID(String stableID) {
129            this.stableID = stableID;
130        }
131    
132        public Integer getCanonicalTranscriptID() {
133            return canonicalTranscriptID;
134        }
135    
136        public void setCanonicalTranscriptID(Integer canonicalTranscriptID) {
137            this.canonicalTranscriptID = canonicalTranscriptID;
138        }
139    
140        public DATranslation getCanonicalTranslation() {
141            if (this.getCanonicalTranscript() != null) {
142                return this.getCanonicalTranscript().getTranslation();
143            } else {
144                return null;
145            }
146        }
147        
148        /**
149         * Returns all Homologies (as a List of HomologyPairRelationships) in the default
150         * ComparaDivision for this Gene. Implemented by 
151         * calling getHomologies(EnsemblComparaDivision comparaDivision) with
152         * the default ComparaDivision for this Gene. 
153         * @return
154         */
155        public List<DAHomologyPairRelationship> getHomologies() {
156            return this.getHomologies(this.getComparaDivision());
157        }
158    
159        /**
160         * Returns all Homologies (as a List of HomologyPairRelationships) in the specified
161         * ComparaDivision for this Gene.  
162         * @param comparaDivision
163         * @return
164         */
165        public List<DAHomologyPairRelationship> getHomologies(EnsemblComparaDivision comparaDivision) {
166    
167            List<DAHomologyPairRelationship> out = null;
168    
169            if (comparaDivision==null) {
170                return out;
171            }
172    
173            if (!this.homologySearchesPerformed.contains(comparaDivision)) {
174    
175                if (this.getStableID() == null || this.getStableID().isEmpty()) {
176                    return out;
177                }
178    
179                try {
180                    out = (List<DAHomologyPairRelationship>) this.getComparaFactory(comparaDivision).getHomologyDAO().getHomologiesForGene(this);
181                    this.homologySearchesPerformed.add(comparaDivision);
182                    //this would over write any existing... maybe ok!
183                    this.homologies.put(comparaDivision, out);
184    
185    //                if (this.homologies.get(comparaDivision) == null) {
186    //                    this.homologies.put(comparaDivision, new ArrayList<DAHomologyPairRelationship>());
187    //                }
188    //                this.homologies.get(comparaDivision).addAll(out);
189    
190                } catch (Exception ex) {
191                    LOGGER.info("failed to get Homologies", ex);
192                }
193    
194            }
195    
196            if (this.homologies.containsKey(comparaDivision)) {
197                return this.homologies.get(comparaDivision);
198            } else {
199                return new ArrayList<DAHomologyPairRelationship>();
200            }
201        }
202    
203    
204        /**
205         * Returns Homologies (as a List of HomologyPairRelationships) in the default
206         * ComparaDivision for this Gene for the specified Species. Implemented by 
207         * calling getHomologies(EnsemblComparaDivision comparaDivision, Species sp) with
208         * the default ComparaDivision for this Gene. 
209         * @param sp
210         * @return
211         */
212        public List<DAHomologyPairRelationship> getHomologies(Species sp) {
213            return this.getHomologies(this.getComparaDivision(), sp);
214        }
215    
216        /**
217         * Returns Homologies (as a List of HomologyPairRelationships) in the specified
218         * ComparaDivision for the specified Species.
219         * Cos of the lack of indices it is much faster to implement using the query
220         * to get  all homologues than restrict to a single gdb.name in the sql [unless
221         * you do it by a specific subselect]. So to get homologues for a single species do
222         * the whole query and do the filterring in the Java. This allows us to store
223         * all homologies at once too.
224         * @param comparaDivision
225         * @param sp
226         * @return
227         */
228        public List<DAHomologyPairRelationship> getHomologies(EnsemblComparaDivision comparaDivision, Species sp) {
229    
230            //make sure basic fetch is done
231            this.getHomologies(comparaDivision);
232            
233            List<DAHomologyPairRelationship> out = new ArrayList<DAHomologyPairRelationship>();
234    
235            if (homologies.get(comparaDivision)!=null && !homologies.get(comparaDivision).isEmpty()) {
236                for (DAHomologyPairRelationship r : homologies.get(comparaDivision)) {
237                    if (r.getTarget().getSpecies()!=null
238                            && r.getTarget().getSpecies().equals(sp)) {
239                        out.add(r);
240                    }
241                }
242            }
243            return out;
244        }
245    
246    
247        public void addHomology(EnsemblComparaDivision division, DAHomologyPairRelationship homology) {
248    
249            if (this.homologies.get(division)==null) {
250                this.homologies.put(division, new ArrayList<DAHomologyPairRelationship>());
251            }
252            this.homologies.get(division).add(homology);
253    
254        }
255    
256        public boolean setSearchedHomologies (EnsemblComparaDivision comparaDivision) {
257            return this.homologySearchesPerformed.add(comparaDivision);
258        }
259        
260        @Override
261        void reinitialize() throws DAOException
262        {
263            try {
264                this.getDaoFactory().getGeneDAO().reInitialize(this);
265            } catch (DAOException dex) {
266                throw dex;
267            } catch (Exception ex) {
268                throw new DAOException("Failed to reinitialize a gene from the Database", ex);
269            }
270        }
271    
272        @Override
273        public String getDisplayName() {
274            return (displayName!=null) ? displayName : stableID ;
275        }
276    
277        /**
278         * Utility method to get all of the current DAHomologyPairRelationships for this Gene
279         *
280         * @return List<DAHomologyPair BinaryRelationship>
281         */
282        public List<DAHomologyPairRelationship> getHomologiesWithoutLazyLoad() {
283    
284            List<DAHomologyPairRelationship> out = new ArrayList<DAHomologyPairRelationship>();
285    
286            for (EnsemblComparaDivision div: homologies.keySet()) {
287                    out.addAll(homologies.get(div));
288            }
289            return out;
290        }
291    }