Changeset 1163


Ignore:
Timestamp:
Sep 22, 2009, 1:52:00 PM (13 years ago)
Author:
Nicklas Nordborg
Message:

References #242: Implement "Save to BASE" function in the MeV gui

The menu item is in place as well as the file saving/upload functionality. There is need for more error handling. The possibility of creating a new child bioassay set is not yet implemented. The file will always be attached to the same bioassay set as it was loaded from. The functionality has only been tested when the original file is an analysis file. Some slight adjustments are probably needed when starting with TDMS or CGH files.

Location:
extensions/net.sf.basedb.mev/trunk
Files:
9 added
7 edited
1 moved

Legend:

Unmodified
Added
Removed
  • extensions/net.sf.basedb.mev/trunk/.classpath

    r1158 r1163  
    1010  <classpathentry kind="lib" path="lib/compile/BASE2Core.jar" sourcepath="/trunk/src/core"/>
    1111  <classpathentry kind="lib" path="resources/jar/mev-base.jar" sourcepath="/mev-4.4.1/source"/>
    12   <classpathentry kind="lib" path="resources/jar/args4j-2.0.9.jar"/>
    1312  <classpathentry kind="lib" path="resources/jar/mev-gui-impl.jar" sourcepath="/mev-4.4.1/source"/>
    14   <classpathentry kind="lib" path="resources/jar/mev-gui-support.jar" sourcepath="/mev-4.4.1/source"/>
    15   <classpathentry kind="lib" path="resources/jar/mev-util.jar" sourcepath="/mev-4.4.1/source"/>
     13  <classpathentry kind="lib" path="resources/jar/HTTPClient.jar"/>
    1614  <classpathentry kind="output" path="bin"/>
    1715</classpath>
  • extensions/net.sf.basedb.mev/trunk/META-INF/servlets.xml

    r666 r1163  
    22<servlets xmlns="http://base.thep.lu.se/servlets.xsd">
    33  <servlet>
    4     <servlet-name>MevExport</servlet-name>
    5     <servlet-class>net.sf.basedb.mev.servlet.MevExport</servlet-class>
     4    <servlet-name>MevDownload</servlet-name>
     5    <servlet-class>net.sf.basedb.mev.servlet.MevDownload</servlet-class>
     6  </servlet>
     7  <servlet>
     8    <servlet-name>MevUpload</servlet-name>
     9    <servlet-class>net.sf.basedb.mev.servlet.MevUpload</servlet-class>
    610  </servlet>
    711</servlets>
  • extensions/net.sf.basedb.mev/trunk/build.xml

    r1157 r1163  
    3232    <fileset dir="resources/jar">
    3333      <include name="mev-base.jar" />
    34       <include name="args4j-2.0.9.jar" />
     34      <include name="mev-gui-impl.jar" />
     35      <include name="HTTPClient.jar" />
    3536    </fileset>
    3637  </path>
  • extensions/net.sf.basedb.mev/trunk/resources/mev_jnlp.jsp

    r1157 r1163  
    5050final String serverName = request.getServerName();
    5151final int serverPort = request.getServerPort();
    52 final String homeUrl = ExtensionsControl.getHomeUrl("net.sf.basedb.mev.launchmev");
    53 final String fullHomeUrl = scheme + "://" + serverName + ":" + serverPort + homeUrl;
     52final String homePath = ExtensionsControl.getHomeUrl("net.sf.basedb.mev.launchmev");
     53final String servletPath = ExtensionsControl.getServletUrl("net.sf.basedb.mev.launchmev", "");
     54final String serverUrl = scheme + "://" + serverName + ":" + serverPort;
    5455final int jvmMaxMemory = Values.getInt(sc.getUserClientSetting("net.sf.basedb.mev.launchmev.jvm.maxmemory"), 512);
    55 String extraFileName = "";
     56String filePath = "";
    5657DbControl dc = sc.newDbControl();
    5758try
     
    5960  BioAssaySet bas = BioAssaySet.getById(dc, bioAssaySetId);
    6061  File mevFile = FileStoreUtil.getDataFile(dc, bas, fileType);
    61  
    6262  if (mevFile == null)
    6363  {
     
    6565      bas.getName());
    6666  }
    67   extraFileName = "-" + mevFile.getId() + "." + mevFile.getLastUpdate().getTime();
     67  filePath = mevFile.getPath().toURLString("UTF-8");
    6868}
    6969finally
     
    7575<!DOCTYPE jnlp PUBLIC "-//Sun Microsystems, Inc.//DTD JNLP 1.5//EN" "http://www.netbeans.org/jnlp/DTD/jnlp.dtd">
    7676<jnlp spec="1.0+"
    77   codebase="<%=fullHomeUrl%>/jar"
     77  codebase="<%=serverUrl + homePath%>/jar"
    7878  version="4.4.1">
    7979
     
    147147 
    148148  <application-desc main-class="net.sf.basedb.mev.webstart.StartMev">
     149    <argument>-base:servletdir</argument>
     150    <argument><%=serverUrl+servletPath%></argument>
     151    <argument>-base:session</argument>
     152    <argument><%=ID%></argument>
     153    <argument>-base:file</argument>
     154    <argument><%=filePath%></argument>
    149155    <argument>-fileType</argument>
    150156    <argument><%=mevFileType%></argument>
    151     <argument>-fileUrl</argument>
    152     <argument><%=fullHomeUrl%>/MevExport/<%=ID%>/<%=bioAssaySetId%>/<%=fileType%><%=extraFileName%>.servlet</argument>
     157    <argument>-base:bioAssaySet</argument>
     158    <argument><%=bioAssaySetId%></argument>
    153159  </application-desc>
    154160</jnlp>
  • extensions/net.sf.basedb.mev/trunk/src/server/net/sf/basedb/mev/servlet/MevDownload.java

    r1157 r1163  
    2525
    2626import net.sf.basedb.core.Application;
    27 import net.sf.basedb.core.BioAssaySet;
    2827import net.sf.basedb.core.File;
    29 import net.sf.basedb.core.FileStoreUtil;
    30 import net.sf.basedb.core.ItemNotFoundException;
     28import net.sf.basedb.core.Path;
    3129import net.sf.basedb.core.SessionControl;
    3230import net.sf.basedb.core.DbControl;
    33 import net.sf.basedb.mev.Mev;
    34 import net.sf.basedb.util.Values;
    3531
    3632import javax.servlet.ServletException;
     
    4238
    4339/**
    44   A servlet for exposing the spot data of a bioassayset that already
    45   exists as a MeV TDMS file attached to the bioassay set. The file is
    46   sent back to the requesting client in the response.
     40  A servlet for downloading a file from the BASE file system to
     41  MeV. The request must specify the BASE file path in the
     42  <code>PATH INFO</code> part of the URL and the session id
     43  as a query string parameter.
     44  Eg.
     45  <code>.../MevDownlod/path/to/file.anl?ID=yyy</code>
    4746
    4847  @author Nicklas
    49   @version 1.0
     48  @since 1.5
    5049  @base.modified $Date$
    5150*/
    52 public final class MevExport
     51public final class MevDownload
    5352  extends HttpServlet
    5453{
    5554
    56   private static final long serialVersionUID = -9123801569423268491L;
     55  private static final long serialVersionUID = -681581186110420461L;
    5756
    5857  public void doGet(HttpServletRequest request, HttpServletResponse response)
    5958    throws IOException, ServletException
    6059  {
    61     // The session ID
    62     String ID = null;
    63     // The bioassay set to export
    64     int bioAssaySetId = 0;
    65     // The file type to look for
    66     String fileType = Mev.TDMS_FILE;
     60    final String ID = request.getParameter("ID");
     61    final String path = request.getPathInfo();
     62    //System.out.println("Download: ID=" + ID + "; path=" + path);
     63
     64    final SessionControl sc = Application.getSessionControl(ID, request.getRemoteAddr());
    6765    DbControl dc = null;
    6866    try
    6967    {
    70       if (request.getQueryString() != null)
    71       {
    72         // Paremeters where given on query string: ?ID=...&bioassayset_id=...&filetype=...
    73         ID = request.getParameter("ID");
    74         bioAssaySetId = Values.getInt(request.getParameter("bioassayset_id"));
    75         fileType = Values.getString(request.getParameter("filetype"), fileType);
    76       }
    77       else if (request.getPathInfo() != null)
    78       {
    79         // Parameters are given as path: /ID/bioassayset_id/filetype
    80         // filetype may optionally end with '-some extra info'
    81         String[] path = request.getPathInfo().split("/");
    82         ID = path[path.length-3];
    83         bioAssaySetId = Values.getInt(path[path.length-2]);
    84         fileType = path[path.length-1];
    85         int extraInfo = fileType.lastIndexOf('-');
    86         if (extraInfo >= 0) fileType = fileType.substring(0, extraInfo);
    87       }
    88       final SessionControl sc = Application.getSessionControl(ID, request.getRemoteAddr());
    89 
    90       // Load bioassay set and file with MeV data
     68     
     69      // Load file with MeV data
    9170      dc = sc.newDbControl();
    92       BioAssaySet bas = BioAssaySet.getById(dc, bioAssaySetId);
    93       File mevFile = FileStoreUtil.getDataFile(dc, bas, fileType);
    94      
    95       if (mevFile == null)
    96       {
    97         throw new ItemNotFoundException("No " + fileType + " file found on bioassay set: " +
    98           bas.getName());
    99       }
     71      File file = File.getByPath(dc, new Path(path, Path.Type.FILE), false);
     72      dc.disconnect();
    10073     
    10174      // Set up output stream
    10275      OutputStream out = response.getOutputStream();
    10376      response.setContentType("text/plain");
    104       if (mevFile.getLastUpdate() != null)
     77      if (file.getLastUpdate() != null)
    10578      {
    106         response.setDateHeader("Last-Modified", mevFile.getLastUpdate().getTime());
     79        response.setDateHeader("Last-Modified", file.getLastUpdate().getTime());
    10780      }
    108       if (mevFile.getSize() < Integer.MAX_VALUE)
     81      if (file.getSize() < Integer.MAX_VALUE)
    10982      {
    110         response.setContentLength((int)mevFile.getSize());
     83        response.setContentLength((int)file.getSize());
    11184      }
    11285      // Do the export
    113       mevFile.download(out, 0);
     86      file.download(out, 0);
    11487      out.flush();
    11588      out.close();
  • extensions/net.sf.basedb.mev/trunk/src/webstart/net/sf/basedb/mev/webstart/CmdLine.java

    r1157 r1163  
    11package net.sf.basedb.mev.webstart;
    22
    3 import java.util.ArrayList;
     3import java.io.UnsupportedEncodingException;
     4import java.net.URLDecoder;
     5import java.util.Arrays;
     6import java.util.Iterator;
     7import java.util.LinkedList;
    48import java.util.List;
     9import java.util.regex.Pattern;
    510
    611/**
    712  A very simple command line parser. It assumes that
    813  the command line is of the form: -option1 value1 -option2 value2 ...
     14  Values are expected to be URL-encoded in UTF-8.
    915 
    1016  @author nicklas
     
    1420{
    1521 
    16   private String[] args;
     22  private List<String> args;
    1723 
    1824  /**
     
    2228  public CmdLine(String... args)
    2329  {
    24     this.args = args;
     30    this.args = new LinkedList<String>(Arrays.asList(args));
    2531  }
    2632
     
    3339  public String getOption(String option)
    3440  {
    35     for (int i = 0; i < args.length - 1; ++i)
     41    Iterator<String> it = args.iterator();
     42    String value = null;
     43    while (it.hasNext())
    3644    {
    37       if (option.equals(args[i])) return args[i+1];
     45      if (option.equals(it.next()) && it.hasNext())
     46      {
     47        value = it.next();
     48        break;
     49      }
    3850    }
    39     return null;
     51    try
     52    {
     53      if (value != null) value = URLDecoder.decode(value, "UTF-8");
     54    }
     55    catch (UnsupportedEncodingException ex)
     56    {} // Should never happen
     57    return value;
     58  }
     59 
     60  /**
     61    Get the value for an option as an integer.
     62    @param option The name of the option, including the '-'
     63    @param defaultValue A default value in case the given value is not
     64      an integer
     65  */
     66  public int getIntOption(String option, int defaultValue)
     67  {
     68    int value = defaultValue;
     69    String sValue = getOption(option);
     70    if (sValue != null)
     71    {
     72      try
     73      {
     74        value = Integer.parseInt(sValue);
     75      }
     76      catch (NumberFormatException ex)
     77      {}
     78    }
     79    return value;
     80  }
     81 
     82  /**
     83    Add an option to the command line.
     84    @param option The name of the option
     85    @param value The value of the option
     86  */
     87  public void add(String option, String value)
     88  {
     89    args.add(option);
     90    args.add(value);
     91  }
     92 
     93  /**
     94    Remove all options matching the given pattern.
     95    @param pattern A regular expression pattern
     96  */
     97  public void remove(Pattern pattern)
     98  {
     99    Iterator<String> it = args.iterator();
     100    while (it.hasNext())
     101    {
     102      String option = it.next();
     103      if (pattern.matcher(option).matches())
     104      {
     105        it.remove();
     106        if (it.hasNext())
     107        {
     108          it.next();
     109          it.remove();
     110        }
     111      }
     112    }
    40113  }
    41114 
     
    45118    @return The modified command line with the options/values removed
    46119    */
    47   public String[] remove(String... options)
     120  public void remove(String... options)
    48121  {
    49     List<String> remain = new ArrayList<String>(args.length);
    50     for (int i = 0; i < args.length; ++i)
     122    Iterator<String> it = args.iterator();
     123    while (it.hasNext())
    51124    {
    52       boolean add = true;
     125      String option = it.next();
    53126      for (int j = 0; j < options.length; ++j)
    54127      {
    55         if (args[i].equals(options[j]))
     128        if (option.equals(options[j]))
    56129        {
    57           add = false;
    58           ++i;
     130          it.remove();
     131          if (it.hasNext())
     132          {
     133            it.next();
     134            it.remove();
     135          }
    59136          break;
    60137        }
    61138      }
    62       if (add)
    63       {
    64         remain.add(args[i]);
    65       }
    66139    }
    67     return remain.toArray(new String[0]);
    68140  }
     141 
     142  /**
     143    Create a new string array with the existing options.
     144  */
     145  public String[] toArray()
     146  {
     147    return args.toArray(new String[args.size()]);
     148  }
     149 
     150  @Override
     151  public String toString()
     152  {
     153    return args.toString();
     154  }
     155 
    69156}
    70157
  • extensions/net.sf.basedb.mev/trunk/src/webstart/net/sf/basedb/mev/webstart/MevUtil.java

    r1157 r1163  
    11package net.sf.basedb.mev.webstart;
    22
     3import java.io.BufferedInputStream;
    34import java.io.File;
     5import java.io.FileInputStream;
     6import java.io.IOException;
     7import java.io.InputStream;
     8import java.io.PrintWriter;
     9import java.io.StringWriter;
    410import java.lang.reflect.Method;
     11import java.net.URL;
     12
     13import javax.swing.JMenu;
     14import javax.swing.JMenuBar;
     15import javax.swing.JMenuItem;
     16import javax.swing.JOptionPane;
     17
     18
     19import net.sf.basedb.mev.webstart.action.SaveToBaseActionListener;
    520
    621import org.tigr.microarray.mev.MultipleArrayViewer;
     22import org.tigr.microarray.mev.cluster.gui.impl.dialogs.Progress;
     23import org.tigr.microarray.mev.resources.FileDownloader;
     24import org.tigr.microarray.mev.resources.SupportFileAccessError;
     25
     26import HTTPClient.HTTPConnection;
     27import HTTPClient.HTTPResponse;
     28import HTTPClient.HttpOutputStream;
     29import HTTPClient.ModuleException;
    730
    831/**
     
    3760  }
    3861 
     62  /**
     63    Saves the current analysis to a file. This method calls the
     64    MultipleArrayViewer.saveState() method using reflection.
     65    <p>
     66    NOTE! MeV starts a new thread for the saving and this method
     67    will return immediately.
     68   
     69    @param viewer The array viewer window that that should be saved
     70    @param file The file to save to
     71  */
     72  public static void saveAnalysisToFile(MultipleArrayViewer viewer, File file)
     73  {
     74    try
     75    {
     76      Method saveState = MultipleArrayViewer.class.getDeclaredMethod("saveState", File.class);
     77      saveState.setAccessible(true);
     78      saveState.invoke(viewer, file);
     79    }
     80    catch (Exception ex)
     81    {
     82      throw new RuntimeException(ex);
     83    }
     84  }
     85 
     86  /**
     87    Adds a top-level menu 'BASE' with a 'Save to BASE' menuitem.
     88    @param viewer The viewer window
     89    @param info Session information for the BASE connection
     90  */
     91  public static void addBaseMenus(MultipleArrayViewer viewer, SessionInfo info)
     92  {
     93    JMenuBar menubar = viewer.getMenubar();
     94    JMenu baseMenu = new JMenu("BASE");
     95    JMenuItem save = new JMenuItem("Save to BASE...");
     96    save.addActionListener(new SaveToBaseActionListener(viewer, info));
     97    baseMenu.add(save);
     98    menubar.add(baseMenu);
     99    menubar.validate();
     100  }
     101 
     102  /**
     103    Uploads a file to a web server by posting it to the given URL. The file
     104    data is written as binary bytes to the http request. This method will
     105    block until the upload has been finished. To interrupt the upload,
     106    call {@link Thread#interrupt()} on this thread.
     107   
     108    @param file The file on the local file system
     109    @param url The URL to post the file to
     110    @param progress An optional progress dialog that should receive
     111      notification about the upload progress
     112    @throws IOException If there is any problem with the upload
     113    @throws InterruptedException If the upload is interrupted
     114  */
     115  public static HTTPResponse uploadFile(File file, URL url, Progress progress)
     116    throws IOException, ModuleException, InterruptedException
     117  {
     118    HttpOutputStream out = null;
     119    InputStream in = null;
     120    HTTPResponse response = null;
     121   
     122    // Prepare the progress reporter
     123    int totalBytes = 0;
     124    if (progress != null)
     125    {
     126      progress.setUnits((int)file.length());
     127      if (!progress.isShowing()) progress.show();
     128    }
     129
     130    try
     131    {
     132      // Open a connection to the server and prepare input and output stream
     133      HTTPConnection c = new HTTPConnection(url.getProtocol(), url.getHost(), url.getPort());
     134      out = new HttpOutputStream((int)file.length());
     135      in = new BufferedInputStream(new FileInputStream(file));
     136      response = c.Post(url.getFile(), out);
     137      byte[] buffer = new byte[4096];
     138      for (int bytes = 0; bytes != -1;) // -1 = end of stream
     139      {
     140        bytes = in.read(buffer, 0, buffer.length);
     141        if (Thread.interrupted())
     142        {
     143          c.stop();
     144          throw new InterruptedException();
     145        }
     146        if (bytes > 0)
     147        {
     148          out.write(buffer, 0, bytes);
     149          totalBytes += bytes;
     150          if (progress != null)
     151          {
     152            progress.setValue(totalBytes);
     153            progress.repaint();
     154          }
     155        }
     156        //Thread.sleep(5);
     157      }
     158    }
     159    finally
     160    {
     161      try
     162      {
     163        if (in != null) in.close();
     164        if (out != null) out.close();
     165      }
     166      catch (IOException ex)
     167      {}
     168    }
     169    return response;
     170  }
     171 
     172  /**
     173    Download the contents from the given URL.
     174    @param url The URL to download from
     175    @return The temporary file where the downloaded data has been stored
     176  */
     177  public static File downloadFile(URL url)
     178    throws SupportFileAccessError
     179  {
     180    FileDownloader downloader = FileDownloader.getInstance(url);
     181    File anlFile = downloader.getTempFile(url.getFile());
     182    return anlFile;
     183  }
     184 
     185  /**
     186    Open a dialog window that shows the error message.
     187    @param title The title of the dialog
     188    @param t The error
     189  */
     190  public static void showError(String title, Throwable t)
     191  {
     192    StringWriter writer = new StringWriter();
     193    t.printStackTrace(new PrintWriter(writer));
     194    JOptionPane.showMessageDialog(null,
     195      t.getMessage() + writer.toString(),
     196      title, JOptionPane.ERROR_MESSAGE);
     197  }
     198 
    39199}
  • extensions/net.sf.basedb.mev/trunk/src/webstart/net/sf/basedb/mev/webstart/StartMev.java

    r1157 r1163  
    33import java.io.File;
    44import java.net.URL;
     5import java.util.regex.Pattern;
    56
    6 import javax.swing.JOptionPane;
    77
    88import org.tigr.microarray.mev.Manager;
    99import org.tigr.microarray.mev.MultipleArrayViewer;
    1010import org.tigr.microarray.mev.TMEV;
    11 import org.tigr.microarray.mev.resources.FileDownloader;
    1211
    1312/**
     
    2827  public static void main(String[] args)
    2928  {
    30     // Parse the command line options
     29    // Parse the command line options and store in the session info object
    3130    CmdLine options = new CmdLine(args);
    32     String fileType = options.getOption("-fileType");
    33     String fileUrl = options.getOption("-fileUrl");
    34     boolean analysisFile = "anl".equals(fileType);
     31    SessionInfo info = new SessionInfo();
     32    info.setSessionId(options.getOption("-base:session"));
     33    info.setServletDir(options.getOption("-base:servletdir"));
     34    info.setFileName(options.getOption("-base:file"));
     35    info.setFileType(options.getOption("-fileType"));
     36    info.setBioAssaySet(options.getIntOption("-base:bioAssaySet", 0));
    3537   
    36     // Remove the 'fileType' and 'fileUrl' options if the file
    37     // is an analysis file since MeV can't handle it
     38    // Remove BASE-specific options from the command line
     39    String downloadUrl = info.getDownloadURL();
     40    boolean analysisFile = info.isAnalysisFile();
     41    options.remove(Pattern.compile("-base.*"));
    3842    if (analysisFile)
    3943    {
    40       args = options.remove("-fileType", "-fileUrl");
     44      // Remove the 'fileType' and 'fileUrl' options if the file
     45      // is an analysis file since MeV can't handle it
     46      options.remove("-fileType", "-fileUrl");
    4147    }
     48    else
     49    {
     50      // For other files, add the 'fileUrl' option
     51      options.add("-fileUrl", downloadUrl);
     52    }
     53    args = options.toArray();
    4254   
    4355    // Start MeV and get the main window
    4456    TMEV.main(args);
    4557    final MultipleArrayViewer viewer = (MultipleArrayViewer)Manager.getLastComponent();
     58   
     59    // Add BASE-specific menu items
     60    MevUtil.addBaseMenus(viewer, info);
    4661   
    4762    if (analysisFile)
     
    5065      try
    5166      {
    52         URL url = new URL(fileUrl);
    53         FileDownloader downloader = FileDownloader.getInstance(url);
    54         File anlFile = downloader.getTempFile(url.getPath());
     67        File anlFile = MevUtil.downloadFile(new URL(downloadUrl));
    5568        if (anlFile != null) MevUtil.loadAnalysisFromFile(viewer, anlFile);
    5669      }
    5770      catch (Exception ex)
    5871      {
    59         ex.printStackTrace();
    60         JOptionPane.showMessageDialog(viewer,
    61           ex.getMessage(),
    62           "Load Analysis Error", JOptionPane.ERROR_MESSAGE);
     72        MevUtil.showError("Load Analysis Error", ex);
    6373      }
    6474    }
    65    
    6675  }
    6776
Note: See TracChangeset for help on using the changeset viewer.