Skip to content
Snippets Groups Projects
DatabaseDocument.java 103 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.Options;
import uk.ac.sanger.artemis.io.ChadoCanonicalGene;
import uk.ac.sanger.artemis.io.DocumentEntry;
import uk.ac.sanger.artemis.io.GFF3Encoder;
tjc's avatar
tjc committed
import uk.ac.sanger.artemis.io.GFFStreamFeature;
import uk.ac.sanger.artemis.io.PartialSequence;
tjc's avatar
tjc committed
import uk.ac.sanger.artemis.io.Range;
import uk.ac.sanger.artemis.io.ReadFormatException;
tjc's avatar
tjc committed
import uk.ac.sanger.artemis.chado.ArtemisUtils;
tjc's avatar
tjc committed
import uk.ac.sanger.artemis.chado.ChadoCvTermView;
import uk.ac.sanger.artemis.chado.ChadoTransactionManager;
import uk.ac.sanger.artemis.chado.FeatureForUpdatingResidues;
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;
import uk.ac.sanger.artemis.components.genebuilder.GeneUtils;
tjc's avatar
tjc committed
import uk.ac.sanger.artemis.components.Splash;
import uk.ac.sanger.artemis.util.DatabaseLocationParser;
tjc's avatar
tjc committed

import org.gmod.schema.sequence.Feature;
import org.gmod.schema.sequence.FeatureProp;
import org.gmod.schema.sequence.FeatureLoc;
tjc's avatar
tjc committed
import org.gmod.schema.sequence.FeaturePub;
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.Cv;
import org.gmod.schema.cv.CvTerm;
tjc's avatar
tjc committed
import org.gmod.schema.general.Db;
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;
import org.postgresql.largeobject.LargeObjectManager;

import com.ibatis.common.jdbc.SimpleDataSource;
tjc's avatar
tjc committed
import java.sql.*;
import java.text.DateFormat;
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.net.InetAddress;
import java.util.Calendar;
tjc's avatar
tjc committed
import java.util.Collections;
import java.util.Comparator;
tjc's avatar
tjc committed
import java.util.HashSet;
tjc's avatar
tjc committed
import java.util.Hashtable;
tjc's avatar
tjc committed
import java.util.Set;
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.
 */
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";

tjc's avatar
tjc committed
  private static Hashtable<Integer, CvTerm> 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 static 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

tjc's avatar
tjc committed
  /** entries to split into - each is given a name and the features within the entry */
tjc's avatar
tjc committed
  private static String[][][] TYPES = 
tjc's avatar
tjc committed
  { 
      { {"repeats"}   , {"repeat_region", "direct_repeat"} }, 
      { {"EST"}       , {"EST_match", "match_part"} },
      { {"contig+gap"}, {"contig", "gap"}}
  };
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 boolean singleSchema = true;
tjc's avatar
tjc committed

tjc's avatar
tjc committed
  //private List schema_list;
tjc's avatar
tjc committed
  private static List<String> organismNames;
tjc's avatar
tjc committed
  
  private boolean gene_builder;
  
  // include children in reading from the database
  private boolean readChildren = true;
  
tjc's avatar
tjc committed
  // range to retrieve features for
tjc's avatar
tjc committed
  private Range range;
  
  private Feature geneFeature;
  
tjc's avatar
tjc committed
  private Hashtable<String, Feature> idFeatureStore;
tjc's avatar
tjc committed
  
  private boolean lazyFeatureLoad = true;
  
tjc's avatar
tjc committed
  public static String EXONMODEL  = "exon-model";
  public static String TRANSCRIPT = "mRNA";
  public static boolean CHADO_INFER_CDS = false;
  /** list of controlled_curation CV names */
tjc's avatar
tjc committed
  private static Vector<String> cvControledCuratioNames;
  private static CvTermThread cvThread;
  
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_";
  /**  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
  
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/database_name?user=username
tjc's avatar
tjc committed
   * 
   */
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);
    
    if(System.getProperty("ibatis") != null ||
       System.getProperty("jdbc") == 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
    initMDC(this);
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;

    if(System.getProperty("ibatis") != null ||
       System.getProperty("jdbc") == 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
    initMDC(this);
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/database_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;
    if(System.getProperty("ibatis") != null ||
       System.getProperty("jdbc") == 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
    initMDC(this);
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 ||
       System.getProperty("jdbc") == null)
    {
      iBatis = true;
      System.setProperty("chado", location);
    }
tjc's avatar
tjc committed
    initMDC(this);
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;
    if(System.getProperty("ibatis") != null ||
       System.getProperty("jdbc") == 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
    initMDC(this);
  /**
   * Use another DatabaseDocument to make a new document.
   * @param originalDocument
   * @param srcFeatureId
   * @param schema
   * @param gene_builder
tjc's avatar
tjc committed
   * @param region_grab
   * @param progress_listener
tjc's avatar
tjc committed
  public DatabaseDocument (final DatabaseDocument originalDocument,
             final String schema, final Feature geneFeature,
             final Range range,
             final InputStreamProgressListener progress_listener)
  {
    this((String)originalDocument.getLocation(), 
         originalDocument.getPfield(),
         "-1", schema, false);
    this.progress_listener = progress_listener;
    this.range = range;
    this.geneFeature = geneFeature;
  }
  
  /**
   * Use another DatabaseDocument to make a new document.
   * @param originalDocument
   * @param srcFeatureId
   * @param schema
   * @param gene_builder
   * @param region_grab
   * @param progress_listener
   */
  public DatabaseDocument (final DatabaseDocument originalDocument,
             final String srcFeatureId, 
             final String schema, 
             final boolean gene_builder,
             final InputStreamProgressListener progress_listener)
  {
    this((String)originalDocument.getLocation(), 
         originalDocument.getPfield(),
         srcFeatureId, schema, gene_builder);
    this.progress_listener = progress_listener;
tjc's avatar
tjc committed
  public static void initMDC(final DatabaseDocument doc)
tjc's avatar
tjc committed
  {
    // add username & host to MDC data for logging
    try
tjc's avatar
tjc committed
      org.apache.log4j.MDC.put("username",doc.getUserName());
tjc's avatar
tjc committed
  	}
  	catch(NullPointerException npe)
	  {
	    org.apache.log4j.MDC.put("username",System.getProperty("user.name"));
	  }
tjc's avatar
tjc committed
	
	  try 
	  {
	    org.apache.log4j.MDC.put("host",
tjc's avatar
tjc committed
    		  InetAddress.getLocalHost().getHostAddress());
	  } 
	  catch(Exception e) {}
  }
  
  public void setReadChildren(final boolean readChildren)
  {
    this.readChildren = readChildren; 
  /**
   * 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);
      if(iBatis && connIB != null)
      {
        try
        {
          connIB.close();
        }
        catch(SQLException e)
        {
          logger4j.warn(e.getMessage());
        }
        connIB  = null;
      }
      
      jdbcDAO = null;
      System.setProperty("chado", (String)getLocation());
tjc's avatar
tjc committed
      logger4j.debug((String)getLocation());
tjc's avatar
tjc committed
  
  /**
   * Reset connection.
   */
  public void reset()
  {
    if(iBatis && connIB != null)
    {
      try
      {
        connIB.close();
      }
      catch(SQLException e)
      {
        logger4j.warn(e.getMessage());
      }
      connIB  = null;
    }
    
    jdbcDAO = null;
  }
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

      if(gene_builder)
      {
tjc's avatar
tjc committed
        // creating a gene builder
tjc's avatar
tjc committed
        List<String> schemaList = new Vector<String>();
tjc's avatar
tjc committed
        schemaList.add(schema);
          
        ByteBuffer bb = getGeneFeature(srcFeatureId,
                                       schemaList, dao, readChildren);          
tjc's avatar
tjc committed
        return new ByteArrayInputStream(bb.getBytes());
      }
tjc's avatar
tjc committed
      else if(range != null)
      {
        //
        // Retrieve all features within a range
tjc's avatar
tjc committed
       // List schemaList = new Vector();
       // schemaList.add(schema);
tjc's avatar
tjc committed
        final Feature srcFeature;
        if(geneFeature != null)
        {
tjc's avatar
tjc committed
          Collection<FeatureLoc> featureLocs = geneFeature.getFeatureLocsForFeatureId();
          Iterator<FeatureLoc> it = featureLocs.iterator();
          final FeatureLoc featureLoc = it.next();
tjc's avatar
tjc committed

          int srcfeatureid = featureLoc.getFeatureBySrcFeatureId().getFeatureId();
          srcFeature = dao.getFeatureById(srcfeatureid);
tjc's avatar
tjc committed
          setName(srcFeature.getUniqueName());
          this.srcFeatureId = Integer.toString(srcfeatureid);     
tjc's avatar
tjc committed
        }
        else
        {
          srcFeature = dao.getFeatureById(Integer.parseInt(srcFeatureId));
        }
tjc's avatar
tjc committed
        
        final ByteBuffer entryBuffer = getFeaturesInRange(srcFeature, range, dao);
tjc's avatar
tjc committed
        getChadoSequence(srcFeature, entryBuffer);

        return new ByteArrayInputStream(entryBuffer.getBytes());
      }
      
      ByteBuffer entryBuffer = new ByteBuffer();
tjc's avatar
tjc committed
      try
        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        Calendar cal = Calendar.getInstance();

tjc's avatar
tjc committed
        entryBuffer.append("##gff-version 3\n");
        entryBuffer.append("#created " + dateFormat.format(cal.getTime()) + "\n");
tjc's avatar
tjc committed
        
tjc's avatar
tjc committed
        ByteBuffer sequenceBuffer = new ByteBuffer();
tjc's avatar
tjc committed
        if(dao instanceof IBatisDAO)
          ((IBatisDAO) dao).startTransaction();
        logger4j.debug("RETRIEVE SOURCE FEATURE FROM: "+getLocation());
tjc's avatar
tjc committed
        Feature srcFeature = getChadoSequence(dao, sequenceBuffer);
tjc's avatar
tjc committed
        
        entryBuffer.append("##sequence-region " + srcFeature.getUniqueName() +
tjc's avatar
tjc committed
            " 1 " + srcFeature.getResidues().length + "\n");
tjc's avatar
tjc committed
        gff_buffer = getGff(dao, srcFeature);
tjc's avatar
tjc committed
        
        if(splitGFFEntry)
tjc's avatar
tjc committed
        {
tjc's avatar
tjc committed
          if(gff_buffer[0].size() > 0)
tjc's avatar
tjc committed
            entryBuffer.append(gff_buffer[0]);
tjc's avatar
tjc committed
        }
        else
        {
          for(int i = 0; i < gff_buffer.length; i++)
          {
            if(gff_buffer[i].size() > 0)
tjc's avatar
tjc committed
              entryBuffer.append(gff_buffer[i]);
tjc's avatar
tjc committed
          }
tjc's avatar
tjc committed
        }
tjc's avatar
tjc committed

tjc's avatar
tjc committed
        if(dao instanceof IBatisDAO)
          ((IBatisDAO) dao).commitTransaction();
tjc's avatar
tjc committed
        entryBuffer.append(sequenceBuffer);
tjc's avatar
tjc committed
      }
      finally
      {
        if(dao instanceof IBatisDAO)
          ((IBatisDAO) dao).endTransaction();
tjc's avatar
tjc committed
      instream = new ByteArrayInputStream(entryBuffer.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 = TYPES[i-1][0][0];
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
   */
tjc's avatar
tjc committed
  private ByteBuffer[] getGff(final GmodDAO dao, 
                              final Feature srcFeature)
tjc's avatar
tjc committed
  {
tjc's avatar
tjc committed
    //final int srcfeature_id = Integer.parseInt(srcFeatureId);
tjc's avatar
tjc committed
    
tjc's avatar
tjc committed
    logger4j.debug("BUILD GFF FEATURES");
tjc's avatar
tjc committed
    
tjc's avatar
tjc committed
    // build srcfeature object
tjc's avatar
tjc committed
    FeatureLoc featureloc = new FeatureLoc();
    featureloc.setFeatureBySrcFeatureId(srcFeature);
tjc's avatar
tjc committed
    Feature child = new Feature();
    
    // ignore match_part (BLAST HSPs)
tjc's avatar
tjc committed
    CvTerm cvTerm;
    try
    {
      cvTerm = getCvTermByCvAndCvTerm("match_part", "sequence");
    }
    catch(NullPointerException ne)
    {
      cvTerm = dao.getCvTermByNameAndCvName("match_part", "sequence");
    }
tjc's avatar
tjc committed
    child.setFeatureLoc(featureloc);
    child.setAnalysis(false);
    child.setCvTerm(cvTerm);
tjc's avatar
tjc committed
    final List<Feature> featList = dao.getFeaturesByLocatedOnFeature(child);
tjc's avatar
tjc committed
    final ByteBuffer[] buffers = new ByteBuffer[TYPES.length + 1];
tjc's avatar
tjc committed
    for(int i = 0; i < buffers.length; i++)
tjc's avatar
tjc committed
      buffers[i] = new ByteBuffer();
tjc's avatar
tjc committed
    
tjc's avatar
tjc committed
    ByteBuffer this_buff;
    int feature_size = featList.size();
tjc's avatar
tjc committed
    final Hashtable<String, Feature> id_store = new Hashtable<String, Feature>(feature_size);
tjc's avatar
tjc committed

tjc's avatar
tjc committed
    // build feature store
    for(int i = 0; i < feature_size; i++)
    {
tjc's avatar
tjc committed
      Feature feat = featList.get(i);
tjc's avatar
tjc committed
      id_store.put(Integer.toString(feat.getFeatureId()), feat);
tjc's avatar
tjc committed

tjc's avatar
tjc committed
    if(lazyFeatureLoad)
      idFeatureStore = id_store;
tjc's avatar
tjc committed

tjc's avatar
tjc committed
    // get all dbrefs & synonyms etc
tjc's avatar
tjc committed
    final Hashtable<Integer, List<String>> dbxrefs;
    final Hashtable<Integer, List<FeatureSynonym>> synonym;
    final Hashtable<Integer, List<FeatureCvTerm>> featureCvTerms;
    final Hashtable<Integer, List<FeatureCvTermDbXRef>> featureCvTermDbXRefs;
    Hashtable<Integer, List<FeatureCvTermPub>> featureCvTermPubs = null;
    final Hashtable<Integer, List<FeaturePub>> featurePubs;
    final List<PubDbXRef> pubDbXRefs;
tjc's avatar
tjc committed
    
    if(lazyFeatureLoad)
    {
      dbxrefs = null;
      synonym = null;
      featureCvTerms = null;
      featureCvTermDbXRefs = null;
      featureCvTermPubs = null;
      featurePubs = null;
      pubDbXRefs = null;
    }
    else
    {
      dbxrefs= IBatisDAO.mergeDbXRef(
tjc's avatar
tjc committed
        dao.getFeatureDbXRefsBySrcFeature(srcFeature));
tjc's avatar
tjc committed
      synonym = getAllFeatureSynonyms(
tjc's avatar
tjc committed
        dao.getFeatureSynonymsBySrcFeature(srcFeature));
tjc's avatar
tjc committed
      featureCvTerms = getFeatureCvTermsByFeature(dao, 
tjc's avatar
tjc committed
        dao.getFeatureCvTermsBySrcFeature(srcFeature));
tjc's avatar
tjc committed
      featureCvTermDbXRefs = getFeatureCvTermDbXRef(dao, 
tjc's avatar
tjc committed
        dao.getFeatureCvTermDbXRefBySrcFeature(srcFeature));
      
      try
      {
        featureCvTermPubs = getFeatureCvTermPub(dao, 
          dao.getFeatureCvTermPubBySrcFeature(srcFeature));
      } 
      catch(Exception e) 
      { 
        e.printStackTrace();
        if(dao instanceof IBatisDAO)
        {
          try
          {
            ((IBatisDAO) dao).endTransaction();
            ((IBatisDAO) dao).startTransaction();
          }
          catch(SQLException sqle){}  
        }
      }
tjc's avatar
tjc committed
      featurePubs = getFeaturePubs(dao,
          dao.getFeaturePubsBySrcFeature(srcFeature));
tjc's avatar
tjc committed
      pubDbXRefs= dao.getPubDbXRef();
    }
tjc's avatar
tjc committed
    
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 = featList.get(i);
tjc's avatar
tjc committed
      int type_id = feat.getCvTerm().getCvTermId();
      String typeName = getCvtermName(type_id, dao, gene_builder);
tjc's avatar
tjc committed
      this_buff = buffers[0];
tjc's avatar
tjc committed

tjc's avatar
tjc committed
      for(int j = 0; j < TYPES.length; j++)
tjc's avatar
tjc committed
      {
tjc's avatar
tjc committed
        for(int k=0; k<TYPES[j][1].length; k++)
          if(TYPES[j][1][k].equals(typeName))
tjc's avatar
tjc committed
            this_buff = buffers[j+1];
tjc's avatar
tjc committed
      }
tjc's avatar
tjc committed

      chadoToGFF(feat, srcFeature.getUniqueName(),
                 dbxrefs, synonym, featureCvTerms,
tjc's avatar
tjc committed
                 pubDbXRefs, featureCvTermDbXRefs, featureCvTermPubs,
tjc's avatar
tjc committed
                 featurePubs,
tjc's avatar
tjc committed
                 id_store, dao, 
                 feat.getFeatureLoc(), this_buff, gene_builder);
      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
   * 
   */
tjc's avatar
tjc committed
  private Hashtable<Integer, List<FeatureSynonym>> getAllFeatureSynonyms(final List<FeatureSynonym> list) 
tjc's avatar
tjc committed
    Hashtable<Integer, List<FeatureSynonym>> synonym = new Hashtable<Integer, List<FeatureSynonym>>();
tjc's avatar
tjc committed
    List<FeatureSynonym> 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 = list.get(i);
      featureId = new Integer(alias.getFeature().getFeatureId());
      if(synonym.containsKey(featureId))
tjc's avatar
tjc committed
        value = synonym.get(featureId);
tjc's avatar
tjc committed
      else
tjc's avatar
tjc committed
        value = new Vector<FeatureSynonym>();
tjc's avatar
tjc committed
      
      value.add(alias);
      synonym.put(featureId, value);
tjc's avatar
tjc committed
    }
    
    return synonym;
tjc's avatar
tjc committed
  /**
   * Get FeaturePub's (i.e. /literature qualifiers).
   * @param dao
tjc's avatar
tjc committed
   * @param list
tjc's avatar
tjc committed
   * @return
   */
tjc's avatar
tjc committed
  private Hashtable<Integer, List<FeaturePub>> getFeaturePubs(final GmodDAO dao,
                                                              final List<FeaturePub> list)
tjc's avatar
tjc committed
  {
tjc's avatar
tjc committed
    final Hashtable<Integer, List<FeaturePub>> featurePubs = new Hashtable<Integer, List<FeaturePub>>();
tjc's avatar
tjc committed
    Integer featureId;
tjc's avatar
tjc committed
    List<FeaturePub> value;
tjc's avatar
tjc committed
    FeaturePub featurePub;
    
    for(int i=0; i<list.size(); i++)
    {
tjc's avatar
tjc committed
      featurePub = list.get(i);
tjc's avatar
tjc committed
      featureId = new Integer(featurePub.getFeature().getFeatureId());
      if(featurePubs.containsKey(featureId))
tjc's avatar
tjc committed
        value = featurePubs.get(featureId);
tjc's avatar
tjc committed
      else
tjc's avatar
tjc committed
        value = new Vector<FeaturePub>();
tjc's avatar
tjc committed
      
      value.add(featurePub);
      featurePubs.put(featureId, value);
    }
    
    return featurePubs;
  }
  
tjc's avatar
tjc committed
  /**
   * @param dao
   * @param chadoFeature null if we want them all
   * @return
   */
tjc's avatar
tjc committed
  private Hashtable<Integer, List<FeatureCvTerm>> getFeatureCvTermsByFeature(
                                final GmodDAO dao, 
                                final List<FeatureCvTerm> list)
tjc's avatar
tjc committed
    Hashtable<Integer, List<FeatureCvTerm>> featureCvTerms = new Hashtable<Integer, List<FeatureCvTerm>>();
tjc's avatar
tjc committed
    List<FeatureCvTerm> value;
    FeatureCvTerm feature_cvterm;
    
    for(int i=0; i<list.size(); i++)
    {
tjc's avatar
tjc committed
      feature_cvterm = list.get(i);
      featureId = new Integer(feature_cvterm.getFeature().getFeatureId());
      if(featureCvTerms.containsKey(featureId))
tjc's avatar
tjc committed
        value = featureCvTerms.get(featureId);
tjc's avatar
tjc committed
        value = new Vector<FeatureCvTerm>();
      
      value.add(feature_cvterm);
      featureCvTerms.put(featureId, value);
    }
    return featureCvTerms;
  }
tjc's avatar
tjc committed
  
tjc's avatar
tjc committed
  /**
   * 
   * @param dao
   * @param chadoFeature null if we want all
   * @return
   */
tjc's avatar
tjc committed
  private Hashtable<Integer, List<FeatureCvTermDbXRef>> getFeatureCvTermDbXRef(
      final GmodDAO dao, final List<FeatureCvTermDbXRef> list)
tjc's avatar
tjc committed
  {
    if(list == null || list.size() == 0)
      return null;
    
tjc's avatar
tjc committed
    Integer featureCvTermDbXRefId;
tjc's avatar
tjc committed
    List<FeatureCvTermDbXRef> value;
tjc's avatar
tjc committed
    
tjc's avatar
tjc committed
    Hashtable<Integer, List<FeatureCvTermDbXRef>> featureCvTermDbXRefs = 
      new Hashtable<Integer, List<FeatureCvTermDbXRef>>(list.size());
tjc's avatar
tjc committed
    for(int i=0; i<list.size(); i++)
    {
      FeatureCvTermDbXRef featureCvTermDbXRef =
tjc's avatar
tjc committed
        list.get(i);
tjc's avatar
tjc committed
      
      featureCvTermDbXRefId = new Integer(
          featureCvTermDbXRef.getFeatureCvTerm().getFeatureCvTermId());
      
      if(featureCvTermDbXRefs.containsKey(featureCvTermDbXRefId))
tjc's avatar
tjc committed
        value = featureCvTermDbXRefs.get(featureCvTermDbXRefId);
tjc's avatar
tjc committed
      else
tjc's avatar
tjc committed
        value = new Vector<FeatureCvTermDbXRef>();
tjc's avatar
tjc committed
      
      value.add(featureCvTermDbXRef);
      featureCvTermDbXRefs.put(featureCvTermDbXRefId, value);
tjc's avatar
tjc committed
    }
     
    return featureCvTermDbXRefs;
  }
  
tjc's avatar
tjc committed
  private Hashtable<Integer, List<FeatureCvTermPub>> getFeatureCvTermPub(
                                        final GmodDAO dao,
                                        final List<FeatureCvTermPub> list)
tjc's avatar
tjc committed
  {
    if(list == null || list.size() == 0)
      return null;
tjc's avatar
tjc committed

tjc's avatar
tjc committed
    Integer featureCvTermId;
tjc's avatar
tjc committed
    List<FeatureCvTermPub> value;

    Hashtable<Integer, List<FeatureCvTermPub>> featureCvTermPubs = 
      new Hashtable<Integer, List<FeatureCvTermPub>>(list.size());
tjc's avatar
tjc committed
    for(int i=0; i<list.size(); i++)
    {
      FeatureCvTermPub featureCvTermPub =
tjc's avatar
tjc committed
        list.get(i);
tjc's avatar
tjc committed
      
      featureCvTermId = new Integer(
          featureCvTermPub.getFeatureCvTerm().getFeatureCvTermId());
      
      if(featureCvTermPubs.containsKey(featureCvTermId))
tjc's avatar
tjc committed
        value = featureCvTermPubs.get(featureCvTermId);
tjc's avatar
tjc committed
      else
tjc's avatar
tjc committed
        value = new Vector<FeatureCvTermPub>();
tjc's avatar
tjc committed
      
      value.add(featureCvTermPub);
      featureCvTermPubs.put(featureCvTermId, value);
    }
    return featureCvTermPubs;
  }
  
tjc's avatar
tjc committed
  /**
   * Retrieve the features in a given range
   * @param srcFeature
   * @param range
   * @param dao
   * @return
   */
  private ByteBuffer getFeaturesInRange(final Feature srcFeature,
                                        final Range range, 
                                        final GmodDAO dao)
  { 
    ByteBuffer buff = new ByteBuffer();

tjc's avatar
tjc committed
    logger4j.debug("GET FEATURES IN RANGE:: "+range.toString());
tjc's avatar
tjc committed
    List featuresInRange = dao.getFeaturesByRange(range.getStart()-1, 
                                range.getEnd(), 0, srcFeature, null);
    
tjc's avatar
tjc committed
    List<Integer> featureIds = new Vector<Integer>(featuresInRange.size());
tjc's avatar
tjc committed
    for(int i=0; i<featuresInRange.size(); i++)
    {
      Feature thisFeature = (Feature)featuresInRange.get(i);
      featureIds.add(new Integer(thisFeature.getFeatureId()));
    }
    
    FeatureLoc featureLoc = new FeatureLoc();
    featureLoc.setFmin(new Integer(range.getStart()));
    featureLoc.setFmax(new Integer(range.getEnd()));
    srcFeature.setFeatureLoc(featureLoc);
    
tjc's avatar
tjc committed
    Hashtable<Integer, List<String>> dbxrefs = IBatisDAO.mergeDbXRef(
tjc's avatar
tjc committed
        dao.getFeatureDbXRefsBySrcFeature(srcFeature));
tjc's avatar
tjc committed
    Hashtable<Integer, List<FeatureSynonym>> synonym = getAllFeatureSynonyms(
tjc's avatar
tjc committed
        dao.getFeatureSynonymsBySrcFeature(srcFeature));
tjc's avatar
tjc committed
    Hashtable<Integer, List<FeatureCvTerm>> featureCvTerms = getFeatureCvTermsByFeature(dao, 
tjc's avatar
tjc committed
        dao.getFeatureCvTermsBySrcFeature(srcFeature));
tjc's avatar
tjc committed
    Hashtable<Integer, List<FeatureCvTermDbXRef>> featureCvTermDbXRefs = getFeatureCvTermDbXRef(dao, 
tjc's avatar
tjc committed
        dao.getFeatureCvTermDbXRefBySrcFeature(srcFeature));
tjc's avatar
tjc committed
    Hashtable<Integer, List<FeatureCvTermPub>> featureCvTermPubs = getFeatureCvTermPub(dao, 
tjc's avatar
tjc committed
        dao.getFeatureCvTermPubBySrcFeature(srcFeature));
tjc's avatar
tjc committed
    Hashtable<Integer, List<FeaturePub>> featurePubs = getFeaturePubs(dao,
tjc's avatar
tjc committed
        dao.getFeaturePubsBySrcFeature(srcFeature));
tjc's avatar
tjc committed

tjc's avatar
tjc committed
    List<PubDbXRef> pubDbXRefs = dao.getPubDbXRef();
tjc's avatar
tjc committed
    
tjc's avatar
tjc committed
    Hashtable<String, Feature> id_store = new Hashtable<String, Feature>(featuresInRange.size());
tjc's avatar
tjc committed

    // build feature name store
    for(int i = 0; i < featuresInRange.size(); i++)
    {
      Feature chadoFeature = (Feature)featuresInRange.get(i);
      String featureId = Integer.toString(chadoFeature.getFeatureId());
tjc's avatar
tjc committed
      id_store.put(featureId, chadoFeature);
tjc's avatar
tjc committed
    }