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