extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/plugins/CaliperSampleNameExporter.java

Code
Comments
Other
Rev Date Author Line
1544 29 Feb 12 nicklas 1 package net.sf.basedb.reggie.plugins;
1544 29 Feb 12 nicklas 2
1544 29 Feb 12 nicklas 3 import java.io.IOException;
1544 29 Feb 12 nicklas 4 import java.io.OutputStreamWriter;
1544 29 Feb 12 nicklas 5 import java.io.Writer;
1544 29 Feb 12 nicklas 6 import java.util.ArrayList;
1544 29 Feb 12 nicklas 7 import java.util.Arrays;
1544 29 Feb 12 nicklas 8 import java.util.Collections;
1544 29 Feb 12 nicklas 9 import java.util.Iterator;
1544 29 Feb 12 nicklas 10 import java.util.List;
1544 29 Feb 12 nicklas 11 import java.util.Set;
1544 29 Feb 12 nicklas 12
1544 29 Feb 12 nicklas 13 import net.sf.basedb.core.BaseException;
1544 29 Feb 12 nicklas 14 import net.sf.basedb.core.BioMaterial;
1544 29 Feb 12 nicklas 15 import net.sf.basedb.core.BioPlate;
1544 29 Feb 12 nicklas 16 import net.sf.basedb.core.BioWell;
1544 29 Feb 12 nicklas 17 import net.sf.basedb.core.DbControl;
1544 29 Feb 12 nicklas 18 import net.sf.basedb.core.Item;
1544 29 Feb 12 nicklas 19 import net.sf.basedb.core.ItemParameterType;
1544 29 Feb 12 nicklas 20 import net.sf.basedb.core.ItemQuery;
1544 29 Feb 12 nicklas 21 import net.sf.basedb.core.Path;
1544 29 Feb 12 nicklas 22 import net.sf.basedb.core.PermissionDeniedException;
1544 29 Feb 12 nicklas 23 import net.sf.basedb.core.PluginDefinition;
1544 29 Feb 12 nicklas 24 import net.sf.basedb.core.PluginParameter;
1544 29 Feb 12 nicklas 25 import net.sf.basedb.core.ProgressReporter;
1544 29 Feb 12 nicklas 26 import net.sf.basedb.core.RequestInformation;
1544 29 Feb 12 nicklas 27 import net.sf.basedb.core.Job.ExecutionTime;
1544 29 Feb 12 nicklas 28 import net.sf.basedb.core.plugin.AbstractExporterPlugin;
1544 29 Feb 12 nicklas 29 import net.sf.basedb.core.plugin.ExportOutputStream;
1544 29 Feb 12 nicklas 30 import net.sf.basedb.core.plugin.GuiContext;
1544 29 Feb 12 nicklas 31 import net.sf.basedb.core.plugin.InteractivePlugin;
1544 29 Feb 12 nicklas 32 import net.sf.basedb.core.plugin.Request;
1544 29 Feb 12 nicklas 33 import net.sf.basedb.core.plugin.Response;
1544 29 Feb 12 nicklas 34 import net.sf.basedb.core.query.Hql;
1544 29 Feb 12 nicklas 35 import net.sf.basedb.core.query.Orders;
1900 07 Mar 13 nicklas 36 import net.sf.basedb.reggie.converter.ValueConverter;
1900 07 Mar 13 nicklas 37 import net.sf.basedb.reggie.converter.WellCoordinateConverter;
1610 23 Apr 12 nicklas 38 import net.sf.basedb.reggie.dao.Annotationtype;
1544 29 Feb 12 nicklas 39 import net.sf.basedb.util.export.TableWriter;
1544 29 Feb 12 nicklas 40
1544 29 Feb 12 nicklas 41 /**
1544 29 Feb 12 nicklas 42   Plug-in for exporting biomaterial names for each well on a plate.
1544 29 Feb 12 nicklas 43   This class can be used as a BASE plug-in or as a standalone exporter.
3571 30 Oct 15 nicklas 44   In the latter case, simply use the {@link #exportSampleNames(DbControl, BioPlate, ValueConverter, Writer)}
1544 29 Feb 12 nicklas 45   method.
1544 29 Feb 12 nicklas 46   <p>
1544 29 Feb 12 nicklas 47   
1544 29 Feb 12 nicklas 48   Since the exporter should be really quick it doesn't implement support for aborting
1544 29 Feb 12 nicklas 49   or progress reporting.
1544 29 Feb 12 nicklas 50   
1544 29 Feb 12 nicklas 51   @author nicklas
1544 29 Feb 12 nicklas 52   @since 2.4
1544 29 Feb 12 nicklas 53 */
1544 29 Feb 12 nicklas 54 public class CaliperSampleNameExporter 
1544 29 Feb 12 nicklas 55   extends AbstractExporterPlugin 
1544 29 Feb 12 nicklas 56   implements InteractivePlugin
1544 29 Feb 12 nicklas 57 {
1544 29 Feb 12 nicklas 58
1544 29 Feb 12 nicklas 59   private RequestInformation configureJob;
1544 29 Feb 12 nicklas 60   
1544 29 Feb 12 nicklas 61   public CaliperSampleNameExporter()
1544 29 Feb 12 nicklas 62   {}
1544 29 Feb 12 nicklas 63   
1544 29 Feb 12 nicklas 64   /*
1544 29 Feb 12 nicklas 65      From the Plugin interface
1544 29 Feb 12 nicklas 66      --------------------------------
1544 29 Feb 12 nicklas 67   */
1544 29 Feb 12 nicklas 68   @Override
1544 29 Feb 12 nicklas 69   public boolean supportsConfigurations()
1544 29 Feb 12 nicklas 70   {
1544 29 Feb 12 nicklas 71     return false;
1544 29 Feb 12 nicklas 72   }
1544 29 Feb 12 nicklas 73   @Override
1544 29 Feb 12 nicklas 74   public boolean requiresConfiguration()
1544 29 Feb 12 nicklas 75   {
1544 29 Feb 12 nicklas 76     return false;
1544 29 Feb 12 nicklas 77   }
1544 29 Feb 12 nicklas 78   // -------------------------------------
1544 29 Feb 12 nicklas 79   
1544 29 Feb 12 nicklas 80   /*
1544 29 Feb 12 nicklas 81      From the InteractivePlugin interface
1544 29 Feb 12 nicklas 82      -------------------------------------------
1544 29 Feb 12 nicklas 83   */
1544 29 Feb 12 nicklas 84   /**
1544 29 Feb 12 nicklas 85     The plug-in will appear on the 
1544 29 Feb 12 nicklas 86    */
1544 29 Feb 12 nicklas 87   @Override
1544 29 Feb 12 nicklas 88   public Set<GuiContext> getGuiContexts()
1544 29 Feb 12 nicklas 89   {
1544 29 Feb 12 nicklas 90     return Collections.singleton(GuiContext.item(Item.BIOPLATE));
1544 29 Feb 12 nicklas 91   }
1544 29 Feb 12 nicklas 92   /**
1544 29 Feb 12 nicklas 93     We accept all bioplates.
1544 29 Feb 12 nicklas 94   */
1544 29 Feb 12 nicklas 95   @Override
1544 29 Feb 12 nicklas 96   public String isInContext(GuiContext context, Object item)
1544 29 Feb 12 nicklas 97   {
1544 29 Feb 12 nicklas 98     String message = null;
1544 29 Feb 12 nicklas 99     if (item == null)
1544 29 Feb 12 nicklas 100     {
1544 29 Feb 12 nicklas 101       message = "The object is null";
1544 29 Feb 12 nicklas 102     }
1544 29 Feb 12 nicklas 103     else if (!(item instanceof BioPlate))
1544 29 Feb 12 nicklas 104     {
1544 29 Feb 12 nicklas 105       message = "The object is not a BioPlate: " + item;
1544 29 Feb 12 nicklas 106     }
1544 29 Feb 12 nicklas 107     return message;
1544 29 Feb 12 nicklas 108   }
1544 29 Feb 12 nicklas 109   @Override
1544 29 Feb 12 nicklas 110   public RequestInformation getRequestInformation(GuiContext context, String command) 
1544 29 Feb 12 nicklas 111     throws BaseException
1544 29 Feb 12 nicklas 112   {
1544 29 Feb 12 nicklas 113     RequestInformation requestInformation = null;
1544 29 Feb 12 nicklas 114     if (Request.COMMAND_CONFIGURE_JOB.equals(command))
1544 29 Feb 12 nicklas 115     {
1544 29 Feb 12 nicklas 116       requestInformation = getConfigureJobParameters(null);
1544 29 Feb 12 nicklas 117     }
1544 29 Feb 12 nicklas 118     return requestInformation;
1544 29 Feb 12 nicklas 119   }
1544 29 Feb 12 nicklas 120   @Override
1544 29 Feb 12 nicklas 121   public void configure(GuiContext context, Request request, Response response)
1544 29 Feb 12 nicklas 122   {
1544 29 Feb 12 nicklas 123     String command = request.getCommand();    
1544 29 Feb 12 nicklas 124     try
1544 29 Feb 12 nicklas 125     {
1544 29 Feb 12 nicklas 126       if (command.equals(Request.COMMAND_CONFIGURE_JOB))
1544 29 Feb 12 nicklas 127       {
1544 29 Feb 12 nicklas 128         RequestInformation ri = getConfigureJobParameters(!request.isAllowedImmediateExecution());
1544 29 Feb 12 nicklas 129         List<Throwable> errors = validateRequestParameters(ri.getParameters(), request);
1544 29 Feb 12 nicklas 130         if (errors != null)
1544 29 Feb 12 nicklas 131         {
1544 29 Feb 12 nicklas 132           response.setError(errors.size() + " invalid parameters were found in the request",errors);
1544 29 Feb 12 nicklas 133           return;
1544 29 Feb 12 nicklas 134         }        
1544 29 Feb 12 nicklas 135         
1544 29 Feb 12 nicklas 136         storeValue(job, request, ri.getParameter("bioplate"));
1544 29 Feb 12 nicklas 137         if (request.getParameterValue(SAVE_AS) == null)
1544 29 Feb 12 nicklas 138         {
1544 29 Feb 12 nicklas 139           if (!request.isAllowedImmediateExecution())
1544 29 Feb 12 nicklas 140           {
1544 29 Feb 12 nicklas 141             response.setError("Immediate download is not allowed. Please specify a filename.", null);
1544 29 Feb 12 nicklas 142             return;
1544 29 Feb 12 nicklas 143           }
1544 29 Feb 12 nicklas 144           BioPlate plate = (BioPlate)request.getParameterValue("bioplate");
1544 29 Feb 12 nicklas 145           response.setDownloadImmediately("Export Caliper sample names for bioplate " + 
1544 29 Feb 12 nicklas 146               plate.getName(), ExecutionTime.SHORTEST, true);
1544 29 Feb 12 nicklas 147         }
1544 29 Feb 12 nicklas 148         else
1544 29 Feb 12 nicklas 149         {
1544 29 Feb 12 nicklas 150           Object parameterValue = request.getParameterValue(OVERWRITE); 
1544 29 Feb 12 nicklas 151           boolean overwrite = parameterValue != null ? (Boolean)parameterValue : false;
1544 29 Feb 12 nicklas 152           if (!pathCanBeUsed((String)request.getParameterValue(ri.getParameter(SAVE_AS).getName()), overwrite))
1544 29 Feb 12 nicklas 153           {
1544 29 Feb 12 nicklas 154             response.setError("File exists: " + (String)request.getParameterValue(ri.getParameter(SAVE_AS).getName()), null);
1544 29 Feb 12 nicklas 155             return;
1544 29 Feb 12 nicklas 156           }
1544 29 Feb 12 nicklas 157           storeValue(job, request, ri.getParameter(SAVE_AS));
1544 29 Feb 12 nicklas 158           storeValue(job, request, ri.getParameter(OVERWRITE));
1544 29 Feb 12 nicklas 159           BioPlate plate = (BioPlate)job.getValue("bioplate");
1544 29 Feb 12 nicklas 160           response.setSuggestedJobName("Export Caliper sample names for bioplate '" + plate.getName() + "'");
1544 29 Feb 12 nicklas 161           response.setDone("The job configuration is complete", ExecutionTime.SHORTEST);
1544 29 Feb 12 nicklas 162         }
1544 29 Feb 12 nicklas 163       }
1544 29 Feb 12 nicklas 164     }
1544 29 Feb 12 nicklas 165     catch(Throwable ex)
1544 29 Feb 12 nicklas 166     {
1544 29 Feb 12 nicklas 167       response.setError(ex.getMessage(), Arrays.asList(ex));
1544 29 Feb 12 nicklas 168     }    
1544 29 Feb 12 nicklas 169   }
1544 29 Feb 12 nicklas 170   // ------------------------------------------------
1544 29 Feb 12 nicklas 171   
1544 29 Feb 12 nicklas 172   
1544 29 Feb 12 nicklas 173   /*
1544 29 Feb 12 nicklas 174     From the AbstractExporterPlugin interface
1544 29 Feb 12 nicklas 175     -----------------------------------------
1544 29 Feb 12 nicklas 176   */
1544 29 Feb 12 nicklas 177   private DbControl dc;
1544 29 Feb 12 nicklas 178   private int numExported;
1544 29 Feb 12 nicklas 179   @Override
1544 29 Feb 12 nicklas 180   protected void begin(DbControl dc)
1544 29 Feb 12 nicklas 181   {
1544 29 Feb 12 nicklas 182     this.dc = dc;
1544 29 Feb 12 nicklas 183   }
1544 29 Feb 12 nicklas 184
1544 29 Feb 12 nicklas 185   @Override
1544 29 Feb 12 nicklas 186   protected void performExport(ExportOutputStream out, ProgressReporter progress) 
1544 29 Feb 12 nicklas 187     throws IOException 
1544 29 Feb 12 nicklas 188   {
1544 29 Feb 12 nicklas 189     
1544 29 Feb 12 nicklas 190     BioPlate plate = (BioPlate)job.getValue("bioplate");
1544 29 Feb 12 nicklas 191     plate = BioPlate.getById(dc, plate.getId());
1544 29 Feb 12 nicklas 192     out.setMimeType("text/csv");
1544 29 Feb 12 nicklas 193     String filename = Path.makeSafeFilename(plate.getName(), "")+".csv";
1544 29 Feb 12 nicklas 194     out.setFilename(filename);
1544 29 Feb 12 nicklas 195     out.setCharacterSet("UTF-8");
1544 29 Feb 12 nicklas 196     
1544 29 Feb 12 nicklas 197     Writer writer = new OutputStreamWriter(out, "UTF-8");
1544 29 Feb 12 nicklas 198     
1900 07 Mar 13 nicklas 199     numExported = exportSampleNames(dc, plate, new WellCoordinateConverter(), writer);
1544 29 Feb 12 nicklas 200     writer.flush();
1544 29 Feb 12 nicklas 201     
1544 29 Feb 12 nicklas 202   }
1751 28 Nov 12 nicklas 203   @Override
1544 29 Feb 12 nicklas 204   protected void end(boolean success)
1544 29 Feb 12 nicklas 205   {
1544 29 Feb 12 nicklas 206     this.dc = null;
1544 29 Feb 12 nicklas 207   }
1751 28 Nov 12 nicklas 208   @Override
1544 29 Feb 12 nicklas 209   protected String getSuccessMessage()
1544 29 Feb 12 nicklas 210   {
1544 29 Feb 12 nicklas 211     return numExported + " sample names exported successfully";
1544 29 Feb 12 nicklas 212   }
1544 29 Feb 12 nicklas 213   // -------------------------------------------
1544 29 Feb 12 nicklas 214   
1544 29 Feb 12 nicklas 215   private RequestInformation getConfigureJobParameters(Boolean requireFile)
1544 29 Feb 12 nicklas 216   {
1544 29 Feb 12 nicklas 217     if (configureJob == null)
1544 29 Feb 12 nicklas 218     {
1544 29 Feb 12 nicklas 219       // Load the current bioplate
1544 29 Feb 12 nicklas 220       BioPlate currentPlate = null;
1544 29 Feb 12 nicklas 221       int currentPlateId = sc.getCurrentContext(Item.BIOPLATE).getId();
1544 29 Feb 12 nicklas 222       if (currentPlateId != 0)
1544 29 Feb 12 nicklas 223       {
1544 29 Feb 12 nicklas 224         DbControl dc = sc.newDbControl();
1544 29 Feb 12 nicklas 225         try
1544 29 Feb 12 nicklas 226         {
1544 29 Feb 12 nicklas 227           currentPlate = BioPlate.getById(dc, currentPlateId);
1544 29 Feb 12 nicklas 228         }
1544 29 Feb 12 nicklas 229         finally
1544 29 Feb 12 nicklas 230         {
1544 29 Feb 12 nicklas 231           if (dc != null) dc.close();
1544 29 Feb 12 nicklas 232         }
1544 29 Feb 12 nicklas 233       }
1544 29 Feb 12 nicklas 234       
1544 29 Feb 12 nicklas 235       List<PluginParameter<?>> parameters = new ArrayList<PluginParameter<?>>();
1544 29 Feb 12 nicklas 236
1544 29 Feb 12 nicklas 237       parameters.add(new PluginParameter<BioPlate>(
1544 29 Feb 12 nicklas 238         "bioplate", "Bioplate", "Select the bioplate to export", 
1544 29 Feb 12 nicklas 239         new ItemParameterType<BioPlate>(BioPlate.class, currentPlate, true, 1, null)
1544 29 Feb 12 nicklas 240       ));
1544 29 Feb 12 nicklas 241       
1544 29 Feb 12 nicklas 242       if (requireFile == null)
1544 29 Feb 12 nicklas 243       {
1544 29 Feb 12 nicklas 244         PluginDefinition pd = job.getPluginDefinition();
1544 29 Feb 12 nicklas 245         requireFile = pd == null ? false : !pd.getAllowImmediateExecution();
1544 29 Feb 12 nicklas 246       }
1544 29 Feb 12 nicklas 247       String defaultPath = null;
1544 29 Feb 12 nicklas 248       if (requireFile && currentPlate != null)
1544 29 Feb 12 nicklas 249       {
1544 29 Feb 12 nicklas 250         defaultPath = "~/" + Path.makeSafeFilename(currentPlate.getName(), "") + ".csv";
1544 29 Feb 12 nicklas 251       }
1544 29 Feb 12 nicklas 252       parameters.add(getSaveAsParameter(null, null, defaultPath, requireFile));
1544 29 Feb 12 nicklas 253       parameters.add(getOverwriteParameter(null, null));
1544 29 Feb 12 nicklas 254       
1544 29 Feb 12 nicklas 255       configureJob = new RequestInformation
1544 29 Feb 12 nicklas 256       (
1544 29 Feb 12 nicklas 257         Request.COMMAND_CONFIGURE_JOB,
1544 29 Feb 12 nicklas 258         "Caliper export options",
1544 29 Feb 12 nicklas 259         "Select bioplate and the file path where the export file should be saved",
1544 29 Feb 12 nicklas 260         parameters
1544 29 Feb 12 nicklas 261       );
1544 29 Feb 12 nicklas 262     }
1544 29 Feb 12 nicklas 263     return configureJob;
1544 29 Feb 12 nicklas 264   }
1544 29 Feb 12 nicklas 265
1544 29 Feb 12 nicklas 266   /**
1544 29 Feb 12 nicklas 267     Export sample names from the given bioplate. The data is written
1544 29 Feb 12 nicklas 268     to the given writer formatted according to the Caliper specifications.
1544 29 Feb 12 nicklas 269     @return The number of samples exported
1544 29 Feb 12 nicklas 270   */
1900 07 Mar 13 nicklas 271   public int exportSampleNames(DbControl dc, BioPlate plate, ValueConverter<BioWell, String> wellMapper, Writer out)
1544 29 Feb 12 nicklas 272     throws IOException
1544 29 Feb 12 nicklas 273   {
1544 29 Feb 12 nicklas 274     int numExported = 0;
1544 29 Feb 12 nicklas 275     
1544 29 Feb 12 nicklas 276     //Query to get all non-empty wells on the plate
1544 29 Feb 12 nicklas 277     ItemQuery<BioWell> query = plate.getBioWells();
1548 06 Mar 12 nicklas 278     // Load only non-empty wells
1548 06 Mar 12 nicklas 279     query.join(Hql.innerJoin(null, "bioMaterial", "bm", true));
1544 29 Feb 12 nicklas 280     query.order(Orders.asc(Hql.property("row")));
1544 29 Feb 12 nicklas 281     query.order(Orders.asc(Hql.property("column")));
1544 29 Feb 12 nicklas 282     
1544 29 Feb 12 nicklas 283     // Wrap the output writer in a table writer
1544 29 Feb 12 nicklas 284     TableWriter tw = new TableWriter(out);
1544 29 Feb 12 nicklas 285     tw.setDataSeparator(","); // CSV file
1544 29 Feb 12 nicklas 286     tw.setNullValue("");
1548 06 Mar 12 nicklas 287     // Get rid of "bad" characters (comma, tab, newline, etc.)
1548 06 Mar 12 nicklas 288     tw.setEncoder(new CsvEncoderDecoder());
1544 29 Feb 12 nicklas 289     
1544 29 Feb 12 nicklas 290     Iterator<BioWell> it = query.iterate(dc);
1544 29 Feb 12 nicklas 291     while (it.hasNext())
1544 29 Feb 12 nicklas 292     {
1544 29 Feb 12 nicklas 293       BioWell well = it.next();
1544 29 Feb 12 nicklas 294       BioMaterial bm = null;
1544 29 Feb 12 nicklas 295       try
1544 29 Feb 12 nicklas 296       {
1544 29 Feb 12 nicklas 297         bm = well.getBioMaterial();
1550 06 Mar 12 nicklas 298         String comment = "";
1610 23 Apr 12 nicklas 299         if (Boolean.TRUE.equals(Annotationtype.QC_HISENSE.getAnnotationValue(dc, bm)))
1550 06 Mar 12 nicklas 300         {
1610 23 Apr 12 nicklas 301           comment = "HiSense";
1550 06 Mar 12 nicklas 302         }
1900 07 Mar 13 nicklas 303         
1900 07 Mar 13 nicklas 304         tw.tablePrintData(wellMapper.convert(well), bm.getName(), comment, "", "");
1544 29 Feb 12 nicklas 305         numExported++;
1544 29 Feb 12 nicklas 306       }
1544 29 Feb 12 nicklas 307       catch (PermissionDeniedException ex)
1544 29 Feb 12 nicklas 308       {}
1544 29 Feb 12 nicklas 309     }
1544 29 Feb 12 nicklas 310     
1544 29 Feb 12 nicklas 311     tw.flush();
1544 29 Feb 12 nicklas 312     out.flush();
1544 29 Feb 12 nicklas 313     return numExported;
1544 29 Feb 12 nicklas 314   }
1544 29 Feb 12 nicklas 315   
1544 29 Feb 12 nicklas 316 }