extensions/net.sf.basedb.genepattern/trunk/src/net/sf/basedb/genepattern/plugin/GenePatternAnalysisPlugin.java

Code
Comments
Other
Rev Date Author Line
1110 05 Jun 09 nicklas 1 package net.sf.basedb.genepattern.plugin;
1110 05 Jun 09 nicklas 2
1110 05 Jun 09 nicklas 3 import java.util.ArrayList;
1110 05 Jun 09 nicklas 4 import java.util.Arrays;
1110 05 Jun 09 nicklas 5 import java.util.Date;
1110 05 Jun 09 nicklas 6 import java.util.List;
1110 05 Jun 09 nicklas 7
1110 05 Jun 09 nicklas 8 import org.genepattern.webservice.Parameter;
1110 05 Jun 09 nicklas 9 import org.genepattern.webservice.WebServiceException;
1110 05 Jun 09 nicklas 10
1110 05 Jun 09 nicklas 11 import net.sf.basedb.clients.web.formatter.FormatterFactory;
1110 05 Jun 09 nicklas 12 import net.sf.basedb.core.AnnotationType;
1110 05 Jun 09 nicklas 13 import net.sf.basedb.core.AnyToAny;
1110 05 Jun 09 nicklas 14 import net.sf.basedb.core.BaseException;
1110 05 Jun 09 nicklas 15 import net.sf.basedb.core.BioAssaySet;
1110 05 Jun 09 nicklas 16 import net.sf.basedb.core.BooleanParameterType;
1110 05 Jun 09 nicklas 17 import net.sf.basedb.core.DbControl;
1110 05 Jun 09 nicklas 18 import net.sf.basedb.core.Directory;
1110 05 Jun 09 nicklas 19 import net.sf.basedb.core.Experiment;
1110 05 Jun 09 nicklas 20 import net.sf.basedb.core.File;
1128 15 Jun 09 nicklas 21 import net.sf.basedb.core.FileStoreUtil;
1110 05 Jun 09 nicklas 22 import net.sf.basedb.core.Item;
1110 05 Jun 09 nicklas 23 import net.sf.basedb.core.ItemQuery;
1110 05 Jun 09 nicklas 24 import net.sf.basedb.core.Job;
1110 05 Jun 09 nicklas 25 import net.sf.basedb.core.Path;
1110 05 Jun 09 nicklas 26 import net.sf.basedb.core.PathParameterType;
1110 05 Jun 09 nicklas 27 import net.sf.basedb.core.PluginConfiguration;
1110 05 Jun 09 nicklas 28 import net.sf.basedb.core.PluginParameter;
1110 05 Jun 09 nicklas 29 import net.sf.basedb.core.Presets;
1110 05 Jun 09 nicklas 30 import net.sf.basedb.core.ProgressReporter;
1110 05 Jun 09 nicklas 31 import net.sf.basedb.core.RequestInformation;
1110 05 Jun 09 nicklas 32 import net.sf.basedb.core.StringParameterType;
1110 05 Jun 09 nicklas 33 import net.sf.basedb.core.Transformation;
1110 05 Jun 09 nicklas 34 import net.sf.basedb.core.User;
1110 05 Jun 09 nicklas 35 import net.sf.basedb.core.plugin.About;
1110 05 Jun 09 nicklas 36 import net.sf.basedb.core.plugin.AboutImpl;
1110 05 Jun 09 nicklas 37 import net.sf.basedb.core.plugin.AbstractAnalysisPlugin;
1110 05 Jun 09 nicklas 38 import net.sf.basedb.core.plugin.AnnotationSetterPlugin;
1110 05 Jun 09 nicklas 39 import net.sf.basedb.core.plugin.GuiContext;
1110 05 Jun 09 nicklas 40 import net.sf.basedb.core.plugin.InteractivePlugin;
1110 05 Jun 09 nicklas 41 import net.sf.basedb.core.plugin.ParameterValuesWrapper;
1110 05 Jun 09 nicklas 42 import net.sf.basedb.core.plugin.Request;
1110 05 Jun 09 nicklas 43 import net.sf.basedb.core.plugin.Response;
1110 05 Jun 09 nicklas 44 import net.sf.basedb.core.signal.SignalHandler;
1110 05 Jun 09 nicklas 45 import net.sf.basedb.core.signal.SignalTarget;
1110 05 Jun 09 nicklas 46 import net.sf.basedb.core.signal.ThreadSignalHandler;
1119 10 Jun 09 nicklas 47 import net.sf.basedb.genepattern.GPServer;
1110 05 Jun 09 nicklas 48 import net.sf.basedb.genepattern.GenePattern;
1110 05 Jun 09 nicklas 49 import net.sf.basedb.genepattern.file.BaseFileProxy;
1110 05 Jun 09 nicklas 50 import net.sf.basedb.genepattern.file.FileTransferGateway;
1131 16 Jun 09 nicklas 51 import net.sf.basedb.genepattern.servlet.Download;
1119 10 Jun 09 nicklas 52 import net.sf.basedb.genepattern.wrapper.GPClient;
1119 10 Jun 09 nicklas 53 import net.sf.basedb.genepattern.wrapper.JobResult;
1119 10 Jun 09 nicklas 54 import net.sf.basedb.genepattern.wrapper.ParameterInfo;
1131 16 Jun 09 nicklas 55 import net.sf.basedb.util.ChainedProgressReporter;
1110 05 Jun 09 nicklas 56
1131 16 Jun 09 nicklas 57 /**
1131 16 Jun 09 nicklas 58   Plug-in that interfaces with GenePattern analysis modules. This plug-in must be
1131 16 Jun 09 nicklas 59   configured before it can be used. The configuration sequence starts by selecting
1131 16 Jun 09 nicklas 60   the GenePattern module or pipeline that is going to be used by this plug-in.
1131 16 Jun 09 nicklas 61   In the second step default values for the module parameters can be specfied
1131 16 Jun 09 nicklas 62   and also some information about the input file types that will make it easier
1131 16 Jun 09 nicklas 63   for the plug-in to automatically find a suitable file.
1131 16 Jun 09 nicklas 64   <p>
1131 16 Jun 09 nicklas 65   When using this plug-in the user selects the input files and parameter values
1131 16 Jun 09 nicklas 66   for the module/pipeline. The execution phase will first copy all files to 
1131 16 Jun 09 nicklas 67   a temporary location that can be accessed by the GenePattern server (via the
1131 16 Jun 09 nicklas 68   BASE webserver and the {@link Download} servlet) without access permission
1131 16 Jun 09 nicklas 69   controls. 
1131 16 Jun 09 nicklas 70   <p>
1131 16 Jun 09 nicklas 71   NOTE! The temporary location is open to anyone and in theory
1131 16 Jun 09 nicklas 72   files can be downloaded without permission checks. However, the file path
1131 16 Jun 09 nicklas 73   is randomized and is hard to guess and the files are removed as soon as
1131 16 Jun 09 nicklas 74   the job on the GenePattern server has finished.
1131 16 Jun 09 nicklas 75   <p>
1131 16 Jun 09 nicklas 76   When the files are in place a web service request is sent to the GenePattern
1131 16 Jun 09 nicklas 77   server which is allowed to do it's work. When the analysis is complete all
1131 16 Jun 09 nicklas 78   results files are downloaded and added to the BASE file system and attached to
1131 16 Jun 09 nicklas 79   a child bioassay set.
1131 16 Jun 09 nicklas 80   
1131 16 Jun 09 nicklas 81   @author nicklas
1131 16 Jun 09 nicklas 82   @since 1.0
1131 16 Jun 09 nicklas 83 */
1110 05 Jun 09 nicklas 84 public class GenePatternAnalysisPlugin 
1110 05 Jun 09 nicklas 85   extends AbstractAnalysisPlugin 
1110 05 Jun 09 nicklas 86   implements InteractivePlugin, SignalTarget, AnnotationSetterPlugin
1110 05 Jun 09 nicklas 87 {
1110 05 Jun 09 nicklas 88
1110 05 Jun 09 nicklas 89   private ThreadSignalHandler signalHandler;
1110 05 Jun 09 nicklas 90   private RequestInformation configureJob;
1110 05 Jun 09 nicklas 91   private RequestInformation configurePlugin;
1110 05 Jun 09 nicklas 92   private RequestInformation configureGpParameters;
1110 05 Jun 09 nicklas 93
1110 05 Jun 09 nicklas 94   private final String CONFIGURE_GP_PARAMETERS = "CONFIGURE_GP_PARAMETERS";
1110 05 Jun 09 nicklas 95   
1110 05 Jun 09 nicklas 96   public GenePatternAnalysisPlugin()
1110 05 Jun 09 nicklas 97   {}
1110 05 Jun 09 nicklas 98   
1110 05 Jun 09 nicklas 99   /*
1110 05 Jun 09 nicklas 100     From the Plugin interface
1110 05 Jun 09 nicklas 101     -------------------------
1110 05 Jun 09 nicklas 102   */
1110 05 Jun 09 nicklas 103   @Override
1110 05 Jun 09 nicklas 104   public About getAbout() 
1110 05 Jun 09 nicklas 105   {
1110 05 Jun 09 nicklas 106     return new AboutImpl(
1110 05 Jun 09 nicklas 107       "GenePattern analysis",
1110 05 Jun 09 nicklas 108       "Submits data to a GenePattern server for analysis. When the analysis is " +
1110 05 Jun 09 nicklas 109       "complete the result files are imported back into BASE. This plug-in can " +
1110 05 Jun 09 nicklas 110       "execute any module or pipeline that has been registered as configuration " +
1110 05 Jun 09 nicklas 111       "of this plug-in.",
1110 05 Jun 09 nicklas 112       GenePattern.VERSION,
1110 05 Jun 09 nicklas 113       GenePattern.COPYRIGHT,
1110 05 Jun 09 nicklas 114       null,
1110 05 Jun 09 nicklas 115       GenePattern.EMAIL,
1110 05 Jun 09 nicklas 116       GenePattern.URL
1110 05 Jun 09 nicklas 117       );
1110 05 Jun 09 nicklas 118   }
1110 05 Jun 09 nicklas 119
1110 05 Jun 09 nicklas 120   @Override
1110 05 Jun 09 nicklas 121   public boolean requiresConfiguration()
1110 05 Jun 09 nicklas 122   {
1110 05 Jun 09 nicklas 123     return true;
1110 05 Jun 09 nicklas 124   }
1110 05 Jun 09 nicklas 125   
1110 05 Jun 09 nicklas 126   @Override
1110 05 Jun 09 nicklas 127   public boolean supportsConfigurations() 
1110 05 Jun 09 nicklas 128   {
1110 05 Jun 09 nicklas 129     return true;
1110 05 Jun 09 nicklas 130   }
1110 05 Jun 09 nicklas 131   
1110 05 Jun 09 nicklas 132   @Override
1110 05 Jun 09 nicklas 133   public void run(Request request, Response response, ProgressReporter progress)
1110 05 Jun 09 nicklas 134   {
1110 05 Jun 09 nicklas 135     DbControl dc = null;
1110 05 Jun 09 nicklas 136     FileTransferGateway gw = null;
1110 05 Jun 09 nicklas 137     try
1110 05 Jun 09 nicklas 138     {
1131 16 Jun 09 nicklas 139       // Initialize things that we need
1110 05 Jun 09 nicklas 140       String gpModule = (String)configuration.getValue("gpModule"); 
1119 10 Jun 09 nicklas 141       GPServer gpServer = GPServer.get(sc, (String)job.getValue("gpServer"));
1131 16 Jun 09 nicklas 142       if (progress != null) progress.display(0, "Initializing " + gpModule + "...");
1119 10 Jun 09 nicklas 143       GPClient gp = new GPClient(gpServer);
1119 10 Jun 09 nicklas 144       ParameterInfo[] info = gp.getParameters(gpModule, null);      
1110 05 Jun 09 nicklas 145       Parameter[] parameters = new Parameter[info.length];
1131 16 Jun 09 nicklas 146       
1131 16 Jun 09 nicklas 147       // Create parameters 
1131 16 Jun 09 nicklas 148       gw = new FileTransferGateway(gpServer.getBaseUrl() + "/" + GenePattern.getServletUrl("Download"));
1131 16 Jun 09 nicklas 149       for (int index = 0; index < info.length; ++index)
1110 05 Jun 09 nicklas 150       {
1131 16 Jun 09 nicklas 151         ParameterInfo pi = info[index];
1110 05 Jun 09 nicklas 152         String name = pi.getName();
1110 05 Jun 09 nicklas 153         Parameter param = null;
1110 05 Jun 09 nicklas 154         if (pi.isInputFile())
1110 05 Jun 09 nicklas 155         {
1110 05 Jun 09 nicklas 156           File file = (File)job.getValue("gp." + name);
1110 05 Jun 09 nicklas 157           if (file != null)
1110 05 Jun 09 nicklas 158           {
1110 05 Jun 09 nicklas 159             param = gw.addFile(name, new BaseFileProxy(file));
1110 05 Jun 09 nicklas 160           }
1110 05 Jun 09 nicklas 161           else
1110 05 Jun 09 nicklas 162           {
1110 05 Jun 09 nicklas 163             param = new Parameter(name, "");
1110 05 Jun 09 nicklas 164           }
1110 05 Jun 09 nicklas 165         }
1110 05 Jun 09 nicklas 166         else
1110 05 Jun 09 nicklas 167         {
1110 05 Jun 09 nicklas 168           Object value = job.getValue("gp." + name);
1110 05 Jun 09 nicklas 169           param = new Parameter(name, value == null ? "" : value.toString());
1110 05 Jun 09 nicklas 170         }
1131 16 Jun 09 nicklas 171         parameters[index] = param;
1110 05 Jun 09 nicklas 172       }
1131 16 Jun 09 nicklas 173       
1131 16 Jun 09 nicklas 174       // Transfer files
1131 16 Jun 09 nicklas 175       ChainedProgressReporter chainedProgress = null;
1131 16 Jun 09 nicklas 176       if (progress != null)
1131 16 Jun 09 nicklas 177       {
1131 16 Jun 09 nicklas 178         chainedProgress = new ChainedProgressReporter(progress);
1131 16 Jun 09 nicklas 179         chainedProgress.setRange(5, 35);
1131 16 Jun 09 nicklas 180       }
1131 16 Jun 09 nicklas 181       int fileTransfered = gw.prepareUpload(chainedProgress);
1110 05 Jun 09 nicklas 182   
1110 05 Jun 09 nicklas 183       // Execute the job on the GenePattern server
1110 05 Jun 09 nicklas 184       if (progress != null) 
1110 05 Jun 09 nicklas 185       {
1131 16 Jun 09 nicklas 186         progress.display(35, "Running " + gpModule + " on GenePattern server: " + gpServer.getUrl());
1110 05 Jun 09 nicklas 187       }
1110 05 Jun 09 nicklas 188       checkInterrupted();
1131 16 Jun 09 nicklas 189       JobResult result = gp.runAnalysis(gpModule, parameters);
1110 05 Jun 09 nicklas 190       
1131 16 Jun 09 nicklas 191       // Was the job successful or not?
1110 05 Jun 09 nicklas 192       boolean failed = result.hasStandardError();
1131 16 Jun 09 nicklas 193       if (failed)
1110 05 Jun 09 nicklas 194       {
1131 16 Jun 09 nicklas 195         if (progress != null) progress.display(75, "Analysis failed. Downloading error information...");
1131 16 Jun 09 nicklas 196         
1131 16 Jun 09 nicklas 197         String error = gw.downloadAsString(result, "stderr.txt", "UTF-8");
1131 16 Jun 09 nicklas 198         response.setError(error, null);
1110 05 Jun 09 nicklas 199       }
1131 16 Jun 09 nicklas 200       else
1131 16 Jun 09 nicklas 201       {
1131 16 Jun 09 nicklas 202         if (progress != null) progress.display(75, "Analysis complete. Downloading result files...");
1110 05 Jun 09 nicklas 203       
1131 16 Jun 09 nicklas 204         // Prepare to create transformation, child bioassay set, etc.
1131 16 Jun 09 nicklas 205         dc = sc.newDbControl();
1131 16 Jun 09 nicklas 206         BioAssaySet source = getSourceBioAssaySet(dc);
1131 16 Jun 09 nicklas 207         Job currentJob = getCurrentJob(dc);
1131 16 Jun 09 nicklas 208         String transformationName = (String)job.getValue(TRANSFORMATION_NAME);
1131 16 Jun 09 nicklas 209         String childName = (String)job.getValue(CHILD_NAME);
1131 16 Jun 09 nicklas 210         String childDescription = (String)job.getValue(CHILD_DESCRIPTION);
1131 16 Jun 09 nicklas 211         boolean copyAnnotations = Boolean.TRUE.equals(job.getValue(COPY_ANNOTATIONS));
1131 16 Jun 09 nicklas 212         boolean keepSpotData = Boolean.TRUE.equals(job.getValue("keepSpotData"));
1110 05 Jun 09 nicklas 213       
1131 16 Jun 09 nicklas 214         // Create child items
1131 16 Jun 09 nicklas 215         Transformation t = source.newTransformation(currentJob);
1131 16 Jun 09 nicklas 216         BioAssaySet child = t.newProduct(null, keepSpotData ? null : "new", keepSpotData);
1131 16 Jun 09 nicklas 217         t.setName(transformationName);
1131 16 Jun 09 nicklas 218         child.setName(childName);
1131 16 Jun 09 nicklas 219         child.setDescription(childDescription);
1131 16 Jun 09 nicklas 220         dc.saveItem(t);
1131 16 Jun 09 nicklas 221         dc.saveItem(child);
1110 05 Jun 09 nicklas 222       
1131 16 Jun 09 nicklas 223         // Copy annotations
1131 16 Jun 09 nicklas 224         if (copyAnnotations)
1131 16 Jun 09 nicklas 225         {
1131 16 Jun 09 nicklas 226           PluginConfiguration cfg = getCurrentConfiguration(dc);
1131 16 Jun 09 nicklas 227           if (cfg != null && cfg.isAnnotated()) child.getAnnotationSet().copyFrom(cfg, false);
1131 16 Jun 09 nicklas 228         }
1110 05 Jun 09 nicklas 229
1131 16 Jun 09 nicklas 230         // Download files
1131 16 Jun 09 nicklas 231         String resultDirectory = (String)job.getValue("resultDirectory");
1131 16 Jun 09 nicklas 232         Directory dir = Directory.getNew(dc, new Path(resultDirectory, Path.Type.DIRECTORY));
1131 16 Jun 09 nicklas 233         String[] files = result.getOutputFileNames();
1131 16 Jun 09 nicklas 234         int i = 0;
1131 16 Jun 09 nicklas 235         int total = files.length;
1131 16 Jun 09 nicklas 236         for (String f : files)
1110 05 Jun 09 nicklas 237         {
1131 16 Jun 09 nicklas 238           checkInterrupted();
1131 16 Jun 09 nicklas 239           File baseFile = File.getFile(dc, dir, f, true);
1131 16 Jun 09 nicklas 240           if (!baseFile.isInDatabase()) dc.saveItem(baseFile);
1131 16 Jun 09 nicklas 241           if (progress != null) 
1131 16 Jun 09 nicklas 242           {
1131 16 Jun 09 nicklas 243             progress.display(80 + (20 * i) / total, "Downloading " + f + "...");
1131 16 Jun 09 nicklas 244           }
1131 16 Jun 09 nicklas 245           gw.downloadResultFile(result, f, baseFile.getUploadStream(false));
1131 16 Jun 09 nicklas 246           AnyToAny ata = AnyToAny.getNew(dc, child, baseFile, f, false);
1131 16 Jun 09 nicklas 247           dc.saveItem(ata);
1131 16 Jun 09 nicklas 248           i++;
1110 05 Jun 09 nicklas 249         }
1131 16 Jun 09 nicklas 250         dc.commit();
1110 05 Jun 09 nicklas 251       
1131 16 Jun 09 nicklas 252         response.setDone(gpModule + " completed successfully.");
1110 05 Jun 09 nicklas 253       }
1110 05 Jun 09 nicklas 254     }
1110 05 Jun 09 nicklas 255     catch (Throwable t)
1110 05 Jun 09 nicklas 256     {
1110 05 Jun 09 nicklas 257       response.setError(t.getMessage(), Arrays.asList(t));
1110 05 Jun 09 nicklas 258     }
1110 05 Jun 09 nicklas 259     finally
1110 05 Jun 09 nicklas 260     {
1110 05 Jun 09 nicklas 261       if (dc != null) dc.close();
1110 05 Jun 09 nicklas 262       if (gw != null) gw.cleanUp();
1110 05 Jun 09 nicklas 263     }
1110 05 Jun 09 nicklas 264   }
1110 05 Jun 09 nicklas 265   // --------------------------------------------
1110 05 Jun 09 nicklas 266   /*
1110 05 Jun 09 nicklas 267     From the SignalTarget interface
1110 05 Jun 09 nicklas 268     -------------------------------------------
1110 05 Jun 09 nicklas 269   */
1110 05 Jun 09 nicklas 270   @Override
1110 05 Jun 09 nicklas 271   public SignalHandler getSignalHandler()
1110 05 Jun 09 nicklas 272   {
1110 05 Jun 09 nicklas 273     signalHandler = new ThreadSignalHandler();
1110 05 Jun 09 nicklas 274     return signalHandler;
1110 05 Jun 09 nicklas 275   }
1110 05 Jun 09 nicklas 276   // -------------------------------------------
1110 05 Jun 09 nicklas 277   /*
1110 05 Jun 09 nicklas 278     From the AnnotationSetterPlugin interface
1110 05 Jun 09 nicklas 279     -------------------------------------------
1110 05 Jun 09 nicklas 280   */
1110 05 Jun 09 nicklas 281   /**
1110 05 Jun 09 nicklas 282     Return a query that finds annotation types for bioassay sets.
1110 05 Jun 09 nicklas 283   */
1110 05 Jun 09 nicklas 284   public ItemQuery<AnnotationType> getAnnotationTypes()
1110 05 Jun 09 nicklas 285   {
1110 05 Jun 09 nicklas 286     return AnnotationType.getQuery(Item.BIOASSAYSET);
1110 05 Jun 09 nicklas 287   }
1110 05 Jun 09 nicklas 288   public String getAnnotationMessage()
1110 05 Jun 09 nicklas 289   {
1110 05 Jun 09 nicklas 290     return "The selected annotations will be copied to the child bioassay set that " +
1110 05 Jun 09 nicklas 291         "is created to hold the results of the GenePattern analysis.";
1110 05 Jun 09 nicklas 292   }
1110 05 Jun 09 nicklas 293   // ----------------------------------------------
1110 05 Jun 09 nicklas 294
1110 05 Jun 09 nicklas 295   /*
1110 05 Jun 09 nicklas 296     From the InteractivePlugin interface
1110 05 Jun 09 nicklas 297     -------------------------------------------
1110 05 Jun 09 nicklas 298   */
1110 05 Jun 09 nicklas 299   @Override
1110 05 Jun 09 nicklas 300   public void configure(GuiContext context, Request request, Response response)
1110 05 Jun 09 nicklas 301   {
1110 05 Jun 09 nicklas 302     try
1110 05 Jun 09 nicklas 303     {
1110 05 Jun 09 nicklas 304       String command = request.getCommand();
1110 05 Jun 09 nicklas 305       if (command.equals(Request.COMMAND_CONFIGURE_PLUGIN))
1110 05 Jun 09 nicklas 306       {
1110 05 Jun 09 nicklas 307         RequestInformation ri = getConfigurePluginParameters(context);
1110 05 Jun 09 nicklas 308         List<Throwable> errors = validateRequestParameters(ri.getParameters(), request);
1110 05 Jun 09 nicklas 309         if (errors != null)
1110 05 Jun 09 nicklas 310         {
1110 05 Jun 09 nicklas 311           response.setError(errors.size()+" invalid parameter(s) were found " +
1110 05 Jun 09 nicklas 312             "in the request", errors);
1110 05 Jun 09 nicklas 313           return;
1110 05 Jun 09 nicklas 314         }
1110 05 Jun 09 nicklas 315         
1110 05 Jun 09 nicklas 316         storeValue(configuration, request, ri.getParameter("gpModule"));
1110 05 Jun 09 nicklas 317         storeValue(configuration, request, ri.getParameter("gpServer"));
1110 05 Jun 09 nicklas 318         response.setContinue(CONFIGURE_GP_PARAMETERS);
1110 05 Jun 09 nicklas 319       }
1110 05 Jun 09 nicklas 320       else if (command.equals(CONFIGURE_GP_PARAMETERS))
1110 05 Jun 09 nicklas 321       {
1110 05 Jun 09 nicklas 322         RequestInformation ri = getConfigureGpParameters(context);
1110 05 Jun 09 nicklas 323         List<Throwable> errors = validateRequestParameters(ri.getParameters(), request);
1110 05 Jun 09 nicklas 324         if (errors != null)
1110 05 Jun 09 nicklas 325         {
1110 05 Jun 09 nicklas 326           response.setError(errors.size()+" invalid parameter(s) were found " +
1110 05 Jun 09 nicklas 327             "in the request", errors);
1110 05 Jun 09 nicklas 328           return;
1110 05 Jun 09 nicklas 329         }
1110 05 Jun 09 nicklas 330         ParameterValuesWrapper wrapper = new ParameterValuesWrapper(request, job, configuration, context != null);
1110 05 Jun 09 nicklas 331         for (PluginParameter<?> pp : ri.getParameters())
1110 05 Jun 09 nicklas 332         {
1128 15 Jun 09 nicklas 333           if (pp.getParameterType() != null) storeValue(wrapper, request, pp);
1110 05 Jun 09 nicklas 334         }
1110 05 Jun 09 nicklas 335         response.setDone("Configuration complete");        
1110 05 Jun 09 nicklas 336       }
1110 05 Jun 09 nicklas 337       else if (command.equals(Request.COMMAND_CONFIGURE_JOB))
1110 05 Jun 09 nicklas 338       {
1110 05 Jun 09 nicklas 339         RequestInformation ri = getConfigureJobParameters(context);
1110 05 Jun 09 nicklas 340         List<Throwable> errors = validateRequestParameters(ri.getParameters(), request);
1110 05 Jun 09 nicklas 341         if (errors != null)
1110 05 Jun 09 nicklas 342         {
1110 05 Jun 09 nicklas 343           response.setError(errors.size()+" invalid parameter(s) were found " +
1110 05 Jun 09 nicklas 344             "in the request", errors);
1110 05 Jun 09 nicklas 345           return;
1110 05 Jun 09 nicklas 346         }
1110 05 Jun 09 nicklas 347         
1110 05 Jun 09 nicklas 348         storeValue(job, request, ri.getParameter(SOURCE_BIOASSAYSET));
1110 05 Jun 09 nicklas 349         storeValue(job, request, ri.getParameter("keepSpotData"));
1110 05 Jun 09 nicklas 350         storeValue(job, request, ri.getParameter(TRANSFORMATION_NAME));
1110 05 Jun 09 nicklas 351         storeValue(job, request, ri.getParameter(CHILD_NAME));
1110 05 Jun 09 nicklas 352         storeValue(job, request, ri.getParameter(CHILD_DESCRIPTION));
1110 05 Jun 09 nicklas 353         storeValue(job, request, ri.getParameter(COPY_ANNOTATIONS));
1110 05 Jun 09 nicklas 354         storeValue(job, request, ri.getParameter("gpServer"));
1110 05 Jun 09 nicklas 355         storeValue(job, request, ri.getParameter("resultDirectory"));
1110 05 Jun 09 nicklas 356         
1110 05 Jun 09 nicklas 357         response.setContinue(CONFIGURE_GP_PARAMETERS);
1110 05 Jun 09 nicklas 358       }
1110 05 Jun 09 nicklas 359     }
1110 05 Jun 09 nicklas 360     catch (Throwable ex)
1110 05 Jun 09 nicklas 361     {
1110 05 Jun 09 nicklas 362       response.setError(ex.getMessage(), Arrays.asList(ex));
1110 05 Jun 09 nicklas 363     }
1110 05 Jun 09 nicklas 364
1110 05 Jun 09 nicklas 365   }
1110 05 Jun 09 nicklas 366
1110 05 Jun 09 nicklas 367   @Override
1110 05 Jun 09 nicklas 368   public RequestInformation getRequestInformation(GuiContext context, String command)
1110 05 Jun 09 nicklas 369     throws BaseException 
1110 05 Jun 09 nicklas 370   {
1110 05 Jun 09 nicklas 371     RequestInformation requestInformation = null;
1110 05 Jun 09 nicklas 372     if (command.equals(Request.COMMAND_CONFIGURE_JOB))
1110 05 Jun 09 nicklas 373     {
1110 05 Jun 09 nicklas 374       requestInformation = getConfigureJobParameters(context);
1110 05 Jun 09 nicklas 375     }
1110 05 Jun 09 nicklas 376     else if (command.equals(Request.COMMAND_CONFIGURE_PLUGIN))
1110 05 Jun 09 nicklas 377     {
1110 05 Jun 09 nicklas 378       requestInformation = getConfigurePluginParameters(context);
1110 05 Jun 09 nicklas 379     }
1110 05 Jun 09 nicklas 380     else if (command.equals(CONFIGURE_GP_PARAMETERS))
1110 05 Jun 09 nicklas 381     {
1110 05 Jun 09 nicklas 382       requestInformation = getConfigureGpParameters(context);
1110 05 Jun 09 nicklas 383     }
1110 05 Jun 09 nicklas 384     return requestInformation;
1110 05 Jun 09 nicklas 385   }
1110 05 Jun 09 nicklas 386   // -------------------------------------------
1110 05 Jun 09 nicklas 387
1110 05 Jun 09 nicklas 388   private RequestInformation getConfigureJobParameters(GuiContext context)
1110 05 Jun 09 nicklas 389   {
1110 05 Jun 09 nicklas 390     if (configureJob != null) return configureJob;
1110 05 Jun 09 nicklas 391
1110 05 Jun 09 nicklas 392     DbControl dc = null;
1110 05 Jun 09 nicklas 393     try
1110 05 Jun 09 nicklas 394     {
1110 05 Jun 09 nicklas 395       dc = sc.newDbControl();
1110 05 Jun 09 nicklas 396       PluginConfiguration config = getCurrentConfiguration(dc);
1110 05 Jun 09 nicklas 397       String gpModule = (String)configuration.getValue("gpModule");
1110 05 Jun 09 nicklas 398       boolean configIsAnnotated = config != null && config.isAnnotated();
1110 05 Jun 09 nicklas 399       BioAssaySet source = getCurrentBioAssaySet(dc);
1110 05 Jun 09 nicklas 400       
1110 05 Jun 09 nicklas 401       List<PluginParameter<?>> parameters = new ArrayList<PluginParameter<?>>();
1110 05 Jun 09 nicklas 402       
1110 05 Jun 09 nicklas 403       // Source bioassay set parameter
1110 05 Jun 09 nicklas 404       parameters.add(getSourceBioAssaySetParameter(null, null));
1110 05 Jun 09 nicklas 405       if (source != null && source.getNumSpots() > 0)
1110 05 Jun 09 nicklas 406       {
1110 05 Jun 09 nicklas 407         parameters.add(new PluginParameter<Boolean>(
1110 05 Jun 09 nicklas 408           "keepSpotData",
1110 05 Jun 09 nicklas 409           "Keep spot data",
1110 05 Jun 09 nicklas 410           "Select this option to let the child bioassay set keep a reference " +
1110 05 Jun 09 nicklas 411           "to the spot data in the source bioassay set. This makes it possible to " +
1110 05 Jun 09 nicklas 412           "run other plug-ins later from the child bioassay set.",
1110 05 Jun 09 nicklas 413           new BooleanParameterType(true, false)
1110 05 Jun 09 nicklas 414         ));
1110 05 Jun 09 nicklas 415       }
1110 05 Jun 09 nicklas 416       // Names of transformation, child bioassay set etc.
1110 05 Jun 09 nicklas 417       String transformationName = getTransformationName(dc);
1110 05 Jun 09 nicklas 418       parameters.add(getTransformationNameParameter(null, null, transformationName));
1110 05 Jun 09 nicklas 419       parameters.add(getChildNameParameter(null, null, "After " + transformationName));
1110 05 Jun 09 nicklas 420       parameters.add(getChildDescriptionParameter(null, null, null));
1110 05 Jun 09 nicklas 421
1110 05 Jun 09 nicklas 422       // Annotations section
1110 05 Jun 09 nicklas 423       if (configIsAnnotated)
1110 05 Jun 09 nicklas 424       {
1110 05 Jun 09 nicklas 425         parameters.add(annotationSection);
1110 05 Jun 09 nicklas 426         parameters.add(getCopyAnnotationsParmeter(null, 
1110 05 Jun 09 nicklas 427           "If selected, annotations are copied from the configuration to the " +
1110 05 Jun 09 nicklas 428           "child bioassay set that is created by the manual transform.", true));
1110 05 Jun 09 nicklas 429       }
1110 05 Jun 09 nicklas 430     
1110 05 Jun 09 nicklas 431
1110 05 Jun 09 nicklas 432       parameters.add(getGPServerParameter(
1110 05 Jun 09 nicklas 433         "Select the GenePattern server to use in this analysis"));
1110 05 Jun 09 nicklas 434
1110 05 Jun 09 nicklas 435       Experiment experiment = getCurrentExperiment(dc);
1110 05 Jun 09 nicklas 436       String homeDirectoryPath = "/gp-" + Path.makeSafeFilename(gpModule, "") + 
1110 05 Jun 09 nicklas 437         "/" + Path.makeSafeFilename(FormatterFactory.getDateFormatter(sc).format(new Date()), ".");
1110 05 Jun 09 nicklas 438       Directory homeDirectory = experiment == null ? null : experiment.getDirectory();
1110 05 Jun 09 nicklas 439       if (homeDirectory == null)
1110 05 Jun 09 nicklas 440       {
1110 05 Jun 09 nicklas 441         homeDirectory = User.getById(dc, sc.getLoggedInUserId()).getHomeDirectory();
1110 05 Jun 09 nicklas 442       }
1110 05 Jun 09 nicklas 443       if (homeDirectory != null)
1110 05 Jun 09 nicklas 444       {
1110 05 Jun 09 nicklas 445         homeDirectoryPath = homeDirectory.getPath() + homeDirectoryPath;
1110 05 Jun 09 nicklas 446       }
1110 05 Jun 09 nicklas 447
1110 05 Jun 09 nicklas 448       parameters.add(new PluginParameter<String>(
1110 05 Jun 09 nicklas 449         "resultDirectory",
1110 05 Jun 09 nicklas 450         "Result files directory",
1110 05 Jun 09 nicklas 451         "Select a directory where result files from GenePattern are stored. " +
1110 05 Jun 09 nicklas 452         "NOTE! Existing files in the selected directory will be overwritten! If " +
1110 05 Jun 09 nicklas 453         "the directory doesn't exists it will be created.",
1110 05 Jun 09 nicklas 454           new PathParameterType(Path.Type.DIRECTORY, homeDirectoryPath, true)
1110 05 Jun 09 nicklas 455       ));
1110 05 Jun 09 nicklas 456       dc.commit();
1110 05 Jun 09 nicklas 457
1110 05 Jun 09 nicklas 458       configureJob = new RequestInformation(
1110 05 Jun 09 nicklas 459           Request.COMMAND_CONFIGURE_JOB,
1110 05 Jun 09 nicklas 460           "Specify BASE options",
1110 05 Jun 09 nicklas 461           "On this page you specify source data and some properties for " +
1110 05 Jun 09 nicklas 462           "child data that is to be created. In the next step you will can " +
1110 05 Jun 09 nicklas 463           "set parameters for the " + gpModule + " module",
1110 05 Jun 09 nicklas 464           parameters
1110 05 Jun 09 nicklas 465         );
1110 05 Jun 09 nicklas 466     }
1110 05 Jun 09 nicklas 467     finally
1110 05 Jun 09 nicklas 468     {
1110 05 Jun 09 nicklas 469       if (dc != null) dc.close();
1110 05 Jun 09 nicklas 470     }
1110 05 Jun 09 nicklas 471     return configureJob;
1110 05 Jun 09 nicklas 472   }
1110 05 Jun 09 nicklas 473
1110 05 Jun 09 nicklas 474   private RequestInformation getConfigurePluginParameters(GuiContext context)
1110 05 Jun 09 nicklas 475   {
1110 05 Jun 09 nicklas 476     if (configurePlugin != null) return configurePlugin;
1110 05 Jun 09 nicklas 477     List<PluginParameter<?>> parameters = new ArrayList<PluginParameter<?>>();
1110 05 Jun 09 nicklas 478     
1110 05 Jun 09 nicklas 479     parameters.add(getGPServerParameter(
1110 05 Jun 09 nicklas 480         "Select a GenePattern server to use for extracting parameter information. " +
1110 05 Jun 09 nicklas 481         "Users doesn't have to use the same server when analysing data."));
1110 05 Jun 09 nicklas 482     parameters.add(new PluginParameter<String>(
1110 05 Jun 09 nicklas 483       "gpModule",
1119 10 Jun 09 nicklas 484       "Module/pipeline",
1110 05 Jun 09 nicklas 485       "Enter the name or LSID of a GenePattern module or pipeline",
1110 05 Jun 09 nicklas 486       new StringParameterType(255, null, true)
1110 05 Jun 09 nicklas 487     ));
1110 05 Jun 09 nicklas 488
1110 05 Jun 09 nicklas 489     configurePlugin = new RequestInformation(
1110 05 Jun 09 nicklas 490       Request.COMMAND_CONFIGURE_PLUGIN,
1119 10 Jun 09 nicklas 491       "Configure GenePattern module/pipeline",
1110 05 Jun 09 nicklas 492       "Select a GenePattern module or pipeline to run " +
1110 05 Jun 09 nicklas 493       "when this configuration is selected.",
1119 10 Jun 09 nicklas 494       parameters,
1119 10 Jun 09 nicklas 495       GenePattern.getHomeUrl() + "/configure_plugin.jsp"
1110 05 Jun 09 nicklas 496     );
1110 05 Jun 09 nicklas 497     
1110 05 Jun 09 nicklas 498     return configurePlugin;
1110 05 Jun 09 nicklas 499   }
1110 05 Jun 09 nicklas 500   
1110 05 Jun 09 nicklas 501   
1110 05 Jun 09 nicklas 502   private RequestInformation getConfigureGpParameters(GuiContext context)
1110 05 Jun 09 nicklas 503   {
1110 05 Jun 09 nicklas 504     if (configureGpParameters != null) return configureGpParameters;
1110 05 Jun 09 nicklas 505     String gpModule = (String)configuration.getValue("gpModule");
1119 10 Jun 09 nicklas 506     GPServer gpServer = GPServer.get(sc,
1110 05 Jun 09 nicklas 507         context == null ? (String)configuration.getValue("gpServer") : (String)job.getValue("gpServer"));
1128 15 Jun 09 nicklas 508     boolean forJob = context != null;
1110 05 Jun 09 nicklas 509     try
1110 05 Jun 09 nicklas 510     {
1119 10 Jun 09 nicklas 511       GPClient gp =  new GPClient(gpServer);
1110 05 Jun 09 nicklas 512       
1119 10 Jun 09 nicklas 513       ParameterInfo[] info = gp.getParameters(gpModule, null);
1110 05 Jun 09 nicklas 514       List<PluginParameter<?>> parameters = new ArrayList<PluginParameter<?>>(info.length);
1128 15 Jun 09 nicklas 515       List<PluginParameter<?>> fileParameters = new ArrayList<PluginParameter<?>>(info.length);
1128 15 Jun 09 nicklas 516       sc.getCurrentContext(Item.FILE).setId(0);
1110 05 Jun 09 nicklas 517       for (ParameterInfo pi : info)
1110 05 Jun 09 nicklas 518       {
1128 15 Jun 09 nicklas 519         PluginParameter<?> pp = null;
1128 15 Jun 09 nicklas 520         if (forJob)
1119 10 Jun 09 nicklas 521         {
1128 15 Jun 09 nicklas 522           Object defaultValue = configuration.getValue("gp." + pi.getName());
1128 15 Jun 09 nicklas 523           if (pi.isInputFile())
1128 15 Jun 09 nicklas 524           {
1128 15 Jun 09 nicklas 525             String fileType = (String)configuration.getValue("filetype." + pi.getName());
1128 15 Jun 09 nicklas 526             DbControl dc = sc.newDbControl();
1128 15 Jun 09 nicklas 527             BioAssaySet bioAssaySet = getCurrentBioAssaySet(dc);
1128 15 Jun 09 nicklas 528             defaultValue = FileStoreUtil.getDataFile(dc, bioAssaySet, fileType);
1128 15 Jun 09 nicklas 529             dc.close();
1128 15 Jun 09 nicklas 530           }
1128 15 Jun 09 nicklas 531           pp = pi.createPluginParameter("gp.", defaultValue);
1119 10 Jun 09 nicklas 532         }
1128 15 Jun 09 nicklas 533         else
1128 15 Jun 09 nicklas 534         {
1128 15 Jun 09 nicklas 535           if (pi.isInputFile())
1128 15 Jun 09 nicklas 536           {
1128 15 Jun 09 nicklas 537             List<String> options = new ArrayList<String>();
1128 15 Jun 09 nicklas 538             options.add(GenePattern.GCT_FILE);
1128 15 Jun 09 nicklas 539             String defaultOption = null;
1128 15 Jun 09 nicklas 540             String description = pi.getDescription();
1128 15 Jun 09 nicklas 541             if (defaultOption == null && description.contains(".gct"))
1128 15 Jun 09 nicklas 542             {
1128 15 Jun 09 nicklas 543               defaultOption = GenePattern.GCT_FILE;
1128 15 Jun 09 nicklas 544             }
1128 15 Jun 09 nicklas 545             pp = new PluginParameter<String>(
1128 15 Jun 09 nicklas 546                 "filetype." + pi.getName(),
1128 15 Jun 09 nicklas 547                 pi.getLabel(),
1128 15 Jun 09 nicklas 548                 pi.getDescription(),
1128 15 Jun 09 nicklas 549                 new StringParameterType(255, defaultOption, false, 1, 0, 0, options)
1128 15 Jun 09 nicklas 550             );
1128 15 Jun 09 nicklas 551           }
1128 15 Jun 09 nicklas 552           else
1128 15 Jun 09 nicklas 553           {
1128 15 Jun 09 nicklas 554             pp = pi.createPluginParameter("gp.", null);
1128 15 Jun 09 nicklas 555           }
1128 15 Jun 09 nicklas 556         }
1128 15 Jun 09 nicklas 557         if (pp != null) 
1128 15 Jun 09 nicklas 558         {
1128 15 Jun 09 nicklas 559           if (pi.isInputFile())
1128 15 Jun 09 nicklas 560           {
1128 15 Jun 09 nicklas 561             fileParameters.add(pp);
1128 15 Jun 09 nicklas 562           }
1128 15 Jun 09 nicklas 563           else
1128 15 Jun 09 nicklas 564           {
1128 15 Jun 09 nicklas 565             parameters.add(pp);
1128 15 Jun 09 nicklas 566           }
1128 15 Jun 09 nicklas 567         }
1110 05 Jun 09 nicklas 568       }
1110 05 Jun 09 nicklas 569       
1128 15 Jun 09 nicklas 570       if (fileParameters.size() > 0)
1128 15 Jun 09 nicklas 571       {
1128 15 Jun 09 nicklas 572         if (parameters.size() > 0)
1128 15 Jun 09 nicklas 573         {
1128 15 Jun 09 nicklas 574           parameters.add(0, new PluginParameter<String>(
1128 15 Jun 09 nicklas 575               "otherSection",
1128 15 Jun 09 nicklas 576               "Other parameters",
1128 15 Jun 09 nicklas 577               "In this section you can specify default values " +
1128 15 Jun 09 nicklas 578               "for all other parameters. The values may be overriden " +
1128 15 Jun 09 nicklas 579               "when used for an actual job.",
1128 15 Jun 09 nicklas 580               null
1128 15 Jun 09 nicklas 581           ));
1128 15 Jun 09 nicklas 582         }
1128 15 Jun 09 nicklas 583         parameters.addAll(0, fileParameters);
1128 15 Jun 09 nicklas 584         parameters.add(0, new PluginParameter<String>(
1128 15 Jun 09 nicklas 585             "filesSection",
1128 15 Jun 09 nicklas 586             "Input files",
1128 15 Jun 09 nicklas 587             "For each input file you can specify a file type " +
1128 15 Jun 09 nicklas 588             "which makes it possible for BASE to generate a sensible " +
1128 15 Jun 09 nicklas 589             "default value or automatically export a file with the data.",
1128 15 Jun 09 nicklas 590             null
1128 15 Jun 09 nicklas 591           ));
1128 15 Jun 09 nicklas 592       }
1128 15 Jun 09 nicklas 593       
1110 05 Jun 09 nicklas 594       configureGpParameters = new RequestInformation(
1110 05 Jun 09 nicklas 595         CONFIGURE_GP_PARAMETERS,
1128 15 Jun 09 nicklas 596         "Files and default parameters values",
1110 05 Jun 09 nicklas 597         "Set default values for the parameters that " +
1110 05 Jun 09 nicklas 598         "are required by this module/pipeline.",
1110 05 Jun 09 nicklas 599         parameters
1110 05 Jun 09 nicklas 600       );
1110 05 Jun 09 nicklas 601       
1110 05 Jun 09 nicklas 602       
1110 05 Jun 09 nicklas 603     }
1110 05 Jun 09 nicklas 604     catch (WebServiceException ex)
1110 05 Jun 09 nicklas 605     {
1110 05 Jun 09 nicklas 606       throw new RuntimeException(ex);
1110 05 Jun 09 nicklas 607     }
1110 05 Jun 09 nicklas 608     return configureGpParameters;    
1110 05 Jun 09 nicklas 609   }
1110 05 Jun 09 nicklas 610   
1110 05 Jun 09 nicklas 611   protected PluginParameter<String> getGPServerParameter(String description)
1110 05 Jun 09 nicklas 612   {
1110 05 Jun 09 nicklas 613     String presetsXml = sc.getUserDefaultSetting("net.sf.basedb.genepattern.options");
1110 05 Jun 09 nicklas 614     Presets presets = new Presets();
1110 05 Jun 09 nicklas 615     if (presetsXml != null) presets.loadFrom(presetsXml);
1110 05 Jun 09 nicklas 616     List<String> servers = new ArrayList<String>();
1110 05 Jun 09 nicklas 617     for (Presets.Preset server : presets)
1110 05 Jun 09 nicklas 618     {
1110 05 Jun 09 nicklas 619       servers.add(server.getName());
1110 05 Jun 09 nicklas 620     }
1110 05 Jun 09 nicklas 621     return new PluginParameter<String>(
1110 05 Jun 09 nicklas 622       "gpServer",
1110 05 Jun 09 nicklas 623       "GenePattern server",
1110 05 Jun 09 nicklas 624       description,
1110 05 Jun 09 nicklas 625       new StringParameterType(255, null, true, 1, 0, 0, servers)
1110 05 Jun 09 nicklas 626     );
1110 05 Jun 09 nicklas 627   }
1110 05 Jun 09 nicklas 628   
1110 05 Jun 09 nicklas 629   
1110 05 Jun 09 nicklas 630 }