extensions/net.sf.basedb.meludi/trunk/src/net/sf/basedb/meludi/servlet/SpecimenTubeServlet.java

Code
Comments
Other
Rev Date Author Line
2933 14 Nov 14 olle 1 package net.sf.basedb.meludi.servlet;
2933 14 Nov 14 olle 2
2933 14 Nov 14 olle 3 import java.io.IOException;
2933 14 Nov 14 olle 4 import java.text.SimpleDateFormat;
2933 14 Nov 14 olle 5 import java.util.ArrayList;
2933 14 Nov 14 olle 6 import java.util.Date;
3478 03 Sep 15 olle 7 import java.util.HashMap;
2933 14 Nov 14 olle 8 import java.util.List;
2933 14 Nov 14 olle 9
2933 14 Nov 14 olle 10 import javax.servlet.ServletException;
2933 14 Nov 14 olle 11 import javax.servlet.http.HttpServlet;
2933 14 Nov 14 olle 12 import javax.servlet.http.HttpServletRequest;
2933 14 Nov 14 olle 13 import javax.servlet.http.HttpServletResponse;
2933 14 Nov 14 olle 14
3028 11 Dec 14 olle 15 import net.sf.basedb.core.Annotatable;
2933 14 Nov 14 olle 16 import net.sf.basedb.core.Application;
2933 14 Nov 14 olle 17 import net.sf.basedb.core.BioMaterialEvent;
2933 14 Nov 14 olle 18 import net.sf.basedb.core.BioPlate;
3478 03 Sep 15 olle 19 import net.sf.basedb.core.BioPlateType;
2933 14 Nov 14 olle 20 import net.sf.basedb.core.BioWell;
2933 14 Nov 14 olle 21 import net.sf.basedb.core.DbControl;
3028 11 Dec 14 olle 22 import net.sf.basedb.core.Extract;
2933 14 Nov 14 olle 23 import net.sf.basedb.core.InvalidDataException;
2933 14 Nov 14 olle 24 import net.sf.basedb.core.ItemQuery;
3478 03 Sep 15 olle 25 import net.sf.basedb.core.ItemResultList;
4198 31 Oct 16 olle 26 import net.sf.basedb.core.PermissionDeniedException;
3478 03 Sep 15 olle 27 import net.sf.basedb.core.PlateGeometry;
2933 14 Nov 14 olle 28 import net.sf.basedb.core.Sample;
2933 14 Nov 14 olle 29 import net.sf.basedb.core.SessionControl;
2933 14 Nov 14 olle 30 import net.sf.basedb.core.query.Expressions;
2933 14 Nov 14 olle 31 import net.sf.basedb.core.query.Hql;
2933 14 Nov 14 olle 32 import net.sf.basedb.core.query.Orders;
2933 14 Nov 14 olle 33 import net.sf.basedb.core.query.Restrictions;
2933 14 Nov 14 olle 34 import net.sf.basedb.core.snapshot.SnapshotManager;
2933 14 Nov 14 olle 35 import net.sf.basedb.meludi.JsonUtil;
4147 03 Oct 16 olle 36 import net.sf.basedb.meludi.Meludi;
2933 14 Nov 14 olle 37 import net.sf.basedb.meludi.Site;
2933 14 Nov 14 olle 38 import net.sf.basedb.meludi.converter.StringToDateConverter;
2933 14 Nov 14 olle 39 import net.sf.basedb.meludi.dao.Annotationtype;
2933 14 Nov 14 olle 40 import net.sf.basedb.meludi.dao.Case;
3104 23 Jan 15 olle 41 import net.sf.basedb.meludi.dao.Dna;
2933 14 Nov 14 olle 42 import net.sf.basedb.meludi.dao.MeludiRole;
3104 23 Jan 15 olle 43 import net.sf.basedb.meludi.dao.Rna;
2933 14 Nov 14 olle 44 import net.sf.basedb.meludi.dao.SpecimenTube;
2933 14 Nov 14 olle 45 import net.sf.basedb.meludi.dao.StoragePlate;
2933 14 Nov 14 olle 46 import net.sf.basedb.meludi.dao.Subtype;
3101 21 Jan 15 olle 47 import net.sf.basedb.meludi.counter.CounterService;
2933 14 Nov 14 olle 48 import net.sf.basedb.util.Values;
2933 14 Nov 14 olle 49 import net.sf.basedb.util.error.ThrowableUtil;
2933 14 Nov 14 olle 50 import net.sf.basedb.util.formatter.WellCoordinateFormatter;
2933 14 Nov 14 olle 51
2933 14 Nov 14 olle 52 import org.json.simple.JSONArray;
2933 14 Nov 14 olle 53 import org.json.simple.JSONObject;
2933 14 Nov 14 olle 54 import org.json.simple.parser.JSONParser;
2933 14 Nov 14 olle 55
2933 14 Nov 14 olle 56
2933 14 Nov 14 olle 57 public class SpecimenTubeServlet 
2933 14 Nov 14 olle 58   extends HttpServlet 
2933 14 Nov 14 olle 59 {  
2933 14 Nov 14 olle 60   private static final long serialVersionUID = -8107161732923753803L;
2933 14 Nov 14 olle 61
2933 14 Nov 14 olle 62   public SpecimenTubeServlet()
2933 14 Nov 14 olle 63   {}
2933 14 Nov 14 olle 64   
2933 14 Nov 14 olle 65   @SuppressWarnings("unchecked")
2933 14 Nov 14 olle 66   @Override
2933 14 Nov 14 olle 67   protected void doGet(HttpServletRequest req, HttpServletResponse resp)
2933 14 Nov 14 olle 68     throws ServletException, IOException 
2933 14 Nov 14 olle 69   {
2933 14 Nov 14 olle 70     String ID = req.getParameter("ID");
2933 14 Nov 14 olle 71     String cmd = req.getParameter("cmd");
2933 14 Nov 14 olle 72     JsonUtil.setJsonResponseHeaders(resp);
2933 14 Nov 14 olle 73     
2933 14 Nov 14 olle 74     JSONObject json = new JSONObject();
2933 14 Nov 14 olle 75     json.put("status", "ok");
2933 14 Nov 14 olle 76     
5468 04 Jun 19 olle 77     //final SessionControl sc = Application.getSessionControl(ID, req.getRemoteAddr());
5744 20 Nov 19 olle 78     //final SessionControl sc  = Application.getSessionControl(ID, "", req.getRemoteAddr(), true);
5744 20 Nov 19 olle 79     final SessionControl sc  = Application.getSessionControl(ID, null, req.getRemoteAddr(), true);
2933 14 Nov 14 olle 80     DbControl dc = null;
2933 14 Nov 14 olle 81     try
2933 14 Nov 14 olle 82     {
3412 22 Jun 15 olle 83       if ("GetExtraMaterialInfo".equals(cmd))
2933 14 Nov 14 olle 84       {
2933 14 Nov 14 olle 85         dc = sc.newDbControl();
2933 14 Nov 14 olle 86         
3412 22 Jun 15 olle 87         String index = req.getParameter("index");
3412 22 Jun 15 olle 88         String name = req.getParameter("name");
3412 22 Jun 15 olle 89         String type = req.getParameter("type");
3412 22 Jun 15 olle 90         String oldName = req.getParameter("oldName");
3412 22 Jun 15 olle 91
3412 22 Jun 15 olle 92         JSONObject jsonEm = new JSONObject();
3412 22 Jun 15 olle 93         jsonEm.put("index", index);
3412 22 Jun 15 olle 94         jsonEm.put("name", name);
3412 22 Jun 15 olle 95         jsonEm.put("type", type);
3412 22 Jun 15 olle 96         jsonEm.put("oldName", oldName);
3412 22 Jun 15 olle 97
3412 22 Jun 15 olle 98         int nofSpecimen = 0;
3412 22 Jun 15 olle 99         int nofDna = 0;
3412 22 Jun 15 olle 100         int nofRna = 0;
3412 22 Jun 15 olle 101         int highestSpecimenNumber = 0;
3412 22 Jun 15 olle 102         int oldNameHighestSpecimenNumber = 0;
3412 22 Jun 15 olle 103         if (type != null && type.equals("Specimen"))
3412 22 Jun 15 olle 104         {
3412 22 Jun 15 olle 105           // Get a list of already existing specimens with same name, excluding suffix "." plus number
3412 22 Jun 15 olle 106           List<SpecimenTube> specimenTubes = SpecimenTube.findByBaseName(dc, name);
3412 22 Jun 15 olle 107           nofSpecimen = specimenTubes.size();
3412 22 Jun 15 olle 108           if (specimenTubes.size() > 0)
3412 22 Jun 15 olle 109           {
3412 22 Jun 15 olle 110             // Found specimens are sorted in ascending order by name
3412 22 Jun 15 olle 111             SpecimenTube specimenWithHighestNumber = (SpecimenTube) specimenTubes.get(specimenTubes.size() - 1);
3412 22 Jun 15 olle 112             String highestNumberName = specimenWithHighestNumber.getName();
3412 22 Jun 15 olle 113             int lastDotIndex = highestNumberName.lastIndexOf(".");
3412 22 Jun 15 olle 114             String highestNumberAsString = null;
3412 22 Jun 15 olle 115             if (lastDotIndex > -1)
3412 22 Jun 15 olle 116             {
3412 22 Jun 15 olle 117               highestNumberAsString = highestNumberName.substring(lastDotIndex + 1);
3412 22 Jun 15 olle 118             }
3412 22 Jun 15 olle 119             if (highestNumberAsString != null && !highestNumberAsString.equals(""))
3412 22 Jun 15 olle 120             {
3412 22 Jun 15 olle 121               highestSpecimenNumber = Integer.parseInt(highestNumberAsString);
3412 22 Jun 15 olle 122             }
3412 22 Jun 15 olle 123           }
3412 22 Jun 15 olle 124         }
3412 22 Jun 15 olle 125         else if (type != null && type.equals("DNA"))
3412 22 Jun 15 olle 126         {
3412 22 Jun 15 olle 127           // Check if any DNA extract already exist
3412 22 Jun 15 olle 128           Dna dna = Dna.findByName(dc, name+".d");
3412 22 Jun 15 olle 129           if (dna != null)
3412 22 Jun 15 olle 130           {
3412 22 Jun 15 olle 131             nofDna = 1;
3412 22 Jun 15 olle 132           }
3412 22 Jun 15 olle 133         }
3412 22 Jun 15 olle 134         else if (type != null && type.equals("RNA"))
3412 22 Jun 15 olle 135         {
3412 22 Jun 15 olle 136           // Check if any RNA extract already exist
3412 22 Jun 15 olle 137           Rna rna = Rna.findByName(dc, name+".r");
3412 22 Jun 15 olle 138           if (rna != null)
3412 22 Jun 15 olle 139           {
3412 22 Jun 15 olle 140             nofRna = 1;
3412 22 Jun 15 olle 141           }
3412 22 Jun 15 olle 142         }
3412 22 Jun 15 olle 143         // Get a list of already existing specimens with same old name, excluding suffix "." plus number
3412 22 Jun 15 olle 144         List<SpecimenTube> specimenTubes2 = SpecimenTube.findByBaseName(dc, oldName);
3412 22 Jun 15 olle 145         int nofSpecimen2 = specimenTubes2.size();
3412 22 Jun 15 olle 146         if (specimenTubes2.size() > 0)
3412 22 Jun 15 olle 147         {
3412 22 Jun 15 olle 148           // Found specimens are sorted in ascending order by name
3412 22 Jun 15 olle 149           SpecimenTube specimenWithHighestNumber = (SpecimenTube) specimenTubes2.get(specimenTubes2.size() - 1);
3412 22 Jun 15 olle 150           String oldNameHighestNumberName = specimenWithHighestNumber.getName();
3412 22 Jun 15 olle 151           int lastDotIndex = oldNameHighestNumberName.lastIndexOf(".");
3412 22 Jun 15 olle 152           String oldNameHighestNumberAsString = null;
3412 22 Jun 15 olle 153           if (lastDotIndex > -1)
3412 22 Jun 15 olle 154           {
3412 22 Jun 15 olle 155             oldNameHighestNumberAsString = oldNameHighestNumberName.substring(lastDotIndex + 1);
3412 22 Jun 15 olle 156           }
3412 22 Jun 15 olle 157           if (oldNameHighestNumberAsString != null && !oldNameHighestNumberAsString.equals(""))
3412 22 Jun 15 olle 158           {
3412 22 Jun 15 olle 159             oldNameHighestSpecimenNumber = Integer.parseInt(oldNameHighestNumberAsString);
3412 22 Jun 15 olle 160           }
3412 22 Jun 15 olle 161         }
3412 22 Jun 15 olle 162         jsonEm.put("nofSpecimen", nofSpecimen);
3412 22 Jun 15 olle 163         jsonEm.put("nofDna", nofDna);
3412 22 Jun 15 olle 164         jsonEm.put("nofRna", nofRna);
3412 22 Jun 15 olle 165         jsonEm.put("highestSpecimenNumber", highestSpecimenNumber);
3412 22 Jun 15 olle 166         jsonEm.put("oldNameHighestSpecimenNumber", oldNameHighestSpecimenNumber);
3412 22 Jun 15 olle 167         json.put("emInfo", jsonEm);
3412 22 Jun 15 olle 168       }
3412 22 Jun 15 olle 169       else if ("GetCaseInfo".equals(cmd))
3412 22 Jun 15 olle 170       {
3412 22 Jun 15 olle 171         dc = sc.newDbControl();
3412 22 Jun 15 olle 172         
2933 14 Nov 14 olle 173         String caseName = req.getParameter("caseName");
2933 14 Nov 14 olle 174         
3104 23 Jan 15 olle 175         // Check that no specimen exist already
2966 20 Nov 14 olle 176         List<SpecimenTube> specimenTubes = SpecimenTube.findByCaseName(dc, caseName);
2933 14 Nov 14 olle 177         if (specimenTubes.size() > 0)
2933 14 Nov 14 olle 178         {
2933 14 Nov 14 olle 179           throw new InvalidDataException(specimenTubes.size() + 
2933 14 Nov 14 olle 180             " specimen tubes have already been registered for this case. This wizard can't be used for updating.");
2933 14 Nov 14 olle 181         }
2933 14 Nov 14 olle 182
3104 23 Jan 15 olle 183         // Check that no DNA extracts exist already
3104 23 Jan 15 olle 184         List<Dna> dnaList = Dna.findByCaseName(dc, caseName);
3104 23 Jan 15 olle 185         if (dnaList.size() > 0)
3104 23 Jan 15 olle 186         {
3104 23 Jan 15 olle 187           throw new InvalidDataException(dnaList.size() + 
3104 23 Jan 15 olle 188             " DNA extract has already been registered for this case. This wizard can't be used for updating.");
3104 23 Jan 15 olle 189         }
2933 14 Nov 14 olle 190         
3104 23 Jan 15 olle 191         // Check that no RNA extracts exist already
3104 23 Jan 15 olle 192         List<Rna> rnaList = Rna.findByCaseName(dc, caseName);
3104 23 Jan 15 olle 193         if (rnaList.size() > 0)
3104 23 Jan 15 olle 194         {
3104 23 Jan 15 olle 195           throw new InvalidDataException(rnaList.size() + 
3104 23 Jan 15 olle 196             " RNA extract has already been registered for this case. This wizard can't be used for updating.");
3104 23 Jan 15 olle 197         }
3104 23 Jan 15 olle 198         
2933 14 Nov 14 olle 199         // Check if there are other specimen tubes for this case with other biopsy types
2933 14 Nov 14 olle 200         int numExisting = 0;
2933 14 Nov 14 olle 201         
2933 14 Nov 14 olle 202         // Check if we already have information about the case
2933 14 Nov 14 olle 203         JSONObject jsonCase = null;
2933 14 Nov 14 olle 204         Case theCase = Case.findByName(dc, caseName);
2933 14 Nov 14 olle 205         Site site = Site.UNKNOWN;
4723 29 Mar 18 olle 206         //System.out.println("SpecimenTubeServlet::doGet(): cmd = '" + cmd + "' theCase = " + theCase);
2933 14 Nov 14 olle 207         
2933 14 Nov 14 olle 208         if (theCase != null)
2933 14 Nov 14 olle 209         {
2933 14 Nov 14 olle 210           // Use stored annotation snapshots for performance reasons
2933 14 Nov 14 olle 211           SnapshotManager manager = new SnapshotManager();        
2933 14 Nov 14 olle 212           site = fetchSite(dc, manager, theCase.getSample());
2933 14 Nov 14 olle 213           jsonCase = theCase.asJSONObject();
2933 14 Nov 14 olle 214         }
2933 14 Nov 14 olle 215         else
2933 14 Nov 14 olle 216         {
2933 14 Nov 14 olle 217           // A new case -- get rid of suffix in the case name
4147 03 Oct 16 olle 218           caseName = Meludi.fetchRootItemName(caseName, sc.getActiveProjectId());
2933 14 Nov 14 olle 219           jsonCase = new JSONObject();
2933 14 Nov 14 olle 220           jsonCase.put("name", caseName);
2933 14 Nov 14 olle 221           jsonCase.put("originalName", caseName);
4723 29 Mar 18 olle 222
4723 29 Mar 18 olle 223           // Check if site should be found from site prefix
4723 29 Mar 18 olle 224           String siteDefault = null;
4723 29 Mar 18 olle 225           Boolean usesSitePrefix = Meludi.fetchUsesSitePrefix(sc.getActiveProjectId());
4723 29 Mar 18 olle 226           if (usesSitePrefix)
4723 29 Mar 18 olle 227           {
4723 29 Mar 18 olle 228             String caseNameDigits = Meludi.fetchRootDigits(caseName, sc.getActiveProjectId());
4723 29 Mar 18 olle 229             String sitePrefix = caseNameDigits.substring(0, 2);
4723 29 Mar 18 olle 230             HashMap<String,String> sitePrefixSiteKeyHashMap = Meludi.fetchSitePrefixSiteKeyHashMap(sc.getActiveProjectId());
4723 29 Mar 18 olle 231             if (sitePrefixSiteKeyHashMap != null)
4723 29 Mar 18 olle 232             {
4723 29 Mar 18 olle 233               siteDefault = sitePrefixSiteKeyHashMap.get(sitePrefix);
4723 29 Mar 18 olle 234               if (siteDefault == null)
4723 29 Mar 18 olle 235               {
4723 29 Mar 18 olle 236                 siteDefault = "";
4723 29 Mar 18 olle 237               }
4723 29 Mar 18 olle 238             }
4723 29 Mar 18 olle 239           }
4723 29 Mar 18 olle 240           jsonCase.put("siteDefault", siteDefault);
2933 14 Nov 14 olle 241         }
2933 14 Nov 14 olle 242         jsonCase.put("specimenFirstIndex", numExisting+1);
2933 14 Nov 14 olle 243         json.put("caseInfo", jsonCase);
2933 14 Nov 14 olle 244       }
2933 14 Nov 14 olle 245       else if ("FindStoragePositions".equals(cmd))
2933 14 Nov 14 olle 246       {
2933 14 Nov 14 olle 247         // Find a given number of storage positions. The process
2933 14 Nov 14 olle 248         // is complicated by the fact that "old" boxes still may have empty
3028 11 Dec 14 olle 249         // locations so we need to find the first box of the right type
3028 11 Dec 14 olle 250         // that has I9 empty.
2933 14 Nov 14 olle 251         Integer nofTubes = Values.getInt(req.getParameter("nofTubes"), 1);
3028 11 Dec 14 olle 252         String storageBoxSuffix = req.getParameter("storageBoxSuffix");
4246 21 Nov 16 olle 253         Boolean extractsFromFirstSpecimenOnly = Values.getBoolean(req.getParameter("extractsFromFirstSpecimenOnly"), false);
4246 21 Nov 16 olle 254         int nofExtracts = nofTubes;
4246 21 Nov 16 olle 255         if (extractsFromFirstSpecimenOnly)
4246 21 Nov 16 olle 256         {
4246 21 Nov 16 olle 257           nofExtracts = 1;
4246 21 Nov 16 olle 258         }
2933 14 Nov 14 olle 259         dc = sc.newDbControl();
2933 14 Nov 14 olle 260         
3253 17 Apr 15 olle 261         JSONArray jsonWells = new JSONArray();
3285 29 Apr 15 olle 262         Boolean fillGaps = false;
3276 29 Apr 15 olle 263         if (storageBoxSuffix.equals("_sp"))
3253 17 Apr 15 olle 264         {
3276 29 Apr 15 olle 265           // Find free wells for specimen
3285 29 Apr 15 olle 266           JSONArray jsonSpecWells = findFreeWells(dc, nofTubes, "_sp", fillGaps);
3276 29 Apr 15 olle 267           // Find free wells for DNA extracts from specimen
4246 21 Nov 16 olle 268           JSONArray jsonDnaWells = findFreeWells(dc, nofExtracts, "_dna", fillGaps);
3276 29 Apr 15 olle 269           // Find free wells for RNA extracts from specimen
4246 21 Nov 16 olle 270           JSONArray jsonRnaWells = findFreeWells(dc, nofExtracts, "_rna", fillGaps);
3276 29 Apr 15 olle 271           // Combine free well results for Specimen/DNA/RNA to JSONArray
3276 29 Apr 15 olle 272           for (int i = 0; i < nofTubes; i++)
3276 29 Apr 15 olle 273           {
3276 29 Apr 15 olle 274             // Find a free well for Specimen, except for first
3276 29 Apr 15 olle 275             JSONObject jsonSpecWell = new JSONObject();
3276 29 Apr 15 olle 276             if (i > 0)
3276 29 Apr 15 olle 277             {
3276 29 Apr 15 olle 278               if (jsonSpecWells.size() > (i-1))
3276 29 Apr 15 olle 279               {
3276 29 Apr 15 olle 280                 jsonSpecWell = (JSONObject)jsonSpecWells.get(i-1);
3276 29 Apr 15 olle 281               }              
3276 29 Apr 15 olle 282               jsonSpecWell = (JSONObject)jsonSpecWells.get(i-1);
3276 29 Apr 15 olle 283             }
3276 29 Apr 15 olle 284             // Find a free well for DNA
3276 29 Apr 15 olle 285             JSONObject jsonDnaWell = new JSONObject();
3276 29 Apr 15 olle 286             if (jsonDnaWells.size() > i)
3276 29 Apr 15 olle 287             {
3276 29 Apr 15 olle 288               jsonDnaWell = (JSONObject)jsonDnaWells.get(i);
3276 29 Apr 15 olle 289             }
3276 29 Apr 15 olle 290             // Find a free well for RNA
3276 29 Apr 15 olle 291             JSONObject jsonRnaWell = new JSONObject();
3276 29 Apr 15 olle 292             if (jsonRnaWells.size() > i)
3276 29 Apr 15 olle 293             {
3276 29 Apr 15 olle 294               jsonRnaWell = (JSONObject)jsonRnaWells.get(i);
3276 29 Apr 15 olle 295             }
3276 29 Apr 15 olle 296             // Combine free well results for Specimen/DNA/RNA to JSONArray for specimen i
3276 29 Apr 15 olle 297             jsonWells.add(jsonSpecWell);
3276 29 Apr 15 olle 298             jsonWells.add(jsonDnaWell);
3276 29 Apr 15 olle 299             jsonWells.add(jsonRnaWell);
3276 29 Apr 15 olle 300           }
3276 29 Apr 15 olle 301         }
3276 29 Apr 15 olle 302         else if (storageBoxSuffix.equals("_dna_rna"))
3276 29 Apr 15 olle 303         {
3253 17 Apr 15 olle 304           // Find a free well for DNA
3253 17 Apr 15 olle 305           JSONObject jsonDnaWell = new JSONObject();
3285 29 Apr 15 olle 306           JSONArray jsonDnaWells = findFreeWells(dc, 1, "_dna", fillGaps);
3253 17 Apr 15 olle 307           if (jsonDnaWells.size() > 0)
3253 17 Apr 15 olle 308           {
3253 17 Apr 15 olle 309             jsonDnaWell = (JSONObject)jsonDnaWells.get(0);
3253 17 Apr 15 olle 310           }
3253 17 Apr 15 olle 311           // Find a free well for RNA
3253 17 Apr 15 olle 312           JSONObject jsonRnaWell = new JSONObject();
3285 29 Apr 15 olle 313           JSONArray jsonRnaWells = findFreeWells(dc, 1, "_rna", fillGaps);
3253 17 Apr 15 olle 314           if (jsonRnaWells.size() > 0)
3253 17 Apr 15 olle 315           {
3253 17 Apr 15 olle 316             jsonRnaWell = (JSONObject)jsonRnaWells.get(0);
3253 17 Apr 15 olle 317           }
3253 17 Apr 15 olle 318           // Combine free well results for DNA and RNA to JSONArray
3253 17 Apr 15 olle 319           jsonWells.add(jsonDnaWell);
3253 17 Apr 15 olle 320           jsonWells.add(jsonRnaWell);
3253 17 Apr 15 olle 321         }
3253 17 Apr 15 olle 322         else
3253 17 Apr 15 olle 323         {
3253 17 Apr 15 olle 324           // Find free wells for storage
3285 29 Apr 15 olle 325           jsonWells = findFreeWells(dc, nofTubes, storageBoxSuffix, fillGaps);
3253 17 Apr 15 olle 326         }
2933 14 Nov 14 olle 327         
2933 14 Nov 14 olle 328         json.put("wells", jsonWells);
2933 14 Nov 14 olle 329       }
2933 14 Nov 14 olle 330       else if ("ValidateWell".equals(cmd))
2933 14 Nov 14 olle 331       {
2933 14 Nov 14 olle 332         dc = sc.newDbControl();
2933 14 Nov 14 olle 333         String box = Values.getStringOrNull(req.getParameter("box"));
2933 14 Nov 14 olle 334         
2933 14 Nov 14 olle 335         String msg = null;
2933 14 Nov 14 olle 336         StoragePlate plate = StoragePlate.findByName(dc, box);
3478 03 Sep 15 olle 337         BioPlate bioPlate = null;
3478 03 Sep 15 olle 338         if (plate != null)
2933 14 Nov 14 olle 339         {
3478 03 Sep 15 olle 340           bioPlate = plate.getBioPlate();
2933 14 Nov 14 olle 341         }
3478 03 Sep 15 olle 342         else
3478 03 Sep 15 olle 343         {
3478 03 Sep 15 olle 344           bioPlate = createStorageBox(dc, box);
3478 03 Sep 15 olle 345           if (bioPlate == null)
3478 03 Sep 15 olle 346           {
3478 03 Sep 15 olle 347             msg = "Can't find or create storage box with name '" + box + "'";
3478 03 Sep 15 olle 348             json.put("box", 1);
3478 03 Sep 15 olle 349           }
3478 03 Sep 15 olle 350         }
2933 14 Nov 14 olle 351         
2933 14 Nov 14 olle 352         if (msg == null)
2933 14 Nov 14 olle 353         {
3478 03 Sep 15 olle 354           int rows = bioPlate.getRows();
3478 03 Sep 15 olle 355           int columns = bioPlate.getColumns();
2933 14 Nov 14 olle 356           
2933 14 Nov 14 olle 357           WellCoordinateFormatter wcfRow = new WellCoordinateFormatter(true);        
2933 14 Nov 14 olle 358           String rowString = req.getParameter("row");
2933 14 Nov 14 olle 359           int rowNumber = wcfRow.parseString(rowString);
2933 14 Nov 14 olle 360                   
2933 14 Nov 14 olle 361           Integer columnIndex = Integer.parseInt(req.getParameter("column")) - 1;
2933 14 Nov 14 olle 362           WellCoordinateFormatter wcfColumn = new WellCoordinateFormatter(false);
2933 14 Nov 14 olle 363           
2933 14 Nov 14 olle 364           if (rowNumber < 1 || rowNumber > rows) 
2933 14 Nov 14 olle 365           {
2933 14 Nov 14 olle 366             msg = "The row must be between "+ wcfRow.format(0) +" and " + wcfRow.format(rows-1);
2933 14 Nov 14 olle 367           }
2933 14 Nov 14 olle 368           else if (columnIndex < 0 || columnIndex > columns)
2933 14 Nov 14 olle 369           {
2933 14 Nov 14 olle 370             msg = "The column must be between " +  1 + " and " + columns;
2933 14 Nov 14 olle 371           }
3478 03 Sep 15 olle 372           else if (bioPlate.getBioWell(rowNumber-1, columnIndex) != null && !bioPlate.getBioWell(rowNumber-1, columnIndex).isEmpty() )
2933 14 Nov 14 olle 373           {
2933 14 Nov 14 olle 374             msg = "Location '"+rowString+wcfColumn.format(columnIndex)+"' is already used.";
2933 14 Nov 14 olle 375           }
2933 14 Nov 14 olle 376           json.put("position", 1);
2933 14 Nov 14 olle 377         }
2933 14 Nov 14 olle 378         json.put("message", msg);
2933 14 Nov 14 olle 379       }
2933 14 Nov 14 olle 380     }
2933 14 Nov 14 olle 381     catch (Throwable t)
2933 14 Nov 14 olle 382     {
2933 14 Nov 14 olle 383       t.printStackTrace();
2933 14 Nov 14 olle 384       json.clear();
2933 14 Nov 14 olle 385       json.put("status", "error");
2933 14 Nov 14 olle 386       json.put("message", t.getMessage());
2933 14 Nov 14 olle 387       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
2933 14 Nov 14 olle 388     }
2933 14 Nov 14 olle 389     finally
2933 14 Nov 14 olle 390     {
2933 14 Nov 14 olle 391       if (dc!=null) dc.close();
2933 14 Nov 14 olle 392       json.writeJSONString(resp.getWriter());
2933 14 Nov 14 olle 393     }
2933 14 Nov 14 olle 394   }
3028 11 Dec 14 olle 395
2933 14 Nov 14 olle 396   @SuppressWarnings("unchecked")
3176 06 Mar 15 olle 397   List<BioWell> findFreeWells2(DbControl dc, Integer nofTubes, String storageBoxSuffix)
3176 06 Mar 15 olle 398   {
3176 06 Mar 15 olle 399     String queryString = "%";
3176 06 Mar 15 olle 400     Integer nofWellsNeeded = 0;
3176 06 Mar 15 olle 401     if (storageBoxSuffix != null)
3176 06 Mar 15 olle 402     {
3176 06 Mar 15 olle 403       queryString = "%" + storageBoxSuffix;
3176 06 Mar 15 olle 404       if (storageBoxSuffix.equals("_sp"))
3176 06 Mar 15 olle 405       {
3176 06 Mar 15 olle 406         // No storage space  is allocated for first specimen,
3176 06 Mar 15 olle 407         // since all amount is expected to be used for analysis
3176 06 Mar 15 olle 408         if (nofTubes != null && nofTubes > 0)
3176 06 Mar 15 olle 409         {
3176 06 Mar 15 olle 410           nofWellsNeeded = nofTubes - 1;
3176 06 Mar 15 olle 411         }
3176 06 Mar 15 olle 412       }
3176 06 Mar 15 olle 413       else
3176 06 Mar 15 olle 414       {
3176 06 Mar 15 olle 415         // All amount is stored
3176 06 Mar 15 olle 416         nofWellsNeeded = nofTubes;
3176 06 Mar 15 olle 417       }
3176 06 Mar 15 olle 418     }
3176 06 Mar 15 olle 419
3176 06 Mar 15 olle 420     ItemQuery<BioPlate> boxQuery = BioPlate.getQuery();
3176 06 Mar 15 olle 421     boxQuery.join(Hql.innerJoin("bioWells", "bw"));
3176 06 Mar 15 olle 422     boxQuery.join(Hql.leftJoin("bw", "bioMaterial", "bm", null, false));
3176 06 Mar 15 olle 423     boxQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.string(queryString)));
3176 06 Mar 15 olle 424     boxQuery.restrict(Restrictions.eq(Hql.property("bw", "row"), Expressions.integer(8)));
3176 06 Mar 15 olle 425     boxQuery.restrict(Restrictions.eq(Hql.property("bw", "column"), Expressions.integer(8)));
3176 06 Mar 15 olle 426     boxQuery.restrict(Restrictions.eq(Hql.alias("bm"), null));
3176 06 Mar 15 olle 427     
3176 06 Mar 15 olle 428     boxQuery.order(Orders.asc(Hql.property("name")));
3176 06 Mar 15 olle 429     List<BioPlate> boxes = boxQuery.list(dc);
3176 06 Mar 15 olle 430     
3176 06 Mar 15 olle 431     List<BioWell> freeWells = new ArrayList<BioWell>();
3176 06 Mar 15 olle 432     if (nofWellsNeeded > 0)
3176 06 Mar 15 olle 433     {
3176 06 Mar 15 olle 434       for (BioPlate box : boxes)
3176 06 Mar 15 olle 435       {
3176 06 Mar 15 olle 436         BioWell free = getFirstFreeWell(box);
3176 06 Mar 15 olle 437         while (free != null)
3176 06 Mar 15 olle 438         {
3176 06 Mar 15 olle 439           freeWells.add(free);
3176 06 Mar 15 olle 440           if (freeWells.size() == nofWellsNeeded) break;
3176 06 Mar 15 olle 441           free = getNextFreeWell(free);
3176 06 Mar 15 olle 442         }
3176 06 Mar 15 olle 443         if (freeWells.size() == nofWellsNeeded) break;
3176 06 Mar 15 olle 444       }
3176 06 Mar 15 olle 445     }
3176 06 Mar 15 olle 446     return freeWells;
3176 06 Mar 15 olle 447   }
3176 06 Mar 15 olle 448
3176 06 Mar 15 olle 449   @SuppressWarnings("unchecked")
3028 11 Dec 14 olle 450   private JSONArray findFreeWells(DbControl dc, Integer nofTubes, String storageBoxSuffix)
3028 11 Dec 14 olle 451   {
3285 29 Apr 15 olle 452     Boolean fillGaps = true;
3285 29 Apr 15 olle 453     JSONArray jsonWells = findFreeWells(dc, nofTubes, storageBoxSuffix, fillGaps);
3285 29 Apr 15 olle 454     return jsonWells;
3285 29 Apr 15 olle 455   }
3285 29 Apr 15 olle 456
3285 29 Apr 15 olle 457   @SuppressWarnings("unchecked")
3285 29 Apr 15 olle 458   private JSONArray findFreeWells(DbControl dc, Integer nofTubes, String storageBoxSuffix, Boolean fillGaps)
3285 29 Apr 15 olle 459   {
4187 28 Oct 16 olle 460     String platePrefix = Meludi.fetchStorageBoxPrefix(dc.getSessionControl().getActiveProjectId());
4217 09 Nov 16 olle 461     Integer plateNumDigits = Meludi.fetchStorageBoxNumDigits(dc.getSessionControl().getActiveProjectId());
3287 30 Apr 15 olle 462     // Default is to fill gaps in plates
3287 30 Apr 15 olle 463     if (fillGaps == null)
3287 30 Apr 15 olle 464     {
3287 30 Apr 15 olle 465       fillGaps = true;
3287 30 Apr 15 olle 466     }
4187 28 Oct 16 olle 467     String queryString = platePrefix + "%";
3028 11 Dec 14 olle 468     Integer nofWellsNeeded = 0;
3028 11 Dec 14 olle 469     if (storageBoxSuffix != null)
3028 11 Dec 14 olle 470     {
4187 28 Oct 16 olle 471       queryString = platePrefix + "%" + storageBoxSuffix;
3028 11 Dec 14 olle 472       if (storageBoxSuffix.equals("_sp"))
3028 11 Dec 14 olle 473       {
3028 11 Dec 14 olle 474         // No storage space  is allocated for first specimen,
3028 11 Dec 14 olle 475         // since all amount is expected to be used for analysis
3028 11 Dec 14 olle 476         if (nofTubes != null && nofTubes > 0)
3028 11 Dec 14 olle 477         {
3028 11 Dec 14 olle 478           nofWellsNeeded = nofTubes - 1;
3028 11 Dec 14 olle 479         }
3028 11 Dec 14 olle 480       }
3028 11 Dec 14 olle 481       else
3028 11 Dec 14 olle 482       {
3028 11 Dec 14 olle 483         // All amount is stored
3028 11 Dec 14 olle 484         nofWellsNeeded = nofTubes;
3028 11 Dec 14 olle 485       }
3028 11 Dec 14 olle 486     }
3028 11 Dec 14 olle 487
3287 30 Apr 15 olle 488     // Get all bioplates of the desired type, in ascending order by name
3028 11 Dec 14 olle 489     ItemQuery<BioPlate> boxQuery = BioPlate.getQuery();
3287 30 Apr 15 olle 490 /*
3028 11 Dec 14 olle 491     boxQuery.join(Hql.innerJoin("bioWells", "bw"));
3028 11 Dec 14 olle 492     boxQuery.join(Hql.leftJoin("bw", "bioMaterial", "bm", null, false));
3287 30 Apr 15 olle 493 */
3028 11 Dec 14 olle 494     boxQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.string(queryString)));
3287 30 Apr 15 olle 495 /*
3028 11 Dec 14 olle 496     boxQuery.restrict(Restrictions.eq(Hql.property("bw", "row"), Expressions.integer(8)));
3028 11 Dec 14 olle 497     boxQuery.restrict(Restrictions.eq(Hql.property("bw", "column"), Expressions.integer(8)));
3028 11 Dec 14 olle 498     boxQuery.restrict(Restrictions.eq(Hql.alias("bm"), null));
3287 30 Apr 15 olle 499 */
3028 11 Dec 14 olle 500     
3028 11 Dec 14 olle 501     boxQuery.order(Orders.asc(Hql.property("name")));
3028 11 Dec 14 olle 502     List<BioPlate> boxes = boxQuery.list(dc);
3028 11 Dec 14 olle 503     
3287 30 Apr 15 olle 504     // Find first box with free well to fill, according to scheme
3287 30 Apr 15 olle 505     int firstBoxIndex = -1;
3287 30 Apr 15 olle 506     if (fillGaps)
3287 30 Apr 15 olle 507     {      
3287 30 Apr 15 olle 508       // Find first box with a free well
3287 30 Apr 15 olle 509       // by checking forwards from first box
3287 30 Apr 15 olle 510       for (int i = 0; i < boxes.size() && firstBoxIndex < 0; i++)
3287 30 Apr 15 olle 511       {
3287 30 Apr 15 olle 512         BioPlate box = (BioPlate) boxes.get(i);
3287 30 Apr 15 olle 513         BioWell firstFreeWell = getFirstFreeWell(box);
3287 30 Apr 15 olle 514         if (firstFreeWell != null)
3287 30 Apr 15 olle 515         {
3287 30 Apr 15 olle 516           // Valid free well found in box
3287 30 Apr 15 olle 517           firstBoxIndex = i;
3287 30 Apr 15 olle 518         }
3287 30 Apr 15 olle 519       }
3287 30 Apr 15 olle 520     }
3287 30 Apr 15 olle 521     else
3287 30 Apr 15 olle 522     {      
3287 30 Apr 15 olle 523       // Find highest box with at least one well filled
3287 30 Apr 15 olle 524       // by checking backwards from highest box
3287 30 Apr 15 olle 525       for (int i = boxes.size() - 1; i >= 0 && firstBoxIndex < 0; i--)
3287 30 Apr 15 olle 526       {
3287 30 Apr 15 olle 527         BioPlate box = (BioPlate) boxes.get(i);
3287 30 Apr 15 olle 528         BioWell firstFilledWell = getFirstFilledWell(box);
3287 30 Apr 15 olle 529         // Skip to next lower box if this box is empty
3287 30 Apr 15 olle 530         if (firstFilledWell == null)
3287 30 Apr 15 olle 531         {
3287 30 Apr 15 olle 532           if (i > 0)
3287 30 Apr 15 olle 533           {
3287 30 Apr 15 olle 534             // Not first box, skip to next lower box
3287 30 Apr 15 olle 535             continue;
3287 30 Apr 15 olle 536           }
3287 30 Apr 15 olle 537           else
3287 30 Apr 15 olle 538           {
3287 30 Apr 15 olle 539             // First box, all boxes empty, select first box
3287 30 Apr 15 olle 540             firstBoxIndex = i;
3287 30 Apr 15 olle 541           }
3287 30 Apr 15 olle 542         }
3287 30 Apr 15 olle 543         // Find first free well followed by only free wells
3287 30 Apr 15 olle 544         BioWell firstFreeWell = getFirstFreeWellWithoutFillingGaps(box);
3287 30 Apr 15 olle 545         if (firstFreeWell != null)
3287 30 Apr 15 olle 546         {
3287 30 Apr 15 olle 547           // Valid free well found in box
3287 30 Apr 15 olle 548           firstBoxIndex = i;
3287 30 Apr 15 olle 549         }
3287 30 Apr 15 olle 550         else
3287 30 Apr 15 olle 551         {
3287 30 Apr 15 olle 552           // No valid free well found
3287 30 Apr 15 olle 553           // If not highest box, select next higher box, which is empty
3287 30 Apr 15 olle 554           if (i < (boxes.size() - 1))
3287 30 Apr 15 olle 555           {
3287 30 Apr 15 olle 556             // First empty box following highest box without valid free well
3287 30 Apr 15 olle 557             firstBoxIndex = i + 1;
3287 30 Apr 15 olle 558           }
3287 30 Apr 15 olle 559         }
3287 30 Apr 15 olle 560       }
3287 30 Apr 15 olle 561     }
3287 30 Apr 15 olle 562     
3028 11 Dec 14 olle 563     JSONArray jsonWells = new JSONArray();
3287 30 Apr 15 olle 564     if (firstBoxIndex >= 0 && nofWellsNeeded > 0)
3028 11 Dec 14 olle 565     {
3287 30 Apr 15 olle 566       for (int i = firstBoxIndex; i < boxes.size(); i++)
3028 11 Dec 14 olle 567       {
3287 30 Apr 15 olle 568         BioPlate box = (BioPlate) boxes.get(i);
3478 03 Sep 15 olle 569         // Get free wells
3478 03 Sep 15 olle 570         jsonWells = updateJsonWells(jsonWells, box, nofWellsNeeded, fillGaps);
3028 11 Dec 14 olle 571         if (jsonWells.size() == nofWellsNeeded) break;
3028 11 Dec 14 olle 572       }
3028 11 Dec 14 olle 573     }
3478 03 Sep 15 olle 574     // Check if more boxes needed
3478 03 Sep 15 olle 575     int plateNumber = 0;
3478 03 Sep 15 olle 576     if (boxes != null)
3478 03 Sep 15 olle 577     {
3478 03 Sep 15 olle 578       plateNumber = boxes.size();
3478 03 Sep 15 olle 579     }
3478 03 Sep 15 olle 580     while (jsonWells.size() < nofWellsNeeded)
3478 03 Sep 15 olle 581     {
3478 03 Sep 15 olle 582       // Get new storage plate
3478 03 Sep 15 olle 583       plateNumber++;
4217 09 Nov 16 olle 584       BioPlate box = createStorageBox(dc, platePrefix, plateNumDigits, storageBoxSuffix, plateNumber);
3478 03 Sep 15 olle 585       // Get free wells
3478 03 Sep 15 olle 586       jsonWells = updateJsonWells(jsonWells, box, nofWellsNeeded, fillGaps);
3478 03 Sep 15 olle 587     }
3028 11 Dec 14 olle 588     return jsonWells;
3028 11 Dec 14 olle 589   }
3028 11 Dec 14 olle 590
3478 03 Sep 15 olle 591
3478 03 Sep 15 olle 592   /**
3478 03 Sep 15 olle 593    * Updates a JSONArray with wells to use.
3478 03 Sep 15 olle 594    * 
3478 03 Sep 15 olle 595    * @param jsonWells JSONArray A JSONArray of wells
3478 03 Sep 15 olle 596    * @param box BioPlate The bioplate to find wells in
3478 03 Sep 15 olle 597    * @param nofWellsNeeded Integer Number of wells needed
3478 03 Sep 15 olle 598    * @param fillGaps Boolean Flag indicating if gaps in the plate should be filled
3478 03 Sep 15 olle 599    * @return JSONArray The input JSONArray updated with free wells to use
3478 03 Sep 15 olle 600    */
3478 03 Sep 15 olle 601   private JSONArray updateJsonWells(JSONArray jsonWells, BioPlate box, Integer nofWellsNeeded, Boolean fillGaps)
3478 03 Sep 15 olle 602   {
3478 03 Sep 15 olle 603     if (nofWellsNeeded == null)
3478 03 Sep 15 olle 604     {
3478 03 Sep 15 olle 605       nofWellsNeeded = 0;
3478 03 Sep 15 olle 606     }
3478 03 Sep 15 olle 607     // Default is to fill gaps in plates
3478 03 Sep 15 olle 608     if (fillGaps == null)
3478 03 Sep 15 olle 609     {
3478 03 Sep 15 olle 610       fillGaps = true;
3478 03 Sep 15 olle 611     }
3478 03 Sep 15 olle 612     // Get free wells
3478 03 Sep 15 olle 613     BioWell free = null;
3478 03 Sep 15 olle 614     if (fillGaps)
3478 03 Sep 15 olle 615     {
3478 03 Sep 15 olle 616       free = getFirstFreeWell(box);
3478 03 Sep 15 olle 617     }
3478 03 Sep 15 olle 618     else
3478 03 Sep 15 olle 619     {
3478 03 Sep 15 olle 620       free = getFirstFreeWellWithoutFillingGaps(box);
3478 03 Sep 15 olle 621     }
3478 03 Sep 15 olle 622     while (free != null && jsonWells.size() < nofWellsNeeded)
3478 03 Sep 15 olle 623     {
3478 03 Sep 15 olle 624       jsonWells.add(JsonUtil.getBioWellAsJSON(free, true));
3478 03 Sep 15 olle 625       free = getNextFreeWell(free);
3478 03 Sep 15 olle 626     }
3478 03 Sep 15 olle 627     return jsonWells;
3478 03 Sep 15 olle 628   }
3478 03 Sep 15 olle 629
3478 03 Sep 15 olle 630
3028 11 Dec 14 olle 631   @SuppressWarnings("unchecked")
2933 14 Nov 14 olle 632   @Override
2933 14 Nov 14 olle 633   protected void doPost(HttpServletRequest req, HttpServletResponse resp)
2933 14 Nov 14 olle 634     throws ServletException, IOException 
2933 14 Nov 14 olle 635   {  
2933 14 Nov 14 olle 636     String ID = req.getParameter("ID");
2933 14 Nov 14 olle 637     String cmd = req.getParameter("cmd");
2933 14 Nov 14 olle 638     JsonUtil.setJsonResponseHeaders(resp);
2933 14 Nov 14 olle 639     
2933 14 Nov 14 olle 640     JSONObject json = new JSONObject();
2933 14 Nov 14 olle 641     json.put("status", "ok");
2933 14 Nov 14 olle 642     
2933 14 Nov 14 olle 643     JSONArray jsonMessages = new JSONArray();
5468 04 Jun 19 olle 644     //final SessionControl sc = Application.getSessionControl(ID, req.getRemoteAddr());
5744 20 Nov 19 olle 645     //final SessionControl sc  = Application.getSessionControl(ID, "", req.getRemoteAddr(), true);
5744 20 Nov 19 olle 646     final SessionControl sc  = Application.getSessionControl(ID, null, req.getRemoteAddr(), true);
2933 14 Nov 14 olle 647     DbControl dc = null;
2933 14 Nov 14 olle 648     
2933 14 Nov 14 olle 649     try
2933 14 Nov 14 olle 650     {
2933 14 Nov 14 olle 651       if ("CreateSpecimenTubes".equals(cmd))
2933 14 Nov 14 olle 652       {
2933 14 Nov 14 olle 653         dc = sc.newDbControl();
2933 14 Nov 14 olle 654         
2933 14 Nov 14 olle 655         MeludiRole.checkPermission(dc, "'" + cmd + "' wizard", MeludiRole.SAMPLE_PREP, MeludiRole.ADMINISTRATOR);
4198 31 Oct 16 olle 656         boolean hasPatientCuratorRole = true;
4198 31 Oct 16 olle 657         try
4198 31 Oct 16 olle 658         {
4198 31 Oct 16 olle 659           MeludiRole.checkPermission(dc, "'" + cmd + "' wizard", MeludiRole.PATIENT_CURATOR, MeludiRole.ADMINISTRATOR);
4198 31 Oct 16 olle 660         }
4198 31 Oct 16 olle 661         catch (PermissionDeniedException e)
4198 31 Oct 16 olle 662         {
4198 31 Oct 16 olle 663           hasPatientCuratorRole = false;
4198 31 Oct 16 olle 664         }
2933 14 Nov 14 olle 665         JSONObject jsonReq = (JSONObject)new JSONParser().parse(req.getReader());        
2933 14 Nov 14 olle 666         JSONObject jsonCase = (JSONObject)jsonReq.get("caseInfo");
2933 14 Nov 14 olle 667         
4198 31 Oct 16 olle 668         String pad = Values.getStringOrNull((String)jsonCase.get("pad"));
4198 31 Oct 16 olle 669
2933 14 Nov 14 olle 670         // Load the case if we already know which case the specimen belong to
2933 14 Nov 14 olle 671         Number caseId = (Number)jsonCase.get("id");
2933 14 Nov 14 olle 672         String caseName = (String)jsonCase.get("name");
2933 14 Nov 14 olle 673         int numTubes = 0;
2933 14 Nov 14 olle 674         JSONArray jsonSpecimenTmp = (JSONArray)jsonCase.get("specimen");    
2933 14 Nov 14 olle 675         if (jsonSpecimenTmp != null)
2933 14 Nov 14 olle 676         {
2933 14 Nov 14 olle 677           numTubes = jsonSpecimenTmp.size();
2933 14 Nov 14 olle 678         }
2933 14 Nov 14 olle 679         String arrivalDateStr = (String)jsonCase.get("arrivalDate");
2933 14 Nov 14 olle 680         String samplingDateStr = (String)jsonCase.get("samplingDate");
2933 14 Nov 14 olle 681         List<String> mutationAnalysisList = new ArrayList<String>();
3123 09 Feb 15 olle 682         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisKras", "KRAS", mutationAnalysisList);
3123 09 Feb 15 olle 683         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisNras", "NRAS", mutationAnalysisList);
2933 14 Nov 14 olle 684         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisBraf", "BRAF", mutationAnalysisList);
2933 14 Nov 14 olle 685         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisEgfr", "EGFR", mutationAnalysisList);
3123 09 Feb 15 olle 686         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisAlkEml4", "ALKEML4", mutationAnalysisList);
3123 09 Feb 15 olle 687         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisPdgfra", "PDGFRA", mutationAnalysisList);
3123 09 Feb 15 olle 688         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisKit", "KIT", mutationAnalysisList);
4730 04 Apr 18 olle 689         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisTst170", "TST170", mutationAnalysisList);
3123 09 Feb 15 olle 690         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisOther", "Other", mutationAnalysisList);
2933 14 Nov 14 olle 691         String siteStr = replaceBlankWithNull((String)jsonCase.get("site"));
3028 11 Dec 14 olle 692         String tubeContentType = Values.getStringOrNull((String)jsonCase.get("tubeContentType"));
3028 11 Dec 14 olle 693         String specimenType = Values.getStringOrNull((String)jsonCase.get("specimenType"));
4195 31 Oct 16 olle 694         String specimenInputType = Values.getStringOrNull((String)jsonCase.get("specimenInputType"));
3028 11 Dec 14 olle 695         String projectFocus = replaceBlankWithNull((String)jsonCase.get("projectFocus"));
4732 04 Apr 18 olle 696         String metastasisSite = Values.getStringOrNull((String)jsonCase.get("metastasisSite"));
3028 11 Dec 14 olle 697         String otherPathNote = Values.getStringOrNull((String)jsonCase.get("otherPathNote"));
4246 21 Nov 16 olle 698         Boolean extractsFromFirstSpecimenOnly = (Boolean)jsonCase.get("extractsFromFirstSpecimenOnly");
4246 21 Nov 16 olle 699         if (extractsFromFirstSpecimenOnly == null)
4246 21 Nov 16 olle 700         {
4246 21 Nov 16 olle 701           extractsFromFirstSpecimenOnly = false;
4246 21 Nov 16 olle 702         }
2933 14 Nov 14 olle 703         Sample theCase = null;
2933 14 Nov 14 olle 704         if (caseId != null)
2933 14 Nov 14 olle 705         {
2933 14 Nov 14 olle 706           theCase = Sample.getById(dc, caseId.intValue());
2933 14 Nov 14 olle 707           // If the Case doesn't belong to a patient yet
2933 14 Nov 14 olle 708           // it is a free-floating consent registration only and
2933 14 Nov 14 olle 709           // we should not link the specimen since the case may
2933 14 Nov 14 olle 710           // have to bve merged with another case of the same patient
2933 14 Nov 14 olle 711           if (!theCase.hasSingleParent()) theCase = null;
2933 14 Nov 14 olle 712         }
2933 14 Nov 14 olle 713         else if (caseName != null && !caseName.equals(""))
2933 14 Nov 14 olle 714         {
2933 14 Nov 14 olle 715           // Register a new case
2933 14 Nov 14 olle 716           theCase = Sample.getNew(dc);
2933 14 Nov 14 olle 717           dc.saveItem(theCase);
2933 14 Nov 14 olle 718           theCase.setItemSubtype(Subtype.CASE.load(dc));
2933 14 Nov 14 olle 719           theCase.setName(caseName);
2933 14 Nov 14 olle 720           Annotationtype.MUTATION_ANALYSIS.setAnnotationValues(dc, theCase, mutationAnalysisList);
2933 14 Nov 14 olle 721           Annotationtype.SITE.setAnnotationValue(dc, theCase, siteStr);
3028 11 Dec 14 olle 722           Annotationtype.TUBE_CONTENT_TYPE.setAnnotationValue(dc, theCase, tubeContentType);
3028 11 Dec 14 olle 723           Annotationtype.PROJECT_FOCUS.setAnnotationValue(dc, theCase, projectFocus);
4732 04 Apr 18 olle 724           Annotationtype.METASTASIS_SITE.setAnnotationValue(dc, theCase, metastasisSite);
3028 11 Dec 14 olle 725           Annotationtype.NOF_DELIVERED_TUBES.setAnnotationValue(dc, theCase, numTubes);
3028 11 Dec 14 olle 726           Annotationtype.OTHER_PATH_NOTE.setAnnotationValue(dc, theCase, otherPathNote);
2933 14 Nov 14 olle 727         }
2933 14 Nov 14 olle 728
2933 14 Nov 14 olle 729         StringToDateConverter dateTimeConverter = new StringToDateConverter(new SimpleDateFormat("yyyyMMdd HHmm"));
2933 14 Nov 14 olle 730         StringToDateConverter dateConverter = new StringToDateConverter(new SimpleDateFormat("yyyyMMdd"));        
2933 14 Nov 14 olle 731         Date arrivalDate = dateConverter.convert((String)jsonCase.get("arrivalDate"));        
2933 14 Nov 14 olle 732         Date samplingDate = dateConverter.convert((String)jsonCase.get("samplingDate"));
2933 14 Nov 14 olle 733         Date createDate = dateConverter.convert((String)jsonCase.get("samplingDate"));
2933 14 Nov 14 olle 734         
2933 14 Nov 14 olle 735         JSONArray jsonSpecimen = (JSONArray)jsonCase.get("specimen");
2933 14 Nov 14 olle 736                 
2933 14 Nov 14 olle 737         if (jsonSpecimen != null && jsonSpecimen.size() > 0)
2933 14 Nov 14 olle 738         {
3478 03 Sep 15 olle 739           HashMap<String, BioPlate> bioPlateNamePlateHashMap = new HashMap<String, BioPlate>();
2933 14 Nov 14 olle 740           int nofTubes = jsonSpecimen.size();
2933 14 Nov 14 olle 741           for (int i=0; i < jsonSpecimen.size(); i++)
2933 14 Nov 14 olle 742           {
2933 14 Nov 14 olle 743             JSONObject jsonSpec = (JSONObject)jsonSpecimen.get(i);
3028 11 Dec 14 olle 744             String itemName = (String)jsonSpec.get("name");
3028 11 Dec 14 olle 745             Integer nofSections = 0;
3028 11 Dec 14 olle 746             String nofSectionsString = (String)jsonSpec.get("nofSections");
3028 11 Dec 14 olle 747             if (nofSectionsString != null && !nofSectionsString.equals(""))
2933 14 Nov 14 olle 748             {
3028 11 Dec 14 olle 749               nofSections = Integer.parseInt(nofSectionsString);
2933 14 Nov 14 olle 750             }
2933 14 Nov 14 olle 751             String operatorComment = Values.getStringOrNull((String)jsonSpec.get("comment"));
3028 11 Dec 14 olle 752             // Create items of correct types
3028 11 Dec 14 olle 753             if (tubeContentType != null && tubeContentType.equals("Specimen"))
2933 14 Nov 14 olle 754             {
3028 11 Dec 14 olle 755               Sample specimen = Sample.getNew(dc);
3028 11 Dec 14 olle 756               specimen.setItemSubtype(Subtype.SPECIMEN.load(dc));
3028 11 Dec 14 olle 757               specimen.setName(itemName);
3028 11 Dec 14 olle 758               dc.saveItem(specimen);
3028 11 Dec 14 olle 759               
3028 11 Dec 14 olle 760               BioMaterialEvent creationEvent = specimen.getCreationEvent();
3028 11 Dec 14 olle 761               // Link the specimen with the case
3028 11 Dec 14 olle 762               if (theCase != null)
3028 11 Dec 14 olle 763               {
3028 11 Dec 14 olle 764                 creationEvent.setSource(theCase);
3028 11 Dec 14 olle 765               }
3028 11 Dec 14 olle 766               creationEvent.setEventDate(createDate);
3028 11 Dec 14 olle 767               
3028 11 Dec 14 olle 768               setAnnotations(dc, specimen, jsonCase, nofSections, operatorComment);
4198 31 Oct 16 olle 769               // Set PAD/CL annotation
4198 31 Oct 16 olle 770               if (hasPatientCuratorRole)
4198 31 Oct 16 olle 771               {
4198 31 Oct 16 olle 772                 Annotationtype.PAD.setAnnotationValue(dc, specimen, pad);
4198 31 Oct 16 olle 773               }
3028 11 Dec 14 olle 774               
3028 11 Dec 14 olle 775               // Get bioWell if it is specified for this tube
3478 03 Sep 15 olle 776               BioWell well = fetchBioWell(dc, jsonSpec, bioPlateNamePlateHashMap);
3028 11 Dec 14 olle 777               // Set storage space for specimen, if former is valid
3028 11 Dec 14 olle 778               if (well != null)
3028 11 Dec 14 olle 779               {
3028 11 Dec 14 olle 780                 specimen.setBioWell(well);              
3028 11 Dec 14 olle 781               }
3028 11 Dec 14 olle 782               jsonMessages.add("Specimen tube '" + specimen.getName() + "' created successfully.");
3276 29 Apr 15 olle 783
4246 21 Nov 16 olle 784               // Optional creation of extracts from specimen
4246 21 Nov 16 olle 785               if (i == 0 || !extractsFromFirstSpecimenOnly)
3276 29 Apr 15 olle 786               {
4246 21 Nov 16 olle 787                 // DNA extract from specimen
4246 21 Nov 16 olle 788                 Extract dna = Extract.getNew(dc);
4246 21 Nov 16 olle 789                 dna.setItemSubtype(Subtype.DNA.load(dc));
4246 21 Nov 16 olle 790                 dna.setName(itemName + ".d");
4246 21 Nov 16 olle 791                 BioMaterialEvent dnaEvent = dna.getCreationEvent();
4246 21 Nov 16 olle 792                 dnaEvent.setSource(specimen);
4246 21 Nov 16 olle 793                 dc.saveItem(dna);
4246 21 Nov 16 olle 794                 // Get bioWell if it is specified for DNA extract
4246 21 Nov 16 olle 795                 BioWell dnaWell = fetchBioWell(dc, jsonSpec, bioPlateNamePlateHashMap, "DNA");
4246 21 Nov 16 olle 796                 // Set storage space for DNA, if former is valid
4246 21 Nov 16 olle 797                 if (dnaWell != null)
4246 21 Nov 16 olle 798                 {
4246 21 Nov 16 olle 799                   dna.setBioWell(dnaWell);              
4246 21 Nov 16 olle 800                 }
4246 21 Nov 16 olle 801                 jsonMessages.add("DNA extract '" + dna.getName() + "' created successfully.");
3276 29 Apr 15 olle 802
4246 21 Nov 16 olle 803                 // RNA extract from specimen
4246 21 Nov 16 olle 804                 Extract rna = Extract.getNew(dc);
4246 21 Nov 16 olle 805                 rna.setItemSubtype(Subtype.RNA.load(dc));
4246 21 Nov 16 olle 806                 rna.setName(itemName + ".r");
4246 21 Nov 16 olle 807                 BioMaterialEvent rnaEvent = rna.getCreationEvent();
4246 21 Nov 16 olle 808                 rnaEvent.setSource(specimen);
4246 21 Nov 16 olle 809                 dc.saveItem(rna);
4246 21 Nov 16 olle 810                 // Get bioWell if it is specified for RNA extract
4246 21 Nov 16 olle 811                 BioWell rnaWell = fetchBioWell(dc, jsonSpec, bioPlateNamePlateHashMap, "RNA");
4246 21 Nov 16 olle 812                 // Set storage space for RNA, if former is valid
4246 21 Nov 16 olle 813                 if (rnaWell != null)
4246 21 Nov 16 olle 814                 {
4246 21 Nov 16 olle 815                   rna.setBioWell(rnaWell);              
4246 21 Nov 16 olle 816                 }
4246 21 Nov 16 olle 817                 jsonMessages.add("RNA extract '" + rna.getName() + "' created successfully.");
3276 29 Apr 15 olle 818               }
2933 14 Nov 14 olle 819             }
3028 11 Dec 14 olle 820             else if (tubeContentType != null)
3028 11 Dec 14 olle 821             {
3028 11 Dec 14 olle 822               Extract extract = Extract.getNew(dc);
3028 11 Dec 14 olle 823               String extractTypeStr = "Extract";
3028 11 Dec 14 olle 824               if (itemName.endsWith(".d"))
3028 11 Dec 14 olle 825               {
3028 11 Dec 14 olle 826                 extractTypeStr = "DNA";
3028 11 Dec 14 olle 827                 extract.setItemSubtype(Subtype.DNA.load(dc));
3028 11 Dec 14 olle 828               }
3028 11 Dec 14 olle 829               else if (itemName.endsWith(".r"))
3028 11 Dec 14 olle 830               {
3028 11 Dec 14 olle 831                 extractTypeStr = "RNA";
3028 11 Dec 14 olle 832                 extract.setItemSubtype(Subtype.RNA.load(dc));
3028 11 Dec 14 olle 833               }
3028 11 Dec 14 olle 834               extract.setName(itemName);
3028 11 Dec 14 olle 835               dc.saveItem(extract);
3028 11 Dec 14 olle 836               
3028 11 Dec 14 olle 837               BioMaterialEvent creationEvent = extract.getCreationEvent();
3028 11 Dec 14 olle 838               // Link the extract with the case
3028 11 Dec 14 olle 839               if (theCase != null)
3028 11 Dec 14 olle 840               {
3028 11 Dec 14 olle 841                 creationEvent.setSource(theCase);
3028 11 Dec 14 olle 842               }
3028 11 Dec 14 olle 843               creationEvent.setEventDate(createDate);
3028 11 Dec 14 olle 844               
3028 11 Dec 14 olle 845               setAnnotations(dc, extract, jsonCase, 0, operatorComment);
3028 11 Dec 14 olle 846               
3028 11 Dec 14 olle 847               // Get bioWell if it is specified for this tube
3478 03 Sep 15 olle 848               BioWell well = fetchBioWell(dc, jsonSpec, bioPlateNamePlateHashMap);
3028 11 Dec 14 olle 849               // Set storage space for specimen, if former is valid
3028 11 Dec 14 olle 850               if (well != null)
3028 11 Dec 14 olle 851               {
3028 11 Dec 14 olle 852                 extract.setBioWell(well);              
3028 11 Dec 14 olle 853               }
3028 11 Dec 14 olle 854               jsonMessages.add(extractTypeStr + " tube '" + extract.getName() + "' created successfully.");
3028 11 Dec 14 olle 855             }
2933 14 Nov 14 olle 856           }
2933 14 Nov 14 olle 857         }
2933 14 Nov 14 olle 858                 
2933 14 Nov 14 olle 859         dc.commit();
2933 14 Nov 14 olle 860         json.put("messages", jsonMessages);
3102 21 Jan 15 olle 861         CounterService.getInstance().setForceCount();
2933 14 Nov 14 olle 862       }      
4247 22 Nov 16 olle 863       else if ("CreateExtractsForExtraSpecimens".equals(cmd))
4247 22 Nov 16 olle 864       {
4247 22 Nov 16 olle 865         dc = sc.newDbControl();
4247 22 Nov 16 olle 866         
4247 22 Nov 16 olle 867         MeludiRole.checkPermission(dc, "'" + cmd + "' wizard", MeludiRole.SAMPLE_PREP, MeludiRole.ADMINISTRATOR);
4247 22 Nov 16 olle 868         boolean hasPatientCuratorRole = true;
4247 22 Nov 16 olle 869         try
4247 22 Nov 16 olle 870         {
4247 22 Nov 16 olle 871           MeludiRole.checkPermission(dc, "'" + cmd + "' wizard", MeludiRole.PATIENT_CURATOR, MeludiRole.ADMINISTRATOR);
4247 22 Nov 16 olle 872         }
4247 22 Nov 16 olle 873         catch (PermissionDeniedException e)
4247 22 Nov 16 olle 874         {
4247 22 Nov 16 olle 875           hasPatientCuratorRole = false;
4247 22 Nov 16 olle 876         }
4247 22 Nov 16 olle 877         JSONObject jsonReq = (JSONObject)new JSONParser().parse(req.getReader());        
4247 22 Nov 16 olle 878         JSONObject jsonCase = (JSONObject)jsonReq.get("caseInfo");
4247 22 Nov 16 olle 879         JSONArray jsonSpecimen = (JSONArray)jsonCase.get("specimen");
4247 22 Nov 16 olle 880                 
4247 22 Nov 16 olle 881         if (jsonSpecimen != null && jsonSpecimen.size() > 0)
4247 22 Nov 16 olle 882         {
4247 22 Nov 16 olle 883           HashMap<String, BioPlate> bioPlateNamePlateHashMap = new HashMap<String, BioPlate>();
4247 22 Nov 16 olle 884           int nofTubes = jsonSpecimen.size();
4247 22 Nov 16 olle 885           for (int i=0; i < jsonSpecimen.size(); i++)
4247 22 Nov 16 olle 886           {
4247 22 Nov 16 olle 887             JSONObject jsonSpec = (JSONObject)jsonSpecimen.get(i);
4247 22 Nov 16 olle 888             String itemName = (String)jsonSpec.get("name");
4247 22 Nov 16 olle 889             // Get specimen item
4247 22 Nov 16 olle 890             ItemQuery<Sample> specQuery = Sample.getQuery();
4247 22 Nov 16 olle 891             specQuery.restrict(Restrictions.eq(Hql.property("name"), Expressions.string(itemName)));
4247 22 Nov 16 olle 892             specQuery.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
4247 22 Nov 16 olle 893             // Filter on Specimen subtype
4247 22 Nov 16 olle 894             Subtype.SPECIMEN.addFilter(dc, specQuery);
4247 22 Nov 16 olle 895             Sample specimen = null;
4247 22 Nov 16 olle 896             List<Sample> sampleList = specQuery.list(dc);
4247 22 Nov 16 olle 897             if (sampleList != null && sampleList.size() > 0)
4247 22 Nov 16 olle 898             {
4247 22 Nov 16 olle 899               specimen = (Sample)sampleList.get(0);
4247 22 Nov 16 olle 900             }
4247 22 Nov 16 olle 901
4247 22 Nov 16 olle 902             // DNA extract from specimen
4247 22 Nov 16 olle 903             Extract dna = Extract.getNew(dc);
4247 22 Nov 16 olle 904             dna.setItemSubtype(Subtype.DNA.load(dc));
4247 22 Nov 16 olle 905             dna.setName(itemName + ".d");
4247 22 Nov 16 olle 906             BioMaterialEvent dnaEvent = dna.getCreationEvent();
4247 22 Nov 16 olle 907             dnaEvent.setSource(specimen);
4247 22 Nov 16 olle 908             dc.saveItem(dna);
4247 22 Nov 16 olle 909             // Get bioWell if it is specified for DNA extract
4247 22 Nov 16 olle 910             BioWell dnaWell = fetchBioWell(dc, jsonSpec, bioPlateNamePlateHashMap, "DNA");
4247 22 Nov 16 olle 911             // Set storage space for DNA, if former is valid
4247 22 Nov 16 olle 912             if (dnaWell != null)
4247 22 Nov 16 olle 913             {
4247 22 Nov 16 olle 914               dna.setBioWell(dnaWell);              
4247 22 Nov 16 olle 915             }
4247 22 Nov 16 olle 916             jsonMessages.add("DNA extract '" + dna.getName() + "' created successfully.");
4247 22 Nov 16 olle 917
4247 22 Nov 16 olle 918             // RNA extract from specimen
4247 22 Nov 16 olle 919             Extract rna = Extract.getNew(dc);
4247 22 Nov 16 olle 920             rna.setItemSubtype(Subtype.RNA.load(dc));
4247 22 Nov 16 olle 921             rna.setName(itemName + ".r");
4247 22 Nov 16 olle 922             BioMaterialEvent rnaEvent = rna.getCreationEvent();
4247 22 Nov 16 olle 923             rnaEvent.setSource(specimen);
4247 22 Nov 16 olle 924             dc.saveItem(rna);
4247 22 Nov 16 olle 925             // Get bioWell if it is specified for RNA extract
4247 22 Nov 16 olle 926             BioWell rnaWell = fetchBioWell(dc, jsonSpec, bioPlateNamePlateHashMap, "RNA");
4247 22 Nov 16 olle 927             // Set storage space for RNA, if former is valid
4247 22 Nov 16 olle 928             if (rnaWell != null)
4247 22 Nov 16 olle 929             {
4247 22 Nov 16 olle 930               rna.setBioWell(rnaWell);              
4247 22 Nov 16 olle 931             }
4247 22 Nov 16 olle 932             jsonMessages.add("RNA extract '" + rna.getName() + "' created successfully.");
4247 22 Nov 16 olle 933           }
4247 22 Nov 16 olle 934         }
4247 22 Nov 16 olle 935                 
4247 22 Nov 16 olle 936         dc.commit();
4247 22 Nov 16 olle 937         json.put("messages", jsonMessages);
4247 22 Nov 16 olle 938         CounterService.getInstance().setForceCount();
4247 22 Nov 16 olle 939       }      
3412 22 Jun 15 olle 940       else if ("CreateExtraMaterial".equals(cmd))
3412 22 Jun 15 olle 941       {
3412 22 Jun 15 olle 942         dc = sc.newDbControl();
3412 22 Jun 15 olle 943         
3412 22 Jun 15 olle 944         MeludiRole.checkPermission(dc, "'" + cmd + "' wizard", MeludiRole.SAMPLE_PREP, MeludiRole.ADMINISTRATOR);
3412 22 Jun 15 olle 945         
3412 22 Jun 15 olle 946         JSONObject jsonReq = (JSONObject)new JSONParser().parse(req.getReader());        
3412 22 Jun 15 olle 947         JSONObject jsonEm = (JSONObject)jsonReq.get("emInfo");
3412 22 Jun 15 olle 948
3412 22 Jun 15 olle 949         StringToDateConverter dateConverter = new StringToDateConverter(new SimpleDateFormat("yyyyMMdd"));        
3412 22 Jun 15 olle 950         JSONArray jsonSpecimen = (JSONArray)jsonEm.get("specimen");
3412 22 Jun 15 olle 951                 
3412 22 Jun 15 olle 952         if (jsonSpecimen != null && jsonSpecimen.size() > 0)
3412 22 Jun 15 olle 953         {
3412 22 Jun 15 olle 954           int nofTubes = jsonSpecimen.size();
3412 22 Jun 15 olle 955           for (int i=0; i < jsonSpecimen.size(); i++)
3412 22 Jun 15 olle 956           {
3412 22 Jun 15 olle 957             JSONObject jsonSpec = (JSONObject)jsonSpecimen.get(i);
3412 22 Jun 15 olle 958             String itemName = (String)jsonSpec.get("name");
3412 22 Jun 15 olle 959             String type = (String)jsonSpec.get("type");
3412 22 Jun 15 olle 960             Date arrivalDate = dateConverter.convert((String)jsonSpec.get("arrivaldate"));        
3637 01 Dec 15 olle 961             String controlLotNo = Values.getStringOrNull((String)jsonSpec.get("controllotno"));
3412 22 Jun 15 olle 962             String operatorComment = Values.getStringOrNull((String)jsonSpec.get("comment"));
3412 22 Jun 15 olle 963             // Create items of correct types
3412 22 Jun 15 olle 964             if (type != null && type.equals("Specimen"))
3412 22 Jun 15 olle 965             {
3412 22 Jun 15 olle 966               Sample specimen = Sample.getNew(dc);
3412 22 Jun 15 olle 967               specimen.setItemSubtype(Subtype.SPECIMEN.load(dc));
3412 22 Jun 15 olle 968               specimen.setName(itemName);
3412 22 Jun 15 olle 969               dc.saveItem(specimen);
3412 22 Jun 15 olle 970               
3412 22 Jun 15 olle 971               BioMaterialEvent creationEvent = specimen.getCreationEvent();
3412 22 Jun 15 olle 972               // There is no case to link the specimen with
3412 22 Jun 15 olle 973               // There is no sampling date to set as create date
3412 22 Jun 15 olle 974               
3412 22 Jun 15 olle 975               setExtraMaterialAnnotations(dc, specimen, type, arrivalDate, operatorComment);
3412 22 Jun 15 olle 976
3412 22 Jun 15 olle 977               jsonMessages.add("Specimen tube '" + specimen.getName() + "' created successfully.");
3412 22 Jun 15 olle 978
3412 22 Jun 15 olle 979               // DNA extract from specimen
3412 22 Jun 15 olle 980               Extract dna = Extract.getNew(dc);
3412 22 Jun 15 olle 981               dna.setItemSubtype(Subtype.DNA.load(dc));
3412 22 Jun 15 olle 982               dna.setName(itemName + ".d");
3412 22 Jun 15 olle 983               BioMaterialEvent dnaEvent = dna.getCreationEvent();
3412 22 Jun 15 olle 984               dnaEvent.setSource(specimen);
3412 22 Jun 15 olle 985               dc.saveItem(dna);
3412 22 Jun 15 olle 986               jsonMessages.add("DNA extract '" + dna.getName() + "' created successfully.");
3412 22 Jun 15 olle 987
3412 22 Jun 15 olle 988               // RNA extract from specimen
3412 22 Jun 15 olle 989               Extract rna = Extract.getNew(dc);
3412 22 Jun 15 olle 990               rna.setItemSubtype(Subtype.RNA.load(dc));
3412 22 Jun 15 olle 991               rna.setName(itemName + ".r");
3412 22 Jun 15 olle 992               BioMaterialEvent rnaEvent = rna.getCreationEvent();
3412 22 Jun 15 olle 993               rnaEvent.setSource(specimen);
3412 22 Jun 15 olle 994               dc.saveItem(rna);
3412 22 Jun 15 olle 995               jsonMessages.add("RNA extract '" + rna.getName() + "' created successfully.");
3412 22 Jun 15 olle 996             }
3412 22 Jun 15 olle 997             else if (type != null)
3412 22 Jun 15 olle 998             {
3412 22 Jun 15 olle 999               Extract extract = Extract.getNew(dc);
3412 22 Jun 15 olle 1000               String extractTypeStr = "Extract";
3412 22 Jun 15 olle 1001               if (itemName.endsWith(".d"))
3412 22 Jun 15 olle 1002               {
3412 22 Jun 15 olle 1003                 extractTypeStr = "DNA";
3412 22 Jun 15 olle 1004                 extract.setItemSubtype(Subtype.DNA.load(dc));
3637 01 Dec 15 olle 1005                 if (controlLotNo != null && !controlLotNo.equals(""))
3637 01 Dec 15 olle 1006                 {
3637 01 Dec 15 olle 1007                   Annotationtype.CONTROL_LOT_NO.setAnnotationValue(dc, extract, controlLotNo);
3637 01 Dec 15 olle 1008                 }
3412 22 Jun 15 olle 1009               }
3412 22 Jun 15 olle 1010               else if (itemName.endsWith(".r"))
3412 22 Jun 15 olle 1011               {
3412 22 Jun 15 olle 1012                 extractTypeStr = "RNA";
3412 22 Jun 15 olle 1013                 extract.setItemSubtype(Subtype.RNA.load(dc));
3412 22 Jun 15 olle 1014               }
3412 22 Jun 15 olle 1015               extract.setName(itemName);
3412 22 Jun 15 olle 1016               dc.saveItem(extract);
3412 22 Jun 15 olle 1017               
3412 22 Jun 15 olle 1018               BioMaterialEvent creationEvent = extract.getCreationEvent();
3412 22 Jun 15 olle 1019               // There is no case to link the extract with
3412 22 Jun 15 olle 1020               // There is no sampling date to set as create date
3412 22 Jun 15 olle 1021               
3412 22 Jun 15 olle 1022               setExtraMaterialAnnotations(dc, extract, type, arrivalDate, operatorComment);
3412 22 Jun 15 olle 1023               jsonMessages.add(extractTypeStr + " tube '" + extract.getName() + "' created successfully.");
3412 22 Jun 15 olle 1024             }
3412 22 Jun 15 olle 1025           }
3412 22 Jun 15 olle 1026         }
3412 22 Jun 15 olle 1027                 
3412 22 Jun 15 olle 1028         dc.commit();
3412 22 Jun 15 olle 1029         json.put("messages", jsonMessages);
3412 22 Jun 15 olle 1030         CounterService.getInstance().setForceCount();
3412 22 Jun 15 olle 1031       }      
2933 14 Nov 14 olle 1032     }
2933 14 Nov 14 olle 1033     catch (Throwable t)
2933 14 Nov 14 olle 1034     {
2933 14 Nov 14 olle 1035       t.printStackTrace();
2933 14 Nov 14 olle 1036       json.clear();
2933 14 Nov 14 olle 1037       json.put("status", "error");
2933 14 Nov 14 olle 1038       json.put("message", t.getMessage());
2933 14 Nov 14 olle 1039       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
2933 14 Nov 14 olle 1040     }
2933 14 Nov 14 olle 1041     finally
2933 14 Nov 14 olle 1042     {
2933 14 Nov 14 olle 1043       if (dc != null) dc.close();
2933 14 Nov 14 olle 1044       json.writeJSONString(resp.getWriter());
2933 14 Nov 14 olle 1045     }
2933 14 Nov 14 olle 1046   }
2933 14 Nov 14 olle 1047   
2933 14 Nov 14 olle 1048
3028 11 Dec 14 olle 1049   private void setAnnotations(DbControl dc, Annotatable item, JSONObject jsonCase, int nofSections, String operatorComment)
3028 11 Dec 14 olle 1050   {
3028 11 Dec 14 olle 1051     String tubeContentType = Values.getStringOrNull((String)jsonCase.get("tubeContentType"));
3028 11 Dec 14 olle 1052     String specimenType = Values.getStringOrNull((String)jsonCase.get("specimenType"));
4195 31 Oct 16 olle 1053     String specimenInputType = Values.getStringOrNull((String)jsonCase.get("specimenInputType"));
3028 11 Dec 14 olle 1054     StringToDateConverter dateConverter = new StringToDateConverter(new SimpleDateFormat("yyyyMMdd"));        
3028 11 Dec 14 olle 1055     Date arrivalDate = dateConverter.convert((String)jsonCase.get("arrivalDate"));        
3028 11 Dec 14 olle 1056     Date samplingDate = dateConverter.convert((String)jsonCase.get("samplingDate"));
3067 08 Jan 15 olle 1057     Integer viableTumourCellsPercent = null;
3067 08 Jan 15 olle 1058     String viableTumourCellsPercentString = (String)jsonCase.get("viableTumourCellsPercent");
3067 08 Jan 15 olle 1059     if (viableTumourCellsPercentString != null && !viableTumourCellsPercentString.equals(""))
3067 08 Jan 15 olle 1060     {
3067 08 Jan 15 olle 1061       viableTumourCellsPercent = Integer.parseInt(viableTumourCellsPercentString);
3067 08 Jan 15 olle 1062     }
3028 11 Dec 14 olle 1063     if (tubeContentType != null && tubeContentType.equals("Specimen"))
3028 11 Dec 14 olle 1064     {
3028 11 Dec 14 olle 1065       Annotationtype.NOF_SECTIONS.setAnnotationValue(dc, item, nofSections);
3028 11 Dec 14 olle 1066       Annotationtype.SPECIMEN_TYPE.setAnnotationValue(dc, item, specimenType);
4195 31 Oct 16 olle 1067       Annotationtype.SPECIMEN_INPUT_TYPE.setAnnotationValue(dc, item, specimenInputType);
3028 11 Dec 14 olle 1068       // The following annotations should not necessarily be restricted to specimens
3028 11 Dec 14 olle 1069       Annotationtype.ARRIVAL_DATE.setAnnotationValue(dc, item, arrivalDate);            
3028 11 Dec 14 olle 1070       Annotationtype.SAMPLING_DATE.setAnnotationValue(dc, item, samplingDate);
3067 08 Jan 15 olle 1071       Annotationtype.VIABLE_TUMOUR_CELLS_PERCENT.setAnnotationValue(dc, item, viableTumourCellsPercent);
3028 11 Dec 14 olle 1072       Annotationtype.OPERATOR_DELIVERY_COMMENT.setAnnotationValue(dc, item, operatorComment);  
3028 11 Dec 14 olle 1073     }
3318 08 May 15 olle 1074     else if (tubeContentType != null)
3318 08 May 15 olle 1075     {
3318 08 May 15 olle 1076       Annotationtype.SPECIMEN_TYPE_EXTRACT.setAnnotationValue(dc, item, specimenType);
3318 08 May 15 olle 1077       Annotationtype.ARRIVAL_DATE_EXTRACT.setAnnotationValue(dc, item, arrivalDate);            
3318 08 May 15 olle 1078       Annotationtype.SAMPLING_DATE_EXTRACT.setAnnotationValue(dc, item, samplingDate);
3318 08 May 15 olle 1079       Annotationtype.VIABLE_TUMOUR_CELLS_PERCENT_EXTRACT.setAnnotationValue(dc, item, viableTumourCellsPercent);
3318 08 May 15 olle 1080       Annotationtype.OPERATOR_DELIVERY_COMMENT_EXTRACT.setAnnotationValue(dc, item, operatorComment);  
3318 08 May 15 olle 1081     }
3028 11 Dec 14 olle 1082   }
3028 11 Dec 14 olle 1083
3028 11 Dec 14 olle 1084
3412 22 Jun 15 olle 1085   private void setExtraMaterialAnnotations(DbControl dc, Annotatable item, String tubeContentType, Date arrivalDate, String operatorComment)
3412 22 Jun 15 olle 1086   {
3412 22 Jun 15 olle 1087     if (tubeContentType != null && tubeContentType.equals("Specimen"))
3412 22 Jun 15 olle 1088     {
3412 22 Jun 15 olle 1089       // The following annotations should not necessarily be restricted to specimens
3412 22 Jun 15 olle 1090       Annotationtype.ARRIVAL_DATE.setAnnotationValue(dc, item, arrivalDate);            
3412 22 Jun 15 olle 1091       Annotationtype.OPERATOR_DELIVERY_COMMENT.setAnnotationValue(dc, item, operatorComment);  
3412 22 Jun 15 olle 1092     }
3412 22 Jun 15 olle 1093     else if (tubeContentType != null)
3412 22 Jun 15 olle 1094     {
3412 22 Jun 15 olle 1095       Annotationtype.ARRIVAL_DATE_EXTRACT.setAnnotationValue(dc, item, arrivalDate);            
3412 22 Jun 15 olle 1096       Annotationtype.OPERATOR_DELIVERY_COMMENT_EXTRACT.setAnnotationValue(dc, item, operatorComment);  
3412 22 Jun 15 olle 1097     }
3412 22 Jun 15 olle 1098   }
3412 22 Jun 15 olle 1099
3412 22 Jun 15 olle 1100
3478 03 Sep 15 olle 1101   private BioWell fetchBioWell(DbControl dc, JSONObject jsonSpec, HashMap<String, BioPlate> bioPlateNamePlateHashMap)
3028 11 Dec 14 olle 1102   {
3276 29 Apr 15 olle 1103     String boxType = null;
3478 03 Sep 15 olle 1104     BioWell well = fetchBioWell(dc, jsonSpec, bioPlateNamePlateHashMap, boxType);
3276 29 Apr 15 olle 1105     return well;
3276 29 Apr 15 olle 1106   }
3276 29 Apr 15 olle 1107
3276 29 Apr 15 olle 1108
3478 03 Sep 15 olle 1109   private BioWell fetchBioWell(DbControl dc, JSONObject jsonSpec, HashMap<String, BioPlate> bioPlateNamePlateHashMap, String boxType)
3276 29 Apr 15 olle 1110   {
3028 11 Dec 14 olle 1111     BioWell well = null;
3276 29 Apr 15 olle 1112     String boxKey = "box";
3276 29 Apr 15 olle 1113     String rowKey = "row";
3276 29 Apr 15 olle 1114     String columnKey = "column";
3276 29 Apr 15 olle 1115     if (boxType != null && boxType.equals("DNA"))
3276 29 Apr 15 olle 1116     {
3276 29 Apr 15 olle 1117       boxKey = "dnaBox";
3276 29 Apr 15 olle 1118       rowKey = "dnaRow";
3276 29 Apr 15 olle 1119       columnKey = "dnaColumn";
3276 29 Apr 15 olle 1120     }
3276 29 Apr 15 olle 1121     else if (boxType != null && boxType.equals("RNA"))
3276 29 Apr 15 olle 1122     {
3276 29 Apr 15 olle 1123       boxKey = "rnaBox";
3276 29 Apr 15 olle 1124       rowKey = "rnaRow";
3276 29 Apr 15 olle 1125       columnKey = "rnaColumn";
3276 29 Apr 15 olle 1126     }
3028 11 Dec 14 olle 1127     // Set biowell if it is specified for this tube
3276 29 Apr 15 olle 1128     String box = (String)jsonSpec.get(boxKey);
3276 29 Apr 15 olle 1129     String rowString = (String)jsonSpec.get(rowKey);
3276 29 Apr 15 olle 1130     String columnString = (String)jsonSpec.get(columnKey);
3478 03 Sep 15 olle 1131
3478 03 Sep 15 olle 1132     BioPlate plate = null;
3028 11 Dec 14 olle 1133     StoragePlate storageBox = StoragePlate.findByName(dc, box);
3478 03 Sep 15 olle 1134     if (storageBox != null)
3478 03 Sep 15 olle 1135     {
3478 03 Sep 15 olle 1136       plate = storageBox.getBioPlate();
3478 03 Sep 15 olle 1137     }
3478 03 Sep 15 olle 1138     else if (box != null && !box.equals(""))
3478 03 Sep 15 olle 1139     {
3478 03 Sep 15 olle 1140       // Use already created new storage box, if existing
3478 03 Sep 15 olle 1141       plate = (BioPlate) bioPlateNamePlateHashMap.get(box);
3478 03 Sep 15 olle 1142       if (plate == null)
3478 03 Sep 15 olle 1143       {
3478 03 Sep 15 olle 1144         // Create new storage box
3478 03 Sep 15 olle 1145         plate = createStorageBox(dc, box);
3478 03 Sep 15 olle 1146         dc.saveItem(plate);
3478 03 Sep 15 olle 1147         // Update hash map with new plate
3478 03 Sep 15 olle 1148         bioPlateNamePlateHashMap.put(box, plate);
3478 03 Sep 15 olle 1149       }
3478 03 Sep 15 olle 1150     }
3028 11 Dec 14 olle 1151
3478 03 Sep 15 olle 1152     // Get storage space for specimen, if former is valid
3028 11 Dec 14 olle 1153     if (box != null && !box.equals("") && rowString != null && !rowString.equals("") && columnString != null && !columnString.equals(""))
3028 11 Dec 14 olle 1154     {
3028 11 Dec 14 olle 1155       WellCoordinateFormatter wcfRow = new WellCoordinateFormatter(true);
3028 11 Dec 14 olle 1156       Integer rowIndex = wcfRow.parseString(rowString)-1;
3478 03 Sep 15 olle 1157       Integer columnIndex = Integer.parseInt(columnString)-1;
3028 11 Dec 14 olle 1158       well = plate.getBioWell(rowIndex, columnIndex);
3028 11 Dec 14 olle 1159     }
3028 11 Dec 14 olle 1160     return well;
3028 11 Dec 14 olle 1161   }
3028 11 Dec 14 olle 1162
3028 11 Dec 14 olle 1163
2933 14 Nov 14 olle 1164   /**
3478 03 Sep 15 olle 1165    * Creates a storage box BioPlate item with a name having
3478 03 Sep 15 olle 1166    * given plate prefix, suffix, and number.
3478 03 Sep 15 olle 1167    * Note that the returned BioPlate item will not automatically
3478 03 Sep 15 olle 1168    * be stored in the database.
3478 03 Sep 15 olle 1169    * 
3478 03 Sep 15 olle 1170    * @param dc DbControl The DbControl to use
3478 03 Sep 15 olle 1171    * @param platePrefix String The plate prefix of the bioplate to create
4217 09 Nov 16 olle 1172    * @param plateNumDigits Integer The number of digits in the name of the bioplate to create
3478 03 Sep 15 olle 1173    * @param plateSuffix String The plate suffix of the bioplate to create
3478 03 Sep 15 olle 1174    * @param plateNumber int The plate number of the bioplate to create
3478 03 Sep 15 olle 1175    * @return BioPlate The created BioPlate item
3478 03 Sep 15 olle 1176    */
3478 03 Sep 15 olle 1177   @SuppressWarnings("unchecked")
4217 09 Nov 16 olle 1178   private BioPlate createStorageBox(DbControl dc, String platePrefix, Integer plateNumDigits, String plateSuffix, int plateNumber)
4217 09 Nov 16 olle 1179   {
4217 09 Nov 16 olle 1180     Integer numDigits = plateNumDigits;
4217 09 Nov 16 olle 1181     if (numDigits == null || numDigits < 1)
4217 09 Nov 16 olle 1182     {
4217 09 Nov 16 olle 1183       numDigits = 4;
4217 09 Nov 16 olle 1184     }
3478 03 Sep 15 olle 1185     // Get new plate name
3478 03 Sep 15 olle 1186     String plateNumberStr = "" + plateNumber;
4217 09 Nov 16 olle 1187     while (plateNumberStr.length() < numDigits)
3478 03 Sep 15 olle 1188     {
3478 03 Sep 15 olle 1189       plateNumberStr = "0" + plateNumberStr;
3478 03 Sep 15 olle 1190     }
3478 03 Sep 15 olle 1191     String plateName = platePrefix + plateNumberStr + plateSuffix;
3478 03 Sep 15 olle 1192     // Create new storage box
3478 03 Sep 15 olle 1193     BioPlate box = createStorageBox(dc, plateName);
3478 03 Sep 15 olle 1194     return box;
3478 03 Sep 15 olle 1195   }
3478 03 Sep 15 olle 1196
3478 03 Sep 15 olle 1197   /**
3478 03 Sep 15 olle 1198    * Creates a storage box BioPlate item with a given name.
3478 03 Sep 15 olle 1199    * Note that the returned BioPlate item will not automatically
3478 03 Sep 15 olle 1200    * be stored in the database.
3478 03 Sep 15 olle 1201    * 
3478 03 Sep 15 olle 1202    * @param dc DbControl The DbControl to use
3478 03 Sep 15 olle 1203    * @param plateName String Name of the bioplate to create
3478 03 Sep 15 olle 1204    * @return BioPlate The created BioPlate item
3478 03 Sep 15 olle 1205    */
3478 03 Sep 15 olle 1206   @SuppressWarnings("unchecked")
3478 03 Sep 15 olle 1207   private BioPlate createStorageBox(DbControl dc, String plateName)
3478 03 Sep 15 olle 1208   {  
3478 03 Sep 15 olle 1209     // Get plate geometry for storage box (81-well (9 x 9))
3478 03 Sep 15 olle 1210     ItemQuery<PlateGeometry> plateGeometryQuery = PlateGeometry.getQuery();
3478 03 Sep 15 olle 1211     plateGeometryQuery.restrict(Restrictions.eq(Hql.property("name"), Expressions.string("81-well (9 x 9)")));
3478 03 Sep 15 olle 1212     ItemResultList<PlateGeometry> plateGeometryList = plateGeometryQuery.list(dc);
3478 03 Sep 15 olle 1213     PlateGeometry geometry = null;
3478 03 Sep 15 olle 1214     if (plateGeometryList != null && plateGeometryList.size() > 0)
3478 03 Sep 15 olle 1215     {
3478 03 Sep 15 olle 1216       geometry = (PlateGeometry) plateGeometryList.get(0);
3478 03 Sep 15 olle 1217     }
3478 03 Sep 15 olle 1218     // Get bioplate type for storage plate (Storage plate)
3478 03 Sep 15 olle 1219     ItemQuery<BioPlateType> bioPlateTypeQuery = BioPlateType.getQuery();
3478 03 Sep 15 olle 1220     bioPlateTypeQuery.restrict(Restrictions.eq(Hql.property("name"), Expressions.string("Storage plate")));
3478 03 Sep 15 olle 1221     ItemResultList<BioPlateType> bioPlateTypeList = bioPlateTypeQuery.list(dc);
3478 03 Sep 15 olle 1222     BioPlateType plateType = null;
3478 03 Sep 15 olle 1223     if (bioPlateTypeList != null && bioPlateTypeList.size() > 0)
3478 03 Sep 15 olle 1224     {
3478 03 Sep 15 olle 1225       plateType = (BioPlateType) bioPlateTypeList.get(0);
3478 03 Sep 15 olle 1226     }
3478 03 Sep 15 olle 1227     // Create new storage box
3478 03 Sep 15 olle 1228     BioPlate box = BioPlate.getNew(dc, geometry, plateType);
3478 03 Sep 15 olle 1229     box.setName(plateName);
3478 03 Sep 15 olle 1230     return box;
3478 03 Sep 15 olle 1231   }
3478 03 Sep 15 olle 1232
3478 03 Sep 15 olle 1233
3478 03 Sep 15 olle 1234   /**
2933 14 Nov 14 olle 1235    * Returns the site for the sample, based on the latter's site annotation.
2933 14 Nov 14 olle 1236    * 
2933 14 Nov 14 olle 1237    * @param dc DbControl The DbControl to use.
2933 14 Nov 14 olle 1238    * @param manager SnapshotManager The SnapshotManager to use for speeding up annotation retrieval.
2933 14 Nov 14 olle 1239    * @param s Sample The sample to find the site for.
2933 14 Nov 14 olle 1240    * @return Site The site object found for the sample or UNKNOWN.
2933 14 Nov 14 olle 1241    */
2933 14 Nov 14 olle 1242   private Site fetchSite(DbControl dc, SnapshotManager manager, Sample s)
2933 14 Nov 14 olle 1243   {
2933 14 Nov 14 olle 1244     Site site = Site.UNKNOWN;
2933 14 Nov 14 olle 1245     String prefix = (String) Annotationtype.SITE.getAnnotationValue(dc, manager, s);
2933 14 Nov 14 olle 1246     if (prefix != null)
2933 14 Nov 14 olle 1247     {
2933 14 Nov 14 olle 1248       site = Site.findByPrefix(prefix);
2933 14 Nov 14 olle 1249     }
2933 14 Nov 14 olle 1250     return site;
2933 14 Nov 14 olle 1251   }
2933 14 Nov 14 olle 1252
2933 14 Nov 14 olle 1253
2933 14 Nov 14 olle 1254   /**
2933 14 Nov 14 olle 1255    * Convenience method that replaces an empty string with `null`.
2933 14 Nov 14 olle 1256    * 
2933 14 Nov 14 olle 1257    * @param str The input string.
2933 14 Nov 14 olle 1258    * @return String The input string; replaced with `null` if empty string.
2933 14 Nov 14 olle 1259    */
2933 14 Nov 14 olle 1260   private String replaceBlankWithNull(String str)
2933 14 Nov 14 olle 1261   {
2933 14 Nov 14 olle 1262     if (str != null && str.equals(""))
2933 14 Nov 14 olle 1263     {
2933 14 Nov 14 olle 1264       str = null;
2933 14 Nov 14 olle 1265     }
2933 14 Nov 14 olle 1266     return str;
2933 14 Nov 14 olle 1267   }
2933 14 Nov 14 olle 1268
2933 14 Nov 14 olle 1269
2933 14 Nov 14 olle 1270   /**
2933 14 Nov 14 olle 1271    * Updates an input mutation analysis list with new String entry if
2933 14 Nov 14 olle 1272    * a boolean flag set to true is found for the specified String key
2933 14 Nov 14 olle 1273    * in the input JSONObject. A string entry is only added once to the
2933 14 Nov 14 olle 1274    * mutation analysis list.
2933 14 Nov 14 olle 1275    * 
2933 14 Nov 14 olle 1276    * @param jsonCase JSONObject The JSONObject to check for mutation analysis flag.
2933 14 Nov 14 olle 1277    * @param jsonKey String JSON key for Boolean mutation analysis flag.
2933 14 Nov 14 olle 1278    * @param mutationAnalysisStr String The annotation string to add to mutation analysis list, if flag is true.
2933 14 Nov 14 olle 1279    * @param mutationAnalysisList List<String> Input mutation analysis list to be updated with new entry if flag is true.
2933 14 Nov 14 olle 1280    * @return List<String> Input mutation analysis list optionally updated with new entry.
2933 14 Nov 14 olle 1281    */
2933 14 Nov 14 olle 1282   private List<String> fetchMutationAnalysisList(JSONObject jsonCase, String jsonKey, String mutationAnalysisStr, List<String> mutationAnalysisList)
2933 14 Nov 14 olle 1283   {
2933 14 Nov 14 olle 1284     if (jsonCase != null && jsonKey != null && mutationAnalysisList != null)
2933 14 Nov 14 olle 1285     {
2933 14 Nov 14 olle 1286       Boolean isIncluded = (Boolean)jsonCase.get(jsonKey);
2933 14 Nov 14 olle 1287       if (isIncluded != null && isIncluded)
2933 14 Nov 14 olle 1288       {
2933 14 Nov 14 olle 1289         if (!mutationAnalysisList.contains(mutationAnalysisStr))
2933 14 Nov 14 olle 1290         {
2933 14 Nov 14 olle 1291           mutationAnalysisList.add(mutationAnalysisStr);
2933 14 Nov 14 olle 1292         }
2933 14 Nov 14 olle 1293       }
2933 14 Nov 14 olle 1294     }
2933 14 Nov 14 olle 1295     return mutationAnalysisList;
2933 14 Nov 14 olle 1296   }
2933 14 Nov 14 olle 1297
2933 14 Nov 14 olle 1298
3042 16 Dec 14 olle 1299   /**
3287 30 Apr 15 olle 1300    * Get first filled well for a bioplate.
3287 30 Apr 15 olle 1301    * 
3287 30 Apr 15 olle 1302    * @param plate BioPlate The storage plate/box to find first filled well in.
3287 30 Apr 15 olle 1303    * @return BioWell First filled well in the bioplate, or `null` if none found.
3287 30 Apr 15 olle 1304    */
3287 30 Apr 15 olle 1305   private BioWell getFirstFilledWell(BioPlate plate)
3287 30 Apr 15 olle 1306   {
3287 30 Apr 15 olle 1307     // First filled well in the plate. 
3287 30 Apr 15 olle 1308     BioWell firstFilledWell = null;    
3287 30 Apr 15 olle 1309     boolean foundNextFilled = false;          
3287 30 Apr 15 olle 1310     for (int row = 0; row < plate.getRows() && !foundNextFilled; row++)
3287 30 Apr 15 olle 1311     {
3287 30 Apr 15 olle 1312       for (int col = 0; col < plate.getColumns() && !foundNextFilled; col++)
3287 30 Apr 15 olle 1313       { 
3287 30 Apr 15 olle 1314         if (!plate.getBioWell(row, col).isEmpty())
3287 30 Apr 15 olle 1315         {
3287 30 Apr 15 olle 1316           firstFilledWell = plate.getBioWell(row, col);
3287 30 Apr 15 olle 1317           foundNextFilled = true;
3287 30 Apr 15 olle 1318         }
3287 30 Apr 15 olle 1319       }
3287 30 Apr 15 olle 1320     }    
3287 30 Apr 15 olle 1321     return firstFilledWell;
3287 30 Apr 15 olle 1322   }
3287 30 Apr 15 olle 1323   
3287 30 Apr 15 olle 1324   /**
3042 16 Dec 14 olle 1325    * Get first free well for a bioplate.
3042 16 Dec 14 olle 1326    * 
3042 16 Dec 14 olle 1327    * @param plate BioPlate The storage plate/box to find first free well in.
3042 16 Dec 14 olle 1328    * @return BioWell First free well in the bioplate, or `null` if none found.
3042 16 Dec 14 olle 1329    */
3042 16 Dec 14 olle 1330   private BioWell getFirstFreeWell(BioPlate plate)
2933 14 Nov 14 olle 1331   {
3042 16 Dec 14 olle 1332     // First free well in the plate. 
3287 30 Apr 15 olle 1333     BioWell firstFreeWell = null;
3042 16 Dec 14 olle 1334     boolean foundNextEmpty = false;          
3042 16 Dec 14 olle 1335     for (int row = 0; row < plate.getRows() && !foundNextEmpty; row++)
2933 14 Nov 14 olle 1336     {
3042 16 Dec 14 olle 1337       for (int col = 0; col < plate.getColumns() && !foundNextEmpty; col++)
2933 14 Nov 14 olle 1338       { 
3042 16 Dec 14 olle 1339         if (plate.getBioWell(row, col).isEmpty())
2933 14 Nov 14 olle 1340         {
3042 16 Dec 14 olle 1341           firstFreeWell = plate.getBioWell(row, col);
3042 16 Dec 14 olle 1342           foundNextEmpty = true;
2933 14 Nov 14 olle 1343         }
2933 14 Nov 14 olle 1344       }
2933 14 Nov 14 olle 1345     }    
2933 14 Nov 14 olle 1346     return firstFreeWell;
2933 14 Nov 14 olle 1347   }
2933 14 Nov 14 olle 1348   
3042 16 Dec 14 olle 1349   /**
3285 29 Apr 15 olle 1350    * Get first free well for a bioplate without filling gaps.
3285 29 Apr 15 olle 1351    * The well found is the first free well with only free wells
3285 29 Apr 15 olle 1352    * following until the end of the plate (lower right corner).
3285 29 Apr 15 olle 1353    * 
3285 29 Apr 15 olle 1354    * @param plate BioPlate The storage plate/box to find first free well in.
3285 29 Apr 15 olle 1355    * @return BioWell First free well in the bioplate, or `null` if none found.
3285 29 Apr 15 olle 1356    */
3285 29 Apr 15 olle 1357   private BioWell getFirstFreeWellWithoutFillingGaps(BioPlate plate)
3285 29 Apr 15 olle 1358   {
3285 29 Apr 15 olle 1359     // First free well in the plate, without filling gaps. 
3285 29 Apr 15 olle 1360     BioWell firstFreeWell = null;    
3285 29 Apr 15 olle 1361     boolean foundPreviousFilled = false;
3285 29 Apr 15 olle 1362     // Check wells backwards, starting at the lower right corner,
3285 29 Apr 15 olle 1363     // until a filled well or the first well is found.
3285 29 Apr 15 olle 1364     for (int row = plate.getRows() - 1; row >= 0 && !foundPreviousFilled; row--)
3285 29 Apr 15 olle 1365     {
3285 29 Apr 15 olle 1366       for (int col = plate.getColumns() - 1; col >= 0 && !foundPreviousFilled; col--)
3285 29 Apr 15 olle 1367       { 
3285 29 Apr 15 olle 1368         if (plate.getBioWell(row, col).isEmpty())
3285 29 Apr 15 olle 1369         {
3285 29 Apr 15 olle 1370           firstFreeWell = plate.getBioWell(row, col);
3285 29 Apr 15 olle 1371         }
3285 29 Apr 15 olle 1372         else
3285 29 Apr 15 olle 1373         {
3285 29 Apr 15 olle 1374           foundPreviousFilled = true;
3285 29 Apr 15 olle 1375         }
3285 29 Apr 15 olle 1376       }
3285 29 Apr 15 olle 1377     }    
3285 29 Apr 15 olle 1378     return firstFreeWell;
3285 29 Apr 15 olle 1379   }
3285 29 Apr 15 olle 1380   
3285 29 Apr 15 olle 1381   /**
3042 16 Dec 14 olle 1382    * Get next free well for a bioplate.
3042 16 Dec 14 olle 1383    * 
3042 16 Dec 14 olle 1384    * @param well BioWell The current well in the storage plate/box.
3042 16 Dec 14 olle 1385    * @return BioWell Next free well in the bioplate, or `null` if none found.
3042 16 Dec 14 olle 1386    */
2933 14 Nov 14 olle 1387   private BioWell getNextFreeWell(BioWell well)
2933 14 Nov 14 olle 1388   {
3042 16 Dec 14 olle 1389     // Next free well in the plate. 
3042 16 Dec 14 olle 1390     BioWell nextFreeWell = null;
2933 14 Nov 14 olle 1391     BioPlate plate = well.getPlate();
2933 14 Nov 14 olle 1392     int numColumns = plate.getColumns();
3042 16 Dec 14 olle 1393
3042 16 Dec 14 olle 1394     // Get position for next well
2933 14 Nov 14 olle 1395     int nextPos = well.getRow() * numColumns + well.getColumn()+1;
3042 16 Dec 14 olle 1396     int nextRow = nextPos / numColumns;
2933 14 Nov 14 olle 1397     int nextCol = nextPos % numColumns;
2933 14 Nov 14 olle 1398     
3042 16 Dec 14 olle 1399     boolean foundNextEmpty = false;          
3042 16 Dec 14 olle 1400     for (int row = nextRow; row < plate.getRows() && !foundNextEmpty; row++)
3042 16 Dec 14 olle 1401     {
3042 16 Dec 14 olle 1402       for (int col = nextCol; col < plate.getColumns() && !foundNextEmpty; col++)
3042 16 Dec 14 olle 1403       { 
3042 16 Dec 14 olle 1404         if (plate.getBioWell(row, col).isEmpty())
3042 16 Dec 14 olle 1405         {
3042 16 Dec 14 olle 1406           nextFreeWell = plate.getBioWell(row, col);
3042 16 Dec 14 olle 1407           foundNextEmpty = true;
3042 16 Dec 14 olle 1408         }
3042 16 Dec 14 olle 1409       }
3042 16 Dec 14 olle 1410     }    
3042 16 Dec 14 olle 1411     return nextFreeWell;
2933 14 Nov 14 olle 1412   }
2933 14 Nov 14 olle 1413 }