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.config;
022    
023    import java.io.ObjectStreamException;
024    import java.io.Serializable;
025    import java.util.Collection;
026    import java.util.HashMap;
027    import java.util.TreeSet;
028    import uk.ac.roslin.ensembl.model.database.DatabaseType;
029    
030    /**
031     * Concrete implementation of DatabaseType interface for representing static
032     * Ensembl DatabaseTypes. Implements static strings representing each of the current enesmbl
033     * database types, and concrete DatabaseTypes for each of these string types.
034     * @author paterson
035     */
036    public class EnsemblDBType extends EnsemblType implements DatabaseType, Comparable<EnsemblDBType> {
037    
038         /**
039         * The SpecificDBType of a given EnsemblDBType Object
040         * i.e. CORE, COMPARA etc.
041         */
042        private SpecificDBType databaseType;
043    
044        /**
045         * The GenericDBType of a given EnsemblDBType Object
046         * i.e. SINGLE_SPECIES, SPECIES_COMPARISON etc.
047         */
048       private GenericDBType ENSEMBL_TYPE ;
049    
050        /**
051         * Static set holding the Database Types use in cross species comparisons
052         */
053        private static TreeSet<EnsemblDBType> speciesComparisonDBTypes = new TreeSet<EnsemblDBType>();
054    
055        /**
056         * Static set holding the single species Database Types
057         */
058        private static TreeSet<EnsemblDBType> singleSpeciesDBTypes = new TreeSet<EnsemblDBType>();
059    
060        /**
061         * Static set holding the multi-species Database Types in ensembl genomes
062         */
063        private static TreeSet<EnsemblDBType> collectionDBTypes = new TreeSet<EnsemblDBType>();
064           
065        /**
066         * Enumeration of the GenericDBTypes 
067         */
068        private static enum GenericDBType implements Serializable {
069            SPECIES_COMPARISON("species_comparison"),
070            SINGLE_SPECIES("single_species"),
071            COLLECTION("collection");
072            
073            private String label;
074            
075            GenericDBType (String label){
076                this.label=label;
077            }
078    
079            @Override
080            public String toString() {
081                return label;
082            }
083        }
084    
085         /**
086         * Enumeration of the SpecificDBTypes
087         */
088        private static enum SpecificDBType  implements Serializable {
089            
090            CDNA("cdna"),
091            CORE("core"),
092            COREEXPRESSIONEST("coreexpressionest"),
093            COREEXPRESSIONGNF("coreexpressiongnf"),
094            FUNCGEN("funcgen"),
095            OTHERFEATURES("otherfeatures"),
096            VARIATION("variation"),
097            VEGA("vega"),
098            ANCESTRAL("ensembl_ancestral"),
099            COMPARA("ensembl_compara"),
100            GO("ensembl_go"),
101            ONTOLOGY("ensembl_ontology"),
102            WEBSITE("ensembl_website"),
103            COLLECTION_CORE("collection_core"),
104            COLLECTION_FUNCGEN("collection_funcgen"),
105            COLLECTION_VARIATION("collection_variation");    
106            
107            private String label;
108            
109            SpecificDBType (String label){
110                this.label=label;
111            }
112    
113            @Override
114            public String toString() {
115                return label;
116            }        
117            
118            
119        }
120                
121        /**
122         * A concrete instantiation of an DatabaseType object representing the ensembl species cDNA database sType
123         */
124        public static  EnsemblDBType cdna;
125    
126        /**
127         * A concrete instantiation of an DatabaseType object representing the ensembl species core database sType
128         */
129        public static EnsemblDBType core;
130    
131        /**
132         * A concrete instantiation of an DatabaseType object representing the ensembl species coreexpressioncdna database sType
133         */
134        public static EnsemblDBType coreexpressionest;
135    
136        /**
137         * A concrete instantiation of an DatabaseType object representing the ensembl species coreexpressiongnf database sType
138         */
139        public static EnsemblDBType coreexpressiongnf;
140    
141        /**
142         * A concrete instantiation of an DatabaseType object representing the ensembl species funcgen database sType
143         */
144        public static EnsemblDBType funcgen;
145    
146        /**
147         * A concrete instantiation of an DatabaseType object representing the ensembl species otherfeatures database sType
148         */
149        public static EnsemblDBType otherfeatures;
150    
151        /**
152         * A concrete instantiation of an DatabaseType object representing the ensembl species variation database sType
153         */
154        public static EnsemblDBType variation;
155    
156        /**
157         * A concrete instantiation of an DatabaseType object representing the ensembl species vega database sType
158         */
159        public static EnsemblDBType vega;
160    
161        /**
162         * A concrete instantiation of an DatabaseType object representing the ensembl ancestral database sType
163         */
164        public static EnsemblDBType ancestral;
165    
166        /**
167         * A concrete instantiation of an DatabaseType object representing the ensembl compara database sType
168         */
169        public static EnsemblDBType compara;
170    
171        /**
172         * A concrete instantiation of an DatabaseType object representing the ensembl go database sType
173         */
174        public static EnsemblDBType go;
175    
176        /**
177         * A concrete instantiation of an DatabaseType object representing the ensembl ontology database sType
178         */
179        public static EnsemblDBType ontology;
180    
181        /**
182         * A concrete instantiation of an DatabaseType object representing the ensembl website database sType
183         */
184        public static EnsemblDBType website;
185    
186        /**
187         * A concrete instantiation of an DatabaseType object representing the ensemblgenomes collection core database sType
188         */
189        public static EnsemblDBType collection_core;
190    
191        /**
192         * A concrete instantiation of an DatabaseType object representing the ensemblgenomes collection funcgen database sType
193         */
194        public static EnsemblDBType collection_funcgen;
195    
196        /**
197         * A concrete instantiation of an DatabaseType object representing the ensemblgenomes collection variation database sType
198         */
199        public static EnsemblDBType collection_variation;
200    
201        /**
202         *
203         */
204        private static HashMap<String, EnsemblDBType> typeHashList = EnsemblDBType.init();
205    
206         /**
207         * A private accessor to make a concrete instantiation of a EnsemblDBType object for a given string name.
208         * This implements a singleton pattern against each name.
209         * @param typeName  String The name of the EnsemblDBType object to be generated.
210         * @return EnsemblDBType the object
211         */
212        private static EnsemblDBType makeDatabaseType(SpecificDBType sType, GenericDBType gType) {
213    
214            //we have to initialize the hash first time called
215            if (EnsemblDBType.typeHashList == null) {
216                EnsemblDBType.typeHashList = new HashMap<String, EnsemblDBType>();
217            }
218    
219            //if we already have this type use it
220            EnsemblDBType dt = getDBTypeForName(sType.toString());
221            //if not make it, and put it in the relevant hashes
222            if (dt == null) {
223                dt = new EnsemblDBType(sType, gType);
224                EnsemblDBType.typeHashList.put(sType.toString(), dt);
225    
226                if (dt.ENSEMBL_TYPE.equals(GenericDBType.SPECIES_COMPARISON)) {
227                    speciesComparisonDBTypes.add(dt);
228                }
229                else if (dt.ENSEMBL_TYPE.equals(GenericDBType.SINGLE_SPECIES)) {
230                    singleSpeciesDBTypes.add(dt);
231                }
232                else if (dt.ENSEMBL_TYPE.equals(GenericDBType.COLLECTION)) {
233                    collectionDBTypes.add(dt);
234                }
235            }
236            return dt;
237        }
238    
239         /**
240         * A private constructor for making EnsemblDBType objects. Should only be
241         * accessed from within the class - and then only the first time that
242         * the class is accessed when the list of acceptable types is constructed.
243         * @param sType String The name/sType of this object
244         */
245        private EnsemblDBType(SpecificDBType sType, GenericDBType gType) {
246            this.databaseType = sType;
247            this.ENSEMBL_TYPE = gType;
248        }
249    
250        /**
251         * private method to make all the EnsemblDBTypes and put them in a hash
252         * @return HashMap the initialized and populated hash of all the types
253         */
254        private static HashMap init() {
255            cdna = EnsemblDBType.makeDatabaseType(SpecificDBType.CDNA, GenericDBType.SINGLE_SPECIES);
256            core = EnsemblDBType.makeDatabaseType(SpecificDBType.CORE, GenericDBType.SINGLE_SPECIES);
257            coreexpressionest = EnsemblDBType.makeDatabaseType(SpecificDBType.COREEXPRESSIONEST, GenericDBType.SINGLE_SPECIES);
258            coreexpressiongnf = EnsemblDBType.makeDatabaseType(SpecificDBType.COREEXPRESSIONGNF, GenericDBType.SINGLE_SPECIES);
259            funcgen = EnsemblDBType.makeDatabaseType(SpecificDBType.FUNCGEN, GenericDBType.SINGLE_SPECIES);
260            otherfeatures = EnsemblDBType.makeDatabaseType(SpecificDBType.OTHERFEATURES, GenericDBType.SINGLE_SPECIES);
261            variation = EnsemblDBType.makeDatabaseType(SpecificDBType.VARIATION, GenericDBType.SINGLE_SPECIES);
262            vega = EnsemblDBType.makeDatabaseType(SpecificDBType.VEGA, GenericDBType.SINGLE_SPECIES);
263            ancestral = EnsemblDBType.makeDatabaseType(SpecificDBType.ANCESTRAL, GenericDBType.SPECIES_COMPARISON);
264            compara = EnsemblDBType.makeDatabaseType(SpecificDBType.COMPARA, GenericDBType.SPECIES_COMPARISON);
265            go = EnsemblDBType.makeDatabaseType(SpecificDBType.GO, GenericDBType.SPECIES_COMPARISON);
266            ontology = EnsemblDBType.makeDatabaseType(SpecificDBType.ONTOLOGY, GenericDBType.SPECIES_COMPARISON);
267            website = EnsemblDBType.makeDatabaseType(SpecificDBType.WEBSITE, GenericDBType.SPECIES_COMPARISON);
268            collection_core = EnsemblDBType.makeDatabaseType(SpecificDBType.COLLECTION_CORE, GenericDBType.COLLECTION);
269            collection_funcgen = EnsemblDBType.makeDatabaseType(SpecificDBType.COLLECTION_FUNCGEN, GenericDBType.COLLECTION);
270            collection_variation = EnsemblDBType.makeDatabaseType(SpecificDBType.COLLECTION_VARIATION, GenericDBType.COLLECTION);
271    
272            return typeHashList;
273    
274        }
275    
276        /**
277         * Ensure Singleton class
278         */
279        private Object readResolve() throws ObjectStreamException {
280            return this;
281        }
282    
283        /**
284         * We often use the constants in a String context, so this routine allows
285         * us to do that easily
286         * @return The String name of this EnsemblDBType object
287         */
288        @Override
289        public String toString() {
290            return this.databaseType.toString();
291        }
292    
293        /**
294         * Overrides the Object method to test for equality
295         * @param   obj   the reference object with which to compare.
296         * @return  <code>true</code> if this object is the same as the obj
297         *          argument; <code>false</code> otherwise.
298         */
299        @Override
300        public boolean equals(Object obj) {
301            if (obj == null) {
302                return false;
303            }
304            if (getClass() != obj.getClass()) {
305                return false;
306            }
307    
308            EnsemblDBType other = (EnsemblDBType)obj;
309            String otherString = other.toString();
310            return this.toString().equals(otherString);
311    
312        }
313    
314        /**
315         * Overrides Object method to generate a hashCode
316         * @return  a hash code value for this object.
317         */
318        @Override
319        public int hashCode() {
320            int hash = 7;
321            hash = 31 * hash + (this.toString() != null ? this.toString().hashCode() : 0);
322            return hash;
323    
324        }
325    
326        /**
327         * Public Method to return the static EnsemblDBType for a typeName.
328         * Checks to see if the supplied sType is the name of a valid EnsemblDBType
329         * and returns the corresponding EnsemblDBType object if it is, or returns null
330         * if not; also returns null if the  typeHashList is not initialized.
331         * @param typeName String
332         * @return EnsemblDBType for the query typeName
333         */
334        public static EnsemblDBType getDBTypeForName (String typeName) {
335            EnsemblDBType dt = null;
336            if ( EnsemblDBType.typeHashList != null
337                    && EnsemblDBType.typeHashList.containsKey(typeName)) {
338                dt =  (EnsemblDBType) EnsemblDBType.typeHashList.get(typeName);
339            }
340            return dt;
341        }
342    
343        public static TreeSet<EnsemblDBType> getSpeciesComparisonDatabaseTypes() {
344            return EnsemblDBType.speciesComparisonDBTypes;
345    
346        }
347    
348        public static TreeSet<EnsemblDBType> getSingleSpeciesDatabaseTypes() {
349            return EnsemblDBType.singleSpeciesDBTypes;
350    
351        }
352    
353        public static TreeSet<EnsemblDBType> getCollectionDatabaseTypes() {
354            return EnsemblDBType.collectionDBTypes;
355    
356        }
357    
358        public static Collection<EnsemblDBType> getAllDatabaseTypes() {
359            return EnsemblDBType.typeHashList.values();
360        }
361    
362        @Override
363        public int compareTo(EnsemblDBType other) {
364            if (other == null || other.toString() == null) {
365                return -1;
366            }
367                return this.toString().compareTo(other.toString());
368        }
369    
370    
371    
372    }