Ignore:
Timestamp:
Sep 25, 2009, 2:10:51 PM (13 years ago)
Author:
Nicklas Nordborg
Message:

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

The complete functionality should now be in place. It is possible to create new child bioassay sets. Error handling has been improved a lot. It's a bit messy when having multiple threads going on at the same time... There is probably need for some more testing with different error scenarios.

Location:
extensions/net.sf.basedb.mev/trunk/src/webstart/net/sf/basedb/mev/webstart
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • extensions/net.sf.basedb.mev/trunk/src/webstart/net/sf/basedb/mev/webstart/BaseUploader.java

    r1163 r1165  
    128128    public void run()
    129129    {
     130      Progress progress = null;
     131      UploadStatusChecker statusChecker = null;
    130132      try
    131133      {
     134        // Send the info in the dialog to the BASE server to check
     135        // things like permissions, etc.
     136        statusChecker = MevUtil.prepareUpload(info);
     137       
     138        // Call MeV and save the analysis file
    132139        File anlFile = File.createTempFile(info.getFileName(), ".anl");
    133         // Let MeV save the analysis file
     140        Thread[] before = getThreads();
    134141        MevUtil.saveAnalysisToFile(viewer, anlFile);
    135         // Unfortunately, MeV starts a new thread and we need to wait for it
    136         Thread mevThread = findMevThread();
     142
     143        // MeV starts a new thread and we need to wait for it
     144        Thread mevThread = findMevThread(before);
    137145        if (mevThread == null) throw new Exception("Could not find MeV saving thread...");
    138 
    139         // Wait until MeV has saved the analysis file
    140146        mevThread.join();
    141147       
     
    144150        long bytes = anlFile.length();
    145151        if (bytes == 0) throw new InterruptedException();
    146 
     152       
    147153        // Upload the file
    148         Progress progress = null;
    149154        if (!silent)
    150155        {
     
    152157            new AbortUploadListener());
    153158        }
    154         MevUtil.uploadFile(anlFile, new URL(info.getUploadURL()), progress);
     159        String result = MevUtil.uploadFile(anlFile, new URL(info.getUploadURL("UploadFile")),
     160          progress, statusChecker);
     161       
     162        // The response is the new bioassay set id (or the old)
     163        try
     164        {
     165          info.setBioAssaySet(Integer.parseInt(result));
     166        }
     167        catch (NumberFormatException ex)
     168        {}
    155169        if (!silent)
    156170        {
     
    175189        aborted = false;
    176190        exception = ex;
    177         if (!silent) MevUtil.showError("Could not upload", ex);
     191        if (!silent)
     192        {
     193          MevUtil.showError(viewer.getFrame(),
     194            "Could not upload file to BASE", ex.getMessage(), ex);
     195        }
    178196      }
    179197      finally
    180198      {
     199        if (statusChecker != null) statusChecker.stop();
     200        if (progress != null && progress.isVisible()) progress.dispose();
    181201        isComplete = true;
    182202        uploader = null;
    183203      }
     204    }
     205   
     206    /**
     207      Get all currently running threads in this thread groups.
     208    */
     209    private Thread[] getThreads()
     210    {
     211      ThreadGroup grp = Thread.currentThread().getThreadGroup();
     212      Thread[] all = new Thread[grp.activeCount()];
     213      grp.enumerate(all, false);
     214      return all;
    184215    }
    185216   
     
    190221      separate thread group and the only other thread in the same
    191222      group should be the MeV thread.
    192     */
    193     private Thread findMevThread()
    194     {
    195       ThreadGroup grp = Thread.currentThread().getThreadGroup();
    196       Thread[] all = new Thread[grp.activeCount()];
    197       grp.enumerate(all);
     223      @param before An array with the threads that existed before MeV was called
     224    */
     225    private Thread findMevThread(Thread[] before)
     226    {
     227      Thread[] all = getThreads();
    198228      Thread mevThread = null;
    199       for (int i = 0; i < all.length; ++i)
    200       {
    201         if (all[i] != Thread.currentThread())
    202         {
    203           mevThread = all[i];
    204           break;
     229      for (int i = 0; i < all.length && mevThread == null; ++i)
     230      {
     231        boolean existedBefore = false;
     232        Thread maybeMevThread = all[i];
     233        for (int j = 0; j < before.length && !existedBefore; ++j)
     234        {
     235          if (maybeMevThread == before[j])
     236          {
     237            existedBefore = true;
     238          }
     239        }
     240        if (!existedBefore)
     241        {
     242          mevThread = maybeMevThread;
    205243        }
    206244      }
    207245      return mevThread;
    208246    }
    209    
    210247  }
    211248
     
    236273    public void actionPerformed(ActionEvent e)
    237274    {
    238       listener.actionPerformed(e);
     275      if (JOptionPane.showConfirmDialog(null,
     276        "Cancel upload?", "Cancel upload?",
     277        JOptionPane.YES_NO_OPTION,
     278        JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION)
     279      {
     280        listener.actionPerformed(e);
     281      }
    239282    }
    240283  }
  • extensions/net.sf.basedb.mev/trunk/src/webstart/net/sf/basedb/mev/webstart/CmdLine.java

    r1163 r1165  
    11package net.sf.basedb.mev.webstart;
    22
    3 import java.io.UnsupportedEncodingException;
    4 import java.net.URLDecoder;
    53import java.util.Arrays;
    64import java.util.Iterator;
     
    4947      }
    5048    }
    51     try
    52     {
    53       if (value != null) value = URLDecoder.decode(value, "UTF-8");
    54     }
    55     catch (UnsupportedEncodingException ex)
    56     {} // Should never happen
    5749    return value;
    5850  }
  • extensions/net.sf.basedb.mev/trunk/src/webstart/net/sf/basedb/mev/webstart/MevUtil.java

    r1163 r1165  
    11package net.sf.basedb.mev.webstart;
    22
     3import java.awt.Frame;
    34import java.io.BufferedInputStream;
    45import java.io.File;
     
    67import java.io.IOException;
    78import java.io.InputStream;
    8 import java.io.PrintWriter;
    9 import java.io.StringWriter;
    109import java.lang.reflect.Method;
    1110import java.net.URL;
     
    1413import javax.swing.JMenuBar;
    1514import javax.swing.JMenuItem;
    16 import javax.swing.JOptionPane;
    1715
    1816
     
    2018
    2119import org.tigr.microarray.mev.MultipleArrayViewer;
     20import org.tigr.microarray.mev.ShowThrowableDialog;
    2221import org.tigr.microarray.mev.cluster.gui.impl.dialogs.Progress;
    2322import org.tigr.microarray.mev.resources.FileDownloader;
     
    2827import HTTPClient.HttpOutputStream;
    2928import HTTPClient.ModuleException;
     29import HTTPClient.NVPair;
     30import HTTPClient.ParseException;
    3031
    3132/**
     
    101102 
    102103  /**
     104    Prepare for uploading a file. This method uses the session information
     105    to check with the BASE server that the upload has a fair chance of
     106    success, eg. it will check that the user has enough permissions, etc.
     107    <p>
     108    It will also create an upload status checker object, that should
     109    be used to detect additional problems during the actual upload.
     110    Call {@link UploadStatusChecker#start(HTTPConnection, int)} before
     111    the file upload.
     112
     113    @param info The current session information
     114    @return An upload status checker object
     115  */
     116  public static UploadStatusChecker prepareUpload(SessionInfo info)
     117    throws IOException, ModuleException, ParseException
     118  {
     119    HTTPConnection conn = null;
     120    UploadStatusChecker checker = null;
     121    try
     122    {
     123      URL url = new URL(info.getUploadURL("PrepareUpload"));
     124      NVPair[] postData = new NVPair[3];
     125      boolean createChild = info.getCreateNewBioAssaySet();
     126      postData[0] = new NVPair("bioAssaySet", Integer.toString(info.getBioAssaySetId()));
     127      postData[1] = new NVPair("childName", createChild ? info.getBioAssaySetName() : "");
     128      postData[2] = new NVPair("childDescription", info.getBioAssaySetDescription());
     129
     130      conn = new HTTPConnection(url.getProtocol(), url.getHost(), url.getPort());
     131      HTTPResponse response = conn.Post(url.getFile(), postData);
     132      if (response.getStatusCode() != 200)
     133      {
     134        throw new IOException(response.getText());
     135      }
     136      checker = new UploadStatusChecker(new URL(info.getUploadURL("CheckStatus")));
     137    }
     138    finally
     139    {
     140      if (conn != null) conn.stop();
     141    }
     142    return checker;
     143  }
     144 
     145  /**
    103146    Uploads a file to a web server by posting it to the given URL. The file
    104147    data is written as binary bytes to the http request. This method will
     
    111154      notification about the upload progress
    112155    @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;
     156    @throws InterruptedException If the upload was interrupted by
     157      the user
     158  */
     159  public static String uploadFile(File file, URL url,
     160    Progress progress, UploadStatusChecker uploadChecker)
     161    throws IOException, ModuleException, InterruptedException, ParseException
     162  {
     163    HTTPConnection conn = null;
     164    HttpOutputStream upload = null;
    119165    InputStream in = null;
    120     HTTPResponse response = null;
     166    String result = null;
    121167   
    122168    // Prepare the progress reporter
     
    127173      if (!progress.isShowing()) progress.show();
    128174    }
    129 
     175   
    130176    try
    131177    {
    132178      // 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());
     179      conn = new HTTPConnection(url.getProtocol(), url.getHost(), url.getPort());
     180      upload = new HttpOutputStream((int)file.length());
    135181      in = new BufferedInputStream(new FileInputStream(file));
    136       response = c.Post(url.getFile(), out);
     182     
     183      // Start the upload and status checker
     184      HTTPResponse response = conn.Post(url.getFile(), upload);
     185      uploadChecker.start(conn, 2500);
     186     
     187      // Write the file to the upload stream
    137188      byte[] buffer = new byte[4096];
    138       for (int bytes = 0; bytes != -1;) // -1 = end of stream
     189      int bytes = 0;
     190      while (bytes != -1) // -1 = end of stream
    139191      {
    140192        bytes = in.read(buffer, 0, buffer.length);
    141         if (Thread.interrupted())
    142         {
    143           c.stop();
    144           throw new InterruptedException();
    145         }
     193        if (Thread.interrupted()) throw new InterruptedException();
    146194        if (bytes > 0)
    147195        {
    148           out.write(buffer, 0, bytes);
     196          upload.write(buffer, 0, bytes);
    149197          totalBytes += bytes;
    150198          if (progress != null)
     
    154202          }
    155203        }
    156         //Thread.sleep(5);
     204        Thread.sleep(5);
     205      }
     206      result = response.getText();
     207      if (response.getStatusCode() != 200)
     208      {
     209        throw new IOException(result);
    157210      }
    158211    }
     
    161214      try
    162215      {
     216        uploadChecker.stop();
     217        if (conn != null) conn.stop();
    163218        if (in != null) in.close();
    164         if (out != null) out.close();
    165       }
    166       catch (IOException ex)
     219        if (upload != null) upload.close();
     220      }
     221      catch (Exception ex)
    167222      {}
    168     }
    169     return response;
     223      uploadChecker.throwException();
     224    }
     225    return result;
    170226  }
    171227 
     
    188244    @param t The error
    189245  */
    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);
     246  public static void showError(Frame frame, String title, String message, Throwable t)
     247  {
     248    ShowThrowableDialog.show(null, title, true,
     249      ShowThrowableDialog.ERROR, t, message);
    197250  }
    198251 
  • extensions/net.sf.basedb.mev/trunk/src/webstart/net/sf/basedb/mev/webstart/SessionInfo.java

    r1163 r1165  
    11package net.sf.basedb.mev.webstart;
     2
     3import java.io.UnsupportedEncodingException;
     4import java.net.URLEncoder;
    25
    36/**
     
    1619  private String fileType;
    1720  private int bioAssaySetId;
     21  private boolean createNewBioAssaySet;
     22  private String bioAssaySetName;
     23  private String bioAssaySetDescription;
    1824 
    1925  /**
     
    6571  }
    6672
    67 
    6873  /**
    6974    Set the filename of the current file as it is known on
     
    7681
    7782  /**
     83    Get the file name and make sure it has the specified extension.
     84    The current extension, if any, will be replaced
     85    @param extension The required extension
     86    @return The filename with the new extension
     87  */
     88  public String getFileNameWithExtension(String extension)
     89  {
     90    String name = getFileName();
     91    int lastDot = name.lastIndexOf('.');
     92    if (lastDot >= 0)
     93    {
     94      name = name.substring(0, lastDot);
     95    }
     96    return name + "." + extension;
     97  }
     98 
     99  /**
     100    Set the filename and make sure it has a given extension.
     101    @param fileName The basic file name, with or without an extension
     102    @param extension The extension that will be added to the file name,
     103      unless it already ends with it
     104  */
     105  public void setFileNameWithExtension(String fileName, String extension)
     106  {
     107    if (!fileName.endsWith(extension)) fileName += "." + extension;
     108    setFileName(fileName);
     109  }
     110 
     111  /**
     112    Get the filename as an URL-encoded string. We can't just call
     113    URLEncoder.encode() since it would encode the / as well. So,
     114    we split the path and encode each part separately, and then
     115    put it together again.
     116  */
     117  public String getFileNameURLEncoded()
     118  {
     119    String[] path = getFileName().split("/");
     120    StringBuilder sb = new StringBuilder();
     121    String separator = "";
     122    for (int i = 0; i < path.length; ++i)
     123    {
     124      sb.append(separator);
     125      try
     126      {
     127        sb.append(URLEncoder.encode(path[i], "UTF-8"));
     128      }
     129      catch (UnsupportedEncodingException ex)
     130      {} // Should never happen
     131      separator = "/";
     132    }
     133    return sb.toString();
     134  }
     135 
     136  /**
    78137    Get the file type.
    79138  */
     
    115174    return "anl".equals(getFileType());
    116175  }
     176 
     177  /**
     178    Get the bioassay set name (from the Save to BASE dialog)
     179  */
     180  public String getBioAssaySetName()
     181  {
     182    return bioAssaySetName;
     183  }
     184 
     185  /**
     186    Set the bioassay set name
     187  */
     188  public void setBioAssaySetName(String name)
     189  {
     190    this.bioAssaySetName = name;
     191  }
     192 
     193  /**
     194    Get the bioassay set description (from the Save to BASE dialog)
     195  */
     196  public String getBioAssaySetDescription()
     197  {
     198    return bioAssaySetDescription;
     199  }
     200 
     201  /**
     202    Set the bioassay set description
     203  */
     204  public void setBioAssaySetDescription(String description)
     205  {
     206    this.bioAssaySetDescription = description;
     207  }
     208 
     209  /**
     210    Checks if a new bioassay set should be created or not.
     211  */
     212  public boolean getCreateNewBioAssaySet()
     213  {
     214    return createNewBioAssaySet;
     215  }
     216 
     217  /**
     218    Set the flag indicating if a new bioassay set should be created or not.
     219  */
     220  public void setCreateNewBioAssaySet(boolean createNew)
     221  {
     222    this.createNewBioAssaySet = createNew;
     223  }
     224
    117225 
    118226  /**
     
    123231  public String getDownloadURL()
    124232  {
    125     return getServletDir() + "MevDownload" + getFileName() + "?ID=" + getSessionId();
     233    return getServletDir() + "MevDownload/" + getSessionId() +
     234        getFileNameURLEncoded();
    126235  }
    127236 
     
    132241    bioassay set id.
    133242  */
    134   public String getUploadURL()
    135   {
    136     return getServletDir() + "MevUpload" + getFileName() +
    137       "?ID=" + getSessionId() +
    138       "&bioAssaySet=" + getBioAssaySetId();
     243  public String getUploadURL(String cmd)
     244  {
     245    return getServletDir() + "MevUpload" + getFileNameURLEncoded() +
     246        "?ID=" + getSessionId() + "&cmd=" + cmd;
    139247  }
    140248 
  • extensions/net.sf.basedb.mev/trunk/src/webstart/net/sf/basedb/mev/webstart/StartMev.java

    r1163 r1165  
    44import java.net.URL;
    55import java.util.regex.Pattern;
    6 
    76
    87import org.tigr.microarray.mev.Manager;
     
    7069      catch (Exception ex)
    7170      {
    72         MevUtil.showError("Load Analysis Error", ex);
     71        MevUtil.showError(viewer.getFrame(), "Load Analysis Error",
     72          ex.getMessage(), ex);
    7373      }
    7474    }
  • extensions/net.sf.basedb.mev/trunk/src/webstart/net/sf/basedb/mev/webstart/action/SaveToBaseActionListener.java

    r1163 r1165  
    4949  {
    5050    SaveToBaseDialog save = new SaveToBaseDialog(viewer);
    51     save.setFileName(info.getFileName());
     51    save.setFileName(info.getFileNameWithExtension("anl"));
     52    save.setCreateNewBioAssaySet(info.getCreateNewBioAssaySet());
     53    save.setBioAssaySetName(info.getBioAssaySetName());
     54    save.setBioAssaySetDescription(info.getBioAssaySetDescription());
     55   
    5256    if (save.showDialog())
    5357    {
    54       info.setFileName(save.getFileName());
     58      info.setFileNameWithExtension(save.getFileName(), "anl");
     59      info.setCreateNewBioAssaySet(save.getCreateNewBioAssaySet());
     60      info.setBioAssaySetName(save.getBioAssaySetName());
     61      info.setBioAssaySetDescription(save.getBioAssaySetDescription());
    5562      BaseUploader uploader = new BaseUploader(viewer, info);
    5663      uploader.saveAnalysisAndUploadAsync(false);
Note: See TracChangeset for help on using the changeset viewer.