Skip to content
Snippets Groups Projects
DatabaseDocument.java 57 KiB
Newer Older
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.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
  /** 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
  public static String RILEY_TAG_CVNAME = "RILEY";
tjc's avatar
tjc committed
  
tjc's avatar
tjc committed
  private static org.apache.log4j.Logger logger4j = 
    org.apache.log4j.Logger.getLogger(DatabaseDocument.class);
  
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
      logger4j.debug((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);
tjc's avatar
tjc committed
          
          
          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

tjc's avatar
tjc committed
    Hashtable featureCvTerms = getFeatureCvTermsByFeature(dao, null);
    Hashtable featureCvTermDbXRefs = getFeatureCvTermDbXRef(dao, null);
    Hashtable featureCvTermPubs = getFeatureCvTermPub(dao, null);
tjc's avatar
tjc committed
    
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;
tjc's avatar
tjc committed
  /**
   * 
   * @param dao
   * @param chadoFeature null if we want them all
   * @return
   */
  private Hashtable getFeatureCvTermsByFeature(final GmodDAO dao, 
                                               final Feature chadoFeature)
tjc's avatar
tjc committed
    List list = dao.getFeatureCvTermsByFeature(chadoFeature);
    
    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
  /**
   * 
   * @param dao
   * @param chadoFeature null if we want all
   * @return
   */
  private Hashtable getFeatureCvTermDbXRef(final GmodDAO dao, final Feature chadoFeature)
tjc's avatar
tjc committed
  {
tjc's avatar
tjc committed
    List list = dao.getFeatureCvTermDbXRefByFeature(chadoFeature);
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,
                                        final Feature chadoFeature)
tjc's avatar
tjc committed
  {
tjc's avatar
tjc committed
    List list = dao.getFeatureCvTermPubByFeature(chadoFeature);
tjc's avatar
tjc committed
    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();

    reset((String)getLocation(), (String)schema_search.get(0));
    dao = getDAO();
tjc's avatar
tjc committed
    Feature chadoFeature = 
      (Feature)(dao.getFeaturesByUniqueName(search_gene).get(0));
    ChadoCanonicalGene chado_gene = new ChadoCanonicalGene();
tjc's avatar
tjc committed
    id_store.put(Integer.toString(chadoFeature.getFeatureId()), 
                 chadoFeature.getUniqueName());
tjc's avatar
tjc committed
    List featurelocs = new Vector(chadoFeature.getFeatureLocsForFeatureId());
tjc's avatar
tjc committed
    FeatureLoc featureloc = (FeatureLoc) featurelocs.get(0);
tjc's avatar
tjc committed
    int src_id = featureloc.getSrcFeatureId();
    srcFeatureId = Integer.toString(src_id);
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);
tjc's avatar
tjc committed
    
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
    buildGffLineFromId(dao, chadoFeature.getFeatureId(), 
        id_store, parent.getUniqueName(), src_id, buff, chadoFeature);
    

    // get children of gene
tjc's avatar
tjc committed
    List relations = new Vector(chadoFeature.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
      
      Feature transcript = buildGffLineFromId(dao, id, id_store, parent.getUniqueName(), 
                                              src_id, buff, null);

      // 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
        

        buildGffLineFromId(dao, id, id_store, parent.getUniqueName(), 
                           src_id, buff, null);
tjc's avatar
tjc committed

    System.out.println( new String(buff.getBytes()) );
tjc's avatar
tjc committed
  private Feature buildGffLineFromId(final GmodDAO dao, 
                                  final int featureId, 
                                  final Hashtable id_store,
                                  final String parentName,
                                  final int srcFeatureId,
                                  final ByteBuffer this_buff,
                                  Feature chadoFeature)
  {
    if(chadoFeature == null)
      chadoFeature = (Feature)dao.getFeatureById(featureId); 

    id_store.put(Integer.toString(chadoFeature.getFeatureId()), 
                 chadoFeature.getUniqueName());
tjc's avatar
tjc committed

tjc's avatar
tjc committed
    FeatureLoc loc = getFeatureLoc(new Vector(
        chadoFeature.getFeatureLocsForFeatureId()), srcFeatureId);
    Hashtable dbxrefs = IBatisDAO.mergeDbXRef(
        dao.getFeatureDbXRefsByFeatureUniquename(chadoFeature.getUniqueName()));
    Hashtable synonym = getAllFeatureSynonyms(dao, chadoFeature.getUniqueName());
    
    Hashtable featureCvTerms = getFeatureCvTermsByFeature(dao, chadoFeature);
    Hashtable featureCvTermDbXRefs = getFeatureCvTermDbXRef(dao, chadoFeature);
    Hashtable featureCvTermPubs = getFeatureCvTermPub(dao, chadoFeature);
    
    chadoToGFF(chadoFeature, parentName, dbxrefs, synonym, featureCvTerms,
        null, featureCvTermDbXRefs, featureCvTermPubs, id_store, dao, loc, this_buff);  
    return chadoFeature;
  }
  
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 + ";");
    this_buff.append("feature_id=" + featureId.toString() + ";");
tjc's avatar
tjc committed

   
    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());
        
tjc's avatar
tjc committed
        //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()));
    }