From b4cc53d4cba79e39ead07665ea2807f582f8d6f9 Mon Sep 17 00:00:00 2001 From: tjc <tjc@ee4ac58c-ac51-4696-9907-e4b3aa274f04> Date: Wed, 22 Jul 2009 12:53:36 +0000 Subject: [PATCH] Add option to read data from a graph table in the database git-svn-id: svn+ssh://svn.internal.sanger.ac.uk/repos/svn/pathsoft/artemis/trunk@11405 ee4ac58c-ac51-4696-9907-e4b3aa274f04 --- artemis_sqlmap/Graph.xml | 50 ++++++++ artemis_sqlmap/chado_iBatis_config.xml | 1 + uk/ac/sanger/artemis/chado/GmodDAO.java | 4 + uk/ac/sanger/artemis/chado/Graph.java | 94 ++++++++++++++ uk/ac/sanger/artemis/chado/IBatisDAO.java | 30 ++++- uk/ac/sanger/artemis/chado/JdbcDAO.java | 24 ++++ .../sanger/artemis/components/GraphMenu.java | 99 +++++++++++++- .../sanger/artemis/util/DatabaseDocument.java | 70 ++++++++++ .../artemis/util/LargeObjectDocument.java | 121 ++++++++++++++++++ 9 files changed, 487 insertions(+), 6 deletions(-) create mode 100644 artemis_sqlmap/Graph.xml create mode 100644 uk/ac/sanger/artemis/chado/Graph.java create mode 100644 uk/ac/sanger/artemis/util/LargeObjectDocument.java diff --git a/artemis_sqlmap/Graph.xml b/artemis_sqlmap/Graph.xml new file mode 100644 index 000000000..341b9c565 --- /dev/null +++ b/artemis_sqlmap/Graph.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<!DOCTYPE sqlMap + PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" + "http://ibatis.apache.org/dtd/sql-map-2.dtd"> + + +<sqlMap namespace="Graph"> + + <typeAlias alias="Graph" + type="uk.ac.sanger.artemis.chado.Graph"/> + + <resultMap id="select-graph" + class="Graph"> + <result property="graphId" column="graph_id"/> + <result property="featureId" column="feature_id"/> + <result property="name" column="name"/> + <result property="description" column="description"/> + </resultMap> + + <resultMap id="select-graphdata" + class="Graph"> + <result property="graphId" column="graph_id"/> + <result property="featureId" column="feature_id"/> + <result property="name" column="name"/> + <result property="description" column="description"/> + <result property="data" column="data"/> + </resultMap> + + <select id="getGraphs" resultMap="select-graph"> + SELECT graph_id, feature_id, name, description FROM graph WHERE feature_id=$featureId$ + </select> + + <select id="getGraph" resultMap="select-graphdata"> + SELECT * FROM graph WHERE graph_id=$graphId$ + </select> + + <select id="getTableColumns" parameterClass="java.lang.String" + resultClass="java.lang.String"> + SELECT pg_attribute.attname + FROM pg_attribute, pg_class, pg_namespace + WHERE pg_namespace.oid=pg_class.relnamespace AND + attrelid=pg_class.oid AND + relname=#value# AND + attnum > 0 + <!--AND nspname=#value#--> + </select> + + +</sqlMap> \ No newline at end of file diff --git a/artemis_sqlmap/chado_iBatis_config.xml b/artemis_sqlmap/chado_iBatis_config.xml index 9db915a0f..30a3d4127 100644 --- a/artemis_sqlmap/chado_iBatis_config.xml +++ b/artemis_sqlmap/chado_iBatis_config.xml @@ -98,6 +98,7 @@ <sqlMap resource="artemis_sqlmap/Synonym.xml" /> <sqlMap resource="artemis_sqlmap/AnalysisFeature.xml" /> <sqlMap resource="artemis_sqlmap/Analysis.xml" /> + <sqlMap resource="artemis_sqlmap/Graph.xml" /> </sqlMapConfig> diff --git a/uk/ac/sanger/artemis/chado/GmodDAO.java b/uk/ac/sanger/artemis/chado/GmodDAO.java index 0994d8504..d0c70a8ec 100644 --- a/uk/ac/sanger/artemis/chado/GmodDAO.java +++ b/uk/ac/sanger/artemis/chado/GmodDAO.java @@ -52,6 +52,10 @@ public abstract class GmodDAO private static org.apache.log4j.Logger logger4j = org.apache.log4j.Logger.getLogger(GmodDAO.class); + public abstract Graph getGraph(final Integer graphId); + public abstract List getGraphs(final Integer featureId); + public abstract List getTableColumns(final String tableName); + public abstract List getOrganismsContainingSrcFeatures(); public abstract List getSimilarityMatchesByFeatureIds(final List featureIds); public abstract List getSimilarityMatches(final Integer srcFeatureId); diff --git a/uk/ac/sanger/artemis/chado/Graph.java b/uk/ac/sanger/artemis/chado/Graph.java new file mode 100644 index 000000000..b59634af7 --- /dev/null +++ b/uk/ac/sanger/artemis/chado/Graph.java @@ -0,0 +1,94 @@ +/* Graph.java + * + * created: 2009 + * + * This file is part of Artemis + * + * Copyright (C) 2009 Genome Research Limited + * + * 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.chado; + +import java.io.Serializable; + +/** + * Database graph. + */ +public class Graph implements Serializable +{ + private static final long serialVersionUID = 1L; + // table columns + private int graphId; + private int featureId; + private String name; + private String description; + private byte[] data; + + public Graph() + { + } + + public int getGraphId() + { + return graphId; + } + + public void setGraphId(int graphId) + { + this.graphId = graphId; + } + + public int getFeatureId() + { + return featureId; + } + + public void setFeatureId(int featureId) + { + this.featureId = featureId; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getDescription() + { + return description; + } + + public void setDescription(String description) + { + this.description = description; + } + + public byte[] getData() + { + return data; + } + + public void setData(byte[] data) + { + this.data = data; + } +} \ No newline at end of file diff --git a/uk/ac/sanger/artemis/chado/IBatisDAO.java b/uk/ac/sanger/artemis/chado/IBatisDAO.java index c204c0efb..40810cdc3 100644 --- a/uk/ac/sanger/artemis/chado/IBatisDAO.java +++ b/uk/ac/sanger/artemis/chado/IBatisDAO.java @@ -52,6 +52,7 @@ import org.gmod.schema.analysis.AnalysisFeature; import org.gmod.schema.cv.Cv; import org.gmod.schema.cv.CvTerm; +import javax.sql.DataSource; import javax.swing.JPasswordField; /** @@ -89,6 +90,11 @@ public class IBatisDAO extends GmodDAO { sqlMap.close(); } + + public DataSource getDataSource() throws SQLException + { + return sqlMap.getSqlMap().getDataSource(); + } /** * Test to see if this is an old chado database version @@ -713,6 +719,26 @@ public class IBatisDAO extends GmodDAO return sqlMap.queryForList("getPubDbXRef", null); } + + // + // Graph data + public Graph getGraph(final Integer graphId) + { + //return (Graph) sqlMap.queryForObject("getGraph", graphId); + return null; + } + + + public List getGraphs(final Integer featureId) + { + return sqlMap.queryForList("getGraphs", featureId); + } + + public List getTableColumns(String tableName) + { + return sqlMap.queryForList("getTableColumns", tableName); + } + // // WRITE BACK // @@ -1252,8 +1278,7 @@ public class IBatisDAO extends GmodDAO { sqlMap.insert("insertPubDbXRef", pubDbXRef); } - - + public void startTransaction() throws SQLException { sqlMap.startTransaction(); @@ -1300,5 +1325,4 @@ public class IBatisDAO extends GmodDAO } return dbxrefHash; } - } diff --git a/uk/ac/sanger/artemis/chado/JdbcDAO.java b/uk/ac/sanger/artemis/chado/JdbcDAO.java index e5f4a951b..de3b8086f 100644 --- a/uk/ac/sanger/artemis/chado/JdbcDAO.java +++ b/uk/ac/sanger/artemis/chado/JdbcDAO.java @@ -2295,4 +2295,28 @@ public class JdbcDAO extends GmodDAO { return null; } + + public Graph getGraph(Integer graphId) + { + // TODO Auto-generated method stub + return null; + } + + public List getGraphs(Integer featureId) + { + // TODO Auto-generated method stub + return null; + } + + public List getFeaturesByUniqueNames(List arg0) + { + // TODO Auto-generated method stub + return null; + } + + public List getTableColumns(String tableName) + { + // TODO Auto-generated method stub + return null; + } } diff --git a/uk/ac/sanger/artemis/components/GraphMenu.java b/uk/ac/sanger/artemis/components/GraphMenu.java index 616e2cffc..8b75387f7 100644 --- a/uk/ac/sanger/artemis/components/GraphMenu.java +++ b/uk/ac/sanger/artemis/components/GraphMenu.java @@ -20,19 +20,24 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * $Header: //tmp/pathsoft/artemis/uk/ac/sanger/artemis/components/GraphMenu.java,v 1.9 2009-06-02 15:32:00 tjc Exp $ + * $Header: //tmp/pathsoft/artemis/uk/ac/sanger/artemis/components/GraphMenu.java,v 1.10 2009-07-22 12:53:36 tjc Exp $ */ package uk.ac.sanger.artemis.components; import uk.ac.sanger.artemis.EntryGroup; import uk.ac.sanger.artemis.Options; +import uk.ac.sanger.artemis.chado.Graph; +import uk.ac.sanger.artemis.io.DatabaseDocumentEntry; +import uk.ac.sanger.artemis.io.DocumentEntry; import uk.ac.sanger.artemis.plot.Algorithm; import uk.ac.sanger.artemis.plot.BaseAlgorithm; import uk.ac.sanger.artemis.plot.CodonUsageAlgorithm; import uk.ac.sanger.artemis.plot.CodonUsageWeight; import uk.ac.sanger.artemis.plot.UserDataAlgorithm; import uk.ac.sanger.artemis.sequence.Strand; +import uk.ac.sanger.artemis.util.DatabaseDocument; +import uk.ac.sanger.artemis.util.Document; import java.awt.Cursor; import java.awt.event.ActionEvent; @@ -41,6 +46,7 @@ import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.IOException; import java.io.File; +import java.util.List; import java.util.Vector; import javax.swing.*; @@ -49,7 +55,7 @@ import javax.swing.*; * This menu controls one particular BasePlotGroup. * * @author Kim Rutherford <kmr@sanger.ac.uk> - * @version $Id: GraphMenu.java,v 1.9 2009-06-02 15:32:00 tjc Exp $ + * @version $Id: GraphMenu.java,v 1.10 2009-07-22 12:53:36 tjc Exp $ **/ public class GraphMenu extends JMenu @@ -178,7 +184,20 @@ public class GraphMenu extends JMenu }); add (user_plot_item); - + + if(getEntryGroup().getSequenceEntry().getEMBLEntry() instanceof + DatabaseDocumentEntry) + { + final JMenu database_user_plot = new JMenu("Add Database Plot ..."); + final DatabaseDocument dbDoc = + (DatabaseDocument) ((DocumentEntry) entry_group + .getSequenceEntry().getEMBLEntry()).getDocument(); + + boolean hasGraphs = addDatabaseUserPlot(dbDoc, database_user_plot); + database_user_plot.setEnabled(hasGraphs); + add(database_user_plot); + } + addSeparator (); } @@ -422,6 +441,80 @@ public class GraphMenu extends JMenu return new_plot; } + /** + * Add a UserDataAlgorithm from the database to the display. + * This returns true only if graph data is found. + * @param dbDoc + * @param database_user_plot + * @return + */ + private boolean addDatabaseUserPlot(final DatabaseDocument dbDoc, + final JMenu database_user_plot) + { + List graphs = dbDoc.getGraphs(); + if(graphs == null || graphs.size() == 0) + return false; + + for (int i = 0; i < graphs.size(); i++) + { + final Graph graph = (Graph) graphs.get(i); + JMenuItem menuGraph = new JMenuItem(graph.getName()); + database_user_plot.add(menuGraph); + + menuGraph.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent event) + { + try + { + Document doc = dbDoc.getGraphData(graph.getGraphId(), graph.getName()); + final JCheckBox logTransform = new JCheckBox("Use log(data+1)", false); + JOptionPane.showMessageDialog(frame, logTransform, + "Transform", JOptionPane.QUESTION_MESSAGE); + frame.setCursor(new Cursor(Cursor.WAIT_CURSOR)); + try + { + UserDataAlgorithm new_algorithm = new UserDataAlgorithm( + getEntryGroup().getBases().getForwardStrand(), doc, + logTransform.isSelected()); + final BasePlot new_base_plot = base_plot_group.addAlgorithm(new_algorithm); + + base_plot_group.setVisibleByAlgorithm(new_algorithm, true); + addAlgorithm(new_algorithm, true, false); + + // XXX hack to force the BasePlot to initialise + final DisplayAdjustmentEvent e = new DisplayAdjustmentEvent( + this, feature_display.getFirstVisibleForwardBase(), + feature_display.getLastVisibleForwardBase(), + feature_display.getMaxVisibleBases(), + feature_display.getScaleValue(), + feature_display.getScaleFactor(), + feature_display.isRevCompDisplay(), + DisplayAdjustmentEvent.ALL_CHANGE_ADJUST_EVENT); + + base_plot_group.displayAdjustmentValueChanged(e); + } + catch (IOException e) + { + e.printStackTrace(); + } + frame.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); + adjustSplitPane(true); + } + catch (java.lang.OutOfMemoryError emem) + { + JOptionPane.showMessageDialog(frame, + "Out of memory. Increase the maximum memory" + + "\navailable for this application and try again.", + "Out Of Memory", JOptionPane.WARNING_MESSAGE); + frame.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); + } + } + }); + } + return true; + } + /** * Add a UserDataAlgorithm to the display. **/ diff --git a/uk/ac/sanger/artemis/util/DatabaseDocument.java b/uk/ac/sanger/artemis/util/DatabaseDocument.java index 1529af7e0..7c73946b0 100644 --- a/uk/ac/sanger/artemis/util/DatabaseDocument.java +++ b/uk/ac/sanger/artemis/util/DatabaseDocument.java @@ -60,6 +60,9 @@ import org.gmod.schema.general.DbXRef; import org.gmod.schema.organism.Organism; import org.gmod.schema.pub.PubDbXRef; import org.gmod.schema.pub.Pub; +import org.postgresql.largeobject.LargeObjectManager; + +import com.ibatis.common.jdbc.SimpleDataSource; import java.sql.*; import java.text.SimpleDateFormat; @@ -2453,6 +2456,73 @@ public class DatabaseDocument extends Document } } + /** + * Get a list of the available graphs + * @return + */ + public List getGraphs() + { + GmodDAO dao = getDAOOnly(); + + List list = dao.getTableColumns("graph"); + if(list == null || list.size() == 0) + return null; + return dao.getGraphs(Integer.parseInt(srcFeatureId)); + } + + /** + * Get the graph data from the database. + * This uses JDBC and the org.postgresql.largeobject API. + * @param graphId + * @param name + * @return + */ + public LargeObjectDocument getGraphData(int graphId, String name) + { + LargeObjectDocument doc = null; + try + { + // this causes class cast problems probably because it gets + // a pool connection rather than the underlying real connection + // Connection conn = ((SimpleDataSource)connIB.getDataSource()).getConnection(); + SimpleDataSource ds = (SimpleDataSource)connIB.getDataSource(); + Connection conn = DriverManager.getConnection( + ds.getJdbcUrl(), ds.getJdbcUsername(), ds.getJdbcPassword()); + + + // All LargeObject API calls must be within a transaction + conn.setAutoCommit(false); + + // Get the Large Object Manager to perform operations with + LargeObjectManager lobj = + ((org.postgresql.PGConnection)conn).getLargeObjectAPI(); + + PreparedStatement pstmt = + conn.prepareStatement("SELECT * FROM graph WHERE graph_id=?"); + pstmt.setInt(1, graphId); + ResultSet rs = pstmt.executeQuery(); + + if (rs != null) + { + while(rs.next()) + { + // open the large object for reading + int oid = rs.getInt(5); + doc = new LargeObjectDocument(ds.getJdbcUrl(), name, + lobj.open(oid, LargeObjectManager.READ)); + } + rs.close(); + } + pstmt.close(); + } + catch (SQLException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return doc; + } + /** * Get the data access object (DAO). * @return data access object diff --git a/uk/ac/sanger/artemis/util/LargeObjectDocument.java b/uk/ac/sanger/artemis/util/LargeObjectDocument.java new file mode 100644 index 000000000..715c248d7 --- /dev/null +++ b/uk/ac/sanger/artemis/util/LargeObjectDocument.java @@ -0,0 +1,121 @@ +/* LargeObjectDocument.java + * + * created: 2009 + * + * This file is part of Artemis + * + * Copyright (C) 2009 Genome Research Limited + * + * 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 java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.sql.SQLException; + +import org.postgresql.largeobject.LargeObject; + +/** + * Objects of this class are Documents created from a database + * and for reading blobs as a LargeObject. + **/ +public class LargeObjectDocument extends Document +{ + private String name; + private LargeObject obj; + + /** + * Create a new FileDocument from a File. + * @param location This should be a file or directory name. + **/ + public LargeObjectDocument (String location, String name, LargeObject obj) + { + super (location); + this.obj = obj; + this.name = name; + } + + /** + * Return the name of this Document (the last element of the Document + * location). + **/ + public String getName () + { + return name; + } + + /** + * 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 + { + try + { + try + { + // assume zipped + return new WorkingGZIPInputStream (obj.getInputStream()); + } + catch(IOException e) + { + obj.seek(0); + return obj.getInputStream(); + } + } + catch (SQLException e) + { + e.printStackTrace(); + throw new IOException( e ); + } + } + + /** + * Create a new OutputStream object from this Document. The Document can + * then be written to using the new object. The old centents of the + * Document will be lost. + * @exception ReadOnlyException is thrown if the Document is read only. + **/ + public OutputStream getOutputStream () throws IOException + { + return null; + } + + public Document append(String name) throws IOException + { + return null; + } + + public Document getParent() + { + return null; + } + + public boolean readable() + { + return false; + } + + public boolean writable() + { + return false; + } +} -- GitLab