Skip to content
Snippets Groups Projects
DatabaseDocument.java 54 KiB
Newer Older
  • Learn to ignore specific revisions
  • tjc's avatar
    tjc committed
    /* DatabaseDocument.java
     *
    
    tjc's avatar
    tjc committed
     * created: 2005
    
    tjc's avatar
    tjc committed
     *
     * This file is part of Artemis
     * 
    
    tjc's avatar
    tjc committed
     * Copyright (C) 2005  Genome Research Limited
    
    tjc's avatar
    tjc committed
     * 
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * as published by the Free Software Foundation; either version 2
     * of the License, or (at your option) any later version.
     * 
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     * 
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     *
     */
    
    package uk.ac.sanger.artemis.util;
    
    
    import uk.ac.sanger.artemis.io.ChadoCanonicalGene;
    
    tjc's avatar
    tjc committed
    import uk.ac.sanger.artemis.io.GFFStreamFeature;
    
    import uk.ac.sanger.artemis.io.ReadFormatException;
    
    tjc's avatar
    tjc committed
    import uk.ac.sanger.artemis.chado.ArtemisUtils;
    
    import uk.ac.sanger.artemis.chado.IBatisDAO;
    import uk.ac.sanger.artemis.chado.JdbcDAO;
    
    import uk.ac.sanger.artemis.chado.GmodDAO;
    
    import uk.ac.sanger.artemis.chado.ChadoTransaction;
    
    import uk.ac.sanger.artemis.components.database.DatabaseEntrySource;
    
    tjc's avatar
    tjc committed
    import uk.ac.sanger.artemis.components.Splash;
    
    tjc's avatar
    tjc committed
    
    
    import org.gmod.schema.sequence.Feature;
    
    import org.gmod.schema.sequence.FeatureProp;
    import org.gmod.schema.sequence.FeatureLoc;
    import org.gmod.schema.sequence.FeatureRelationship;
    import org.gmod.schema.sequence.FeatureSynonym;
    
    import org.gmod.schema.sequence.FeatureCvTerm;
    
    import org.gmod.schema.sequence.FeatureCvTermProp;
    
    tjc's avatar
    tjc committed
    import org.gmod.schema.sequence.FeatureCvTermDbXRef;
    
    tjc's avatar
    tjc committed
    import org.gmod.schema.sequence.FeatureCvTermPub;
    
    import org.gmod.schema.cv.CvTerm;
    
    import org.gmod.schema.general.DbXRef;
    
    tjc's avatar
    tjc committed
    import org.gmod.schema.organism.Organism;
    
    tjc's avatar
    tjc committed
    import org.gmod.schema.pub.PubDbXRef;
    import org.gmod.schema.pub.Pub;
    
    tjc's avatar
    tjc committed
    import java.sql.*;
    
    import java.text.SimpleDateFormat;
    
    tjc's avatar
    tjc committed
    import java.io.*;
    
    tjc's avatar
    tjc committed
    import java.net.ConnectException;
    
    tjc's avatar
    tjc committed
    import java.util.Hashtable;
    
    tjc's avatar
    tjc committed
    import java.util.HashMap;
    
    import java.util.Vector;
    
    tjc's avatar
    tjc committed
    import java.util.Enumeration;
    
    tjc's avatar
    tjc committed
    import java.util.List;
    import java.util.Iterator;
    
    tjc's avatar
    tjc committed
    import java.util.Collection;
    
    
    tjc's avatar
    tjc committed
    import javax.swing.JOptionPane;
    
    tjc's avatar
    tjc committed
    import javax.swing.JPasswordField;
    
    tjc's avatar
    tjc committed
    
    /**
    
    tjc's avatar
    tjc committed
     * Objects of this class are Documents created from a relational database.
     * 
     */
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
    public class DatabaseDocument extends Document
    
    tjc's avatar
    tjc committed
    {
      private String name = null;
    
    tjc's avatar
    tjc committed
    
    
      /** source feature_id */
      private String srcFeatureId = "1";
    
    tjc's avatar
    tjc committed
    
      /** database schema */
      private String schema = "public";
    
    
      private static Hashtable cvterms;
    
    tjc's avatar
    tjc committed
    
    
      private InputStreamProgressListener progress_listener;
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
      private HashMap db;
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
      /** JDBC DAO */
      private JdbcDAO jdbcDAO = null;
    
      /** iBatis DAO */
      private IBatisDAO connIB = null;
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
      private ByteBuffer[] gff_buffer;
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
      private ByteBuffer gff_buff;
    
    tjc's avatar
    tjc committed
    
      /** entries to split into */
    
    tjc's avatar
    tjc committed
      private String[] types = { "exon", "gene", "CDS", "transcript" };
    
    tjc's avatar
    tjc committed
    
      /** true if splitting the GFF into entries */
    
    tjc's avatar
    tjc committed
      private boolean splitGFFEntry;
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
      private boolean iBatis = false;
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
      private JPasswordField pfield;
    
    tjc's avatar
    tjc committed
    
    
      private List schema_list;
      
    
      private boolean gene_builder;
      
    
    tjc's avatar
    tjc committed
      // controlled vocabulary
      /** controlled_curation controlled vocabulary */
    
    tjc's avatar
    tjc committed
      public static String CONTROLLED_CURATION_TAG_CVNAME = 
    
    tjc's avatar
    tjc committed
                                     "CC_";
    
    tjc's avatar
    tjc committed
      /** product controlled vocabulary */
    
    tjc's avatar
    tjc committed
      public static String PRODUCTS_TAG_CVNAME = "genedb_products";
    
    tjc's avatar
    tjc committed
      
    
    tjc's avatar
    tjc committed
      /**
    
    tjc's avatar
    tjc committed
       * 
       * Create a new Document from a database.
       * 
       * @param location
       *          This should be a URL string giving:
       *          jdbc:postgresql://host:port/datbase_name?user=username
       * 
       */
    
    tjc's avatar
    tjc committed
      public DatabaseDocument(String location, JPasswordField pfield)
    
    tjc's avatar
    tjc committed
      {
        super(location);
    
    tjc's avatar
    tjc committed
        this.pfield = pfield;
    
    
    tjc's avatar
    tjc committed
        if(location.indexOf('=') > -1)
          this.schema = location.substring( location.indexOf('=')+ 1);
        
    
    tjc's avatar
    tjc committed
        if(System.getProperty("ibatis") != null)
    
    tjc's avatar
    tjc committed
        {
    
    tjc's avatar
    tjc committed
          iBatis = true;
    
    tjc's avatar
    tjc committed
          System.setProperty("chado", location);
    
    tjc's avatar
    tjc committed
        }
    
    tjc's avatar
    tjc committed
      }
    
    
    tjc's avatar
    tjc committed
      /**
    
    tjc's avatar
    tjc committed
       * 
       * Create a new Document from a database.
       * 
       * @param location
       *          This should be a URL string giving:
    
    tjc's avatar
    tjc committed
       *          jdbc:postgresql://host:port/database_name?user=username
    
    tjc's avatar
    tjc committed
       * @param feature_id
       *          ID of a feature to be extracted.
       * 
       */
    
    tjc's avatar
    tjc committed
      public DatabaseDocument(String location, JPasswordField pfield,
    
                              String srcFeatureId, String schema)
    
    tjc's avatar
    tjc committed
      {
        super(location);
    
    tjc's avatar
    tjc committed
        this.pfield = pfield;
    
    
        this.srcFeatureId = srcFeatureId;
    
    tjc's avatar
    tjc committed
        this.schema = schema;
    
    
    tjc's avatar
    tjc committed
        if(System.getProperty("ibatis") != null)
    
    tjc's avatar
    tjc committed
        {
    
    tjc's avatar
    tjc committed
          iBatis = true;
    
    tjc's avatar
    tjc committed
          System.setProperty("chado", location);
    
    tjc's avatar
    tjc committed
        }
    
    tjc's avatar
    tjc committed
      }
    
    
    tjc's avatar
    tjc committed
      /**
    
    tjc's avatar
    tjc committed
       * 
       * Create a new Document from a database.
       * 
       * @param location
       *          This should be a URL string giving:
       *          jdbc:postgresql://host:port/datbase_name?user=username
    
    tjc's avatar
    tjc committed
       *          ID of a feature to be extracted.
       * @param splitGFFEntry
       *          split into separate entries based on feature types.
       * @param progress_listener
       *          input stream progress listener
       * 
       */
    
    tjc's avatar
    tjc committed
      public DatabaseDocument(String location, JPasswordField pfield,
    
                              String srcFeatureId, String schema, boolean splitGFFEntry,
    
                              InputStreamProgressListener progress_listener)
      {
        super(location);
    
    tjc's avatar
    tjc committed
        this.pfield = pfield;
    
        this.srcFeatureId = srcFeatureId;
    
    tjc's avatar
    tjc committed
        this.schema = schema;
    
    tjc's avatar
    tjc committed
        this.splitGFFEntry = splitGFFEntry;
    
        this.progress_listener = progress_listener;
    
    tjc's avatar
    tjc committed
        if(System.getProperty("ibatis") != null)
    
    tjc's avatar
    tjc committed
        {
    
    tjc's avatar
    tjc committed
          iBatis = true;
    
    tjc's avatar
    tjc committed
          System.setProperty("chado", location);
    
    tjc's avatar
    tjc committed
        }
    
        
        reset(location, schema);
    
    tjc's avatar
    tjc committed
    
    
      /**
       * Used by the gene builder to read a database entry
       * for a single gene.
       * @param location
       * @param pfield
    
       * @param schema
       * @param gene_builder
       */
      public DatabaseDocument(String location, JPasswordField pfield,
    
              String srcFeatureId, String schema, boolean gene_builder)
    
      {
        super(location);
        this.pfield = pfield;
    
        this.srcFeatureId = srcFeatureId;
    
        this.schema = schema;
        this.gene_builder = gene_builder;
    
        if(System.getProperty("ibatis") != null)
        {
          iBatis = true;
          System.setProperty("chado", location);
        }
      }
      
    
    tjc's avatar
    tjc committed
      public DatabaseDocument(String location, JPasswordField pfield,
    
                              String srcFeatureId, String schema,
    
    tjc's avatar
    tjc committed
                              ByteBuffer gff_buff, String name)
    
    tjc's avatar
    tjc committed
      {
        super(location);
    
    tjc's avatar
    tjc committed
        this.pfield = pfield;
    
        this.srcFeatureId = srcFeatureId;
    
    tjc's avatar
    tjc committed
        this.schema = schema;
        this.gff_buff = gff_buff;
    
    tjc's avatar
    tjc committed
        this.name = name;
    
    tjc's avatar
    tjc committed
        if(System.getProperty("ibatis") != null)
    
    tjc's avatar
    tjc committed
        {
    
    tjc's avatar
    tjc committed
          iBatis = true;
    
    tjc's avatar
    tjc committed
          System.setProperty("chado", location);
    
    tjc's avatar
    tjc committed
        }
    
      
      /**
       * Reset the schema.
       * @param location
       * @param schema
       */
      private void reset(String location, String schema)
      {
        this.schema = schema;
    
    tjc's avatar
    tjc committed
    
    
        if(!location.endsWith("="+schema))
        {
          int index = location.lastIndexOf('=');
          setLocation(location.substring(0,index+1) + schema);
          connIB  = null;
          jdbcDAO = null;
          System.setProperty("chado", (String)getLocation());
        }
      }
    
    tjc's avatar
    tjc committed
      /**
    
    tjc's avatar
    tjc committed
       * Append a String to the Document location.
    
    tjc's avatar
    tjc committed
       * @param name  the name to append.
    
    tjc's avatar
    tjc committed
       */
      public Document append(String name) throws IOException
    
    tjc's avatar
    tjc committed
      {
    
    tjc's avatar
    tjc committed
        return new DatabaseDocument( ((String)getLocation()) + name, pfield);
    
    tjc's avatar
    tjc committed
      }
    
      /**
    
    tjc's avatar
    tjc committed
       * Return the name of this Document (the last element of the Document
       * location).
       */
      public String getName()
    
    tjc's avatar
    tjc committed
      {
        if(name == null)
        {
    
    tjc's avatar
    tjc committed
          int ind     = ((String) getLocation()).indexOf("?");
          String name = ((String) getLocation()).substring(0, ind);
    
    tjc's avatar
    tjc committed
          ind = name.lastIndexOf("/");
    
    tjc's avatar
    tjc committed
          return name.substring(ind + 1);
    
    tjc's avatar
    tjc committed
        }
        return name;
      }
    
    
    tjc's avatar
    tjc committed
    
      /**
      *  Set the name of this document.
      */
      public void setName(String name)
      {
        this.name = name;
      }
    
    
    
      public DatabaseDocument createDatabaseDocument()
    
    tjc's avatar
    tjc committed
      {
    
        return new DatabaseDocument( (String)getLocation(), pfield,
    
    tjc's avatar
    tjc committed
      }
    
    tjc's avatar
    tjc committed
      /**
    
    tjc's avatar
    tjc committed
       * Return true if and only if the Document refered to by this object exists
       * and is readable. Always returns true.
       */
      public boolean readable()
    
    tjc's avatar
    tjc committed
      {
        return true;
      }
    
      /**
    
    tjc's avatar
    tjc committed
       * Return true if and only if the Document refered to by this object exists
       * and can be written to. Always returns false.
       */
      public boolean writable()
    
    tjc's avatar
    tjc committed
      {
        return true;
      }
    
      /**
    
    tjc's avatar
    tjc committed
       * Create a new InputStream object from this Document. The contents of the
       * Document can be read from the InputStream.
       * 
       * @exception IOException
       *              Thrown if the Document can't be read from (for example if it
       *              doesn't exist).
       */
      public InputStream getInputStream() throws IOException
    
    tjc's avatar
    tjc committed
      {
    
    tjc's avatar
    tjc committed
        ByteArrayInputStream instream;
    
        if(gff_buff != null)
        {
    
    tjc's avatar
    tjc committed
          instream = new ByteArrayInputStream(gff_buff.getBytes());
    
    tjc's avatar
    tjc committed
          return instream;
        }
    
    
    tjc's avatar
    tjc committed
        try
        {
    
          GmodDAO dao = getDAO();
    
    tjc's avatar
    tjc committed
          ByteBuffer entry = new ByteBuffer();
    
    tjc's avatar
    tjc committed
          try
    
    tjc's avatar
    tjc committed
            if(dao instanceof IBatisDAO)
              ((IBatisDAO) dao).startTransaction();
    
    tjc's avatar
    tjc committed
            // if creating a gene builder
            if(gene_builder)
            {
              List schemaList = new Vector();
              schemaList.add(schema);
    
              return new ByteArrayInputStream(getGeneFeature(srcFeatureId,
    
    tjc's avatar
    tjc committed
                  schemaList, dao).getBytes());
            }
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
    
            
            if(splitGFFEntry)
    
    tjc's avatar
    tjc committed
            {
    
    tjc's avatar
    tjc committed
              if(gff_buffer[0].size() > 0)
                entry.append(gff_buffer[0]);
    
              getChadoSequence(dao, entry);
            }
            else
            {
              for(int i = 0; i < gff_buffer.length; i++)
              {
                if(gff_buffer[i].size() > 0)
                  entry.append(gff_buffer[i]);
              }
    
              getChadoSequence(dao, entry);
    
    tjc's avatar
    tjc committed
            }
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
            if(dao instanceof IBatisDAO)
              ((IBatisDAO) dao).commitTransaction();
          }
          finally
          {
            if(dao instanceof IBatisDAO)
              ((IBatisDAO) dao).endTransaction();
    
    tjc's avatar
    tjc committed
          }
    
          instream = new ByteArrayInputStream(entry.getBytes());
    
    tjc's avatar
    tjc committed
          return instream;
        }
    
        catch(RuntimeException re)
        {
          JOptionPane.showMessageDialog(null, "Problems Reading...\n" +
              re.getMessage(),
              "Problems Reading From the Database ",
              JOptionPane.ERROR_MESSAGE);
          
          re.printStackTrace();
        }
    
    tjc's avatar
    tjc committed
        catch(java.sql.SQLException sqlExp)
        {
    
    tjc's avatar
    tjc committed
          JOptionPane.showMessageDialog(null, "Problems Reading...\n" +
              sqlExp.getMessage(),
    
              "Problems Reading From the Database ",
    
    tjc's avatar
    tjc committed
              JOptionPane.ERROR_MESSAGE);
          
    
    tjc's avatar
    tjc committed
          sqlExp.printStackTrace();
        }
    
        return null;
      }
    
    
    tjc's avatar
    tjc committed
      /**
    
    tjc's avatar
    tjc committed
       * 
       * Called (by DatabaseEntrySource) to retrieve all the documents for each
       * entry created.
       * 
       */
      public DatabaseDocument[] getGffDocuments(String location, String id,
                                                String schema)
    
    tjc's avatar
    tjc committed
        int nentries = 0;
    
    tjc's avatar
    tjc committed
        for(int i = 1; i < gff_buffer.length; i++)
    
    tjc's avatar
    tjc committed
        {
          if(gff_buffer[i].size() > 0)
            nentries++;
        }
    
        DatabaseDocument[] new_docs = new DatabaseDocument[nentries];
        nentries = 0;
    
    tjc's avatar
    tjc committed
        for(int i = 1; i < gff_buffer.length; i++)
    
    tjc's avatar
    tjc committed
          if(gff_buffer[i].size() == 0)
            continue;
    
    
    tjc's avatar
    tjc committed
          String name;
          if(i >= types.length)
            name = "other";
          else
            name = types[i];
    
    
    tjc's avatar
    tjc committed
          new_docs[nentries] = new DatabaseDocument(location, pfield, id, schema,
                                                    gff_buffer[i], name);
    
    tjc's avatar
    tjc committed
          nentries++;
    
    tjc's avatar
    tjc committed
        }
    
        return new_docs;
      }
    
    
    tjc's avatar
    tjc committed
      /**
    
    tjc's avatar
    tjc committed
       * Create an array of GFF lines.
       * @param dao                 the data access object 
       * @param parentFeatureID     the parent identifier for the features to 
       *                            extract
       * @return   the <code>ByteBuffer</code> array of GFF lines
    
    tjc's avatar
    tjc committed
       */
    
      private ByteBuffer[] getGff(GmodDAO dao)
    
    tjc's avatar
    tjc committed
      {
    
        final int srcfeature_id = Integer.parseInt(srcFeatureId);
    
    tjc's avatar
    tjc committed
        
    
    tjc's avatar
    tjc committed
        Splash.logger4j.debug("Build GFF");
        
    
    tjc's avatar
    tjc committed
        // build srcfeature object
    
    tjc's avatar
    tjc committed
        FeatureLoc featureloc = new FeatureLoc();
    
        Feature srcFeature = new Feature();
        srcFeature.setFeatureId(srcfeature_id);
        featureloc.setFeatureBySrcFeatureId(srcFeature);
        
        //featureloc.setSrcfeature_id(srcfeature_id);
    
    tjc's avatar
    tjc committed
        Feature parent = new Feature();
    
        parent.setFeatureLoc(featureloc);
    
    tjc's avatar
    tjc committed
        
    
    tjc's avatar
    tjc committed
        List featList = dao.getFeaturesByLocatedOnFeature(parent);
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
        ByteBuffer[] buffers = new ByteBuffer[types.length + 1];
        for(int i = 0; i < buffers.length; i++)
    
    tjc's avatar
    tjc committed
          buffers[i] = new ByteBuffer();
    
    
    tjc's avatar
    tjc committed
        final Feature parentFeature = dao.getFeatureById(srcfeature_id);
    
    tjc's avatar
    tjc committed
        
    
    tjc's avatar
    tjc committed
        ByteBuffer this_buff;
    
        int feature_size = featList.size();
    
    tjc's avatar
    tjc committed
        Hashtable id_store = new Hashtable(feature_size);
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
        // build feature name store
    
        for(int i = 0; i < feature_size; i++)
        {
    
    tjc's avatar
    tjc committed
          Feature feat = (Feature)featList.get(i);
    
    tjc's avatar
    tjc committed
          String name       = feat.getUniqueName();
    
          String featureId = Integer.toString(feat.getFeatureId());
    
          id_store.put(featureId, name);
    
    tjc's avatar
    tjc committed
        
    
    tjc's avatar
    tjc committed
        // get all dbrefs & synonyms
    
    tjc's avatar
    tjc committed
        Hashtable dbxrefs = IBatisDAO.mergeDbXRef(
    
                     dao.getFeatureDbXRefsByFeatureUniquename(null));
    
    tjc's avatar
    tjc committed
        Hashtable synonym = getAllFeatureSynonyms(dao, null);
    
    tjc's avatar
    tjc committed
    
    
        Hashtable featureCvTerms = getFeatureCvTermsByFeature(dao);
    
    tjc's avatar
    tjc committed
        Hashtable featureCvTermDbXRefs = getFeatureCvTermDbXRef(dao);
    
    tjc's avatar
    tjc committed
        Hashtable featureCvTermPubs = getFeatureCvTermPub(dao);
        
    
    tjc's avatar
    tjc committed
        List pubDbXRefs= dao.getPubDbXRef();
    
    
    tjc's avatar
    tjc committed
        // create gff byte stream
    
    tjc's avatar
    tjc committed
        for(int i = 0; i < feature_size; i++)
    
    tjc's avatar
    tjc committed
          // select buffer based on feature type
    
    tjc's avatar
    tjc committed
          Feature feat = (Feature)featList.get(i);
    
    tjc's avatar
    tjc committed
          int type_id = feat.getCvTerm().getCvTermId();
    
          String typeName = getCvtermName(type_id, dao);
    
    tjc's avatar
    tjc committed
          this_buff = buffers[types.length];
    
    tjc's avatar
    tjc committed
          for(int j = 0; j < types.length; j++)
    
    tjc's avatar
    tjc committed
          {
            if(types[j].equals(typeName))
              this_buff = buffers[j];
          }
    
    tjc's avatar
    tjc committed
          chadoToGFF(feat, parentFeature.getUniqueName(),
    
                     dbxrefs, synonym, featureCvTerms,
    
    tjc's avatar
    tjc committed
                     pubDbXRefs, featureCvTermDbXRefs, featureCvTermPubs,
                     id_store, dao, 
    
                     feat.getFeatureLoc(), this_buff);
    
          if( i%10 == 0 || i == feature_size-1)
            progress_listener.progressMade("Read from database: " + 
    
    tjc's avatar
    tjc committed
                                           feat.getUniqueName());
    
    tjc's avatar
    tjc committed
        }
    
        return buffers;
      }
    
    
    tjc's avatar
    tjc committed
      /**
    
    tjc's avatar
    tjc committed
       * Get a <code>Hashtable</code> of feature_id keys and their corresponding 
       * feature_synonym
    
    tjc's avatar
    tjc committed
       * 
       */
    
      private Hashtable getAllFeatureSynonyms(final GmodDAO dao, 
    
    tjc's avatar
    tjc committed
              final String uniquename) 
    
    tjc's avatar
    tjc committed
      {
    
        List list = dao.getFeatureSynonymsByFeatureUniquename(uniquename);  
    
    tjc's avatar
    tjc committed
        
        Hashtable synonym = new Hashtable();
    
    tjc's avatar
    tjc committed
        List value;
    
    tjc's avatar
    tjc committed
        FeatureSynonym alias;
    
    tjc's avatar
    tjc committed
        
        for(int i=0; i<list.size(); i++)
        {
    
    tjc's avatar
    tjc committed
          alias = (FeatureSynonym)list.get(i);
    
          featureId = new Integer(alias.getFeature().getFeatureId());
          if(synonym.containsKey(featureId))
            value = (Vector)synonym.get(featureId);
    
    tjc's avatar
    tjc committed
          else
            value = new Vector();
          
          value.add(alias);
    
          synonym.put(featureId, value);
    
    tjc's avatar
    tjc committed
        }
        
        return synonym;
    
      }
      
      private Hashtable getFeatureCvTermsByFeature(final GmodDAO dao)
      {
        List list = dao.getFeatureCvTermsByFeature(null);
        
        Hashtable featureCvTerms = new Hashtable();
    
        List value;
        FeatureCvTerm feature_cvterm;
        
        for(int i=0; i<list.size(); i++)
        {
          feature_cvterm = (FeatureCvTerm)list.get(i);
    
          featureId = new Integer(feature_cvterm.getFeature().getFeatureId());
          if(featureCvTerms.containsKey(featureId))
            value = (Vector)featureCvTerms.get(featureId);
    
          else
            value = new Vector();
          
          value.add(feature_cvterm);
    
          featureCvTerms.put(featureId, value);
    
    tjc's avatar
    tjc committed
      
    
    tjc's avatar
    tjc committed
      
    
    tjc's avatar
    tjc committed
      private Hashtable getFeatureCvTermDbXRef(final GmodDAO dao)
      {
    
    tjc's avatar
    tjc committed
        List list = dao.getFeatureCvTermDbXRefByFeature(null);
    
    tjc's avatar
    tjc committed
        if(list == null || list.size() == 0)
          return null;
        
    
    tjc's avatar
    tjc committed
        Integer featureCvTermDbXRefId;
        List value;
        
    
    tjc's avatar
    tjc committed
        Hashtable featureCvTermDbXRefs = new Hashtable(list.size());
        for(int i=0; i<list.size(); i++)
        {
          FeatureCvTermDbXRef featureCvTermDbXRef =
            (FeatureCvTermDbXRef)list.get(i);
    
    tjc's avatar
    tjc committed
          
          featureCvTermDbXRefId = new Integer(
              featureCvTermDbXRef.getFeatureCvTerm().getFeatureCvTermId());
          
          if(featureCvTermDbXRefs.containsKey(featureCvTermDbXRefId))
            value = (Vector)featureCvTermDbXRefs.get(featureCvTermDbXRefId);
          else
            value = new Vector();
          
          value.add(featureCvTermDbXRef);
          featureCvTermDbXRefs.put(featureCvTermDbXRefId, value);
    
    tjc's avatar
    tjc committed
        }
         
        return featureCvTermDbXRefs;
      }
      
    
    tjc's avatar
    tjc committed
      private Hashtable getFeatureCvTermPub(final GmodDAO dao)
      {
        List list = dao.getFeatureCvTermPubByFeature(null);
        if(list == null || list.size() == 0)
          return null;
        
        Integer featureCvTermId;
        List value;
        
        Hashtable featureCvTermPubs = new Hashtable(list.size());
        for(int i=0; i<list.size(); i++)
        {
          FeatureCvTermPub featureCvTermPub =
            (FeatureCvTermPub)list.get(i);
          
          featureCvTermId = new Integer(
              featureCvTermPub.getFeatureCvTerm().getFeatureCvTermId());
          
          if(featureCvTermPubs.containsKey(featureCvTermId))
            value = (Vector)featureCvTermPubs.get(featureCvTermId);
          else
            value = new Vector();
          
          value.add(featureCvTermPub);
          featureCvTermPubs.put(featureCvTermId, value);
        }
         
        return featureCvTermPubs;
      }
      
    
    tjc's avatar
    tjc committed
      /**
       * Use by the gene editor to retrieve the gene and related
       * features
       * @param search_gene     gene uniquename
       * @param schema_search   schema list to search
       * @param dao             data access method
       * @return  GFF byte buffer
       * @throws SQLException
       * @throws ReadFormatException
    
       * @throws ConnectException 
    
    tjc's avatar
    tjc committed
       */
    
      private ByteBuffer getGeneFeature(final String search_gene, 
                                        final List schema_search,
    
                                        GmodDAO dao) 
    
              throws SQLException, ReadFormatException, ConnectException
    
      {
        Hashtable id_store = new Hashtable();
    
    
    tjc's avatar
    tjc committed
        //Feature feature = new Feature();
    
    tjc's avatar
    tjc committed
        //feature.setUniquename(search_gene);
    
        reset((String)getLocation(), (String)schema_search.get(0));
        dao = getDAO();
    
        Feature feature = 
    
          (Feature)(dao.getFeaturesByUniqueName(search_gene).get(0));
    
        ChadoCanonicalGene chado_gene = new ChadoCanonicalGene();
    
    tjc's avatar
    tjc committed
        id_store.put(Integer.toString(feature.getFeatureId()), feature.getUniqueName());
    
        List featurelocs = new Vector(feature.getFeatureLocsForFeatureId());
    
    tjc's avatar
    tjc committed
        FeatureLoc featureloc = (FeatureLoc) featurelocs.get(0);
    
        int src_id = featureloc.getFeatureBySrcFeatureId().getFeatureId();
    
    tjc's avatar
    tjc committed
        Feature parent = new Feature();
    
    tjc's avatar
    tjc committed
        parent.setFeatureId(src_id);
    
    tjc's avatar
    tjc committed
        parent = dao.getFeatureById(src_id);  //.getLazyFeature(parent);
        
    
    tjc's avatar
    tjc committed
        chado_gene.setSeqlen(parent.getSeqLen());
    
    tjc's avatar
    tjc committed
        chado_gene.setSrcfeature_id(src_id);
    
    
        ByteBuffer buff = new ByteBuffer();
        
    
    tjc's avatar
    tjc committed
        chadoToGFF(feature, null, null, null, null, null, null, null, null, dao,
    
                   featureloc, buff);
    
        // get children of gene
    
    tjc's avatar
    tjc committed
        List relations = new Vector(feature.getFeatureRelationshipsForObjectId());
    
        for(int i = 0; i < relations.size(); i++)
        {
    
    tjc's avatar
    tjc committed
          //Feature transcript = new Feature();
    
    tjc's avatar
    tjc committed
          
    
    tjc's avatar
    tjc committed
          int id = ((FeatureRelationship) relations.get(i)).getFeatureBySubjectId().getFeatureId();
    
    tjc's avatar
    tjc committed
          //transcript.setId(id);
    
          Feature transcript = 
            (Feature)dao.getFeatureById(id); //.getLazyFeature(transcript);
    
    tjc's avatar
    tjc committed
          id_store.put(Integer.toString(transcript.getFeatureId()), 
    
    tjc's avatar
    tjc committed
              transcript.getUniqueName());
    
          FeatureLoc loc = getFeatureLoc(new Vector(
    
              transcript.getFeatureLocsForFeatureId()), src_id);
    
    tjc's avatar
    tjc committed
          chadoToGFF(transcript, feature.getUniqueName(), null, null, null,
    
    tjc's avatar
    tjc committed
              null, null, null, id_store, dao, loc, buff);
    
    
          // get children of transcript - exons and pp
    
    tjc's avatar
    tjc committed
          List transcipt_relations = new Vector(
              transcript.getFeatureRelationshipsForObjectId());
    
    
          for(int j = 0; j < transcipt_relations.size(); j++)
          {
    
    tjc's avatar
    tjc committed
            id = ((FeatureRelationship) transcipt_relations.get(j)).getFeatureBySubjectId().getFeatureId();
    
    tjc's avatar
    tjc committed
            //Feature child = new Feature();
            //child.setId(((FeatureRelationship) transcipt_relations.get(j))
    
    tjc's avatar
    tjc committed
            //    .getSubject_id());
    
            Feature child = 
              (Feature)dao.getFeatureById(id); //dao.getLazyFeature(child);
    
    tjc's avatar
    tjc committed
            id_store.put(Integer.toString(child.getFeatureId()), child.getUniqueName());
    
            loc = getFeatureLoc(
    
                new Vector(child.getFeatureLocsForFeatureId()),src_id);
    
    tjc's avatar
    tjc committed
            chadoToGFF(child, transcript.getUniqueName(), null,null, null,
    
    tjc's avatar
    tjc committed
                       null, null, null, id_store, dao, loc, buff);
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
      /**
       * Convert the chado feature into a GFF line
       * @param feat           Chado feature
       * @param parentFeature  parent of this feature
       * @param dbxrefs        hashtable containing dbxrefs
       * @param synonym        hashtable containing synonynms
    
    tjc's avatar
    tjc committed
       * @param featureCvTerms
       * @param pubDbXRefs
       * @param featureCvTermDbXRefs
    
    tjc's avatar
    tjc committed
       * @param id_store       id store for looking up parent names
       * @param dao            chado data access
    
    tjc's avatar
    tjc committed
       * @param featureloc     feature location for this chado feature
    
    tjc's avatar
    tjc committed
       * @param this_buff      byte buffer of GFF line 
       */
    
    tjc's avatar
    tjc committed
      private static void chadoToGFF(final Feature feat,
    
                                     final String parentFeature,
                                     final Hashtable dbxrefs,
                                     final Hashtable synonym,
    
                                     final Hashtable featureCvTerms,
    
    tjc's avatar
    tjc committed
                                     final List pubDbXRefs,
    
    tjc's avatar
    tjc committed
                                     final Hashtable featureCvTermDbXRefs,
    
    tjc's avatar
    tjc committed
                                     final Hashtable featureCvTermPubs,
    
                                     final Hashtable id_store,
    
                                     final GmodDAO dao,
    
    tjc's avatar
    tjc committed
                                     final FeatureLoc featureloc,
    
                                     final ByteBuffer this_buff)
    
    tjc's avatar
    tjc committed
      {
        String gff_source = null;
        
    
        final int fmin          = featureloc.getFmin().intValue() + 1;
        final int fmax          = featureloc.getFmax().intValue();
        final int type_id       = feat.getCvTerm().getCvTermId();
        final Short strand      = featureloc.getStrand();
        final Integer phase     = featureloc.getPhase();
        final String name       = feat.getUniqueName();
        final String typeName   = getCvtermName(type_id, dao);
        final Integer featureId = new Integer(feat.getFeatureId());
    
        final String timelastmodified = Long.toString(feat.getTimeLastModified().getTime());
    
    tjc's avatar
    tjc committed
    
        String parent_id = null;
        String parent_relationship = null;
    
    tjc's avatar
    tjc committed
        int rank = -1;
    
    /*    if(feat.getFeatureRelationship() != null)
    
    tjc's avatar
    tjc committed
        {
    
          FeatureRelationship feat_relationship = feat.getFeatureRelationship();
    
    tjc's avatar
    tjc committed
          parent_id = Integer.toString(feat_relationship.getFeatureByObjectId().getFeatureId());
    
    tjc's avatar
    tjc committed
          long parent_type_id = feat_relationship.getCvTerm().getCvTermId();
    
    tjc's avatar
    tjc committed
          
    
    tjc's avatar
    tjc committed
          parent_relationship = feat_relationship.getCvTerm().getName();
    
    tjc's avatar
    tjc committed
          
    
    tjc's avatar
    tjc committed
          rank= feat_relationship.getRank();
    
    tjc's avatar
    tjc committed
          if(parent_relationship == null)
            parent_relationship = getCvtermName(parent_type_id, dao);
        }
    
        else */
          
        if(feat.getFeatureRelationshipsForSubjectId() != null)
    
    tjc's avatar
    tjc committed
        {
    
    tjc's avatar
    tjc committed
          List relations = new Vector(feat.getFeatureRelationshipsForSubjectId());
    
    tjc's avatar
    tjc committed
          for(int i=0; i<relations.size(); i++)
          {
    
    tjc's avatar
    tjc committed
            FeatureRelationship feat_relationship = 
                                (FeatureRelationship)relations.get(i);
    
    tjc's avatar
    tjc committed
            parent_id = Integer.toString(feat_relationship.getFeatureByObjectId().getFeatureId());
    
    tjc's avatar
    tjc committed
            rank      = feat_relationship.getRank();
    
            
            if( feat_relationship.getCvTerm().getName() == null )
            {
    
    tjc's avatar
    tjc committed
              int parent_type_id = feat_relationship.getCvTerm().getCvTermId();
    
              parent_relationship = getCvtermName(parent_type_id, dao);
            }
            else
              parent_relationship = feat_relationship.getCvTerm().getName();
    
    tjc's avatar
    tjc committed
          }
        }
              
        if(parent_id != null && id_store != null &&  id_store.containsKey(parent_id))
          parent_id = (String)id_store.get(parent_id);
     
        // make gff format
        
        Vector dbxref = null;
        // append dbxrefs
        if(dbxrefs != null &&
    
           dbxrefs.containsKey(featureId))
    
    tjc's avatar
    tjc committed
        {
    
          dbxref = (Vector)dbxrefs.get(featureId);
    
    tjc's avatar
    tjc committed
          for(int j=0; j<dbxref.size(); j++)
    
    tjc's avatar
    tjc committed
            if(((String)dbxref.get(j)).startsWith("GFF_source:"))
    
    tjc's avatar
    tjc committed
              gff_source = ((String)dbxref.get(j)).substring(11);
              dbxref.removeElementAt(j);
    
    tjc's avatar
    tjc committed
        }
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
        this_buff.append(parentFeature + "\t"); // seqid
        
        if(gff_source != null)
          this_buff.append(gff_source+"\t");    // source
        else
          this_buff.append("chado\t");            
        this_buff.append(typeName + "\t");      // type
        this_buff.append(fmin + "\t");          // start
        this_buff.append(fmax + "\t");          // end
        this_buff.append(".\t");                // score
    
        if(strand.equals( new Short((short)-1)) )                        // strand
    
    tjc's avatar
    tjc committed
          this_buff.append("-\t");
    
        else if(strand.equals( new Short((short)1)) )
    
    tjc's avatar
    tjc committed
          this_buff.append("+\t");
        else
          this_buff.append(".\t");
    
    
        if(phase == null)
    
    tjc's avatar
    tjc committed
          this_buff.append(".\t");               // phase
        else
          this_buff.append(phase+"\t"); 
    
        this_buff.append("ID=" + name + ";");
    
       
        if(parent_id != null && !parent_id.equals("0"))
        {
          if(parent_relationship.equals("derives_from"))
            this_buff.append("Derives_from=" + parent_id + ";");
    
    tjc's avatar
    tjc committed
          else
    
    tjc's avatar
    tjc committed
            this_buff.append("Parent=" + parent_id + ";");
        }
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
        this_buff.append("timelastmodified=" + timelastmodified + ";");
    
    tjc's avatar
    tjc committed
        
        // this is the chado feature_relationship.rank used
    
    tjc's avatar
    tjc committed
        // to order joined features e.g. exons
    
    tjc's avatar
    tjc committed
        if(rank > -1)
    
    tjc's avatar
    tjc committed
          this_buff.append("feature_relationship_rank="+rank+";"); 
    
    tjc's avatar
    tjc committed
    
    
        //this_buff.append("feature_id="+feature_id+";");
        
    
    tjc's avatar
    tjc committed
        // attributes
    
        if(feat.getFeatureProps() != null &&
           feat.getFeatureProps().size() > 0)
    
    tjc's avatar
    tjc committed
        {
    
    tjc's avatar
    tjc committed
          Collection featureprops = feat.getFeatureProps();
          Iterator it = featureprops.iterator();
          
          while(it.hasNext())
    
    tjc's avatar
    tjc committed
          {
    
    tjc's avatar
    tjc committed
            FeatureProp featprop = (FeatureProp)it.next();
    
    tjc's avatar
    tjc committed
            String qualifier_name = getCvtermName(featprop.getCvTerm().getCvTermId(), dao);
    
    tjc's avatar
    tjc committed
            if(qualifier_name == null)
              continue;
    
    tjc's avatar
    tjc committed
            if(featprop.getValue() != null)
              this_buff.append(qualifier_name+ "=" +
                               GFFStreamFeature.encode(featprop.getValue())+";");
    
    tjc's avatar
    tjc committed
          }
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
        // append dbxrefs
        if(dbxref != null && dbxref.size() > 0)
        {
          this_buff.append("Dbxref=");
          for(int j=0; j<dbxref.size(); j++)
    
    tjc's avatar
    tjc committed
          {
    
    tjc's avatar
    tjc committed
            this_buff.append((String)dbxref.get(j));
            if(j<dbxref.size()-1)
              this_buff.append(",");
    
    tjc's avatar
    tjc committed
          }
    
    tjc's avatar
    tjc committed
          this_buff.append(";");
        }
        
        // append synonyms
        if(synonym != null &&
    
           synonym.containsKey(featureId))
    
    tjc's avatar
    tjc committed
        {   
    
    tjc's avatar
    tjc committed
          FeatureSynonym alias;
    
          Vector v_synonyms = (Vector)synonym.get(featureId);
    
    tjc's avatar
    tjc committed
          for(int j=0; j<v_synonyms.size(); j++)
          {
    
    tjc's avatar
    tjc committed
            alias = (FeatureSynonym)v_synonyms.get(j);
    
    tjc's avatar
    tjc committed
            
    
    tjc's avatar
    tjc committed
            this_buff.append( getCvtermName(alias.getSynonym().getCvTerm().getCvTermId(), dao) + "=" );
    
    tjc's avatar
    tjc committed
            //this_buff.append(alias.getSynonym().getCvterm().getName()+"=");
    
    tjc's avatar
    tjc committed
            this_buff.append(alias.getSynonym().getName());
            
            if(j<v_synonyms.size()-1)
              this_buff.append(";");
    
    tjc's avatar
    tjc committed
          }
    
    tjc's avatar
    tjc committed
        }
    
    tjc's avatar
    tjc committed
        
    
    tjc's avatar
    tjc committed
        // GO, controlled_curation, product
    
        if(featureCvTerms != null && 
    
           featureCvTerms.containsKey(featureId))
    
        {
          FeatureCvTerm feature_cvterm;
    
          Vector v_feature_cvterms = (Vector)featureCvTerms.get(featureId);
    
          for(int j=0; j<v_feature_cvterms.size(); j++)
          {
            feature_cvterm = (FeatureCvTerm)v_feature_cvterms.get(j);
            
    
    tjc's avatar
    tjc committed
            Integer featureCvTermId = new Integer( feature_cvterm.getFeatureCvTermId() );
            
    
    tjc's avatar
    tjc committed
            List featureCvTermDbXRefList = null;
    
    tjc's avatar
    tjc committed
            
    
    tjc's avatar
    tjc committed
            if(featureCvTermDbXRefs != null)
              featureCvTermDbXRefList = (List)featureCvTermDbXRefs.get(featureCvTermId);
            
            List featureCvTermPubList = null;
            
            if(featureCvTermPubs != null)
              featureCvTermPubList = (List)featureCvTermPubs.get(featureCvTermId);
    
    tjc's avatar
    tjc committed
            appendControlledVocabulary(this_buff, dao, feature_cvterm,
    
    tjc's avatar
    tjc committed
                                       featureCvTermDbXRefList,featureCvTermPubList, pubDbXRefs);
    
    tjc's avatar
    tjc committed
          }
          //System.out.println(new String(this_buff.getBytes()));
        }
          
        this_buff.append("\n");
      }
      
      /**
       * Appends controlled vocabulary terms to the buffer
       * @param attr_buff
       * @param dao
       * @param feature_cvterm
       * @param featureCvTermDbXRef
       */
      public static void appendControlledVocabulary(final ByteBuffer attr_buff,
                                              final GmodDAO dao,
                                              final FeatureCvTerm feature_cvterm,
                                              final List featureCvTermDbXRefs,
    
    tjc's avatar
    tjc committed
                                              final List featureCvTermPubs,
    
    tjc's avatar
    tjc committed
                                              final List pubDbXRefs)
      {
        CvTerm cvterm =  getCvTerm( feature_cvterm.getCvTerm().getCvTermId(), dao);
        DbXRef dbXRef = feature_cvterm.getCvTerm().getDbXRef();
        
        if(cvterm.getCv().getName().startsWith(DatabaseDocument.CONTROLLED_CURATION_TAG_CVNAME))
        {
          attr_buff.append("controlled_curation=");
          
          attr_buff.append("term="+feature_cvterm.getCvTerm().getName()+"%3B");
          attr_buff.append("cv="+feature_cvterm.getCvTerm().getCv().getName()+"%3B");   
          
          // N.B. the db_xref may be a FeatureCvTermDbXRef or a Pub for /controlled_curation
          int nfound_dbxref = 0;
          if(feature_cvterm.getPub().getUniqueName() != null &&
             !feature_cvterm.getPub().getUniqueName().equals("NULL"))
          {