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;
023
024import java.util.ArrayList;
025import java.util.List;
026import java.util.TreeSet;
027import org.apache.ibatis.session.SqlSession;
028import org.slf4j.Logger;
029import org.slf4j.LoggerFactory;
030import uk.ac.roslin.ensembl.dao.XRefDAO;
031import uk.ac.roslin.ensembl.dao.factory.DAOCoreFactory;
032import uk.ac.roslin.ensembl.dao.factory.DAOFactory;
033import uk.ac.roslin.ensembl.datasourceaware.DAXRef;
034import uk.ac.roslin.ensembl.exception.DAOException;
035import uk.ac.roslin.ensembl.mapper.XRefMapper;
036import uk.ac.roslin.ensembl.mapper.query.FeatureQuery;
037import uk.ac.roslin.ensembl.model.ExternalDB;
038import uk.ac.roslin.ensembl.model.IdentifiableObject;
039import uk.ac.roslin.ensembl.model.XRef;
040import uk.ac.roslin.ensembl.model.XRefed;
041import uk.ac.roslin.ensembl.model.core.WithDisplayXRef;
042import uk.ac.roslin.ensembl.model.database.CoreDatabase;
043
044
045
046public class DBXRefDAO extends DBBaseDAO implements XRefDAO {
047    
048    final static Logger LOGGER = LoggerFactory.getLogger(DBXRefDAO.class);
049
050    public DBXRefDAO() {
051        super();
052    }
053
054    public DBXRefDAO(DAOFactory factory) throws DAOException {
055        super(factory);
056    }
057
058    @Override
059    public List<DAXRef> getAllXRefs(IdentifiableObject feature) throws DAOException {
060        
061        if (feature==null
062                || feature.getId()==null || feature.getType() == null) {
063            throw new DAOException("Failed to call getXRefs() on a Feature");
064        }
065
066        FeatureQuery q = new FeatureQuery();
067        q.setFeatureID(feature.getId());
068        q.setFeatureType(feature.getType().toString());
069        
070        List<DAXRef> result = null;
071        SqlSession session = null;
072
073        try {
074            //need this Factory Cast to get mock test to work
075            ((CoreDatabase) ((DAOCoreFactory) this.getFactory()).getDatabase()).initializeExternalDBs();
076            session = this.getFactory().getNewSqlSession();
077            XRefMapper mapper = session.getMapper(XRefMapper.class);
078            
079            //if things go wrong with the handler we may need to re-register/and initialize here
080            
081//            if (session.getConfiguration().getTypeHandlerRegistry().getTypeHandler(ExternalDB.class, JdbcType.INTEGER) != null) {
082//                ((ExternalDBTypeHandler) session.getConfiguration().getTypeHandlerRegistry().getTypeHandler(ExternalDB.class, JdbcType.INTEGER)).setDatabase((CoreDatabase) this.getFactory().getDatabase());
083//            }   else {
084//                ExternalDBTypeHandler h =  new ExternalDBTypeHandler();
085//                h.setDatabase((CoreDatabase) this.getFactory().getDatabase());
086//                 session.getConfiguration().getTypeHandlerRegistry().register(
087//                         ExternalDB.class, JdbcType.INTEGER, h);
088//            }         
089            
090            result= mapper.getXRefs(q);
091        } catch (Exception e) {
092            throw new DAOException("Failed to call getXRefs() on Feature "+feature.toString(), e);
093        } finally {
094            if (session != null) {
095                session.close();
096            }
097        }
098        /* shouldn't be necessary now */        
099//        if (result != null && this.getFactory()!= null) {
100//            for (XRef x : result) {
101//                ExternalDB db = x.getDB();
102//                if (db != null) {
103//                    db = ((CoreDatabase) this.getFactory().getDatabase()).validateExternalDB(db);
104//                    ((DAXRef)x).setDB(db);
105//                }
106//            }
107//        }
108                
109        return result;
110
111    }
112        
113
114    /**
115     * Uses the xref_id of an xref to fill in missing data that would have been
116     * present if the the xref had initially been made by a call to getXRefs 
117     * on the identifiable object.
118     * @param xref
119     * @throws DAOException
120     */
121    @Override
122    public void reInitialize(IdentifiableObject xref) throws DAOException {
123
124
125        //the DAO method requires an xref_id
126        if (
127              !(xref instanceof DAXRef)
128                || xref.getId()==null || xref.getId()==0 ) {
129             throw new DAOException("Failed to reinitialize an XREF, due to missing ID.");
130        }
131
132        DAXRef in = (DAXRef) xref;
133        
134        FeatureQuery q = new FeatureQuery();
135        q.setFeatureID(xref.getId());
136        
137        SqlSession session = null;
138        DAXRef temp  = null;
139        
140        try {
141            //Mock test fails here
142//            ((CoreDatabase) this.getFactory().getDatabase()).initializeExternalDBs();
143  
144            //works
145            ((CoreDatabase) ((DAOCoreFactory) this.getFactory()).getDatabase()).initializeExternalDBs();          
146                        
147            session = this.getFactory().getNewSqlSession();
148            XRefMapper mapper = session.getMapper(XRefMapper.class);
149            temp = mapper.reInitialize(q);
150        } catch (Exception e) {
151            throw new DAOException("Failed to reinitialize an XREF", e);
152        } finally {
153            if (session != null) {
154                session.close();
155            }
156        }
157
158        if (temp==null) {
159            in.setInitialized(true);
160        } else {
161            
162            //to *ensure* we don't try lazyloading!!!
163            temp.setInitialized(true);
164
165            ExternalDB db = temp.getDB();
166
167            /*
168             * shouldn't be necessary now
169             */
170//            if (db != null) {
171//                db = ((CoreDatabase) this.getFactory().getDatabase()).validateExternalDB(db);
172//            }
173            in.setDB(db);
174            
175//            in.setDBName(temp.getDBDisplayName()!=null?temp.getDBDisplayName():"");
176            in.setDescription(temp.getDescription()!=null?temp.getDescription():"");
177            in.setDisplayID(temp.getDisplayID()!=null?temp.getDisplayID():"");
178            in.setInfo(temp.getInfo()!=null?temp.getInfo():"");
179            in.setInfoType(temp.getInfoType()!=null?temp.getInfoType():"");
180            in.setPrimaryAccession(temp.getPrimaryAccession()!=null?temp.getPrimaryAccession():"");
181            in.setVersion(temp.getVersion()!=null?temp.getVersion():"");
182            in.setEvidence(temp.getEvidence());
183            in.setInitialized(true);
184        }
185
186    }
187
188    @Override
189    public TreeSet<String> getSynonyms(XRef xref) throws DAOException {
190        
191       if (xref==null || xref.getId()==null || xref.getId()==0) {
192            throw new DAOException("Failed to call getSynonyms() for an XRef.");
193        } 
194
195        TreeSet<String> out = new TreeSet<String>();
196        List<String> result = new ArrayList<String>();
197        SqlSession session = null;
198        try {
199            session = this.getFactory().getNewSqlSession();
200            XRefMapper mapper = session.getMapper(XRefMapper.class);
201            result = mapper.getSynonyms(xref);
202        } catch (Exception e) {
203            throw new DAOException("Failed to call getSynonyms() on object "+xref.toString(), e);
204        } finally {
205            if (session != null) {
206                session.close();
207            }
208        }
209        
210        if (result == null) {
211            result =  new ArrayList<String>();
212        }
213        
214        out.addAll(result);
215        return out;
216    }
217    
218    @Override
219    public TreeSet<String> getAllSynonyms(XRefed object) throws DAOException {
220        
221        if (object==null || object.getId()==null || object.getId()==0 
222                || object.getType() == null || object.getType().toString().isEmpty() ) {
223            throw new DAOException("Failed to call getAllSynonyms() for an object");
224        }
225        
226        /*
227         * The synonyms listed for a display xref may not be accessible
228         * through the object_xref table.
229         */
230        TreeSet<String> displaySynonyms = new TreeSet<String>();
231        if (object instanceof WithDisplayXRef) {
232            XRef x = ((WithDisplayXRef) object).getDisplayXRef();
233            if (x!=null) {
234               displaySynonyms =  x.getSynonyms();
235            }
236            if (displaySynonyms==null) {
237                displaySynonyms = new TreeSet<String>();
238            }
239        } 
240        
241        List<String> out = new ArrayList<String>();
242        
243        FeatureQuery query = new FeatureQuery();
244        query.setFeatureID(object.getId());
245        query.setFeatureType(object.getType().toString());
246        
247        SqlSession session = null;
248
249        try {
250            session = this.getFactory().getNewSqlSession();
251            XRefMapper mapper = session.getMapper(XRefMapper.class);
252            out = mapper.getAllSynonyms(query);
253        } catch (Exception e) {
254            throw new DAOException("Failed to call getAllSynonyms() on object "+object.toString(), e);
255        } finally {
256            if (session != null) {
257                session.close();
258            }
259        }
260        
261        if (out == null) {
262            out =  new ArrayList<String>();
263        }
264        
265        displaySynonyms.addAll(out);
266        return displaySynonyms;
267    }
268}