extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/LinkedSpecimenServlet.java

Code
Comments
Other
Rev Date Author Line
3394 12 Jun 15 nicklas 1 package net.sf.basedb.reggie.servlet;
3394 12 Jun 15 nicklas 2
3394 12 Jun 15 nicklas 3 import java.io.IOException;
3394 12 Jun 15 nicklas 4 import java.util.Date;
3394 12 Jun 15 nicklas 5 import java.util.HashMap;
3394 12 Jun 15 nicklas 6 import java.util.HashSet;
3905 29 Apr 16 nicklas 7 import java.util.Iterator;
3394 12 Jun 15 nicklas 8 import java.util.Map;
3394 12 Jun 15 nicklas 9 import java.util.Set;
3394 12 Jun 15 nicklas 10
3394 12 Jun 15 nicklas 11 import javax.servlet.ServletException;
3394 12 Jun 15 nicklas 12 import javax.servlet.http.HttpServlet;
3394 12 Jun 15 nicklas 13 import javax.servlet.http.HttpServletRequest;
3394 12 Jun 15 nicklas 14 import javax.servlet.http.HttpServletResponse;
3394 12 Jun 15 nicklas 15
3394 12 Jun 15 nicklas 16 import org.json.simple.JSONArray;
3394 12 Jun 15 nicklas 17 import org.json.simple.JSONObject;
3394 12 Jun 15 nicklas 18
3394 12 Jun 15 nicklas 19 import net.sf.basedb.core.BioMaterial;
3394 12 Jun 15 nicklas 20 import net.sf.basedb.core.BioSource;
3394 12 Jun 15 nicklas 21 import net.sf.basedb.core.DbControl;
3394 12 Jun 15 nicklas 22 import net.sf.basedb.core.ItemQuery;
3394 12 Jun 15 nicklas 23 import net.sf.basedb.core.Sample;
3394 12 Jun 15 nicklas 24 import net.sf.basedb.core.SessionControl;
3905 29 Apr 16 nicklas 25 import net.sf.basedb.core.SimpleProgressReporter;
3394 12 Jun 15 nicklas 26 import net.sf.basedb.core.query.Hql;
3394 12 Jun 15 nicklas 27 import net.sf.basedb.core.query.Orders;
3394 12 Jun 15 nicklas 28 import net.sf.basedb.core.query.Restrictions;
3394 12 Jun 15 nicklas 29 import net.sf.basedb.core.snapshot.SnapshotManager;
3394 12 Jun 15 nicklas 30 import net.sf.basedb.reggie.JsonUtil;
3394 12 Jun 15 nicklas 31 import net.sf.basedb.reggie.Reggie;
3394 12 Jun 15 nicklas 32 import net.sf.basedb.reggie.counter.CounterService;
3394 12 Jun 15 nicklas 33 import net.sf.basedb.reggie.dao.Annotationtype;
3394 12 Jun 15 nicklas 34 import net.sf.basedb.reggie.dao.ReggieRole;
3394 12 Jun 15 nicklas 35 import net.sf.basedb.reggie.dao.Subtype;
3394 12 Jun 15 nicklas 36 import net.sf.basedb.util.EqualsHelper;
3394 12 Jun 15 nicklas 37 import net.sf.basedb.util.error.ThrowableUtil;
3394 12 Jun 15 nicklas 38
3394 12 Jun 15 nicklas 39
3394 12 Jun 15 nicklas 40 public class LinkedSpecimenServlet 
3394 12 Jun 15 nicklas 41   extends HttpServlet 
3394 12 Jun 15 nicklas 42 {
3394 12 Jun 15 nicklas 43
3394 12 Jun 15 nicklas 44   private static final long serialVersionUID = 8047423138847961359L;
3394 12 Jun 15 nicklas 45
3394 12 Jun 15 nicklas 46   public LinkedSpecimenServlet()
3394 12 Jun 15 nicklas 47   {}
3394 12 Jun 15 nicklas 48
3394 12 Jun 15 nicklas 49   @Override
3394 12 Jun 15 nicklas 50   protected void doGet(HttpServletRequest req, HttpServletResponse resp)
3394 12 Jun 15 nicklas 51     throws ServletException, IOException 
3394 12 Jun 15 nicklas 52   {
3394 12 Jun 15 nicklas 53     String cmd = req.getParameter("cmd");
3394 12 Jun 15 nicklas 54     JsonUtil.setJsonResponseHeaders(resp);
3394 12 Jun 15 nicklas 55     
3394 12 Jun 15 nicklas 56     JSONObject json = new JSONObject();
3394 12 Jun 15 nicklas 57     json.put("status", "ok");
3394 12 Jun 15 nicklas 58   
3975 26 May 16 nicklas 59     final SessionControl sc = Reggie.getSessionControl(req);
3394 12 Jun 15 nicklas 60     DbControl dc = null;
3394 12 Jun 15 nicklas 61     try
3394 12 Jun 15 nicklas 62     {
3394 12 Jun 15 nicklas 63
3394 12 Jun 15 nicklas 64     }
3394 12 Jun 15 nicklas 65     catch (Throwable t)
3394 12 Jun 15 nicklas 66     {
3394 12 Jun 15 nicklas 67       t.printStackTrace();
3394 12 Jun 15 nicklas 68       json.clear();
3394 12 Jun 15 nicklas 69       json.put("status", "error");
3394 12 Jun 15 nicklas 70       json.put("message", t.getMessage());
3394 12 Jun 15 nicklas 71       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
3394 12 Jun 15 nicklas 72     }
3394 12 Jun 15 nicklas 73     finally
3394 12 Jun 15 nicklas 74     {
3394 12 Jun 15 nicklas 75       if (dc != null) dc.close();
3394 12 Jun 15 nicklas 76       json.writeJSONString(resp.getWriter());
3394 12 Jun 15 nicklas 77     }
3394 12 Jun 15 nicklas 78     
3394 12 Jun 15 nicklas 79     
3394 12 Jun 15 nicklas 80   }
3394 12 Jun 15 nicklas 81
3394 12 Jun 15 nicklas 82   @Override
3394 12 Jun 15 nicklas 83   protected void doPost(HttpServletRequest req, HttpServletResponse resp)
3394 12 Jun 15 nicklas 84     throws ServletException, IOException 
3394 12 Jun 15 nicklas 85   {
3394 12 Jun 15 nicklas 86     String cmd = req.getParameter("cmd");
3394 12 Jun 15 nicklas 87     JsonUtil.setJsonResponseHeaders(resp);
3394 12 Jun 15 nicklas 88     
3394 12 Jun 15 nicklas 89     JSONObject json = new JSONObject();
3394 12 Jun 15 nicklas 90     json.put("status", "ok");
3394 12 Jun 15 nicklas 91     
3394 12 Jun 15 nicklas 92     JSONArray jsonMessages = new JSONArray();
3394 12 Jun 15 nicklas 93   
3975 26 May 16 nicklas 94     final SessionControl sc = Reggie.getSessionControl(req);
3394 12 Jun 15 nicklas 95     DbControl dc = null;
3394 12 Jun 15 nicklas 96     try
3394 12 Jun 15 nicklas 97     {
3394 12 Jun 15 nicklas 98       if ("UpdateAllLinkedSpecimenAnnotations".equals(cmd))
3394 12 Jun 15 nicklas 99       {
6336 16 Jun 21 nicklas 100         dc = sc.newDbControl(":Linked specimen wizard");
3394 12 Jun 15 nicklas 101
3394 12 Jun 15 nicklas 102         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.PREP_CURATOR, ReggieRole.ADMINISTRATOR);
3905 29 Apr 16 nicklas 103         
3905 29 Apr 16 nicklas 104         SimpleProgressReporter progress = new SimpleProgressReporter(null);
3905 29 Apr 16 nicklas 105         sc.setSessionSetting("linked-specimen-progress", progress);
3905 29 Apr 16 nicklas 106         progress.display(1, "Loading samples...");
3905 29 Apr 16 nicklas 107         
3394 12 Jun 15 nicklas 108         SnapshotManager snapshot = new SnapshotManager();
3394 12 Jun 15 nicklas 109
3394 12 Jun 15 nicklas 110         // Initialize counters
3394 12 Jun 15 nicklas 111         int numUpdated = 0;
3394 12 Jun 15 nicklas 112         int numNoDate = 0;
3394 12 Jun 15 nicklas 113         Map<String, Counter> counters = new HashMap<String, Counter>();
3394 12 Jun 15 nicklas 114         counters.put(null, new Counter(null));
3481 09 Sep 15 nicklas 115         counters.put("MissingDate", new Counter("MissingDate"));
3394 12 Jun 15 nicklas 116         counters.put("IpsilateralCoreBiopsy", new Counter("IpsilateralCoreBiopsy"));
3394 12 Jun 15 nicklas 117         counters.put("ContralateralCoreBiopsy", new Counter("ContralateralCoreBiopsy"));
3394 12 Jun 15 nicklas 118         counters.put("IpsilateralSample", new Counter("IpsilateralSample"));
3394 12 Jun 15 nicklas 119         counters.put("ContralateralSample", new Counter("ContralateralSample"));
3394 12 Jun 15 nicklas 120
3394 12 Jun 15 nicklas 121         // Load all patients and cases that have at least one 
6510 03 Dec 21 nicklas 122         // specimen/nospecimen without creation date
3905 29 Apr 16 nicklas 123         ItemQuery<Sample> queryNoDate = Sample.getQuery();
3905 29 Apr 16 nicklas 124         queryNoDate.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
3905 29 Apr 16 nicklas 125         queryNoDate.restrict(
3394 12 Jun 15 nicklas 126           Restrictions.or(
3394 12 Jun 15 nicklas 127             Subtype.SPECIMEN.restriction(dc, null),
6510 03 Dec 21 nicklas 128             Subtype.NO_SPECIMEN.restriction(dc, null)
3394 12 Jun 15 nicklas 129           ));
3905 29 Apr 16 nicklas 130         queryNoDate.join(Hql.innerJoin(null, "parent", "c", null, true));
3905 29 Apr 16 nicklas 131         queryNoDate.join(Hql.innerJoin("c", "parent", "pat", null, true));
3905 29 Apr 16 nicklas 132         queryNoDate.join(Hql.innerJoin("creationEvent", "ce"));
3394 12 Jun 15 nicklas 133         
3394 12 Jun 15 nicklas 134         // creation date == null
3905 29 Apr 16 nicklas 135         queryNoDate.restrict(Restrictions.eq(Hql.property("ce", "eventDate"), null));
3394 12 Jun 15 nicklas 136         
6510 03 Dec 21 nicklas 137         // Load all specimen/nospecimen with a known creation date
3905 29 Apr 16 nicklas 138         // IMPORTANT!! Sort by oldest first 
3905 29 Apr 16 nicklas 139         ItemQuery<Sample> queryHasDate = Sample.getQuery();
3905 29 Apr 16 nicklas 140         queryHasDate.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
3905 29 Apr 16 nicklas 141         queryHasDate.restrict(
3905 29 Apr 16 nicklas 142           Restrictions.or(
3905 29 Apr 16 nicklas 143             Subtype.SPECIMEN.restriction(dc, null),
6510 03 Dec 21 nicklas 144             Subtype.NO_SPECIMEN.restriction(dc, null)
3905 29 Apr 16 nicklas 145           ));
3905 29 Apr 16 nicklas 146         queryHasDate.join(Hql.innerJoin(null, "parent", "c", null, true));
3905 29 Apr 16 nicklas 147         queryHasDate.join(Hql.innerJoin("c", "parent", "pat", null, true));
3905 29 Apr 16 nicklas 148         queryHasDate.join(Hql.innerJoin(null, "creationEvent", "ce", null, true));
3905 29 Apr 16 nicklas 149         
3905 29 Apr 16 nicklas 150         queryHasDate.restrict(Restrictions.neq(Hql.property("ce", "eventDate"), null));
3905 29 Apr 16 nicklas 151         queryHasDate.order(Orders.asc(Hql.property("ce", "eventDate")));
3905 29 Apr 16 nicklas 152         
3905 29 Apr 16 nicklas 153         long totalCount = queryNoDate.count(dc) + queryHasDate.count(dc);
3905 29 Apr 16 nicklas 154         long count = 0;
3905 29 Apr 16 nicklas 155         
3394 12 Jun 15 nicklas 156         // All patients and cases with a specimen that is missing creation date
3905 29 Apr 16 nicklas 157         Set<BioMaterial> unknownDate = new HashSet<BioMaterial>();
3905 29 Apr 16 nicklas 158         Iterator<Sample> it = queryNoDate.iterate(dc);
3905 29 Apr 16 nicklas 159         while (it.hasNext())
3394 12 Jun 15 nicklas 160         {
3905 29 Apr 16 nicklas 161           if (count % 100 == 0)
3905 29 Apr 16 nicklas 162           {
3905 29 Apr 16 nicklas 163             progress.display(5 + (int)((95 * count) / totalCount), count + " of " + totalCount + " done");
3905 29 Apr 16 nicklas 164           }
3905 29 Apr 16 nicklas 165           count++;
3905 29 Apr 16 nicklas 166           
3905 29 Apr 16 nicklas 167           Sample specimen = it.next();
3394 12 Jun 15 nicklas 168           Sample theCase = (Sample)specimen.getParent();
3394 12 Jun 15 nicklas 169           BioSource patient = (BioSource)theCase.getParent();
3394 12 Jun 15 nicklas 170           unknownDate.add(theCase);
3394 12 Jun 15 nicklas 171           unknownDate.add(patient);
3394 12 Jun 15 nicklas 172           numNoDate++;
3394 12 Jun 15 nicklas 173           
3394 12 Jun 15 nicklas 174           String currentLinkedSpecimenValue = (String)Annotationtype.LINKED_SPECIMEN.getAnnotationValue(dc, snapshot, specimen);
3481 09 Sep 15 nicklas 175           String newLinkedSpecimenValue = "MissingDate";
3394 12 Jun 15 nicklas 176           
3394 12 Jun 15 nicklas 177           // Update counter and the annotation if needed
3394 12 Jun 15 nicklas 178           Counter counter = counters.get(currentLinkedSpecimenValue);
3394 12 Jun 15 nicklas 179           if (counter != null) counter.numBefore++;
3394 12 Jun 15 nicklas 180           counter = counters.get(newLinkedSpecimenValue);
3394 12 Jun 15 nicklas 181           if (counter != null) counter.numAfter++;
3394 12 Jun 15 nicklas 182           if (!EqualsHelper.equals(newLinkedSpecimenValue, currentLinkedSpecimenValue))
3394 12 Jun 15 nicklas 183           {
3394 12 Jun 15 nicklas 184             numUpdated++;
3394 12 Jun 15 nicklas 185             Annotationtype.LINKED_SPECIMEN.setAnnotationValue(dc, specimen, newLinkedSpecimenValue);
3394 12 Jun 15 nicklas 186           }
3394 12 Jun 15 nicklas 187         }
3394 12 Jun 15 nicklas 188         
3394 12 Jun 15 nicklas 189         
3394 12 Jun 15 nicklas 190         
3394 12 Jun 15 nicklas 191         // Stores info about first specimen and core biopsy per patient and case
3394 12 Jun 15 nicklas 192         Map<BioMaterial, LinkedSpecimenInfo> info = new HashMap<BioMaterial, LinkedSpecimenInfo>();
3394 12 Jun 15 nicklas 193         
3905 29 Apr 16 nicklas 194         it = queryHasDate.iterate(dc);
3905 29 Apr 16 nicklas 195         while (it.hasNext())
3394 12 Jun 15 nicklas 196         {
3905 29 Apr 16 nicklas 197           if (count % 100 == 0)
3905 29 Apr 16 nicklas 198           {
3905 29 Apr 16 nicklas 199             progress.display(5 + (int)((95 * count) / totalCount), count + " of " + totalCount + " done");
3905 29 Apr 16 nicklas 200           }
3905 29 Apr 16 nicklas 201           count++;
3905 29 Apr 16 nicklas 202           
3905 29 Apr 16 nicklas 203           Sample specimen = it.next();
3905 29 Apr 16 nicklas 204           
3394 12 Jun 15 nicklas 205           // Load parent case and patient
3394 12 Jun 15 nicklas 206           Sample theCase = (Sample)specimen.getParent();
3394 12 Jun 15 nicklas 207           BioSource patient = (BioSource)theCase.getParent();
3394 12 Jun 15 nicklas 208           
3394 12 Jun 15 nicklas 209           // Load the creation date and check if this is a core biopsy or not
3394 12 Jun 15 nicklas 210           Date created = specimen.getCreationEvent().getEventDate();
3394 12 Jun 15 nicklas 211           
3394 12 Jun 15 nicklas 212           String biopsyType = (String)Annotationtype.BIOPSY_TYPE.getAnnotationValue(dc, snapshot, specimen);
3394 12 Jun 15 nicklas 213           boolean isCoreBiopsy = "SpecimenCoreBiopsy".equals(biopsyType) || "SpecimenCoreBiopsy2nd".equals(biopsyType);
3394 12 Jun 15 nicklas 214           
3394 12 Jun 15 nicklas 215           String currentLinkedSpecimenValue = (String)Annotationtype.LINKED_SPECIMEN.getAnnotationValue(dc, snapshot, specimen);
3394 12 Jun 15 nicklas 216           String newLinkedSpecimenValue = null;
3394 12 Jun 15 nicklas 217           
3394 12 Jun 15 nicklas 218           Counter counter = counters.get(currentLinkedSpecimenValue);
3394 12 Jun 15 nicklas 219           if (counter != null) counter.numBefore++;
3394 12 Jun 15 nicklas 220           
3394 12 Jun 15 nicklas 221           // Check if the case or patient has another specimen without creation date
3394 12 Jun 15 nicklas 222           if (unknownDate.contains(theCase) || unknownDate.contains(patient))
3394 12 Jun 15 nicklas 223           {
3394 12 Jun 15 nicklas 224             // Clear annotations
3481 09 Sep 15 nicklas 225             newLinkedSpecimenValue = "MissingDate";
3394 12 Jun 15 nicklas 226             numNoDate++;
3394 12 Jun 15 nicklas 227           }
3394 12 Jun 15 nicklas 228           else
3394 12 Jun 15 nicklas 229           {
3394 12 Jun 15 nicklas 230             // Get/update information about prior specimen for the case and patient
3394 12 Jun 15 nicklas 231             // Since we are processing them in date order we can simply
3394 12 Jun 15 nicklas 232             // compare the current that agains any prior information
3394 12 Jun 15 nicklas 233             LinkedSpecimenInfo forCase = info.get(theCase);
3394 12 Jun 15 nicklas 234             if (forCase == null)
3394 12 Jun 15 nicklas 235             {
3394 12 Jun 15 nicklas 236               forCase = new LinkedSpecimenInfo(created, isCoreBiopsy);
3394 12 Jun 15 nicklas 237               info.put(theCase, forCase);
3394 12 Jun 15 nicklas 238             }
3394 12 Jun 15 nicklas 239             else if (isCoreBiopsy)
3394 12 Jun 15 nicklas 240             {
3394 12 Jun 15 nicklas 241               forCase.setCoreBiopsy(created);
3394 12 Jun 15 nicklas 242             }
3394 12 Jun 15 nicklas 243             
3394 12 Jun 15 nicklas 244             LinkedSpecimenInfo forPatient = info.get(patient);
3394 12 Jun 15 nicklas 245             if (forPatient == null)
3394 12 Jun 15 nicklas 246             {
3394 12 Jun 15 nicklas 247               forPatient = new LinkedSpecimenInfo(created, isCoreBiopsy);
3394 12 Jun 15 nicklas 248               info.put(patient, forPatient);
3394 12 Jun 15 nicklas 249             }
3394 12 Jun 15 nicklas 250             else if (isCoreBiopsy)
3394 12 Jun 15 nicklas 251             {
3394 12 Jun 15 nicklas 252               forPatient.setCoreBiopsy(created);
3394 12 Jun 15 nicklas 253             }
3394 12 Jun 15 nicklas 254             
3394 12 Jun 15 nicklas 255             if (forCase.hasPriorCoreBiopsy(created))
3394 12 Jun 15 nicklas 256             {
3394 12 Jun 15 nicklas 257               newLinkedSpecimenValue = "IpsilateralCoreBiopsy";
3394 12 Jun 15 nicklas 258             }
3394 12 Jun 15 nicklas 259             else if (forPatient.hasPriorCoreBiopsy(created))
3394 12 Jun 15 nicklas 260             {
3394 12 Jun 15 nicklas 261               newLinkedSpecimenValue = "ContralateralCoreBiopsy";
3394 12 Jun 15 nicklas 262             }
3394 12 Jun 15 nicklas 263             else if (forCase.hasPriorSpecimen(created))
3394 12 Jun 15 nicklas 264             {
3394 12 Jun 15 nicklas 265               newLinkedSpecimenValue = "IpsilateralSample";
3394 12 Jun 15 nicklas 266             }
3394 12 Jun 15 nicklas 267             else if (forPatient.hasPriorSpecimen(created))
3394 12 Jun 15 nicklas 268             {
3394 12 Jun 15 nicklas 269               newLinkedSpecimenValue = "ContralateralSample";
3394 12 Jun 15 nicklas 270             }
3394 12 Jun 15 nicklas 271           }
3394 12 Jun 15 nicklas 272         
3394 12 Jun 15 nicklas 273           // Update counter and the annotation if needed
3394 12 Jun 15 nicklas 274           counter = counters.get(newLinkedSpecimenValue);
3394 12 Jun 15 nicklas 275           if (counter != null) counter.numAfter++;
3394 12 Jun 15 nicklas 276           if (!EqualsHelper.equals(newLinkedSpecimenValue, currentLinkedSpecimenValue))
3394 12 Jun 15 nicklas 277           {
3394 12 Jun 15 nicklas 278             numUpdated++;
3394 12 Jun 15 nicklas 279             Annotationtype.LINKED_SPECIMEN.setAnnotationValue(dc, specimen, newLinkedSpecimenValue);
3394 12 Jun 15 nicklas 280           }
3394 12 Jun 15 nicklas 281         }
3394 12 Jun 15 nicklas 282         
3394 12 Jun 15 nicklas 283         JSONArray jsonCounters = new JSONArray();
3394 12 Jun 15 nicklas 284         for (Counter c : counters.values())
3394 12 Jun 15 nicklas 285         {
3394 12 Jun 15 nicklas 286           JSONObject jsonCount = new JSONObject();
3394 12 Jun 15 nicklas 287           jsonCount.put("name", c.name);
3394 12 Jun 15 nicklas 288           jsonCount.put("before", c.numBefore);
3394 12 Jun 15 nicklas 289           jsonCount.put("after", c.numAfter);
3394 12 Jun 15 nicklas 290           jsonCounters.add(jsonCount);
3394 12 Jun 15 nicklas 291         }
3394 12 Jun 15 nicklas 292         json.put("counters", jsonCounters);
3394 12 Jun 15 nicklas 293         json.put("numUpdated", numUpdated);
3394 12 Jun 15 nicklas 294         json.put("numNoDate", numNoDate);
3394 12 Jun 15 nicklas 295
3394 12 Jun 15 nicklas 296         dc.commit();
3394 12 Jun 15 nicklas 297         json.put("messages", jsonMessages);
3394 12 Jun 15 nicklas 298       }
3394 12 Jun 15 nicklas 299       
3394 12 Jun 15 nicklas 300
3394 12 Jun 15 nicklas 301       CounterService.getInstance().setForceCount();
3394 12 Jun 15 nicklas 302     }
3394 12 Jun 15 nicklas 303     catch (Throwable t)
3394 12 Jun 15 nicklas 304     {
3394 12 Jun 15 nicklas 305       t.printStackTrace();
3394 12 Jun 15 nicklas 306       json.clear();
3394 12 Jun 15 nicklas 307       json.put("status", "error");
3394 12 Jun 15 nicklas 308       json.put("message", t.getMessage());
3394 12 Jun 15 nicklas 309       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
3394 12 Jun 15 nicklas 310     }
3394 12 Jun 15 nicklas 311     finally
3394 12 Jun 15 nicklas 312     {
3394 12 Jun 15 nicklas 313       if (dc != null) dc.close();
3905 29 Apr 16 nicklas 314       if (sc != null) sc.setSessionSetting("linked-specimen-progress", null);
3394 12 Jun 15 nicklas 315       json.writeJSONString(resp.getWriter());
3394 12 Jun 15 nicklas 316     }
3394 12 Jun 15 nicklas 317     
3394 12 Jun 15 nicklas 318   }
3394 12 Jun 15 nicklas 319
3394 12 Jun 15 nicklas 320   
3394 12 Jun 15 nicklas 321   static class Counter
3394 12 Jun 15 nicklas 322   {
3394 12 Jun 15 nicklas 323     
3394 12 Jun 15 nicklas 324     final String name;
3394 12 Jun 15 nicklas 325
3394 12 Jun 15 nicklas 326     Counter(String name)
3394 12 Jun 15 nicklas 327     {
3394 12 Jun 15 nicklas 328       this.name = name;
3394 12 Jun 15 nicklas 329     }
3394 12 Jun 15 nicklas 330     
3394 12 Jun 15 nicklas 331     int numBefore = 0;
3394 12 Jun 15 nicklas 332     int numAfter = 0;
3394 12 Jun 15 nicklas 333   }
3394 12 Jun 15 nicklas 334   
3394 12 Jun 15 nicklas 335   static class LinkedSpecimenInfo
3394 12 Jun 15 nicklas 336   {
3394 12 Jun 15 nicklas 337     private Date firstCoreBiopsy;
3394 12 Jun 15 nicklas 338     private Date firstSpecimen;
3394 12 Jun 15 nicklas 339     
3394 12 Jun 15 nicklas 340     LinkedSpecimenInfo(Date created, boolean isCoreBiopsy)
3394 12 Jun 15 nicklas 341     {
3394 12 Jun 15 nicklas 342       firstSpecimen = created;
3394 12 Jun 15 nicklas 343       if (isCoreBiopsy) firstCoreBiopsy = created;
3394 12 Jun 15 nicklas 344     }
3394 12 Jun 15 nicklas 345     
3394 12 Jun 15 nicklas 346     void setCoreBiopsy(Date created)
3394 12 Jun 15 nicklas 347     {
3394 12 Jun 15 nicklas 348       if (firstCoreBiopsy == null) firstCoreBiopsy = created;
3394 12 Jun 15 nicklas 349     }
3394 12 Jun 15 nicklas 350     
3394 12 Jun 15 nicklas 351     boolean hasPriorCoreBiopsy(Date created)
3394 12 Jun 15 nicklas 352     {
3394 12 Jun 15 nicklas 353       return firstCoreBiopsy != null && firstCoreBiopsy.before(created);
3394 12 Jun 15 nicklas 354     }
3394 12 Jun 15 nicklas 355
3394 12 Jun 15 nicklas 356     boolean hasPriorSpecimen(Date created)
3394 12 Jun 15 nicklas 357     {
3394 12 Jun 15 nicklas 358       return firstSpecimen != null && firstSpecimen.before(created);
3394 12 Jun 15 nicklas 359     }
3394 12 Jun 15 nicklas 360
3394 12 Jun 15 nicklas 361   }
3394 12 Jun 15 nicklas 362 }