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

Code
Comments
Other
Rev Date Author Line
5777 06 Dec 19 nicklas 1 package net.sf.basedb.reggie.plugins;
5777 06 Dec 19 nicklas 2
5777 06 Dec 19 nicklas 3 import java.io.InputStream;
5777 06 Dec 19 nicklas 4 import java.util.ArrayList;
5777 06 Dec 19 nicklas 5 import java.util.Arrays;
5777 06 Dec 19 nicklas 6 import java.util.Collections;
5777 06 Dec 19 nicklas 7 import java.util.List;
5777 06 Dec 19 nicklas 8 import java.util.Set;
5777 06 Dec 19 nicklas 9
5777 06 Dec 19 nicklas 10 import net.sf.basedb.core.BaseException;
5777 06 Dec 19 nicklas 11 import net.sf.basedb.core.DbControl;
5777 06 Dec 19 nicklas 12 import net.sf.basedb.core.File;
5777 06 Dec 19 nicklas 13 import net.sf.basedb.core.InvalidDataException;
5777 06 Dec 19 nicklas 14 import net.sf.basedb.core.Item;
5777 06 Dec 19 nicklas 15 import net.sf.basedb.core.ItemNotFoundException;
5777 06 Dec 19 nicklas 16 import net.sf.basedb.core.ItemQuery;
5777 06 Dec 19 nicklas 17 import net.sf.basedb.core.Job;
5777 06 Dec 19 nicklas 18 import net.sf.basedb.core.PluginParameter;
5777 06 Dec 19 nicklas 19 import net.sf.basedb.core.RequestInformation;
5777 06 Dec 19 nicklas 20 import net.sf.basedb.core.Sample;
5777 06 Dec 19 nicklas 21 import net.sf.basedb.core.StringParameterType;
5806 09 Jan 20 nicklas 22 import net.sf.basedb.core.Type;
5777 06 Dec 19 nicklas 23 import net.sf.basedb.core.plugin.GuiContext;
5777 06 Dec 19 nicklas 24 import net.sf.basedb.core.plugin.InteractivePlugin;
5777 06 Dec 19 nicklas 25 import net.sf.basedb.core.plugin.ParameterValues;
5777 06 Dec 19 nicklas 26 import net.sf.basedb.core.plugin.ParameterValuesWrapper;
5777 06 Dec 19 nicklas 27 import net.sf.basedb.core.plugin.Request;
5777 06 Dec 19 nicklas 28 import net.sf.basedb.core.plugin.Response;
5777 06 Dec 19 nicklas 29 import net.sf.basedb.plugins.AbstractFlatFileImporter;
5781 11 Dec 19 nicklas 30 import net.sf.basedb.plugins.batchimport.IdMethod;
5781 11 Dec 19 nicklas 31 import net.sf.basedb.plugins.batchimport.PropertyIdMethod;
5777 06 Dec 19 nicklas 32 import net.sf.basedb.plugins.util.Parameters;
5777 06 Dec 19 nicklas 33 import net.sf.basedb.reggie.Reggie;
5778 09 Dec 19 nicklas 34 import net.sf.basedb.reggie.dao.Annotationtype;
5777 06 Dec 19 nicklas 35 import net.sf.basedb.reggie.dao.Case;
5777 06 Dec 19 nicklas 36 import net.sf.basedb.reggie.dao.ReggieItem;
5777 06 Dec 19 nicklas 37 import net.sf.basedb.reggie.dao.Subtype;
5781 11 Dec 19 nicklas 38 import net.sf.basedb.util.Enumeration;
5777 06 Dec 19 nicklas 39 import net.sf.basedb.util.parser.ConfigureByExample;
5777 06 Dec 19 nicklas 40 import net.sf.basedb.util.parser.FlatFileParser;
5777 06 Dec 19 nicklas 41 import net.sf.basedb.util.parser.Mapper;
5777 06 Dec 19 nicklas 42 import net.sf.basedb.util.parser.FlatFileParser.Data;
5777 06 Dec 19 nicklas 43
5777 06 Dec 19 nicklas 44 /**
5777 06 Dec 19 nicklas 45   Plug-in for importing TMA specimen items in a batch. 
5777 06 Dec 19 nicklas 46   The plug-in will always create new items base on a Case that is referenced
5777 06 Dec 19 nicklas 47   in the file. Child items are named after the case with suffix '.tmaN' where
5777 06 Dec 19 nicklas 48   N is an auto-incrementing counter. If N=1 it is not included in the name (as usual).
5777 06 Dec 19 nicklas 49
5777 06 Dec 19 nicklas 50   @since 4.25
5777 06 Dec 19 nicklas 51 */
5777 06 Dec 19 nicklas 52 public class TMASpecimenImporter
5777 06 Dec 19 nicklas 53   extends AbstractFlatFileImporter
5777 06 Dec 19 nicklas 54   implements InteractivePlugin, ConfigureByExample
5777 06 Dec 19 nicklas 55 {
5777 06 Dec 19 nicklas 56
5777 06 Dec 19 nicklas 57   private static final Set<GuiContext> guiContexts =  
5777 06 Dec 19 nicklas 58     Collections.singleton(new GuiContext(Item.SAMPLE, GuiContext.Type.LIST));
5777 06 Dec 19 nicklas 59
5777 06 Dec 19 nicklas 60   private static final StringParameterType requiredColumnMapping = new StringParameterType(255, null, true);
5779 10 Dec 19 nicklas 61   private static final StringParameterType optionalColumnMapping = new StringParameterType(255, null, false);
5777 06 Dec 19 nicklas 62   
5777 06 Dec 19 nicklas 63   private static final PluginParameter<String> caseColumnMapping = new PluginParameter<String>(
5777 06 Dec 19 nicklas 64       "caseColumnMapping",
5781 11 Dec 19 nicklas 65       "Case ID",
5781 11 Dec 19 nicklas 66       "Mapping that picks the name or external id for the Case from the data columns. This " +
5777 06 Dec 19 nicklas 67       "parameter is required. " +
5781 11 Dec 19 nicklas 68       "Example: \\Case ID\\",
5777 06 Dec 19 nicklas 69       requiredColumnMapping
5777 06 Dec 19 nicklas 70       );
5777 06 Dec 19 nicklas 71
5778 09 Dec 19 nicklas 72   private static final PluginParameter<String> tmaBlockColumnMapping = new PluginParameter<String>(
5778 09 Dec 19 nicklas 73       "tmaBlockColumnMapping",
5778 09 Dec 19 nicklas 74       "TMA Block",
5778 09 Dec 19 nicklas 75       "Mapping that picks the name of the TMA Block on which the specimen is located. This " +
5778 09 Dec 19 nicklas 76       "parameter is required. " +
5778 09 Dec 19 nicklas 77       "Example: \\TMABlock\\",
5778 09 Dec 19 nicklas 78       requiredColumnMapping
5778 09 Dec 19 nicklas 79       );
5777 06 Dec 19 nicklas 80   
5778 09 Dec 19 nicklas 81   private static final PluginParameter<String> tmaBlockPosColumnMapping = new PluginParameter<String>(
5778 09 Dec 19 nicklas 82       "tmaBlockPosColumnMapping",
5778 09 Dec 19 nicklas 83       "TMA Block Position",
5778 09 Dec 19 nicklas 84       "Mapping that picks the position on the TMA block were the specimen is located. This " +
5778 09 Dec 19 nicklas 85       "parameter is required. " +
5778 09 Dec 19 nicklas 86       "Example: \\TMABlockPos\\",
5778 09 Dec 19 nicklas 87       requiredColumnMapping
5778 09 Dec 19 nicklas 88       );
5778 09 Dec 19 nicklas 89   
5778 09 Dec 19 nicklas 90   private static final PluginParameter<String> padColumnMapping = new PluginParameter<String>(
5778 09 Dec 19 nicklas 91       "padColumnMapping",
5778 09 Dec 19 nicklas 92       "PAD",
5799 18 Dec 19 nicklas 93       "Mapping that picks the PAD that was actually used to create the TMA. This " +
5778 09 Dec 19 nicklas 94       "parameter is required. " +
5778 09 Dec 19 nicklas 95       "Example: \\PAD\\",
5778 09 Dec 19 nicklas 96       requiredColumnMapping
5778 09 Dec 19 nicklas 97       );
5799 18 Dec 19 nicklas 98   
5799 18 Dec 19 nicklas 99   private static final PluginParameter<String> padRequestedColumnMapping = new PluginParameter<String>(
5799 18 Dec 19 nicklas 100       "padRequestedColumnMapping",
5799 18 Dec 19 nicklas 101       "PAD Requested",
5799 18 Dec 19 nicklas 102       "Mapping that picks the PAD that was requested when creating the TMA. This " +
5799 18 Dec 19 nicklas 103       "parameter is required. " +
5799 18 Dec 19 nicklas 104       "Example: \\PADRequested\\",
5799 18 Dec 19 nicklas 105       requiredColumnMapping
5799 18 Dec 19 nicklas 106       );
5778 09 Dec 19 nicklas 107
5779 10 Dec 19 nicklas 108   private static final PluginParameter<String> commentColumnMapping = new PluginParameter<String>(
5779 10 Dec 19 nicklas 109       "commentColumnMapping",
5779 10 Dec 19 nicklas 110       "Comment",
5779 10 Dec 19 nicklas 111       "Optional mapping that picks a comment for the TMA. The comment is stored " +
5779 10 Dec 19 nicklas 112       "in the Description field of the specimen. " +
5779 10 Dec 19 nicklas 113       "Example: \\Comment\\",
5779 10 Dec 19 nicklas 114       optionalColumnMapping
5779 10 Dec 19 nicklas 115       );
5779 10 Dec 19 nicklas 116   
5779 10 Dec 19 nicklas 117   
5806 09 Jan 20 nicklas 118   private static final IdMethod SCANB_ID = new PropertyIdMethod("scanbId", "SCAN-B ID", "name", "caseColumnMapping", false, Type.STRING);
5806 09 Jan 20 nicklas 119   private static final IdMethod RELEASE_ID = new PropertyIdMethod("releaseId", "Release ID", "externalId", "caseColumnMapping", false, Type.STRING);
5806 09 Jan 20 nicklas 120   
5777 06 Dec 19 nicklas 121   public TMASpecimenImporter()
5777 06 Dec 19 nicklas 122   {}
5777 06 Dec 19 nicklas 123
5777 06 Dec 19 nicklas 124   /*
5777 06 Dec 19 nicklas 125     From the Plugin interface
5777 06 Dec 19 nicklas 126     -------------------------------------------
5777 06 Dec 19 nicklas 127   */
5777 06 Dec 19 nicklas 128   @Override
5777 06 Dec 19 nicklas 129   public boolean requiresConfiguration()
5777 06 Dec 19 nicklas 130   {
5777 06 Dec 19 nicklas 131     return false;
5777 06 Dec 19 nicklas 132   }
5777 06 Dec 19 nicklas 133   @Override
5777 06 Dec 19 nicklas 134   public boolean supportsConfigurations()
5777 06 Dec 19 nicklas 135   {
5777 06 Dec 19 nicklas 136     return false;
5777 06 Dec 19 nicklas 137   }
5777 06 Dec 19 nicklas 138
5777 06 Dec 19 nicklas 139   /*
5777 06 Dec 19 nicklas 140     From the InteractivePlugin interface
5777 06 Dec 19 nicklas 141     ------------------------------------
5777 06 Dec 19 nicklas 142   */
5777 06 Dec 19 nicklas 143   @Override
5777 06 Dec 19 nicklas 144   public Set<GuiContext> getGuiContexts()
5777 06 Dec 19 nicklas 145   {
5777 06 Dec 19 nicklas 146     return guiContexts;
5777 06 Dec 19 nicklas 147   }
5777 06 Dec 19 nicklas 148   @Override
5777 06 Dec 19 nicklas 149   public String isInContext(GuiContext context, Object item)
5777 06 Dec 19 nicklas 150   {
5777 06 Dec 19 nicklas 151     String message = null;
5777 06 Dec 19 nicklas 152     if (!getGuiContexts().contains(context))
5777 06 Dec 19 nicklas 153     {
5777 06 Dec 19 nicklas 154       message = "This plug-in can't be used in context: " + context;
5777 06 Dec 19 nicklas 155     }
5777 06 Dec 19 nicklas 156     else
5777 06 Dec 19 nicklas 157     {
5777 06 Dec 19 nicklas 158       String subcontext = context.getSubContext();
5777 06 Dec 19 nicklas 159       if (subcontext != null && subcontext.startsWith("listmembers"))
5777 06 Dec 19 nicklas 160       {
5777 06 Dec 19 nicklas 161         message = "This plug-in can't be used in item list context";
5777 06 Dec 19 nicklas 162       }
5777 06 Dec 19 nicklas 163     }
5777 06 Dec 19 nicklas 164     return message;
5777 06 Dec 19 nicklas 165   }  
5777 06 Dec 19 nicklas 166   // ------------------------------------
5777 06 Dec 19 nicklas 167
5781 11 Dec 19 nicklas 168   protected IdMethod[] getIdMethods()
5781 11 Dec 19 nicklas 169   {
5806 09 Jan 20 nicklas 170     return new IdMethod[] { SCANB_ID, RELEASE_ID };
5781 11 Dec 19 nicklas 171   }
5781 11 Dec 19 nicklas 172   
5781 11 Dec 19 nicklas 173   /**
5781 11 Dec 19 nicklas 174     Get the id method to use for finding cases. This implementation 
5781 11 Dec 19 nicklas 175     searches the methods returned by {@link #getIdMethods()} 
5781 11 Dec 19 nicklas 176   */
5781 11 Dec 19 nicklas 177   protected IdMethod getIdMethod(String method)
5781 11 Dec 19 nicklas 178   {
5781 11 Dec 19 nicklas 179     for (IdMethod im : getIdMethods())
5781 11 Dec 19 nicklas 180     {
5781 11 Dec 19 nicklas 181       if (im.getMethod().equals(method))
5781 11 Dec 19 nicklas 182       {
5781 11 Dec 19 nicklas 183         return im;
5781 11 Dec 19 nicklas 184       }
5781 11 Dec 19 nicklas 185     }
5806 09 Jan 20 nicklas 186     return SCANB_ID;
5781 11 Dec 19 nicklas 187   }
5781 11 Dec 19 nicklas 188   
5777 06 Dec 19 nicklas 189   @Override
5777 06 Dec 19 nicklas 190   public RequestInformation getRequestInformation(GuiContext context, String command) 
5777 06 Dec 19 nicklas 191     throws BaseException
5777 06 Dec 19 nicklas 192   {
5777 06 Dec 19 nicklas 193     RequestInformation requestInformation = null;
5777 06 Dec 19 nicklas 194     if (command.equals(Request.COMMAND_CONFIGURE_JOB))
5777 06 Dec 19 nicklas 195     {
5777 06 Dec 19 nicklas 196       requestInformation = getConfigureParserParameters(context);
5777 06 Dec 19 nicklas 197     }
5777 06 Dec 19 nicklas 198     return requestInformation;
5777 06 Dec 19 nicklas 199   }
5777 06 Dec 19 nicklas 200
5777 06 Dec 19 nicklas 201   @Override
5777 06 Dec 19 nicklas 202   public void configure(GuiContext context, Request request, Response response)
5777 06 Dec 19 nicklas 203   {
5777 06 Dec 19 nicklas 204     String command = request.getCommand();
5777 06 Dec 19 nicklas 205     DbControl dc = null;
5777 06 Dec 19 nicklas 206     try
5777 06 Dec 19 nicklas 207     {
5777 06 Dec 19 nicklas 208       if (command.equals(Request.COMMAND_CONFIGURE_JOB))
5777 06 Dec 19 nicklas 209       {
5777 06 Dec 19 nicklas 210         RequestInformation ri = getConfigureParserParameters(context);
5777 06 Dec 19 nicklas 211         List<Throwable> errors = validateRequestParameters(ri.getParameters(), request);
5777 06 Dec 19 nicklas 212         if (errors != null)
5777 06 Dec 19 nicklas 213         {
5777 06 Dec 19 nicklas 214           response.setError(errors.size()+" invalid parameter(s) were found in the request", errors);
5777 06 Dec 19 nicklas 215           return;
5777 06 Dec 19 nicklas 216         }
5777 06 Dec 19 nicklas 217
5777 06 Dec 19 nicklas 218         ParameterValues wrapper = new ParameterValuesWrapper(request, job, configuration, true);
5777 06 Dec 19 nicklas 219         FlatFileParser parser = getInitializedFlatFileParser(wrapper);
5777 06 Dec 19 nicklas 220         File f = (File)request.getParameterValue("file");
5777 06 Dec 19 nicklas 221         InputStream in = f.getDownloadStream(0);
5777 06 Dec 19 nicklas 222         parser.setInputStream(in, getCharset(request));
5777 06 Dec 19 nicklas 223         parser.setDefaultNumberFormat(getNumberFormat());
5777 06 Dec 19 nicklas 224         FlatFileParser.LineType result = parser.parseHeaders();
5777 06 Dec 19 nicklas 225         in.close();
5777 06 Dec 19 nicklas 226         if (result == FlatFileParser.LineType.UNKNOWN)
5777 06 Dec 19 nicklas 227         {
5777 06 Dec 19 nicklas 228           response.setError("The file could not be parsed with the given settings, " +
5777 06 Dec 19 nicklas 229             "no data found after " + parser.getLineCount() + " lines.", null);
5777 06 Dec 19 nicklas 230           return;
5777 06 Dec 19 nicklas 231         }
5781 11 Dec 19 nicklas 232         
5781 11 Dec 19 nicklas 233         // Check that a mapping has been provided for the selected idMethod
5781 11 Dec 19 nicklas 234         IdMethod idMethod = getIdMethod((String)request.getParameterValue("idMethod"));
5781 11 Dec 19 nicklas 235         if (idMethod == null)
5781 11 Dec 19 nicklas 236         {
5781 11 Dec 19 nicklas 237           response.setError("Unknown method for item identification: " + 
5781 11 Dec 19 nicklas 238               request.getParameterValue("idMethod"), null);
5781 11 Dec 19 nicklas 239           return;
5781 11 Dec 19 nicklas 240         }
5777 06 Dec 19 nicklas 241
5777 06 Dec 19 nicklas 242         // Check the mapping expressions
5777 06 Dec 19 nicklas 243         boolean allowComplex = "allow".equals(request.getParameterValue(complexMappings.getName()));
5777 06 Dec 19 nicklas 244         //checkColumnMapping(parser, idMapping, allowComplex, idMappingParameter.getLabel());
5777 06 Dec 19 nicklas 245
5777 06 Dec 19 nicklas 246         // Everything is ok, save values
5777 06 Dec 19 nicklas 247         storeValue(wrapper, request, fileParameter);
5777 06 Dec 19 nicklas 248         storeValue(wrapper, request, ri.getParameter(Parameters.LOGFILE_PARAMETER));
5777 06 Dec 19 nicklas 249         storeValue(wrapper, request, excelSheetParameter);
5798 18 Dec 19 nicklas 250         storeValue(wrapper, request, ri.getParameter("sampleOwner"));
5781 11 Dec 19 nicklas 251         storeValue(wrapper, request, ri.getParameter("idMethod"));
5777 06 Dec 19 nicklas 252
5777 06 Dec 19 nicklas 253         storeValue(wrapper, request, dataHeaderRegexpParameter);
5777 06 Dec 19 nicklas 254         storeValue(wrapper, request, dataSplitterRegexpParameter);
5777 06 Dec 19 nicklas 255         storeValue(wrapper, request, trimQuotesParameter);
5777 06 Dec 19 nicklas 256         storeValue(wrapper, request, ignoreRegexpParameter);
5777 06 Dec 19 nicklas 257         storeValue(wrapper, request, dataFooterRegexpParameter);
5777 06 Dec 19 nicklas 258         storeValue(wrapper, request, minDataColumnsParameter);
5777 06 Dec 19 nicklas 259         storeValue(wrapper, request, maxDataColumnsParameter);
5777 06 Dec 19 nicklas 260         storeValue(wrapper, request, ri.getParameter(Parameters.CHARSET_PARAMETER));
5777 06 Dec 19 nicklas 261         
5777 06 Dec 19 nicklas 262         // Column mappings
5777 06 Dec 19 nicklas 263         storeValue(wrapper, request, complexMappings);
5777 06 Dec 19 nicklas 264         storeValue(wrapper, request, caseColumnMapping);
5778 09 Dec 19 nicklas 265         storeValue(wrapper, request, tmaBlockColumnMapping);
5778 09 Dec 19 nicklas 266         storeValue(wrapper, request, tmaBlockPosColumnMapping);
5778 09 Dec 19 nicklas 267         storeValue(wrapper, request, padColumnMapping);
5799 18 Dec 19 nicklas 268         storeValue(wrapper, request, padRequestedColumnMapping);
5779 10 Dec 19 nicklas 269         storeValue(wrapper, request, commentColumnMapping);
5777 06 Dec 19 nicklas 270         
5777 06 Dec 19 nicklas 271         response.setDryRun(Boolean.TRUE.equals(request.getParameterValue(Parameters.DRY_RUN_PARAMETER)));
5777 06 Dec 19 nicklas 272         File file = (File)job.getValue("file");
5777 06 Dec 19 nicklas 273         response.setSuggestedJobName("Import TMA Specimen from file '" + file.getName() + "'");
5777 06 Dec 19 nicklas 274         response.setDone("Job configuration complete", Job.ExecutionTime.SHORT);    
5777 06 Dec 19 nicklas 275
5777 06 Dec 19 nicklas 276       }
5777 06 Dec 19 nicklas 277     }
5777 06 Dec 19 nicklas 278     catch (Throwable ex)
5777 06 Dec 19 nicklas 279     {
5777 06 Dec 19 nicklas 280       response.setError(ex.getMessage(), Arrays.asList(ex));
5777 06 Dec 19 nicklas 281     }
5777 06 Dec 19 nicklas 282     finally
5777 06 Dec 19 nicklas 283     {
5777 06 Dec 19 nicklas 284       if (dc != null) dc.close();
5777 06 Dec 19 nicklas 285     }
5777 06 Dec 19 nicklas 286   }
5777 06 Dec 19 nicklas 287   
5777 06 Dec 19 nicklas 288   private DbControl dc;
5777 06 Dec 19 nicklas 289   private FlatFileParser ffp;
5781 11 Dec 19 nicklas 290   private IdMethod idMethod;
5777 06 Dec 19 nicklas 291   private ItemQuery<Sample> caseQuery;
5777 06 Dec 19 nicklas 292   private Mapper caseMapper;
5778 09 Dec 19 nicklas 293   private Mapper tmaBlockMapper;
5778 09 Dec 19 nicklas 294   private Mapper tmaBlockPosMapper;
5778 09 Dec 19 nicklas 295   private Mapper padMapper;
5799 18 Dec 19 nicklas 296   private Mapper padRequestedMapper;
5779 10 Dec 19 nicklas 297   private Mapper commentMapper;
5777 06 Dec 19 nicklas 298   private String lastTMA_XId;
5798 18 Dec 19 nicklas 299   private String sampleOwner;
5777 06 Dec 19 nicklas 300   
5777 06 Dec 19 nicklas 301   private boolean dryRun;  
5777 06 Dec 19 nicklas 302   private int numCreated;
5777 06 Dec 19 nicklas 303
5777 06 Dec 19 nicklas 304   @Override
5777 06 Dec 19 nicklas 305   protected void begin(FlatFileParser ffp)
5777 06 Dec 19 nicklas 306   {
5777 06 Dec 19 nicklas 307     this.ffp = ffp;
5777 06 Dec 19 nicklas 308     this.dc = sc.newDbControl();
5777 06 Dec 19 nicklas 309     this.dryRun = job.getJob().isDryRun();
5781 11 Dec 19 nicklas 310     this.idMethod = getIdMethod(job.getValue("idMethod"));
5798 18 Dec 19 nicklas 311     this.sampleOwner = job.getValue("sampleOwner");
5777 06 Dec 19 nicklas 312     this.caseQuery = Sample.getQuery();
5777 06 Dec 19 nicklas 313     Subtype.CASE.addFilter(dc, caseQuery);
5777 06 Dec 19 nicklas 314     caseQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
5781 11 Dec 19 nicklas 315     idMethod.prepareQuery(dc, caseQuery);
5777 06 Dec 19 nicklas 316     if (ffp.getExcelSheet() != null)
5777 06 Dec 19 nicklas 317     {
5777 06 Dec 19 nicklas 318       log("Parsing from Excel sheet: " + ffp.getExcelSheet());
5777 06 Dec 19 nicklas 319     }
5777 06 Dec 19 nicklas 320   }
5777 06 Dec 19 nicklas 321   
5777 06 Dec 19 nicklas 322   @Override
5777 06 Dec 19 nicklas 323   protected void beginData()
5777 06 Dec 19 nicklas 324   {
5781 11 Dec 19 nicklas 325     caseMapper = NotNullMapper.wrap("Case ID is null", getMapper(ffp, job.getValue("caseColumnMapping"), null, null));
5779 10 Dec 19 nicklas 326     tmaBlockMapper = NotNullMapper.wrap("TMABlock is null", getMapper(ffp, job.getValue("tmaBlockColumnMapping"), null, null));
5779 10 Dec 19 nicklas 327     tmaBlockPosMapper = NotNullMapper.wrap("TMABlockPos is null", getMapper(ffp, job.getValue("tmaBlockPosColumnMapping"), null, null));
5779 10 Dec 19 nicklas 328     padMapper = NotNullMapper.wrap("PAD is null", getMapper(ffp, job.getValue("padColumnMapping"), null, null));
5799 18 Dec 19 nicklas 329     padRequestedMapper = NotNullMapper.wrap("PADRequested is null", getMapper(ffp, job.getValue("padRequestedColumnMapping"), null, null));
5779 10 Dec 19 nicklas 330     commentMapper = getMapper(ffp, job.getValue("commentColumnMapping"), null, null);
5777 06 Dec 19 nicklas 331     numCreated = 0;
5777 06 Dec 19 nicklas 332   }
5777 06 Dec 19 nicklas 333   
5777 06 Dec 19 nicklas 334   @Override
5777 06 Dec 19 nicklas 335   protected void handleData(Data data) 
5777 06 Dec 19 nicklas 336     throws BaseException
5777 06 Dec 19 nicklas 337   {
5781 11 Dec 19 nicklas 338     String caseId = caseMapper.getString(data);
5781 11 Dec 19 nicklas 339     List<Sample> cases = idMethod.find(dc, caseQuery, caseId);
5777 06 Dec 19 nicklas 340     if (cases.size() > 1)
5777 06 Dec 19 nicklas 341     {
5781 11 Dec 19 nicklas 342       throw new InvalidDataException("Found " + cases.size() + " cases [" + idMethod + "=" + caseId + "]");
5777 06 Dec 19 nicklas 343     }
5777 06 Dec 19 nicklas 344     else if (cases.size() == 0)
5777 06 Dec 19 nicklas 345     {
5781 11 Dec 19 nicklas 346       throw new ItemNotFoundException("Case[" + idMethod + "=" + caseId + "]");
5777 06 Dec 19 nicklas 347     }
5777 06 Dec 19 nicklas 348
5778 09 Dec 19 nicklas 349     Sample theCase = cases.get(0);
5778 09 Dec 19 nicklas 350     Case c = Case.get(theCase);
5778 09 Dec 19 nicklas 351     String tmaName = c.getNextTMASpecimenName(dc);
5777 06 Dec 19 nicklas 352     if (lastTMA_XId == null)
5777 06 Dec 19 nicklas 353     {
5777 06 Dec 19 nicklas 354       // The first new external id is generated from what is already in the database
5777 06 Dec 19 nicklas 355       lastTMA_XId = ReggieItem.getNextExternalId(dc, Sample.getQuery(), Subtype.TMA_SPECIMEN.getExternalIdPrefix());
5777 06 Dec 19 nicklas 356     }
5777 06 Dec 19 nicklas 357     else
5777 06 Dec 19 nicklas 358     {
5777 06 Dec 19 nicklas 359       // After that we simply use the last id to get a new one
5777 06 Dec 19 nicklas 360       lastTMA_XId = ReggieItem.getNextExternalId(dc, lastTMA_XId);
5777 06 Dec 19 nicklas 361     }
5777 06 Dec 19 nicklas 362     
5777 06 Dec 19 nicklas 363     Sample tmaSpecimen = Sample.getNew(dc);
5777 06 Dec 19 nicklas 364     tmaSpecimen.setItemSubtype(Subtype.TMA_SPECIMEN.get(dc));
5777 06 Dec 19 nicklas 365     tmaSpecimen.setName(tmaName);
5777 06 Dec 19 nicklas 366     tmaSpecimen.setExternalId(lastTMA_XId);
5778 09 Dec 19 nicklas 367     tmaSpecimen.getCreationEvent().setSource(theCase);
5779 10 Dec 19 nicklas 368     if (commentMapper != null) tmaSpecimen.setDescription(commentMapper.getString(data));
5777 06 Dec 19 nicklas 369     dc.saveItem(tmaSpecimen);
5777 06 Dec 19 nicklas 370     
5778 09 Dec 19 nicklas 371     Annotationtype.TMA_BLOCK.setAnnotationValue(dc, tmaSpecimen, tmaBlockMapper.getString(data));
5778 09 Dec 19 nicklas 372     Annotationtype.TMA_BLOCK_POS.setAnnotationValue(dc, tmaSpecimen, tmaBlockPosMapper.getString(data));
5778 09 Dec 19 nicklas 373     Annotationtype.PAD.setAnnotationValue(dc, tmaSpecimen, padMapper.getString(data));
5799 18 Dec 19 nicklas 374     Annotationtype.PAD_REQUESTED.setAnnotationValue(dc, tmaSpecimen, padRequestedMapper.getString(data));
5798 18 Dec 19 nicklas 375     Annotationtype.SAMPLE_OWNER.setAnnotationValue(dc, tmaSpecimen, sampleOwner);
5778 09 Dec 19 nicklas 376     
5777 06 Dec 19 nicklas 377     numCreated++;
5777 06 Dec 19 nicklas 378     log(numCreated + ": Created TMA specimen: " + tmaSpecimen.getName() + "; " + tmaSpecimen.getExternalId());
5777 06 Dec 19 nicklas 379   }
5777 06 Dec 19 nicklas 380   
5777 06 Dec 19 nicklas 381   
5777 06 Dec 19 nicklas 382   @Override
5777 06 Dec 19 nicklas 383   protected void end(boolean success)
5777 06 Dec 19 nicklas 384   {
5777 06 Dec 19 nicklas 385     try
5777 06 Dec 19 nicklas 386     {
5777 06 Dec 19 nicklas 387       if (success)
5777 06 Dec 19 nicklas 388       {
5777 06 Dec 19 nicklas 389         // Commit if it is not a dry-run
5777 06 Dec 19 nicklas 390         if (!dryRun) dc.commit();
5777 06 Dec 19 nicklas 391       }
5777 06 Dec 19 nicklas 392     }
5777 06 Dec 19 nicklas 393     catch (BaseException ex)
5777 06 Dec 19 nicklas 394     {
5777 06 Dec 19 nicklas 395       success = false;
5777 06 Dec 19 nicklas 396       throw ex;
5777 06 Dec 19 nicklas 397     }
5777 06 Dec 19 nicklas 398     finally
5777 06 Dec 19 nicklas 399     {
5777 06 Dec 19 nicklas 400       if (dc != null) dc.close();
5777 06 Dec 19 nicklas 401       super.end(success);
5777 06 Dec 19 nicklas 402     }
5777 06 Dec 19 nicklas 403   }
5777 06 Dec 19 nicklas 404
5777 06 Dec 19 nicklas 405   @Override
5777 06 Dec 19 nicklas 406   protected String getSuccessMessage(int skippedLines)
5777 06 Dec 19 nicklas 407   {
5777 06 Dec 19 nicklas 408     String msg = "Parsed " + ffp.getParsedLines() + " lines";
5777 06 Dec 19 nicklas 409     if (numCreated > 0) msg += "; " + numCreated + " TMA specimen created";
5777 06 Dec 19 nicklas 410     return msg;
5777 06 Dec 19 nicklas 411   }
5777 06 Dec 19 nicklas 412
5777 06 Dec 19 nicklas 413   private RequestInformation configureParser;
5777 06 Dec 19 nicklas 414   private RequestInformation getConfigureParserParameters(GuiContext context)
5777 06 Dec 19 nicklas 415   {
5777 06 Dec 19 nicklas 416     if (configureParser == null)
5777 06 Dec 19 nicklas 417     {
5777 06 Dec 19 nicklas 418       DbControl dc = null;
5777 06 Dec 19 nicklas 419       try
5777 06 Dec 19 nicklas 420       {
5777 06 Dec 19 nicklas 421         dc = sc.newDbControl();
5777 06 Dec 19 nicklas 422         List<PluginParameter<?>> parameters = new ArrayList<PluginParameter<?>>();
5777 06 Dec 19 nicklas 423   
5777 06 Dec 19 nicklas 424         
5777 06 Dec 19 nicklas 425         // The file to import from
5777 06 Dec 19 nicklas 426         parameters.add(fileParameter);
5777 06 Dec 19 nicklas 427         parameters.add(excelSheetParameter);
5777 06 Dec 19 nicklas 428
5777 06 Dec 19 nicklas 429         parameters.add(Parameters.logFileParameter(null, null, null));
5777 06 Dec 19 nicklas 430         parameters.add(Parameters.dryRunParameter(null, null, null));
5777 06 Dec 19 nicklas 431         
5798 18 Dec 19 nicklas 432         parameters.add(new PluginParameter<>("sampleOwner", "Sample owner", 
5798 18 Dec 19 nicklas 433           "Name of PI or other external entity that is the owner of TMA samples.", 
5798 18 Dec 19 nicklas 434           new StringParameterType(255, null, true)));
5798 18 Dec 19 nicklas 435         
5781 11 Dec 19 nicklas 436         Enumeration<String, String> idMethods = new Enumeration<String, String>();
5781 11 Dec 19 nicklas 437         idMethods.add(null, null);
5806 09 Jan 20 nicklas 438         idMethods.add(SCANB_ID.getMethod(), SCANB_ID.getTitle());
5806 09 Jan 20 nicklas 439         idMethods.add(RELEASE_ID.getMethod(), RELEASE_ID.getTitle());
5781 11 Dec 19 nicklas 440         PluginParameter<String> idMethodParameter = new PluginParameter<String>(
5781 11 Dec 19 nicklas 441           "idMethod",
5781 11 Dec 19 nicklas 442           "Case identification method",
5781 11 Dec 19 nicklas 443           "The method to use for finding existing cases. The plug-in can use either the " +
5781 11 Dec 19 nicklas 444           "SCAN-B ID or the Release ID.",
5798 18 Dec 19 nicklas 445           new StringParameterType(255, null, true, 1, 0, 0, idMethods)
5781 11 Dec 19 nicklas 446         );
5781 11 Dec 19 nicklas 447         parameters.add(idMethodParameter);
5781 11 Dec 19 nicklas 448
5781 11 Dec 19 nicklas 449         
5777 06 Dec 19 nicklas 450         // Parser regular expressions
5777 06 Dec 19 nicklas 451         parameters.add(parserSection);
5777 06 Dec 19 nicklas 452         parameters.add(dataHeaderRegexpParameter);
5777 06 Dec 19 nicklas 453         parameters.add(dataSplitterRegexpParameter);
5777 06 Dec 19 nicklas 454         parameters.add(trimQuotesParameter);
5777 06 Dec 19 nicklas 455         parameters.add(ignoreRegexpParameter);
5777 06 Dec 19 nicklas 456         parameters.add(dataFooterRegexpParameter);
5777 06 Dec 19 nicklas 457         parameters.add(minDataColumnsParameter);
5777 06 Dec 19 nicklas 458         parameters.add(maxDataColumnsParameter);
5777 06 Dec 19 nicklas 459         parameters.add(Parameters.charsetParameter(null, null, getCharset(), true));
5777 06 Dec 19 nicklas 460         
5777 06 Dec 19 nicklas 461         // Mappings for Name and External ID
5777 06 Dec 19 nicklas 462         parameters.add(mappingSection);
5777 06 Dec 19 nicklas 463         parameters.add(complexMappings);
5777 06 Dec 19 nicklas 464         parameters.add(caseColumnMapping);
5778 09 Dec 19 nicklas 465         parameters.add(tmaBlockColumnMapping);
5778 09 Dec 19 nicklas 466         parameters.add(tmaBlockPosColumnMapping);
5778 09 Dec 19 nicklas 467         parameters.add(padColumnMapping);
5799 18 Dec 19 nicklas 468         parameters.add(padRequestedColumnMapping);
5779 10 Dec 19 nicklas 469         parameters.add(commentColumnMapping);
5777 06 Dec 19 nicklas 470         
5777 06 Dec 19 nicklas 471         configureParser = new RequestInformation
5777 06 Dec 19 nicklas 472         (
5777 06 Dec 19 nicklas 473           Request.COMMAND_CONFIGURE_JOB,
5777 06 Dec 19 nicklas 474           "Select the file that contains data for the TMA Specimen",
5777 06 Dec 19 nicklas 475           "Here you select which file to import from, and the " +
5777 06 Dec 19 nicklas 476           "regular expressions and other settings used to parse it.",
5777 06 Dec 19 nicklas 477           parameters
5777 06 Dec 19 nicklas 478         );
5777 06 Dec 19 nicklas 479       }
5777 06 Dec 19 nicklas 480       finally
5777 06 Dec 19 nicklas 481       {
5777 06 Dec 19 nicklas 482         if (dc != null) dc.close();
5777 06 Dec 19 nicklas 483       }
5777 06 Dec 19 nicklas 484     }
5777 06 Dec 19 nicklas 485     return configureParser;
5777 06 Dec 19 nicklas 486   }  
5777 06 Dec 19 nicklas 487
5777 06 Dec 19 nicklas 488 }