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.dao.database.variation;
023
024import java.util.ArrayList;
025import uk.ac.roslin.ensembl.exception.DAOException;
026import java.util.List;
027import org.apache.ibatis.session.SqlSession;
028import uk.ac.roslin.ensembl.config.FeatureType;
029import uk.ac.roslin.ensembl.model.Mapping;
030import uk.ac.roslin.ensembl.model.Coordinate;
031import uk.ac.roslin.ensembl.model.core.DNASequence;
032import uk.ac.roslin.ensembl.dao.database.DBBaseDAO;
033import uk.ac.roslin.ensembl.dao.database.DBSingleSpeciesVariationDatabase;
034import uk.ac.roslin.ensembl.dao.factory.DAOVariationFactory;
035import uk.ac.roslin.ensembl.dao.variation.VariationDAO;
036import uk.ac.roslin.ensembl.datasourceaware.core.DAAssembledDNASequence;
037import uk.ac.roslin.ensembl.datasourceaware.core.DADNASequence;
038import uk.ac.roslin.ensembl.datasourceaware.variation.DAVariation;
039import uk.ac.roslin.ensembl.datasourceaware.variation.VariationMapping;
040import uk.ac.roslin.ensembl.mapper.query.FeatureQuery;
041import uk.ac.roslin.ensembl.mapper.variation.VariationMapper;
042
043public class DBVariationDAO extends DBBaseDAO implements VariationDAO {
044
045    public DBVariationDAO() {
046        super();
047    }
048
049    public DBVariationDAO(DAOVariationFactory factory) throws DAOException {
050        super(factory);
051
052    }
053
054    private DAOVariationFactory getVariationFactory() {
055        return (DAOVariationFactory) this.daoFactory;
056    }
057
058    @Override
059    public List<VariationMapping> getVariationMappingsOnRegion(DNASequence region, Coordinate coords) throws DAOException {
060
061        if (region == null || region.getId() == null || region.getCoordSystem() == null) {
062            throw new DAOException("No valid region or coordinate system specified");
063        }
064
065        // if the region is annotated with variation features this is straightforward
066        if (((DBSingleSpeciesVariationDatabase) this.getVariationFactory().getDatabase()).getCSForFeature(FeatureType.variation).contains(region.getCoordSystem())) {
067
068            List<VariationMapping> mappings = new ArrayList<VariationMapping>();
069            FeatureQuery q = new FeatureQuery();
070            q.setParentSequenceID(region.getId());
071
072            if (coords != null) {
073                q.setParentStart(coords.getStart());
074                q.setParentStop(coords.getEnd());
075            }
076
077
078            Integer max = null;
079            max = ((DBSingleSpeciesVariationDatabase) this.getVariationFactory().getDatabase()).getMaxLengthForFeature(FeatureType.variation, region.getCoordSystem());
080
081            if (max != null) {
082                q.setMaximumFeatureLength(max);
083            }
084
085
086            mappings = this.getMappingsOnParent(q, (DADNASequence) region);
087
088            return mappings;
089
090        } else if (region instanceof DAAssembledDNASequence) {
091
092
093            //do some nasty assembly shit
094            return null;
095
096        } else {
097            return null;
098        }
099    }
100
101    @Override
102    public List<DAVariation> getVariationsOnRegion(DNASequence region, Coordinate coords) throws DAOException {
103
104        if (region == null || region.getId() == null || region.getCoordSystem() == null) {
105            throw new DAOException("No valid region or coordinate system specified");
106        }
107
108        // if the region is annotated with variation features this is straightforward
109        if (((DBSingleSpeciesVariationDatabase) this.getVariationFactory().getDatabase()).getCSForFeature(FeatureType.variation).contains(region.getCoordSystem())) {
110
111            // List<DAVariation> mappings = new ArrayList<DAVariation>();
112            List<DAVariation> mappings;
113            FeatureQuery q = new FeatureQuery();
114            q.setParentSequenceID(region.getId());
115
116            if (coords != null) {
117                q.setParentStart(coords.getStart());
118                q.setParentStop(coords.getEnd());
119            }
120
121
122            Integer max = null;
123            max = ((DBSingleSpeciesVariationDatabase) this.getVariationFactory().getDatabase()).getMaxLengthForFeature(FeatureType.variation, region.getCoordSystem());
124
125            if (max != null) {
126                q.setMaximumFeatureLength(max);
127            }
128
129
130            mappings = this.getVariationsOnParent(q, (DADNASequence) region);
131
132            return mappings;
133
134        } else if (region instanceof DAAssembledDNASequence) {
135
136
137            //do some nasty assembly shit
138            return null;
139
140        } else {
141            return null;
142        }
143    }
144
145    //**********************************************
146    private List<DAVariation> getVariationsOnParent(FeatureQuery query, DADNASequence parent) throws DAOException {
147        //List<HashMap> out = null;
148        List<DAVariation> out = null;
149        SqlSession session = null;
150
151        try {
152            session = this.getFactory().getNewSqlSession();
153            VariationMapper mapper = session.getMapper(VariationMapper.class);
154            out = mapper.getVariationsOnParentSequence(query);
155        } catch (Exception e) {
156            throw new DAOException("Failed to call getMappingsOnParent", e);
157        } finally {
158            if (session != null) {
159                session.close();
160            }
161        }
162
163        for (DAVariation v : out) {
164            for (Mapping m : v.getLoadedMappings()) {
165
166                // i think that this should be set to parent in all circumstances
167                //if (m.getTarget() == null) {
168                m.setTarget(parent);
169                //}
170                if (m.getSource() == null) {
171                    m.setSource(v);
172                }
173//                //heavy weight if we dont need it 
174//                //i'm not sure we want the VariationMappings stored on the dna sequences by default 
175//                VariationMapping.addReverseMapping(m);
176            }
177        }
178
179        return out;
180    }
181
182    private List<VariationMapping> getMappingsOnParent(FeatureQuery query, DADNASequence parent) throws DAOException {
183
184
185        //MappingRowHandler handler = null;
186        List<VariationMapping> result;
187
188        SqlSession session = null;
189
190        try {
191            session = this.getFactory().getNewSqlSession();
192            VariationMapper mapper = session.getMapper(VariationMapper.class);
193            result = mapper.getMappingsOnParentSequence(query);
194        } catch (Exception e) {
195            throw new DAOException("Failed to call getMappingsOnParent", e);
196        } finally {
197            if (session != null) {
198                session.close();
199            }
200        }
201
202        for (Mapping m : result) {
203            m.setSource(parent);
204
205//            //heavy wieght if we dont need it
206//            VariationMapping.addReverseMapping(m);
207            // also  - will we need to set the VariationFactory on the variation
208            //or would we just set the core factory ( as the variation factory can be 
209            //returned from this
210            //of course the core factory is already set on  the parent
211            
212        }
213
214        return result;
215    }
216
217    @Override
218    public DAVariation getUniquelyMappedVariation(String variationName) throws DAOException {
219
220        //note that the qury searches for the give name in both the variation_feature table and the variation synonym table
221
222        //if it is found in the synonym table this original name will  be returned as a variation.synonym, and the variation.name will be the rs name found in variation_feature table
223
224        //this meansd that if a returned variation has a synonym set, this will equal the search name, but if the synonym field is not set, 
225        //the search name becomes the synonym.name
226        FeatureQuery q = new FeatureQuery();
227        q.setFeatureName(variationName);
228
229        List<DAVariation> results = null;
230        DAVariation var = null;
231
232        SqlSession session = null;
233
234        try {
235            session = this.getFactory().getNewSqlSession();
236            VariationMapper mapper = session.getMapper(VariationMapper.class);
237            results = mapper.getUniquelyMappedVariations(q);
238        } catch (Exception e) {
239            throw new DAOException("Failed to call getUniquelyMappedVariation", e);
240        } finally {
241            if (session != null) {
242                session.close();
243            }
244        }
245
246        if (results == null || results.isEmpty()) {
247            return null;
248        } else {
249            var = results.iterator().next();
250
251
252        }
253
254        return var;
255
256    }
257
258    @Override
259    public List<DAVariation> getUniquelyMappedVariations(List<String> variationNames) throws DAOException {
260
261        //note that the qury searches for the give name in both the variation_feature table and the variation synonym table
262
263        //if it is found in the synonym table this original name will  be returned as a variation.synonym, and the variation.name will be the rs name found in variation_feature table
264
265        //this meansd that if a returned variation has a synonym set, this will equal the search name, but if the synonym field is not set, 
266        //the search name becomes the synonym.name
267        FeatureQuery q = new FeatureQuery();
268        q.setQueryStringList(variationNames);
269
270        List<DAVariation> vars = null;
271
272        SqlSession session = null;
273
274        try {
275            session = this.getFactory().getNewSqlSession();
276            VariationMapper mapper = session.getMapper(VariationMapper.class);
277            vars = mapper.getUniquelyMappedVariations(q);
278        } catch (Exception e) {
279            throw new DAOException("Failed to call getMappedVariations", e);
280        } finally {
281            if (session != null) {
282                session.close();
283            }
284        }
285
286        return vars;
287    }
288}