extensions/net.sf.basedb.meludi/trunk/src/net/sf/basedb/meludi/servlet/PersonalRegistrationServlet.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;
4189 28 Oct 16 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
2933 14 Nov 14 olle 15 import org.json.simple.JSONArray;
2933 14 Nov 14 olle 16 import org.json.simple.JSONObject;
2933 14 Nov 14 olle 17 import org.json.simple.parser.JSONParser;
2933 14 Nov 14 olle 18
3028 11 Dec 14 olle 19 import net.sf.basedb.core.Annotatable;
2933 14 Nov 14 olle 20 import net.sf.basedb.core.Application;
2933 14 Nov 14 olle 21 import net.sf.basedb.core.BioMaterialEvent;
2933 14 Nov 14 olle 22 import net.sf.basedb.core.BioPlate;
4189 28 Oct 16 olle 23 import net.sf.basedb.core.BioPlateType;
2933 14 Nov 14 olle 24 import net.sf.basedb.core.BioSource;
2933 14 Nov 14 olle 25 import net.sf.basedb.core.BioWell;
2933 14 Nov 14 olle 26 import net.sf.basedb.core.DbControl;
3028 11 Dec 14 olle 27 import net.sf.basedb.core.Extract;
2933 14 Nov 14 olle 28 import net.sf.basedb.core.InvalidDataException;
4189 28 Oct 16 olle 29 import net.sf.basedb.core.ItemQuery;
4189 28 Oct 16 olle 30 import net.sf.basedb.core.ItemResultList;
4189 28 Oct 16 olle 31 import net.sf.basedb.core.PlateGeometry;
2933 14 Nov 14 olle 32 import net.sf.basedb.core.Sample;
2933 14 Nov 14 olle 33 import net.sf.basedb.core.SessionControl;
4189 28 Oct 16 olle 34 import net.sf.basedb.core.query.Expressions;
4189 28 Oct 16 olle 35 import net.sf.basedb.core.query.Hql;
4189 28 Oct 16 olle 36 import net.sf.basedb.core.query.Restrictions;
2933 14 Nov 14 olle 37 import net.sf.basedb.meludi.JsonUtil;
2933 14 Nov 14 olle 38 import net.sf.basedb.meludi.Meludi;
2933 14 Nov 14 olle 39 import net.sf.basedb.meludi.Site;
2933 14 Nov 14 olle 40 import net.sf.basedb.meludi.converter.StringToDateConverter;
2933 14 Nov 14 olle 41 import net.sf.basedb.meludi.dao.Annotationtype;
2933 14 Nov 14 olle 42 import net.sf.basedb.meludi.dao.Case;
3028 11 Dec 14 olle 43 import net.sf.basedb.meludi.dao.Dna;
2933 14 Nov 14 olle 44 import net.sf.basedb.meludi.dao.Patient;
2933 14 Nov 14 olle 45 import net.sf.basedb.meludi.dao.MeludiRole;
3028 11 Dec 14 olle 46 import net.sf.basedb.meludi.dao.Rna;
2933 14 Nov 14 olle 47 import net.sf.basedb.meludi.dao.SpecimenTube;
2933 14 Nov 14 olle 48 import net.sf.basedb.meludi.dao.StoragePlate;
2933 14 Nov 14 olle 49 import net.sf.basedb.meludi.dao.Subtype;
3101 21 Jan 15 olle 50 import net.sf.basedb.meludi.counter.CounterService;
2933 14 Nov 14 olle 51 import net.sf.basedb.util.MD5;
2933 14 Nov 14 olle 52 import net.sf.basedb.util.Values;
2933 14 Nov 14 olle 53 import net.sf.basedb.util.error.ThrowableUtil;
2933 14 Nov 14 olle 54 import net.sf.basedb.util.formatter.WellCoordinateFormatter;
2933 14 Nov 14 olle 55
2933 14 Nov 14 olle 56
2933 14 Nov 14 olle 57 public class PersonalRegistrationServlet 
2933 14 Nov 14 olle 58   extends HttpServlet 
2933 14 Nov 14 olle 59 {
2933 14 Nov 14 olle 60
2933 14 Nov 14 olle 61   private static final long serialVersionUID = 8770173686061080429L;
2933 14 Nov 14 olle 62   
2933 14 Nov 14 olle 63   public PersonalRegistrationServlet()
2933 14 Nov 14 olle 64   {}
2933 14 Nov 14 olle 65
2933 14 Nov 14 olle 66   @SuppressWarnings("unchecked")
2933 14 Nov 14 olle 67   @Override
2933 14 Nov 14 olle 68   protected void doGet(HttpServletRequest req, HttpServletResponse resp)
2933 14 Nov 14 olle 69     throws ServletException, IOException 
2933 14 Nov 14 olle 70   {
2933 14 Nov 14 olle 71
2933 14 Nov 14 olle 72     String ID = req.getParameter("ID");
2933 14 Nov 14 olle 73     String cmd = req.getParameter("cmd");
2933 14 Nov 14 olle 74     JsonUtil.setJsonResponseHeaders(resp);
2933 14 Nov 14 olle 75     
2933 14 Nov 14 olle 76     JSONObject json = new JSONObject();
2933 14 Nov 14 olle 77     json.put("status", "ok");
2933 14 Nov 14 olle 78   
5468 04 Jun 19 olle 79     //final SessionControl sc = Application.getSessionControl(ID, req.getRemoteAddr());
5744 20 Nov 19 olle 80     //final SessionControl sc  = Application.getSessionControl(ID, "", req.getRemoteAddr(), true);
5744 20 Nov 19 olle 81     final SessionControl sc  = Application.getSessionControl(ID, null, req.getRemoteAddr(), true);
2933 14 Nov 14 olle 82     DbControl dc = null;
2933 14 Nov 14 olle 83     try
2933 14 Nov 14 olle 84     {
2933 14 Nov 14 olle 85       if ("GetCaseInfo".equals(cmd))
2933 14 Nov 14 olle 86       {
2933 14 Nov 14 olle 87         /*
2933 14 Nov 14 olle 88           Load information about a single case when given the case name/barcode
2933 14 Nov 14 olle 89           If a case is found we will load annotations, the patient it is associated with
2933 14 Nov 14 olle 90           and specimen tubes for the case. If no case is found we check to see
2933 14 Nov 14 olle 91           if there are any specimen tubes that have the case name as prefix and
2933 14 Nov 14 olle 92           load information about them.
2933 14 Nov 14 olle 93         */
2933 14 Nov 14 olle 94         dc = sc.newDbControl();
2933 14 Nov 14 olle 95         
2933 14 Nov 14 olle 96         // Find a case by name
2933 14 Nov 14 olle 97         String caseName = req.getParameter("caseName");
2933 14 Nov 14 olle 98         Site site = Site.findByCaseName(caseName);
2933 14 Nov 14 olle 99         Case theCase = Case.findByName(dc, caseName);
2933 14 Nov 14 olle 100         
2933 14 Nov 14 olle 101         List<SpecimenTube> specimenTubes = null;
3028 11 Dec 14 olle 102         List<Dna> dnaTubes = null;
3028 11 Dec 14 olle 103         List<Rna> rnaTubes = null;
2933 14 Nov 14 olle 104         JSONObject jsonCase = null;
3028 11 Dec 14 olle 105         
2933 14 Nov 14 olle 106         int numExisting = 0;
2933 14 Nov 14 olle 107         if (theCase != null)
2933 14 Nov 14 olle 108         {
3028 11 Dec 14 olle 109           theCase.loadAnnotations(dc, "tubeContentType", Annotationtype.TUBE_CONTENT_TYPE, null);
3028 11 Dec 14 olle 110
2933 14 Nov 14 olle 111           // Load specimen tubes for the case
2966 20 Nov 14 olle 112           specimenTubes = SpecimenTube.findByCase(dc, theCase, caseName);
2933 14 Nov 14 olle 113           if (specimenTubes.size() == 0)
2933 14 Nov 14 olle 114           {
2933 14 Nov 14 olle 115             // No specimen tubes are linked with the case -- see if we can find some unlinked
2966 20 Nov 14 olle 116             specimenTubes = SpecimenTube.findByCaseName(dc, caseName);
2933 14 Nov 14 olle 117           }
2933 14 Nov 14 olle 118           
3028 11 Dec 14 olle 119           // Load DNA tubes for the case
3028 11 Dec 14 olle 120           dnaTubes = Dna.findByCaseName(dc, caseName);
3028 11 Dec 14 olle 121           
3028 11 Dec 14 olle 122           // Load RNA tubes for the case
3028 11 Dec 14 olle 123           rnaTubes = Rna.findByCaseName(dc, caseName);
3028 11 Dec 14 olle 124           
2933 14 Nov 14 olle 125           // Wrap what we have so far up into JSON objects
2933 14 Nov 14 olle 126           jsonCase = theCase.asJSONObject();
2933 14 Nov 14 olle 127           
2933 14 Nov 14 olle 128           // Load the patient associated with the case
2933 14 Nov 14 olle 129           Patient patient = Patient.findByCase(dc, theCase);
2933 14 Nov 14 olle 130           // The patient can be null if (for example) we have only registered consent=yes so far
2933 14 Nov 14 olle 131           if (patient != null) 
2933 14 Nov 14 olle 132           {
2933 14 Nov 14 olle 133             patient.loadDefaultAnnotations(dc);
2933 14 Nov 14 olle 134             jsonCase.put("patient", patient.asJSONObject());
2933 14 Nov 14 olle 135           }
2933 14 Nov 14 olle 136         }
2933 14 Nov 14 olle 137         else
2933 14 Nov 14 olle 138         {
2933 14 Nov 14 olle 139           // Could not find the registered case -- see if we can find any specimen tubes
2966 20 Nov 14 olle 140           specimenTubes = SpecimenTube.findByCaseName(dc, caseName);
2933 14 Nov 14 olle 141           // Get rid of suffix in the case name
4148 03 Oct 16 olle 142           caseName = Meludi.fetchRootItemName(caseName, sc.getActiveProjectId());
2933 14 Nov 14 olle 143           jsonCase = new JSONObject();
2933 14 Nov 14 olle 144           jsonCase.put("name", caseName);
2933 14 Nov 14 olle 145           jsonCase.put("originalName", caseName);
4723 29 Mar 18 olle 146
4723 29 Mar 18 olle 147           // Check if site should be found from site prefix
4723 29 Mar 18 olle 148           String siteDefault = null;
4723 29 Mar 18 olle 149           Boolean usesSitePrefix = Meludi.fetchUsesSitePrefix(sc.getActiveProjectId());
4723 29 Mar 18 olle 150           if (usesSitePrefix)
4723 29 Mar 18 olle 151           {
4723 29 Mar 18 olle 152             String caseNameDigits = Meludi.fetchRootDigits(caseName, sc.getActiveProjectId());
4723 29 Mar 18 olle 153             String sitePrefix = caseNameDigits.substring(0, 2);
4723 29 Mar 18 olle 154             HashMap<String,String> sitePrefixSiteKeyHashMap = Meludi.fetchSitePrefixSiteKeyHashMap(sc.getActiveProjectId());
4723 29 Mar 18 olle 155             if (sitePrefixSiteKeyHashMap != null)
4723 29 Mar 18 olle 156             {
4723 29 Mar 18 olle 157               siteDefault = sitePrefixSiteKeyHashMap.get(sitePrefix);
4723 29 Mar 18 olle 158               if (siteDefault == null)
4723 29 Mar 18 olle 159               {
4723 29 Mar 18 olle 160                 siteDefault = "";
4723 29 Mar 18 olle 161               }
4723 29 Mar 18 olle 162             }
4723 29 Mar 18 olle 163           }
4723 29 Mar 18 olle 164           jsonCase.put("siteDefault", siteDefault);
2933 14 Nov 14 olle 165         }
2933 14 Nov 14 olle 166
3028 11 Dec 14 olle 167         // Load 'Specimen' annotations
2933 14 Nov 14 olle 168         JSONArray jsonTubes = new JSONArray();
3028 11 Dec 14 olle 169         if (specimenTubes != null && specimenTubes.size() > 0)
2933 14 Nov 14 olle 170         {
2933 14 Nov 14 olle 171           for (SpecimenTube tube : specimenTubes)
2933 14 Nov 14 olle 172           {
2933 14 Nov 14 olle 173             tube.loadAnnotations(dc, "plNumber", Annotationtype.PL_NUMBER, null);
2933 14 Nov 14 olle 174             tube.loadAnnotations(dc, "pad", Annotationtype.PAD, null);
3028 11 Dec 14 olle 175             tube.loadAnnotations(dc, "samplingDate", Annotationtype.SAMPLING_DATE, Meludi.CONVERTER_DATE_TO_STRING);
3028 11 Dec 14 olle 176             tube.loadAnnotations(dc, "specimenType", Annotationtype.SPECIMEN_TYPE, null);
4195 31 Oct 16 olle 177             tube.loadAnnotations(dc, "specimenInputType", Annotationtype.SPECIMEN_INPUT_TYPE, null);
3067 08 Jan 15 olle 178             tube.loadAnnotations(dc, "viableTumourCellsPercent", Annotationtype.VIABLE_TUMOUR_CELLS_PERCENT, null);
2933 14 Nov 14 olle 179             jsonTubes.add(tube.asJSONObject());
2933 14 Nov 14 olle 180           }
2933 14 Nov 14 olle 181         }
2933 14 Nov 14 olle 182         jsonCase.put("specimen", jsonTubes);
2933 14 Nov 14 olle 183         jsonCase.put("specimenFirstIndex", numExisting+1);
3028 11 Dec 14 olle 184
3028 11 Dec 14 olle 185         // Load 'DNA' annotations
3028 11 Dec 14 olle 186         JSONArray jsonDna = new JSONArray();
3028 11 Dec 14 olle 187         if (dnaTubes != null && dnaTubes.size() > 0)
3028 11 Dec 14 olle 188         {
3028 11 Dec 14 olle 189           for (Dna d : dnaTubes)
3028 11 Dec 14 olle 190           {
3028 11 Dec 14 olle 191             Extract e = d.getExtract();
3028 11 Dec 14 olle 192             BioMaterialEvent created = e.getCreationEvent();
3028 11 Dec 14 olle 193             d.setAnnotation("extractionDate", Meludi.CONVERTER_DATE_TO_STRING.convert(created.getEventDate()));
3028 11 Dec 14 olle 194             jsonDna.add(d.asJSONObject());
3028 11 Dec 14 olle 195           }
3028 11 Dec 14 olle 196         }
3028 11 Dec 14 olle 197         jsonCase.put("dna", jsonDna);
3028 11 Dec 14 olle 198
3028 11 Dec 14 olle 199         // Load 'RNA' annotations
3028 11 Dec 14 olle 200         JSONArray jsonRna = new JSONArray();
3028 11 Dec 14 olle 201         if (rnaTubes != null && rnaTubes.size() > 0)
3028 11 Dec 14 olle 202         {
3028 11 Dec 14 olle 203           for (Rna r : rnaTubes)
3028 11 Dec 14 olle 204           {
3028 11 Dec 14 olle 205             Extract e = r.getExtract();
3028 11 Dec 14 olle 206             BioMaterialEvent created = e.getCreationEvent();
3028 11 Dec 14 olle 207             r.setAnnotation("extractionDate", Meludi.CONVERTER_DATE_TO_STRING.convert(created.getEventDate()));
3028 11 Dec 14 olle 208             jsonRna.add(r.asJSONObject());
3028 11 Dec 14 olle 209           }
3028 11 Dec 14 olle 210         }
3028 11 Dec 14 olle 211         jsonCase.put("rna", jsonRna);
3028 11 Dec 14 olle 212
2933 14 Nov 14 olle 213         // This is what we send back to the browser
2933 14 Nov 14 olle 214         json.put("caseInfo", jsonCase);
2933 14 Nov 14 olle 215       }
2933 14 Nov 14 olle 216       
2933 14 Nov 14 olle 217       else if ("GetPatientInfo".equals(cmd))
2933 14 Nov 14 olle 218       {
2933 14 Nov 14 olle 219         /*
2933 14 Nov 14 olle 220           Load information about a single patient when given a personal number
2933 14 Nov 14 olle 221           If a patient is found we will load annotations and the cases associated 
2933 14 Nov 14 olle 222           with it. If no patient is found, we populate a new object with some
2933 14 Nov 14 olle 223           information (eg. birth date and gender) from the information we have.
2933 14 Nov 14 olle 224         */
2933 14 Nov 14 olle 225         dc = sc.newDbControl();
2933 14 Nov 14 olle 226         
2933 14 Nov 14 olle 227         // Request parameters
2933 14 Nov 14 olle 228         String pnr = req.getParameter("personalNumber");
2933 14 Nov 14 olle 229         boolean pnrIsValid = Values.getBoolean(req.getParameter("pnrIsValid"));
2933 14 Nov 14 olle 230
2933 14 Nov 14 olle 231         // Find a patient by personalNumber
2933 14 Nov 14 olle 232         Patient patient = Patient.findByPersonalNumber(dc, pnr);
2933 14 Nov 14 olle 233         JSONObject jsonPat = null;
2933 14 Nov 14 olle 234         
2933 14 Nov 14 olle 235         if (patient != null)
2933 14 Nov 14 olle 236         {
2933 14 Nov 14 olle 237           // Load patient annotations
2933 14 Nov 14 olle 238           patient.loadDefaultAnnotations(dc);
2933 14 Nov 14 olle 239
2933 14 Nov 14 olle 240           // Load cases associated with this patient
2933 14 Nov 14 olle 241           List<Case> cases = Case.findByPatient(dc, patient);
2933 14 Nov 14 olle 242           
2933 14 Nov 14 olle 243           // Load case annotations
2933 14 Nov 14 olle 244           JSONArray jsonCases = new JSONArray();
2933 14 Nov 14 olle 245           if (cases.size() > 0)
2933 14 Nov 14 olle 246           {
2933 14 Nov 14 olle 247             for (Case c : cases)
2933 14 Nov 14 olle 248             {
2933 14 Nov 14 olle 249               jsonCases.add(c.asJSONObject());
2933 14 Nov 14 olle 250             }
2933 14 Nov 14 olle 251           }
2933 14 Nov 14 olle 252           
2933 14 Nov 14 olle 253           jsonPat = patient.asJSONObject();
2933 14 Nov 14 olle 254           jsonPat.put("cases", jsonCases);
2933 14 Nov 14 olle 255
2933 14 Nov 14 olle 256         }
2933 14 Nov 14 olle 257         else
2933 14 Nov 14 olle 258         {
2933 14 Nov 14 olle 259           // No patient was found -- try to find the highest existing patient number
4155 07 Oct 16 olle 260           String patientItemPrefix = Meludi.fetchPatientItemPrefix(sc.getActiveProjectId());
2933 14 Nov 14 olle 261           jsonPat = new JSONObject();
2933 14 Nov 14 olle 262           jsonPat.put("personalNumber", pnr);
4155 07 Oct 16 olle 263           jsonPat.put("name", Patient.generateNextName(dc, patientItemPrefix, Subtype.PATIENT));
2933 14 Nov 14 olle 264           if (pnrIsValid)
2933 14 Nov 14 olle 265           {
2933 14 Nov 14 olle 266             // 'Samordningsnummer' have day-in-month + 60
2933 14 Nov 14 olle 267             int dayInMonth = Values.getInt(pnr.substring(6,8));
2933 14 Nov 14 olle 268             if (dayInMonth > 60) dayInMonth -= 60;
2933 14 Nov 14 olle 269             jsonPat.put("dateOfBirth", pnr.substring(0,4) + '-' + pnr.substring(4,6)+'-'+MD5.leftPad(Integer.toString(dayInMonth), '0', 2));
2933 14 Nov 14 olle 270             jsonPat.put("gender", Integer.parseInt(pnr.substring(10,11)) % 2 == 0 ? "F" : "M");
2933 14 Nov 14 olle 271           }
2933 14 Nov 14 olle 272         }
2933 14 Nov 14 olle 273
2933 14 Nov 14 olle 274         json.put("patientInfo", jsonPat);
2933 14 Nov 14 olle 275       }
2933 14 Nov 14 olle 276     }
2933 14 Nov 14 olle 277     catch (Throwable t)
2933 14 Nov 14 olle 278     {
2933 14 Nov 14 olle 279       t.printStackTrace();
2933 14 Nov 14 olle 280       json.clear();
2933 14 Nov 14 olle 281       json.put("status", "error");
2933 14 Nov 14 olle 282       json.put("message", t.getMessage());
2933 14 Nov 14 olle 283       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
2933 14 Nov 14 olle 284     }
2933 14 Nov 14 olle 285     finally
2933 14 Nov 14 olle 286     {
2933 14 Nov 14 olle 287       if (dc != null) dc.close();
2933 14 Nov 14 olle 288       json.writeJSONString(resp.getWriter());
2933 14 Nov 14 olle 289     }
2933 14 Nov 14 olle 290     
2933 14 Nov 14 olle 291     
2933 14 Nov 14 olle 292   }
2933 14 Nov 14 olle 293
2933 14 Nov 14 olle 294   @SuppressWarnings("unchecked")
2933 14 Nov 14 olle 295   @Override
2933 14 Nov 14 olle 296   protected void doPost(HttpServletRequest req, HttpServletResponse resp)
2933 14 Nov 14 olle 297     throws ServletException, IOException 
2933 14 Nov 14 olle 298   {
2933 14 Nov 14 olle 299     String ID = req.getParameter("ID");
2933 14 Nov 14 olle 300     String cmd = req.getParameter("cmd");
2933 14 Nov 14 olle 301     JsonUtil.setJsonResponseHeaders(resp);
2933 14 Nov 14 olle 302     
2933 14 Nov 14 olle 303     JSONObject json = new JSONObject();
2933 14 Nov 14 olle 304     json.put("status", "ok");
2933 14 Nov 14 olle 305     
2933 14 Nov 14 olle 306     JSONArray jsonMessages = new JSONArray();
2933 14 Nov 14 olle 307   
5468 04 Jun 19 olle 308     //final SessionControl sc = Application.getSessionControl(ID, req.getRemoteAddr());
5744 20 Nov 19 olle 309     //final SessionControl sc  = Application.getSessionControl(ID, "", req.getRemoteAddr(), true);
5744 20 Nov 19 olle 310     final SessionControl sc  = Application.getSessionControl(ID, null, req.getRemoteAddr(), true);
2933 14 Nov 14 olle 311     DbControl dc = null;
2933 14 Nov 14 olle 312     try
2933 14 Nov 14 olle 313     {
2933 14 Nov 14 olle 314       if ("CreateCase".equals(cmd))
2933 14 Nov 14 olle 315       {
2933 14 Nov 14 olle 316         dc = sc.newDbControl();
2933 14 Nov 14 olle 317
2933 14 Nov 14 olle 318         MeludiRole.checkPermission(dc, "'" + cmd + "' wizard", MeludiRole.PATIENT_CURATOR, MeludiRole.ADMINISTRATOR);
2933 14 Nov 14 olle 319
2933 14 Nov 14 olle 320         JSONObject jsonReq = (JSONObject)new JSONParser().parse(req.getReader());
2933 14 Nov 14 olle 321         JSONObject jsonPat = (JSONObject)jsonReq.get("patientInfo");
2933 14 Nov 14 olle 322         JSONObject jsonCase = (JSONObject)jsonReq.get("caseInfo");
2933 14 Nov 14 olle 323
2933 14 Nov 14 olle 324         BioSource patient = getOrCreatePatient(dc, jsonPat, jsonMessages);
2933 14 Nov 14 olle 325         
2933 14 Nov 14 olle 326         // If we already have a case with id it is probably due to an already registered consent=yes
2933 14 Nov 14 olle 327         Number preCaseId = (Number)jsonCase.get("id");
2933 14 Nov 14 olle 328
2933 14 Nov 14 olle 329         // Load/create case
2933 14 Nov 14 olle 330         String originalCaseName = (String)jsonCase.get("name");
2933 14 Nov 14 olle 331
2933 14 Nov 14 olle 332         Sample theCase = null;
2933 14 Nov 14 olle 333         if (preCaseId != null)
2933 14 Nov 14 olle 334         {
2933 14 Nov 14 olle 335           // Load existing case
2933 14 Nov 14 olle 336           theCase = Sample.getById(dc, preCaseId.intValue());
2933 14 Nov 14 olle 337         }
2933 14 Nov 14 olle 338         else
2933 14 Nov 14 olle 339         {
2933 14 Nov 14 olle 340           // Register a new case
2933 14 Nov 14 olle 341           theCase = Sample.getNew(dc);
2933 14 Nov 14 olle 342           dc.saveItem(theCase);
2933 14 Nov 14 olle 343         }
2933 14 Nov 14 olle 344         theCase.setItemSubtype(Subtype.CASE.load(dc));
2933 14 Nov 14 olle 345         theCase.setName(originalCaseName);
2933 14 Nov 14 olle 346         theCase.getCreationEvent().setSource(patient);
2933 14 Nov 14 olle 347         jsonMessages.add("Case '" + originalCaseName + "' created successfully.");
2933 14 Nov 14 olle 348         
2933 14 Nov 14 olle 349         String plNumber = Values.getStringOrNull((String)jsonCase.get("plNumber"));
2933 14 Nov 14 olle 350         String pad = Values.getStringOrNull((String)jsonCase.get("pad"));
2933 14 Nov 14 olle 351
2933 14 Nov 14 olle 352         // Case and specimen tube registration
2933 14 Nov 14 olle 353         // Load the case if we already know which case the specimen belong to
2933 14 Nov 14 olle 354         Number caseId = (Number)jsonCase.get("id");
2933 14 Nov 14 olle 355         String caseName = (String)jsonCase.get("name");
2933 14 Nov 14 olle 356         int numTubes = 0;
2933 14 Nov 14 olle 357         JSONArray jsonSpecimenTmp = (JSONArray)jsonCase.get("specimen");    
2933 14 Nov 14 olle 358         if (jsonSpecimenTmp != null)
2933 14 Nov 14 olle 359         {
2933 14 Nov 14 olle 360           numTubes = jsonSpecimenTmp.size();
2933 14 Nov 14 olle 361         }
2933 14 Nov 14 olle 362         String arrivalDateStr = (String)jsonCase.get("arrivalDate");
2933 14 Nov 14 olle 363         String samplingDateStr = (String)jsonCase.get("samplingDate");
2933 14 Nov 14 olle 364         List<String> mutationAnalysisList = new ArrayList<String>();
3123 09 Feb 15 olle 365         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisKras", "KRAS", mutationAnalysisList);
3123 09 Feb 15 olle 366         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisNras", "NRAS", mutationAnalysisList);
2933 14 Nov 14 olle 367         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisBraf", "BRAF", mutationAnalysisList);
2933 14 Nov 14 olle 368         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisEgfr", "EGFR", mutationAnalysisList);
3123 09 Feb 15 olle 369         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisAlkEml4", "ALKEML4", mutationAnalysisList);
3123 09 Feb 15 olle 370         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisPdgfra", "PDGFRA", mutationAnalysisList);
3123 09 Feb 15 olle 371         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisKit", "KIT", mutationAnalysisList);
4730 04 Apr 18 olle 372         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisTst170", "TST170", mutationAnalysisList);
3123 09 Feb 15 olle 373         mutationAnalysisList = fetchMutationAnalysisList(jsonCase, "mutationAnalysisOther", "Other", mutationAnalysisList);
2933 14 Nov 14 olle 374         String siteStr = replaceBlankWithNull((String)jsonCase.get("site"));
3028 11 Dec 14 olle 375         String tubeContentType = Values.getStringOrNull((String)jsonCase.get("tubeContentType"));
3028 11 Dec 14 olle 376         String specimenType = Values.getStringOrNull((String)jsonCase.get("specimenType"));
4195 31 Oct 16 olle 377         String specimenInputType = Values.getStringOrNull((String)jsonCase.get("specimenInputType"));
3028 11 Dec 14 olle 378         String projectFocus = replaceBlankWithNull((String)jsonCase.get("projectFocus"));
4732 04 Apr 18 olle 379         String metastasisSite = Values.getStringOrNull((String)jsonCase.get("metastasisSite"));
3028 11 Dec 14 olle 380         String otherPathNote = Values.getStringOrNull((String)jsonCase.get("otherPathNote"));
4246 21 Nov 16 olle 381         Boolean extractsFromFirstSpecimenOnly = (Boolean)jsonCase.get("extractsFromFirstSpecimenOnly");
4246 21 Nov 16 olle 382         if (extractsFromFirstSpecimenOnly == null)
4246 21 Nov 16 olle 383         {
4246 21 Nov 16 olle 384           extractsFromFirstSpecimenOnly = false;
4246 21 Nov 16 olle 385         }
2933 14 Nov 14 olle 386
2933 14 Nov 14 olle 387         if (caseId != null)
2933 14 Nov 14 olle 388         {
2933 14 Nov 14 olle 389           theCase = Sample.getById(dc, caseId.intValue());
2933 14 Nov 14 olle 390           // If the Case doesn't belong to a patient yet
2933 14 Nov 14 olle 391           // it is a free-floating consent registration only and
2933 14 Nov 14 olle 392           // we should not link the specimen since the case may
2933 14 Nov 14 olle 393           // have to be merged with another case of the same patient
2933 14 Nov 14 olle 394           if (!theCase.hasSingleParent()) theCase = null;
2933 14 Nov 14 olle 395         }
2933 14 Nov 14 olle 396         else if (caseName != null && !caseName.equals(""))
2933 14 Nov 14 olle 397         {
2933 14 Nov 14 olle 398           Annotationtype.MUTATION_ANALYSIS.setAnnotationValues(dc, theCase, mutationAnalysisList);
2933 14 Nov 14 olle 399           Annotationtype.SITE.setAnnotationValue(dc, theCase, siteStr);
3028 11 Dec 14 olle 400           Annotationtype.TUBE_CONTENT_TYPE.setAnnotationValue(dc, theCase, tubeContentType);
3028 11 Dec 14 olle 401           Annotationtype.PROJECT_FOCUS.setAnnotationValue(dc, theCase, projectFocus);
4732 04 Apr 18 olle 402           Annotationtype.METASTASIS_SITE.setAnnotationValue(dc, theCase, metastasisSite);
3028 11 Dec 14 olle 403           Annotationtype.NOF_DELIVERED_TUBES.setAnnotationValue(dc, theCase, numTubes);
3028 11 Dec 14 olle 404           Annotationtype.OTHER_PATH_NOTE.setAnnotationValue(dc, theCase, otherPathNote);
2933 14 Nov 14 olle 405         }
2933 14 Nov 14 olle 406
2933 14 Nov 14 olle 407         StringToDateConverter dateConverter = new StringToDateConverter(new SimpleDateFormat("yyyyMMdd"));        
2933 14 Nov 14 olle 408         Date arrivalDate = dateConverter.convert((String)jsonCase.get("arrivalDate"));        
2933 14 Nov 14 olle 409         Date samplingDate = dateConverter.convert((String)jsonCase.get("samplingDate"));
2933 14 Nov 14 olle 410         Date createDate = dateConverter.convert((String)jsonCase.get("samplingDate"));
2933 14 Nov 14 olle 411         
2933 14 Nov 14 olle 412         JSONArray jsonSpecimen = (JSONArray)jsonCase.get("specimen");
2933 14 Nov 14 olle 413                 
2933 14 Nov 14 olle 414         if (jsonSpecimen != null && jsonSpecimen.size() > 0)
2933 14 Nov 14 olle 415         {
4189 28 Oct 16 olle 416           HashMap<String, BioPlate> bioPlateNamePlateHashMap = new HashMap<String, BioPlate>();
2933 14 Nov 14 olle 417           int nofTubes = jsonSpecimen.size();
2933 14 Nov 14 olle 418           for (int i=0; i < jsonSpecimen.size(); i++)
2933 14 Nov 14 olle 419           {
2933 14 Nov 14 olle 420             JSONObject jsonSpec = (JSONObject)jsonSpecimen.get(i);
3028 11 Dec 14 olle 421             String itemName = (String)jsonSpec.get("name");
3028 11 Dec 14 olle 422             Integer nofSections = 0;
3028 11 Dec 14 olle 423             String nofSectionsString = (String)jsonSpec.get("nofSections");
3028 11 Dec 14 olle 424             if (nofSectionsString != null && !nofSectionsString.equals(""))
2933 14 Nov 14 olle 425             {
3028 11 Dec 14 olle 426               nofSections = Integer.parseInt(nofSectionsString);
2933 14 Nov 14 olle 427             }
2933 14 Nov 14 olle 428             String operatorComment = Values.getStringOrNull((String)jsonSpec.get("comment"));
3028 11 Dec 14 olle 429             // Create items of correct types
3028 11 Dec 14 olle 430             if (tubeContentType != null && tubeContentType.equals("Specimen"))
3028 11 Dec 14 olle 431             {
3028 11 Dec 14 olle 432               Sample specimen = Sample.getNew(dc);
3028 11 Dec 14 olle 433               specimen.setItemSubtype(Subtype.SPECIMEN.load(dc));
3028 11 Dec 14 olle 434               specimen.setName(itemName);
3028 11 Dec 14 olle 435               dc.saveItem(specimen);
2933 14 Nov 14 olle 436
3028 11 Dec 14 olle 437               BioMaterialEvent creationEvent = specimen.getCreationEvent();
3028 11 Dec 14 olle 438               // Link the specimen with the case
3028 11 Dec 14 olle 439               if (theCase != null)
3028 11 Dec 14 olle 440               {
3028 11 Dec 14 olle 441                 creationEvent.setSource(theCase);
3028 11 Dec 14 olle 442               }
3028 11 Dec 14 olle 443               creationEvent.setEventDate(createDate);
3028 11 Dec 14 olle 444               
3028 11 Dec 14 olle 445               setAnnotations(dc, specimen, jsonCase, nofSections, operatorComment);
3028 11 Dec 14 olle 446               // Set PL-number and PAD/CL annotations
3028 11 Dec 14 olle 447               Annotationtype.PL_NUMBER.setAnnotationValue(dc, specimen, plNumber);
3028 11 Dec 14 olle 448               Annotationtype.PAD.setAnnotationValue(dc, specimen, pad);
3028 11 Dec 14 olle 449               
3028 11 Dec 14 olle 450               // Get biowell if it is specified for this tube
4189 28 Oct 16 olle 451               BioWell well = fetchBioWell(dc, jsonSpec, bioPlateNamePlateHashMap);
3028 11 Dec 14 olle 452               // Set storage space for specimen, if former is valid
3028 11 Dec 14 olle 453               if (well != null)
3028 11 Dec 14 olle 454               {
3028 11 Dec 14 olle 455                 specimen.setBioWell(well);              
3028 11 Dec 14 olle 456               }
3028 11 Dec 14 olle 457               jsonMessages.add("Specimen tube '" + specimen.getName() + "' created successfully.");
3276 29 Apr 15 olle 458
4246 21 Nov 16 olle 459               // Optional creation of extracts from specimen
4246 21 Nov 16 olle 460               if (i == 0 || !extractsFromFirstSpecimenOnly)
3276 29 Apr 15 olle 461               {
4246 21 Nov 16 olle 462                 // DNA extract from specimen
4246 21 Nov 16 olle 463                 Extract dna = Extract.getNew(dc);
4246 21 Nov 16 olle 464                 dna.setItemSubtype(Subtype.DNA.load(dc));
4246 21 Nov 16 olle 465                 dna.setName(itemName + ".d");
4246 21 Nov 16 olle 466                 BioMaterialEvent dnaEvent = dna.getCreationEvent();
4246 21 Nov 16 olle 467                 dnaEvent.setSource(specimen);
4246 21 Nov 16 olle 468                 dc.saveItem(dna);
4246 21 Nov 16 olle 469                 // Get bioWell if it is specified for DNA extract
4246 21 Nov 16 olle 470                 BioWell dnaWell = fetchBioWell(dc, jsonSpec, bioPlateNamePlateHashMap, "DNA");
4246 21 Nov 16 olle 471                 // Set storage space for DNA, if former is valid
4246 21 Nov 16 olle 472                 if (dnaWell != null)
4246 21 Nov 16 olle 473                 {
4246 21 Nov 16 olle 474                   dna.setBioWell(dnaWell);              
4246 21 Nov 16 olle 475                 }
4246 21 Nov 16 olle 476                 jsonMessages.add("DNA extract '" + dna.getName() + "' created successfully.");
3276 29 Apr 15 olle 477
4246 21 Nov 16 olle 478                 // RNA extract from specimen
4246 21 Nov 16 olle 479                 Extract rna = Extract.getNew(dc);
4246 21 Nov 16 olle 480                 rna.setItemSubtype(Subtype.RNA.load(dc));
4246 21 Nov 16 olle 481                 rna.setName(itemName + ".r");
4246 21 Nov 16 olle 482                 BioMaterialEvent rnaEvent = rna.getCreationEvent();
4246 21 Nov 16 olle 483                 rnaEvent.setSource(specimen);
4246 21 Nov 16 olle 484                 dc.saveItem(rna);
4246 21 Nov 16 olle 485                 // Get bioWell if it is specified for RNA extract
4246 21 Nov 16 olle 486                 BioWell rnaWell = fetchBioWell(dc, jsonSpec, bioPlateNamePlateHashMap, "RNA");
4246 21 Nov 16 olle 487                 // Set storage space for RNA, if former is valid
4246 21 Nov 16 olle 488                 if (rnaWell != null)
4246 21 Nov 16 olle 489                 {
4246 21 Nov 16 olle 490                   rna.setBioWell(rnaWell);              
4246 21 Nov 16 olle 491                 }
4246 21 Nov 16 olle 492                 jsonMessages.add("RNA extract '" + rna.getName() + "' created successfully.");
3276 29 Apr 15 olle 493               }
3028 11 Dec 14 olle 494             }
3028 11 Dec 14 olle 495             else if (tubeContentType != null)
2933 14 Nov 14 olle 496             {
3028 11 Dec 14 olle 497               Extract extract = Extract.getNew(dc);
3028 11 Dec 14 olle 498               String extractTypeStr = "Extract";
3028 11 Dec 14 olle 499               if (itemName.endsWith(".d"))
3028 11 Dec 14 olle 500               {
3028 11 Dec 14 olle 501                 extractTypeStr = "DNA";
3028 11 Dec 14 olle 502                 extract.setItemSubtype(Subtype.DNA.load(dc));
3028 11 Dec 14 olle 503               }
3028 11 Dec 14 olle 504               else if (itemName.endsWith(".r"))
3028 11 Dec 14 olle 505               {
3028 11 Dec 14 olle 506                 extractTypeStr = "RNA";
3028 11 Dec 14 olle 507                 extract.setItemSubtype(Subtype.RNA.load(dc));
3028 11 Dec 14 olle 508               }
3028 11 Dec 14 olle 509               extract.setName(itemName);
3028 11 Dec 14 olle 510               dc.saveItem(extract);
3028 11 Dec 14 olle 511               
3028 11 Dec 14 olle 512               BioMaterialEvent creationEvent = extract.getCreationEvent();
3028 11 Dec 14 olle 513               // Link the extract with the case
3028 11 Dec 14 olle 514               if (theCase != null)
3028 11 Dec 14 olle 515               {
3028 11 Dec 14 olle 516                 creationEvent.setSource(theCase);
3028 11 Dec 14 olle 517               }
3028 11 Dec 14 olle 518               creationEvent.setEventDate(createDate);
3028 11 Dec 14 olle 519               
3028 11 Dec 14 olle 520               setAnnotations(dc, extract, jsonCase, 0, operatorComment);
3028 11 Dec 14 olle 521               
3028 11 Dec 14 olle 522               // Get bioWell if it is specified for this tube
4189 28 Oct 16 olle 523               BioWell well = fetchBioWell(dc, jsonSpec, bioPlateNamePlateHashMap);
3028 11 Dec 14 olle 524               // Set storage space for specimen, if former is valid
3028 11 Dec 14 olle 525               if (well != null)
3028 11 Dec 14 olle 526               {
3028 11 Dec 14 olle 527                 extract.setBioWell(well);              
3028 11 Dec 14 olle 528               }
3028 11 Dec 14 olle 529               jsonMessages.add(extractTypeStr + " tube '" + extract.getName() + "' created successfully.");
2933 14 Nov 14 olle 530             }
2933 14 Nov 14 olle 531           }
2933 14 Nov 14 olle 532         }
2933 14 Nov 14 olle 533         dc.commit();
2933 14 Nov 14 olle 534         json.put("messages", jsonMessages);
3028 11 Dec 14 olle 535       }      
2933 14 Nov 14 olle 536       else if ("UpdateCase".equals(cmd))
2933 14 Nov 14 olle 537       {
2933 14 Nov 14 olle 538         dc = sc.newDbControl();
2933 14 Nov 14 olle 539
2933 14 Nov 14 olle 540         MeludiRole.checkPermission(dc, "'" + cmd + "' wizard", MeludiRole.PATIENT_CURATOR, MeludiRole.ADMINISTRATOR);
2933 14 Nov 14 olle 541
2933 14 Nov 14 olle 542         JSONObject jsonReq = (JSONObject)new JSONParser().parse(req.getReader());
2933 14 Nov 14 olle 543         JSONObject jsonCase = (JSONObject)jsonReq.get("caseInfo");
2933 14 Nov 14 olle 544         JSONObject jsonPat = (JSONObject)jsonReq.get("patientInfo");
2933 14 Nov 14 olle 545         
2933 14 Nov 14 olle 546         BioSource patient = getOrCreatePatient(dc, jsonPat, jsonMessages);
2933 14 Nov 14 olle 547       
2933 14 Nov 14 olle 548         Number caseId = (Number)jsonCase.get("id");
2933 14 Nov 14 olle 549         Sample theCase = Sample.getById(dc, caseId.intValue());
2933 14 Nov 14 olle 550         String originalCaseName = (String)jsonCase.get("originalName");
3028 11 Dec 14 olle 551         String tubeContentType = Values.getStringOrNull((String)jsonCase.get("tubeContentType"));
2933 14 Nov 14 olle 552
2933 14 Nov 14 olle 553         // Check if a patient is already associated with the case
2933 14 Nov 14 olle 554         Patient casePatient = null;
2933 14 Nov 14 olle 555         if (caseId != null && caseId.intValue() > 0)
2933 14 Nov 14 olle 556         {
2933 14 Nov 14 olle 557           Case aCase = Case.getById(dc, caseId.intValue());
2933 14 Nov 14 olle 558           casePatient = Patient.findByCase(dc, aCase);
2933 14 Nov 14 olle 559         }
2933 14 Nov 14 olle 560         // If the case has no associated patient, associate it with new patient
2933 14 Nov 14 olle 561         if (casePatient == null)
2933 14 Nov 14 olle 562         {
2933 14 Nov 14 olle 563           theCase.getCreationEvent().setSource(patient);
2933 14 Nov 14 olle 564         }
2933 14 Nov 14 olle 565
2933 14 Nov 14 olle 566         // Get updated case information
2933 14 Nov 14 olle 567         String plNumber = Values.getStringOrNull((String)jsonCase.get("plNumber"));
2933 14 Nov 14 olle 568         String pad = Values.getStringOrNull((String)jsonCase.get("pad"));
2933 14 Nov 14 olle 569         JSONArray jsonSpecimen = (JSONArray)jsonCase.get("specimen");
2933 14 Nov 14 olle 570
2933 14 Nov 14 olle 571         jsonMessages.add("Case '" + originalCaseName + "' updated successfully.");
3028 11 Dec 14 olle 572
3028 11 Dec 14 olle 573         int numUpdatedSpecimenTubes = 0;
2933 14 Nov 14 olle 574         // Update the specimen tubes
2933 14 Nov 14 olle 575         if (jsonSpecimen != null && jsonSpecimen.size() > 0)
2933 14 Nov 14 olle 576         {
2933 14 Nov 14 olle 577           Date samplingDate = Meludi.CONVERTER_STRING_TO_DATE.convert((String)jsonCase.get("samplingDate"));
2933 14 Nov 14 olle 578           
2933 14 Nov 14 olle 579           for (int i = 0; i < jsonSpecimen.size(); ++i)
2933 14 Nov 14 olle 580           {
2933 14 Nov 14 olle 581             JSONObject jsonSpec = (JSONObject)jsonSpecimen.get(i);
3028 11 Dec 14 olle 582             if (tubeContentType != null && tubeContentType.equals("Specimen"))
2933 14 Nov 14 olle 583             {
3028 11 Dec 14 olle 584               Sample specimen = Sample.getById(dc, ((Number)jsonSpec.get("id")).intValue());
3028 11 Dec 14 olle 585               // !IMPORTANT - The sampling date must be set here and as an 'SamplingDateTime' annotation
3028 11 Dec 14 olle 586               BioMaterialEvent creationEvent = specimen.getCreationEvent();
3028 11 Dec 14 olle 587               creationEvent.setEventDate(samplingDate);
3028 11 Dec 14 olle 588     
3028 11 Dec 14 olle 589               // Ensure the specimen is linked with the case 
3028 11 Dec 14 olle 590               if (specimen.getParentType() == null)
3028 11 Dec 14 olle 591               {
3028 11 Dec 14 olle 592                 creationEvent.setSource(theCase);
3028 11 Dec 14 olle 593               }
3028 11 Dec 14 olle 594               
3028 11 Dec 14 olle 595               // Update the specimen annotations
3028 11 Dec 14 olle 596               Annotationtype.PL_NUMBER.setAnnotationValue(dc, specimen, plNumber);
3028 11 Dec 14 olle 597               Annotationtype.PAD.setAnnotationValue(dc, specimen, pad);
3028 11 Dec 14 olle 598               if (samplingDate != null) Annotationtype.SAMPLING_DATE.setAnnotationValue(dc, specimen, samplingDate);
3028 11 Dec 14 olle 599               numUpdatedSpecimenTubes++;
2933 14 Nov 14 olle 600             }
2933 14 Nov 14 olle 601           }
3028 11 Dec 14 olle 602           jsonMessages.add(numUpdatedSpecimenTubes + " specimen tube(s) updated.");
2933 14 Nov 14 olle 603         }
2933 14 Nov 14 olle 604         dc.commit();
2933 14 Nov 14 olle 605         json.put("messages", jsonMessages);
3101 21 Jan 15 olle 606         CounterService.getInstance().setForceCount();
2933 14 Nov 14 olle 607       }
2933 14 Nov 14 olle 608     }
2933 14 Nov 14 olle 609     catch (Throwable t)
2933 14 Nov 14 olle 610     {
2933 14 Nov 14 olle 611       t.printStackTrace();
2933 14 Nov 14 olle 612       json.clear();
2933 14 Nov 14 olle 613       json.put("status", "error");
2933 14 Nov 14 olle 614       json.put("message", t.getMessage());
2933 14 Nov 14 olle 615       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
2933 14 Nov 14 olle 616     }
2933 14 Nov 14 olle 617     finally
2933 14 Nov 14 olle 618     {
2933 14 Nov 14 olle 619       if (dc != null) dc.close();
2933 14 Nov 14 olle 620       json.writeJSONString(resp.getWriter());
2933 14 Nov 14 olle 621     }
2933 14 Nov 14 olle 622   }
2933 14 Nov 14 olle 623   
3028 11 Dec 14 olle 624   private void setAnnotations(DbControl dc, Annotatable item, JSONObject jsonCase, int nofSections, String operatorComment)
3028 11 Dec 14 olle 625   {
3028 11 Dec 14 olle 626     String tubeContentType = Values.getStringOrNull((String)jsonCase.get("tubeContentType"));
3028 11 Dec 14 olle 627     String specimenType = Values.getStringOrNull((String)jsonCase.get("specimenType"));
4195 31 Oct 16 olle 628     String specimenInputType = Values.getStringOrNull((String)jsonCase.get("specimenInputType"));
3028 11 Dec 14 olle 629     StringToDateConverter dateConverter = new StringToDateConverter(new SimpleDateFormat("yyyyMMdd"));        
3028 11 Dec 14 olle 630     Date arrivalDate = dateConverter.convert((String)jsonCase.get("arrivalDate"));        
3028 11 Dec 14 olle 631     Date samplingDate = dateConverter.convert((String)jsonCase.get("samplingDate"));
3067 08 Jan 15 olle 632     Integer viableTumourCellsPercent = null;
3067 08 Jan 15 olle 633     String viableTumourCellsPercentString = (String)jsonCase.get("viableTumourCellsPercent");
3067 08 Jan 15 olle 634     if (viableTumourCellsPercentString != null && !viableTumourCellsPercentString.equals(""))
3067 08 Jan 15 olle 635     {
3067 08 Jan 15 olle 636       viableTumourCellsPercent = Integer.parseInt(viableTumourCellsPercentString);
3067 08 Jan 15 olle 637     }
3028 11 Dec 14 olle 638     if (tubeContentType != null && tubeContentType.equals("Specimen"))
3028 11 Dec 14 olle 639     {
3028 11 Dec 14 olle 640       Annotationtype.NOF_SECTIONS.setAnnotationValue(dc, item, nofSections);
3028 11 Dec 14 olle 641       Annotationtype.SPECIMEN_TYPE.setAnnotationValue(dc, item, specimenType);
4195 31 Oct 16 olle 642       Annotationtype.SPECIMEN_INPUT_TYPE.setAnnotationValue(dc, item, specimenInputType);
3028 11 Dec 14 olle 643       // The following annotations should not necessarily be restricted to specimens
3028 11 Dec 14 olle 644       Annotationtype.ARRIVAL_DATE.setAnnotationValue(dc, item, arrivalDate);            
3028 11 Dec 14 olle 645       Annotationtype.SAMPLING_DATE.setAnnotationValue(dc, item, samplingDate);
3067 08 Jan 15 olle 646       Annotationtype.VIABLE_TUMOUR_CELLS_PERCENT.setAnnotationValue(dc, item, viableTumourCellsPercent);
3028 11 Dec 14 olle 647       Annotationtype.OPERATOR_DELIVERY_COMMENT.setAnnotationValue(dc, item, operatorComment);  
3028 11 Dec 14 olle 648     }
3318 08 May 15 olle 649     else if (tubeContentType != null)
3318 08 May 15 olle 650     {
3318 08 May 15 olle 651       Annotationtype.SPECIMEN_TYPE_EXTRACT.setAnnotationValue(dc, item, specimenType);
3318 08 May 15 olle 652       Annotationtype.ARRIVAL_DATE_EXTRACT.setAnnotationValue(dc, item, arrivalDate);            
3318 08 May 15 olle 653       Annotationtype.SAMPLING_DATE_EXTRACT.setAnnotationValue(dc, item, samplingDate);
3318 08 May 15 olle 654       Annotationtype.VIABLE_TUMOUR_CELLS_PERCENT_EXTRACT.setAnnotationValue(dc, item, viableTumourCellsPercent);
3318 08 May 15 olle 655       Annotationtype.OPERATOR_DELIVERY_COMMENT_EXTRACT.setAnnotationValue(dc, item, operatorComment);  
3318 08 May 15 olle 656     }
3028 11 Dec 14 olle 657   }
3028 11 Dec 14 olle 658
4189 28 Oct 16 olle 659   private BioWell fetchBioWell(DbControl dc, JSONObject jsonSpec, HashMap<String, BioPlate> bioPlateNamePlateHashMap)
3028 11 Dec 14 olle 660   {
3276 29 Apr 15 olle 661     String boxType = null;
4189 28 Oct 16 olle 662     BioWell well = fetchBioWell(dc, jsonSpec, bioPlateNamePlateHashMap, boxType);
3276 29 Apr 15 olle 663     return well;
3276 29 Apr 15 olle 664   }
3276 29 Apr 15 olle 665
4189 28 Oct 16 olle 666   private BioWell fetchBioWell(DbControl dc, JSONObject jsonSpec, HashMap<String, BioPlate> bioPlateNamePlateHashMap, String boxType)
3276 29 Apr 15 olle 667   {
3028 11 Dec 14 olle 668     BioWell well = null;
3276 29 Apr 15 olle 669     String boxKey = "box";
3276 29 Apr 15 olle 670     String rowKey = "row";
3276 29 Apr 15 olle 671     String columnKey = "column";
3276 29 Apr 15 olle 672     if (boxType != null && boxType.equals("DNA"))
3276 29 Apr 15 olle 673     {
3276 29 Apr 15 olle 674       boxKey = "dnaBox";
3276 29 Apr 15 olle 675       rowKey = "dnaRow";
3276 29 Apr 15 olle 676       columnKey = "dnaColumn";
3276 29 Apr 15 olle 677     }
3276 29 Apr 15 olle 678     else if (boxType != null && boxType.equals("RNA"))
3276 29 Apr 15 olle 679     {
3276 29 Apr 15 olle 680       boxKey = "rnaBox";
3276 29 Apr 15 olle 681       rowKey = "rnaRow";
3276 29 Apr 15 olle 682       columnKey = "rnaColumn";
3276 29 Apr 15 olle 683     }
3028 11 Dec 14 olle 684     // Set biowell if it is specified for this tube
3276 29 Apr 15 olle 685     String box = (String)jsonSpec.get(boxKey);
3276 29 Apr 15 olle 686     String rowString = (String)jsonSpec.get(rowKey);
3276 29 Apr 15 olle 687     String columnString = (String)jsonSpec.get(columnKey);
3028 11 Dec 14 olle 688     
4189 28 Oct 16 olle 689     BioPlate plate = null;
3028 11 Dec 14 olle 690     StoragePlate storageBox = StoragePlate.findByName(dc, box);
4189 28 Oct 16 olle 691     if (storageBox != null)
4189 28 Oct 16 olle 692     {
4189 28 Oct 16 olle 693       plate = storageBox.getBioPlate();
4189 28 Oct 16 olle 694     }
4189 28 Oct 16 olle 695     else if (box != null && !box.equals(""))
4189 28 Oct 16 olle 696     {
4189 28 Oct 16 olle 697       // Use already created new storage box, if existing
4189 28 Oct 16 olle 698       plate = (BioPlate) bioPlateNamePlateHashMap.get(box);
4189 28 Oct 16 olle 699       if (plate == null)
4189 28 Oct 16 olle 700       {
4189 28 Oct 16 olle 701         // Create new storage box
4189 28 Oct 16 olle 702         plate = createStorageBox(dc, box);
4189 28 Oct 16 olle 703         dc.saveItem(plate);
4189 28 Oct 16 olle 704         // Update hash map with new plate
4189 28 Oct 16 olle 705         bioPlateNamePlateHashMap.put(box, plate);
4189 28 Oct 16 olle 706       }
4189 28 Oct 16 olle 707     }
3028 11 Dec 14 olle 708
3028 11 Dec 14 olle 709     // Set storage space for specimen, if former is valid
3028 11 Dec 14 olle 710     if (box != null && !box.equals("") && rowString != null && !rowString.equals("") && columnString != null && !columnString.equals(""))
3028 11 Dec 14 olle 711     {
3028 11 Dec 14 olle 712       WellCoordinateFormatter wcfRow = new WellCoordinateFormatter(true);
3028 11 Dec 14 olle 713       Integer rowIndex = wcfRow.parseString(rowString)-1;
3028 11 Dec 14 olle 714       Integer columnIndex = Integer.parseInt(columnString)-1;              
3028 11 Dec 14 olle 715       well = plate.getBioWell(rowIndex, columnIndex);
3028 11 Dec 14 olle 716     }
3028 11 Dec 14 olle 717     return well;
3028 11 Dec 14 olle 718   }
3028 11 Dec 14 olle 719
4189 28 Oct 16 olle 720   /**
4189 28 Oct 16 olle 721    * Creates a storage box BioPlate item with a given name.
4189 28 Oct 16 olle 722    * Note that the returned BioPlate item will not automatically
4189 28 Oct 16 olle 723    * be stored in the database.
4189 28 Oct 16 olle 724    * 
4189 28 Oct 16 olle 725    * @param dc DbControl The DbControl to use
4189 28 Oct 16 olle 726    * @param plateName String Name of the bioplate to create
4189 28 Oct 16 olle 727    * @return BioPlate The created BioPlate item
4189 28 Oct 16 olle 728    */
2933 14 Nov 14 olle 729   @SuppressWarnings("unchecked")
4189 28 Oct 16 olle 730   private BioPlate createStorageBox(DbControl dc, String plateName)
4189 28 Oct 16 olle 731   {  
4189 28 Oct 16 olle 732     // Get plate geometry for storage box (81-well (9 x 9))
4189 28 Oct 16 olle 733     ItemQuery<PlateGeometry> plateGeometryQuery = PlateGeometry.getQuery();
4189 28 Oct 16 olle 734     plateGeometryQuery.restrict(Restrictions.eq(Hql.property("name"), Expressions.string("81-well (9 x 9)")));
4189 28 Oct 16 olle 735     ItemResultList<PlateGeometry> plateGeometryList = plateGeometryQuery.list(dc);
4189 28 Oct 16 olle 736     PlateGeometry geometry = null;
4189 28 Oct 16 olle 737     if (plateGeometryList != null && plateGeometryList.size() > 0)
4189 28 Oct 16 olle 738     {
4189 28 Oct 16 olle 739       geometry = (PlateGeometry) plateGeometryList.get(0);
4189 28 Oct 16 olle 740     }
4189 28 Oct 16 olle 741     // Get bioplate type for storage plate (Storage plate)
4189 28 Oct 16 olle 742     ItemQuery<BioPlateType> bioPlateTypeQuery = BioPlateType.getQuery();
4189 28 Oct 16 olle 743     bioPlateTypeQuery.restrict(Restrictions.eq(Hql.property("name"), Expressions.string("Storage plate")));
4189 28 Oct 16 olle 744     ItemResultList<BioPlateType> bioPlateTypeList = bioPlateTypeQuery.list(dc);
4189 28 Oct 16 olle 745     BioPlateType plateType = null;
4189 28 Oct 16 olle 746     if (bioPlateTypeList != null && bioPlateTypeList.size() > 0)
4189 28 Oct 16 olle 747     {
4189 28 Oct 16 olle 748       plateType = (BioPlateType) bioPlateTypeList.get(0);
4189 28 Oct 16 olle 749     }
4189 28 Oct 16 olle 750     // Create new storage box
4189 28 Oct 16 olle 751     BioPlate box = BioPlate.getNew(dc, geometry, plateType);
4189 28 Oct 16 olle 752     box.setName(plateName);
4189 28 Oct 16 olle 753     return box;
4189 28 Oct 16 olle 754   }
4189 28 Oct 16 olle 755
4189 28 Oct 16 olle 756   @SuppressWarnings("unchecked")
2933 14 Nov 14 olle 757   private BioSource getOrCreatePatient(DbControl dc, JSONObject jsonPat, JSONArray jsonMessages)
2933 14 Nov 14 olle 758     throws Exception
2933 14 Nov 14 olle 759   {
2933 14 Nov 14 olle 760     Number patientId = (Number)jsonPat.get("id");
2933 14 Nov 14 olle 761     BioSource patient = null;
2933 14 Nov 14 olle 762     String familyName = Values.getStringOrNull((String)jsonPat.get("familyName"));
2933 14 Nov 14 olle 763     String allFirstNames = Values.getStringOrNull((String)jsonPat.get("allFirstNames"));
2933 14 Nov 14 olle 764     if (patientId != null)
2933 14 Nov 14 olle 765     {
2933 14 Nov 14 olle 766       patient = BioSource.getById(dc, patientId.intValue());
2933 14 Nov 14 olle 767       // Update names
2933 14 Nov 14 olle 768       Annotationtype.FAMILY_NAME.setAnnotationValue(dc, patient, familyName);
2933 14 Nov 14 olle 769       Annotationtype.ALL_FIRST_NAMES.setAnnotationValue(dc, patient, allFirstNames);
2933 14 Nov 14 olle 770     }
2933 14 Nov 14 olle 771     else
2933 14 Nov 14 olle 772     {
2933 14 Nov 14 olle 773       String pnr = (String)jsonPat.get("personalNumber");
2933 14 Nov 14 olle 774       String patName = (String)jsonPat.get("name");
2933 14 Nov 14 olle 775       Patient.ensureNotExistingPatient(dc, pnr, patName);
2933 14 Nov 14 olle 776
2933 14 Nov 14 olle 777       // Create new patient
2933 14 Nov 14 olle 778       patient = BioSource.getNew(dc);
2933 14 Nov 14 olle 779       patient.setItemSubtype(Subtype.PATIENT.load(dc));
2933 14 Nov 14 olle 780       patient.setName((String)jsonPat.get("name"));
2933 14 Nov 14 olle 781       StringToDateConverter dateConverter = new StringToDateConverter(new SimpleDateFormat("yyyy-MM-dd"));
2933 14 Nov 14 olle 782       Date dateOfBirth = dateConverter.convert((String)jsonPat.get("dateOfBirth"));
2933 14 Nov 14 olle 783       String gender = Values.getStringOrNull((String)jsonPat.get("gender"));
2933 14 Nov 14 olle 784       
2933 14 Nov 14 olle 785       Annotationtype.PERSONAL_NUMBER.setAnnotationValue(dc, patient, pnr);
2933 14 Nov 14 olle 786       Annotationtype.FAMILY_NAME.setAnnotationValue(dc, patient, familyName);
2933 14 Nov 14 olle 787       Annotationtype.ALL_FIRST_NAMES.setAnnotationValue(dc, patient, allFirstNames);
2933 14 Nov 14 olle 788       Annotationtype.GENDER.setAnnotationValue(dc, patient, gender);
2933 14 Nov 14 olle 789       Annotationtype.DATE_OF_BIRTH.setAnnotationValue(dc, patient, dateOfBirth);
2933 14 Nov 14 olle 790       
2933 14 Nov 14 olle 791       if (gender == null || dateOfBirth == null)
2933 14 Nov 14 olle 792       {
2933 14 Nov 14 olle 793         patient.setDescription("This patient was recorded with a non-standard PersonalNumber. " +
2933 14 Nov 14 olle 794             "DateOfBirth and Gender annotations could not be automatically generated.");
2933 14 Nov 14 olle 795       }
2933 14 Nov 14 olle 796       dc.saveItem(patient);
2933 14 Nov 14 olle 797       
2933 14 Nov 14 olle 798       jsonMessages.add("Patient '" + patient.getName() + "' created successfully.");
2933 14 Nov 14 olle 799     }
2933 14 Nov 14 olle 800     return patient;
2933 14 Nov 14 olle 801
2933 14 Nov 14 olle 802   }
2933 14 Nov 14 olle 803   
2933 14 Nov 14 olle 804   /**
2933 14 Nov 14 olle 805    * Convenience method that replaces an empty string with `null`.
2933 14 Nov 14 olle 806    * 
2933 14 Nov 14 olle 807    * @param str The input string.
2933 14 Nov 14 olle 808    * @return String The input string; replaced with `null` if empty string.
2933 14 Nov 14 olle 809    */
2933 14 Nov 14 olle 810   private String replaceBlankWithNull(String str)
2933 14 Nov 14 olle 811   {
2933 14 Nov 14 olle 812     if (str != null && str.equals(""))
2933 14 Nov 14 olle 813     {
2933 14 Nov 14 olle 814       str = null;
2933 14 Nov 14 olle 815     }
2933 14 Nov 14 olle 816     return str;
2933 14 Nov 14 olle 817   }
2933 14 Nov 14 olle 818
2933 14 Nov 14 olle 819   /**
2933 14 Nov 14 olle 820    * Updates an input mutation analysis list with new String entry if
2933 14 Nov 14 olle 821    * a boolean flag set to true is found for the specified String key
2933 14 Nov 14 olle 822    * in the input JSONObject. A string entry is only added once to the
2933 14 Nov 14 olle 823    * mutation analysis list.
2933 14 Nov 14 olle 824    * 
2933 14 Nov 14 olle 825    * @param jsonCase JSONObject The JSONObject to check for mutation analysis flag.
2933 14 Nov 14 olle 826    * @param jsonKey String JSON key for Boolean mutation analysis flag.
2933 14 Nov 14 olle 827    * @param mutationAnalysisStr String The annotation string to add to mutation analysis list, if flag is true.
2933 14 Nov 14 olle 828    * @param mutationAnalysisList List<String> Input mutation analysis list to be updated with new entry if flag is true.
2933 14 Nov 14 olle 829    * @return List<String> Input mutation analysis list optionally updated with new entry.
2933 14 Nov 14 olle 830    */
2933 14 Nov 14 olle 831   private List<String> fetchMutationAnalysisList(JSONObject jsonCase, String jsonKey, String mutationAnalysisStr, List<String> mutationAnalysisList)
2933 14 Nov 14 olle 832   {
2933 14 Nov 14 olle 833     if (jsonCase != null && jsonKey != null && mutationAnalysisList != null)
2933 14 Nov 14 olle 834     {
2933 14 Nov 14 olle 835       Boolean isIncluded = (Boolean)jsonCase.get(jsonKey);
2933 14 Nov 14 olle 836       if (isIncluded != null && isIncluded)
2933 14 Nov 14 olle 837       {
2933 14 Nov 14 olle 838         if (!mutationAnalysisList.contains(mutationAnalysisStr))
2933 14 Nov 14 olle 839         {
2933 14 Nov 14 olle 840           mutationAnalysisList.add(mutationAnalysisStr);
2933 14 Nov 14 olle 841         }
2933 14 Nov 14 olle 842       }
2933 14 Nov 14 olle 843     }
2933 14 Nov 14 olle 844     return mutationAnalysisList;
2933 14 Nov 14 olle 845   }
2933 14 Nov 14 olle 846 }