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.datasourceaware.core;
023
024import java.util.HashMap;
025import uk.ac.roslin.ensembl.config.AssemblyExceptionType;
026import uk.ac.roslin.ensembl.config.EnsemblCoordSystemType;
027import uk.ac.roslin.ensembl.dao.factory.DAOCoreFactory;
028import uk.ac.roslin.ensembl.exception.DAOException;
029import uk.ac.roslin.ensembl.model.Mapping;
030import uk.ac.roslin.ensembl.model.MappingSet;
031import uk.ac.roslin.ensembl.model.ObjectType;
032import uk.ac.roslin.ensembl.model.core.Chromosome;
033
034/**
035 * A DAChromosome is a particular type of DAAssembledDNASequence for representing
036 * whole chromosomes.
037 * @author paterson
038 */
039public class DAChromosome extends DAAssembledDNASequence implements Chromosome {
040
041    MappingSet pseudoAutosomalRegion = null;
042    DAChromosome parChromosome = null;
043    boolean PAR = false;
044    HashMap<AssemblyExceptionType, MappingSet> exceptions = null;
045
046    public DAChromosome() {
047        super();
048    }
049
050    public DAChromosome(DAOCoreFactory factory) {
051        super(factory);
052    }
053
054    @Override
055    public String getChromosomeName() {
056        return this.getName();
057    }
058
059    @Override
060    public void setChromosomeName(String name) {
061        this.setName(name);
062    }
063
064    @Override
065    public String toString() {
066        return this.getChromosomeName();
067    }
068
069    @Override
070    public ObjectType getType() {
071        //forces a lazy load so make sure we get CS for all retrieved sequenceIDS in the first query!
072        if (this.getCoordSystem() != null) {
073            return this.getCoordSystem().getType();
074        } else {
075            return EnsemblCoordSystemType.chromosome;
076        }
077    }
078    
079    @Override
080    public MappingSet getPseudoAutosomalRegion() {
081        if (!PAR) {
082            return null;
083        } else if (this.pseudoAutosomalRegion == null) {
084            this.setPseudoAutosomalRegion();
085        }
086
087        return this.pseudoAutosomalRegion;
088    }
089
090    @Override
091    public boolean isPAR() {
092        return PAR;
093    }
094
095    public void setPAR(boolean hasPAR) {
096        this.PAR = hasPAR;
097    }
098
099    /**
100     * Returns the sex-linked 'PAR' chromosome associated with this Chromosome.
101     * Null if this chromsome is not flagged as a PAR/Sex-linked chromosome.
102     * Triggers lazy loading when not set.
103     */
104    @Override
105    public DAChromosome getParChromosome() {
106        if (!PAR) {
107            return null;
108        }
109        if (parChromosome == null && this.getDaoFactory() != null) {
110            try {
111                parChromosome = (DAChromosome) this.getDaoFactory().getChromosomeDAO().getSexLinkedChromosome(this);
112            } catch (DAOException ex) {
113            }
114        }
115        return parChromosome;
116    }
117    /**
118
119     * private routine to retrieve and set the PAR mappings on this chromosome.
120     */
121    private void setPseudoAutosomalRegion() {
122
123        parChromosome = this.getParChromosome();
124
125        if (parChromosome != null && this.getDaoFactory() != null) {
126            try {
127                this.pseudoAutosomalRegion = this.getDaoFactory().getAssemblyDAO().getPARMappingsByStartStop(this, this.getBioBegin(), this.getLength());
128            } catch (DAOException ex) {
129
130            }
131        }
132        
133        if (this.pseudoAutosomalRegion==null) {
134            this.pseudoAutosomalRegion = new MappingSet();
135        }
136    }
137    
138    /**
139     * Returns a MappingSet of AssemblyExceptions of the indicated AssemblyExceptionType.
140     * Triggers lazy load on this Species to retrieve AssemblyExceptions if necessary.
141     * @param type
142     * 
143     * @throws DAOException 
144     */
145    public MappingSet getAssemblyExceptions(AssemblyExceptionType type) throws DAOException {
146        if (exceptions ==null) {
147            //call the lazyload
148            this.getSpecies().setAssemblyExceptions(this.getDBVersion());
149            if (exceptions ==null) {
150                exceptions = new HashMap<AssemblyExceptionType, MappingSet>();
151            }
152        }
153        return (exceptions.get(type)!=null) ? exceptions.get(type) : new MappingSet();
154    }
155    
156    /**
157     * Returns whether this chromosome has any AssemblyExceptions.
158     * Triggers lazy load on this Species to retrieve AssemblyExceptions if necessary.
159     */
160    public boolean hasExceptions() {
161        if (exceptions !=null && !exceptions.isEmpty()) {
162            return true;
163        }else{
164            try {
165                this.getAssemblyExceptions(null);
166            } catch (DAOException ex) {
167                return false;
168            }
169            return (!exceptions.isEmpty());
170        }
171        
172    }
173    
174    /**
175     * public method called by the DA infrastructure when adding an
176     * AssemblyException mapping of the indicated type.
177     * @param type
178     * @param mapping 
179     */
180    public void addException(AssemblyExceptionType type, Mapping mapping) {
181        if (exceptions==null) {
182            this.setExceptions(true);
183        }
184        if (!exceptions.containsKey(type)) {
185            exceptions.put(type, new MappingSet());
186        }
187        exceptions.get(type).add(mapping);
188    }
189    
190    /**
191     * flag method to create the 'exceptions' HashMap for this chromosome if necessary.
192     * @param set 
193     */
194    public void setExceptions(boolean set) {
195        if (exceptions ==null)  {
196            this.exceptions = new HashMap<AssemblyExceptionType, MappingSet>();
197        }
198    }
199}