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

Code
Comments
Other
Rev Date Author Line
4477 03 May 17 nicklas 1 package net.sf.basedb.reggie.servlet;
4477 03 May 17 nicklas 2
4477 03 May 17 nicklas 3 import java.io.IOException;
6098 11 Jan 21 nicklas 4 import java.time.Instant;
6098 11 Jan 21 nicklas 5 import java.time.LocalDateTime;
6098 11 Jan 21 nicklas 6 import java.time.ZoneId;
6098 11 Jan 21 nicklas 7 import java.time.temporal.ChronoUnit;
4477 03 May 17 nicklas 8 import java.util.Date;
4477 03 May 17 nicklas 9 import java.util.HashMap;
4701 16 Mar 18 nicklas 10 import java.util.HashSet;
4477 03 May 17 nicklas 11 import java.util.Iterator;
4477 03 May 17 nicklas 12 import java.util.Map;
4701 16 Mar 18 nicklas 13 import java.util.Set;
4477 03 May 17 nicklas 14
4477 03 May 17 nicklas 15 import javax.servlet.ServletException;
4477 03 May 17 nicklas 16 import javax.servlet.http.HttpServlet;
4477 03 May 17 nicklas 17 import javax.servlet.http.HttpServletRequest;
4477 03 May 17 nicklas 18 import javax.servlet.http.HttpServletResponse;
4477 03 May 17 nicklas 19
4477 03 May 17 nicklas 20 import org.json.simple.JSONArray;
4477 03 May 17 nicklas 21 import org.json.simple.JSONObject;
4477 03 May 17 nicklas 22
6098 11 Jan 21 nicklas 23 import net.sf.basedb.core.BioSource;
4477 03 May 17 nicklas 24 import net.sf.basedb.core.DbControl;
4477 03 May 17 nicklas 25 import net.sf.basedb.core.Item;
4477 03 May 17 nicklas 26 import net.sf.basedb.core.ItemQuery;
4477 03 May 17 nicklas 27 import net.sf.basedb.core.Sample;
4477 03 May 17 nicklas 28 import net.sf.basedb.core.SessionControl;
4477 03 May 17 nicklas 29 import net.sf.basedb.core.SimpleProgressReporter;
4701 16 Mar 18 nicklas 30 import net.sf.basedb.core.query.Annotations;
4701 16 Mar 18 nicklas 31 import net.sf.basedb.core.query.Expressions;
4477 03 May 17 nicklas 32 import net.sf.basedb.core.query.Hql;
4477 03 May 17 nicklas 33 import net.sf.basedb.core.query.Orders;
4477 03 May 17 nicklas 34 import net.sf.basedb.core.query.Restrictions;
4477 03 May 17 nicklas 35 import net.sf.basedb.core.snapshot.SnapshotManager;
4477 03 May 17 nicklas 36 import net.sf.basedb.reggie.JsonUtil;
4477 03 May 17 nicklas 37 import net.sf.basedb.reggie.Reggie;
4477 03 May 17 nicklas 38 import net.sf.basedb.reggie.counter.CounterService;
4477 03 May 17 nicklas 39 import net.sf.basedb.reggie.dao.Annotationtype;
4477 03 May 17 nicklas 40 import net.sf.basedb.reggie.dao.ReferenceDateSource;
4477 03 May 17 nicklas 41 import net.sf.basedb.reggie.dao.ReferenceDateWithSource;
4477 03 May 17 nicklas 42 import net.sf.basedb.reggie.dao.ReggieRole;
4477 03 May 17 nicklas 43 import net.sf.basedb.reggie.dao.Subtype;
4477 03 May 17 nicklas 44 import net.sf.basedb.util.error.ThrowableUtil;
4477 03 May 17 nicklas 45
4477 03 May 17 nicklas 46
4477 03 May 17 nicklas 47 public class ReferenceDateServlet 
4477 03 May 17 nicklas 48   extends HttpServlet 
4477 03 May 17 nicklas 49 {
4477 03 May 17 nicklas 50
4477 03 May 17 nicklas 51   private static final long serialVersionUID = 8047423138847961359L;
4477 03 May 17 nicklas 52
4477 03 May 17 nicklas 53   public ReferenceDateServlet()
4477 03 May 17 nicklas 54   {}
4477 03 May 17 nicklas 55
4477 03 May 17 nicklas 56   @Override
4477 03 May 17 nicklas 57   protected void doGet(HttpServletRequest req, HttpServletResponse resp)
4477 03 May 17 nicklas 58     throws ServletException, IOException 
4477 03 May 17 nicklas 59   {
4477 03 May 17 nicklas 60     String cmd = req.getParameter("cmd");
4477 03 May 17 nicklas 61     JsonUtil.setJsonResponseHeaders(resp);
4477 03 May 17 nicklas 62     
4477 03 May 17 nicklas 63     JSONObject json = new JSONObject();
4477 03 May 17 nicklas 64     json.put("status", "ok");
4477 03 May 17 nicklas 65   
4477 03 May 17 nicklas 66     final SessionControl sc = Reggie.getSessionControl(req);
4477 03 May 17 nicklas 67     DbControl dc = null;
4477 03 May 17 nicklas 68     try
4477 03 May 17 nicklas 69     {
4477 03 May 17 nicklas 70
4477 03 May 17 nicklas 71     }
4477 03 May 17 nicklas 72     catch (Throwable t)
4477 03 May 17 nicklas 73     {
4477 03 May 17 nicklas 74       t.printStackTrace();
4477 03 May 17 nicklas 75       json.clear();
4477 03 May 17 nicklas 76       json.put("status", "error");
4477 03 May 17 nicklas 77       json.put("message", t.getMessage());
4477 03 May 17 nicklas 78       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
4477 03 May 17 nicklas 79     }
4477 03 May 17 nicklas 80     finally
4477 03 May 17 nicklas 81     {
4477 03 May 17 nicklas 82       if (dc != null) dc.close();
4477 03 May 17 nicklas 83       json.writeJSONString(resp.getWriter());
4477 03 May 17 nicklas 84     }
4477 03 May 17 nicklas 85     
4477 03 May 17 nicklas 86     
4477 03 May 17 nicklas 87   }
4477 03 May 17 nicklas 88
4477 03 May 17 nicklas 89   @Override
4477 03 May 17 nicklas 90   protected void doPost(HttpServletRequest req, HttpServletResponse resp)
4477 03 May 17 nicklas 91     throws ServletException, IOException 
4477 03 May 17 nicklas 92   {
4477 03 May 17 nicklas 93     String cmd = req.getParameter("cmd");
4477 03 May 17 nicklas 94     JsonUtil.setJsonResponseHeaders(resp);
4477 03 May 17 nicklas 95     
4477 03 May 17 nicklas 96     JSONObject json = new JSONObject();
4477 03 May 17 nicklas 97     json.put("status", "ok");
4477 03 May 17 nicklas 98     
4477 03 May 17 nicklas 99     JSONArray jsonMessages = new JSONArray();
4477 03 May 17 nicklas 100   
4477 03 May 17 nicklas 101     final SessionControl sc = Reggie.getSessionControl(req);
4477 03 May 17 nicklas 102     DbControl dc = null;
4477 03 May 17 nicklas 103     try
4477 03 May 17 nicklas 104     {
4477 03 May 17 nicklas 105       if ("UpdateAllReferenceDateAnnotations".equals(cmd))
4477 03 May 17 nicklas 106       {
6336 16 Jun 21 nicklas 107         dc = sc.newDbControl(":Reference date wizard");
4477 03 May 17 nicklas 108
4477 03 May 17 nicklas 109         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.PREP_CURATOR, ReggieRole.ADMINISTRATOR);
4477 03 May 17 nicklas 110         
4477 03 May 17 nicklas 111         SimpleProgressReporter progress = new SimpleProgressReporter(null);
4477 03 May 17 nicklas 112         sc.setSessionSetting("ref-date-progress", progress);
4477 03 May 17 nicklas 113         progress.display(1, "Loading cases...");
4477 03 May 17 nicklas 114         
4477 03 May 17 nicklas 115         SnapshotManager snapshot = new SnapshotManager();
4477 03 May 17 nicklas 116
4477 03 May 17 nicklas 117         // Initialize counters
4477 03 May 17 nicklas 118         int numUpdated = 0;
4701 16 Mar 18 nicklas 119         int numSkipped = 0;
6098 11 Jan 21 nicklas 120         int numLinkedCasesUpdated = 0;
4477 03 May 17 nicklas 121         Map<ReferenceDateSource, Counter> counters = new HashMap<ReferenceDateSource, Counter>();
4701 16 Mar 18 nicklas 122         Counter incaDiagnosisDateCounter = new Counter(ReferenceDateSource.INCA_DIAGNOSIS_DATE);
4477 03 May 17 nicklas 123         counters.put(null, new Counter(null));
4701 16 Mar 18 nicklas 124         counters.put(ReferenceDateSource.INCA_DIAGNOSIS_DATE, incaDiagnosisDateCounter);
4701 16 Mar 18 nicklas 125         counters.put(ReferenceDateSource.SAMPLING_DATE, new Counter(ReferenceDateSource.SAMPLING_DATE));
4701 16 Mar 18 nicklas 126         counters.put(ReferenceDateSource.CONSENT_DATE, new Counter(ReferenceDateSource.CONSENT_DATE));
4701 16 Mar 18 nicklas 127         counters.put(ReferenceDateSource.REGISTRATION_DATE, new Counter(ReferenceDateSource.REGISTRATION_DATE));
4477 03 May 17 nicklas 128
4701 16 Mar 18 nicklas 129         // Query to load all cases with ReferenceDateSource=IncaDiagnosisDate AND RefererenceDate=INCA2_a_diag_dat
4701 16 Mar 18 nicklas 130         // They are already correct and will not have to be checked furthur which should speed up the update process
4701 16 Mar 18 nicklas 131         ItemQuery<Sample> ccQuery = Sample.getQuery();
4701 16 Mar 18 nicklas 132         ccQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
4701 16 Mar 18 nicklas 133         Subtype.CASE.addFilter(dc, ccQuery);
4701 16 Mar 18 nicklas 134         ccQuery.join(Annotations.innerJoin(Annotationtype.REFERENCE_DATE_SOURCE.load(dc), "refs"));
4701 16 Mar 18 nicklas 135         ccQuery.join(Annotations.innerJoin(Annotationtype.INCA2_a_diag_dat.load(dc), "idat"));
4701 16 Mar 18 nicklas 136         ccQuery.join(Annotations.innerJoin(Annotationtype.REFERENCE_DATE.load(dc), "rdat"));
4701 16 Mar 18 nicklas 137         ccQuery.restrict(Restrictions.eq(Hql.alias("refs"), Expressions.string(ReferenceDateSource.INCA_DIAGNOSIS_DATE.getTitle())));
4701 16 Mar 18 nicklas 138         ccQuery.restrict(Restrictions.eq(Hql.alias("idat"), Hql.alias("rdat")));
4701 16 Mar 18 nicklas 139         
4701 16 Mar 18 nicklas 140         Set<Integer> okCases = new HashSet<>(ccQuery.idList(dc));
4701 16 Mar 18 nicklas 141         
4477 03 May 17 nicklas 142         // Load all cases
4477 03 May 17 nicklas 143         ItemQuery<Sample> caseQuery = Sample.getQuery();
4477 03 May 17 nicklas 144         caseQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
4477 03 May 17 nicklas 145         Subtype.CASE.addFilter(dc, caseQuery);
6098 11 Jan 21 nicklas 146         // IMPORTANT!! Sort by patient so that we can calculate LinkedCase annotation easy
6098 11 Jan 21 nicklas 147         caseQuery.order(Orders.asc(Hql.property("parent.id")));
4477 03 May 17 nicklas 148         
6510 03 Dec 21 nicklas 149         // Load all child Specimen/NoSpecimen with a known creation date
4477 03 May 17 nicklas 150         // IMPORTANT!! Sort by oldest first 
4477 03 May 17 nicklas 151         ItemQuery<Sample> specimenQuery = Sample.getQuery();
4477 03 May 17 nicklas 152         specimenQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
4477 03 May 17 nicklas 153         specimenQuery.restrict(
4477 03 May 17 nicklas 154           Restrictions.or(
4477 03 May 17 nicklas 155             Subtype.SPECIMEN.restriction(dc, null),
6510 03 Dec 21 nicklas 156             Subtype.NO_SPECIMEN.restriction(dc, null)
4477 03 May 17 nicklas 157           ));
4477 03 May 17 nicklas 158         specimenQuery.join(Hql.innerJoin(null, "parent", "c", null, true));
4477 03 May 17 nicklas 159         specimenQuery.join(Hql.innerJoin(null, "creationEvent", "ce", null, true));
4477 03 May 17 nicklas 160         
4477 03 May 17 nicklas 161         specimenQuery.restrict(Restrictions.eq(Hql.alias("c"), Hql.entityParameter("c", Item.SAMPLE)));
4477 03 May 17 nicklas 162         
4477 03 May 17 nicklas 163         specimenQuery.restrict(Restrictions.neq(Hql.property("ce", "eventDate"), null));
4477 03 May 17 nicklas 164         specimenQuery.order(Orders.asc(Hql.property("ce", "eventDate")));
4477 03 May 17 nicklas 165         
6098 11 Jan 21 nicklas 166         // Keep track of last case and patient 
6098 11 Jan 21 nicklas 167         Sample lastCase = null;
6098 11 Jan 21 nicklas 168         BioSource lastPatient = null;
6440 11 Oct 21 nicklas 169         ReferenceDateWithSource lastRefAfter = null;
4477 03 May 17 nicklas 170         long totalCount = caseQuery.count(dc);
4477 03 May 17 nicklas 171         long count = 0;
4477 03 May 17 nicklas 172         Iterator<Sample> it = caseQuery.iterate(dc);
4477 03 May 17 nicklas 173         while (it.hasNext())
4477 03 May 17 nicklas 174         {
4477 03 May 17 nicklas 175           if (count % 100 == 0)
4477 03 May 17 nicklas 176           {
6098 11 Jan 21 nicklas 177             progress.display(5 + (int)((90 * count) / totalCount), count + " of " + totalCount + 
6098 11 Jan 21 nicklas 178               " done (" + numUpdated + " reference dates and " + numLinkedCasesUpdated + " linked cases updated)");
4477 03 May 17 nicklas 179           }
4477 03 May 17 nicklas 180           count++;
4477 03 May 17 nicklas 181           
4477 03 May 17 nicklas 182           Sample theCase = it.next();
6440 11 Oct 21 nicklas 183           ReferenceDateWithSource refAfter = null;
4701 16 Mar 18 nicklas 184           if (okCases.contains(theCase.getId()))
4477 03 May 17 nicklas 185           {
4701 16 Mar 18 nicklas 186             incaDiagnosisDateCounter.numBefore++;
4701 16 Mar 18 nicklas 187             incaDiagnosisDateCounter.numAfter++;
4701 16 Mar 18 nicklas 188             numSkipped++;
4477 03 May 17 nicklas 189           }
4701 16 Mar 18 nicklas 190           else
4477 03 May 17 nicklas 191           {
4477 03 May 17 nicklas 192           
4701 16 Mar 18 nicklas 193             // Load the information that we already have
4701 16 Mar 18 nicklas 194             Date dateBefore = (Date)Annotationtype.REFERENCE_DATE.getAnnotationValue(dc, snapshot, theCase);
4701 16 Mar 18 nicklas 195             String sourceBefore = (String)Annotationtype.REFERENCE_DATE_SOURCE.getAnnotationValue(dc, snapshot, theCase);
4701 16 Mar 18 nicklas 196             ReferenceDateWithSource refBefore = null;
4701 16 Mar 18 nicklas 197             if (dateBefore != null && sourceBefore != null) 
4477 03 May 17 nicklas 198             {
4701 16 Mar 18 nicklas 199               refBefore = new ReferenceDateWithSource(dateBefore, ReferenceDateSource.fromTitle(sourceBefore));
4477 03 May 17 nicklas 200             }
4701 16 Mar 18 nicklas 201             
4701 16 Mar 18 nicklas 202             // Check for INCA diagnosis date
4701 16 Mar 18 nicklas 203             Date incaDiaDate = (Date)Annotationtype.INCA2_a_diag_dat.getAnnotationValue(dc, snapshot, theCase);
4701 16 Mar 18 nicklas 204             if (incaDiaDate != null)
4477 03 May 17 nicklas 205             {
4701 16 Mar 18 nicklas 206               refAfter = new ReferenceDateWithSource(incaDiaDate, ReferenceDateSource.INCA_DIAGNOSIS_DATE);
4477 03 May 17 nicklas 207             }
4701 16 Mar 18 nicklas 208             
4701 16 Mar 18 nicklas 209             // Check for sampling date of Specimen/NoSpecimen
4701 16 Mar 18 nicklas 210             if (refAfter == null)
4701 16 Mar 18 nicklas 211             {
4701 16 Mar 18 nicklas 212               specimenQuery.setEntityParameter("c", theCase);
4701 16 Mar 18 nicklas 213               Iterator<Sample> it2 = specimenQuery.iterate(dc);
4701 16 Mar 18 nicklas 214               if (it2.hasNext())
4701 16 Mar 18 nicklas 215               {
4701 16 Mar 18 nicklas 216                 Sample specimen = it2.next();
4701 16 Mar 18 nicklas 217                 refAfter = new ReferenceDateWithSource(specimen.getCreationEvent().getEventDate(), ReferenceDateSource.SAMPLING_DATE);
4701 16 Mar 18 nicklas 218               }
4701 16 Mar 18 nicklas 219             }
4701 16 Mar 18 nicklas 220             
4701 16 Mar 18 nicklas 221             // Check for consent date
4701 16 Mar 18 nicklas 222             if (refAfter == null)
4701 16 Mar 18 nicklas 223             {
4701 16 Mar 18 nicklas 224               Date consentDate = (Date)Annotationtype.CONSENT_DATE.getAnnotationValue(dc, snapshot, theCase);
4701 16 Mar 18 nicklas 225               if (consentDate != null)
4701 16 Mar 18 nicklas 226               {
4701 16 Mar 18 nicklas 227                 refAfter = new ReferenceDateWithSource(consentDate, ReferenceDateSource.CONSENT_DATE);
4701 16 Mar 18 nicklas 228               }
4701 16 Mar 18 nicklas 229             }
4701 16 Mar 18 nicklas 230             
4701 16 Mar 18 nicklas 231             // We always have a registration date
4701 16 Mar 18 nicklas 232             if (refAfter == null)
4701 16 Mar 18 nicklas 233             {
4701 16 Mar 18 nicklas 234               refAfter = new ReferenceDateWithSource(theCase.getEntryDate(), ReferenceDateSource.REGISTRATION_DATE);
4701 16 Mar 18 nicklas 235             }
4701 16 Mar 18 nicklas 236             
4701 16 Mar 18 nicklas 237             // Update counter and the annotation if needed
4701 16 Mar 18 nicklas 238             Counter counter = counters.get(refBefore == null ? null : refBefore.getSource());
4701 16 Mar 18 nicklas 239             if (counter != null) counter.numBefore++;
4477 03 May 17 nicklas 240
4701 16 Mar 18 nicklas 241             counter = counters.get(refAfter.getSource());
4701 16 Mar 18 nicklas 242             if (counter != null) counter.numAfter++;
4701 16 Mar 18 nicklas 243             if (!refAfter.equals(refBefore))
4701 16 Mar 18 nicklas 244             {
4701 16 Mar 18 nicklas 245               refAfter.updateAnnotations(dc, theCase);
4701 16 Mar 18 nicklas 246               numUpdated++;
4701 16 Mar 18 nicklas 247             }
4477 03 May 17 nicklas 248           }
6098 11 Jan 21 nicklas 249           
6098 11 Jan 21 nicklas 250           // Update LinkedCase if there is a second case for the same patient
6098 11 Jan 21 nicklas 251           BioSource patient = (BioSource)theCase.getParent();
6440 11 Oct 21 nicklas 252           if (patient != null && patient.equals(lastPatient))
6098 11 Jan 21 nicklas 253           {
6098 11 Jan 21 nicklas 254             // We have a patient with two case -- calculate and update LinkedSpecimen
6440 11 Oct 21 nicklas 255             Date thisDate = refAfter == null ? (Date)Annotationtype.REFERENCE_DATE.getAnnotationValue(dc, snapshot, theCase) : refAfter.getDate();
6440 11 Oct 21 nicklas 256             Date otherDate = lastRefAfter == null ? (Date)Annotationtype.REFERENCE_DATE.getAnnotationValue(dc, snapshot, lastCase) : lastRefAfter.getDate();
6098 11 Jan 21 nicklas 257             
6440 11 Oct 21 nicklas 258             // The dates SHOULD never be null, but just in case...
6440 11 Oct 21 nicklas 259             if (thisDate != null && otherDate != null)
6440 11 Oct 21 nicklas 260             {
6440 11 Oct 21 nicklas 261               LocalDateTime thisDay = LocalDateTime.ofInstant(Instant.ofEpochMilli(thisDate.getTime()), ZoneId.systemDefault());
6440 11 Oct 21 nicklas 262               LocalDateTime otherDay = LocalDateTime.ofInstant(Instant.ofEpochMilli(otherDate.getTime()), ZoneId.systemDefault());
6440 11 Oct 21 nicklas 263               
6440 11 Oct 21 nicklas 264               int daysBetween = (int)ChronoUnit.DAYS.between(thisDay, otherDay);
6440 11 Oct 21 nicklas 265               if (Annotationtype.LINKED_CASE.setAnnotationValue(dc, theCase, daysBetween)) numLinkedCasesUpdated++;
6440 11 Oct 21 nicklas 266               if (Annotationtype.LINKED_CASE.setAnnotationValue(dc, lastCase, -daysBetween)) numLinkedCasesUpdated++;
6440 11 Oct 21 nicklas 267             }
6098 11 Jan 21 nicklas 268             lastCase = null;
6098 11 Jan 21 nicklas 269             lastPatient = null;
6440 11 Oct 21 nicklas 270             lastRefAfter = null;
6098 11 Jan 21 nicklas 271           }
6098 11 Jan 21 nicklas 272           else
6098 11 Jan 21 nicklas 273           {
6098 11 Jan 21 nicklas 274             // The last case was a patient with a single case -- clear the LinkedSpecimen annotation
6440 11 Oct 21 nicklas 275             if (lastCase != null)
6440 11 Oct 21 nicklas 276             {
6440 11 Oct 21 nicklas 277               if (Annotationtype.LINKED_CASE.setAnnotationValue(dc, lastCase, null)) numLinkedCasesUpdated++;
6440 11 Oct 21 nicklas 278             }
6098 11 Jan 21 nicklas 279             lastCase = theCase;
6098 11 Jan 21 nicklas 280             lastPatient = patient;
6440 11 Oct 21 nicklas 281             lastRefAfter = refAfter;
6098 11 Jan 21 nicklas 282           }
4477 03 May 17 nicklas 283         }
4477 03 May 17 nicklas 284         
6098 11 Jan 21 nicklas 285         if (lastCase != null)
6098 11 Jan 21 nicklas 286         {
6098 11 Jan 21 nicklas 287           // The last case was a patient with a single case -- clear the LinkedSpecimen annotation
6098 11 Jan 21 nicklas 288           if (Annotationtype.LINKED_CASE.setAnnotationValue(dc, lastCase, null)) numLinkedCasesUpdated++;
6098 11 Jan 21 nicklas 289         }
6098 11 Jan 21 nicklas 290         
6098 11 Jan 21 nicklas 291         progress.display(98, count + " of " + totalCount + " done (" + numUpdated + " reference dates and " + 
6098 11 Jan 21 nicklas 292           numLinkedCasesUpdated + " linked cases updated). Saving to database...");
4477 03 May 17 nicklas 293   
4477 03 May 17 nicklas 294         JSONArray jsonCounters = new JSONArray();
4477 03 May 17 nicklas 295         for (Counter c : counters.values())
4477 03 May 17 nicklas 296         {
4477 03 May 17 nicklas 297           JSONObject jsonCount = new JSONObject();
4701 16 Mar 18 nicklas 298           jsonCount.put("name", c.refSource == null ? null : c.refSource.getTitle());
4477 03 May 17 nicklas 299           jsonCount.put("before", c.numBefore);
4477 03 May 17 nicklas 300           jsonCount.put("after", c.numAfter);
4477 03 May 17 nicklas 301           jsonCounters.add(jsonCount);
4477 03 May 17 nicklas 302         }
4477 03 May 17 nicklas 303         json.put("counters", jsonCounters);
6098 11 Jan 21 nicklas 304         jsonMessages.add("Number of updated reference dates: " + numUpdated);
6098 11 Jan 21 nicklas 305         jsonMessages.add("Number of updated linked cases: " + numLinkedCasesUpdated);
4477 03 May 17 nicklas 306         json.put("numUpdated", numUpdated);
6098 11 Jan 21 nicklas 307         json.put("numLinkedCasesUpdated", numLinkedCasesUpdated);
4477 03 May 17 nicklas 308
4477 03 May 17 nicklas 309         dc.commit();
4477 03 May 17 nicklas 310         json.put("messages", jsonMessages);
4477 03 May 17 nicklas 311       }
4477 03 May 17 nicklas 312       
4477 03 May 17 nicklas 313
4477 03 May 17 nicklas 314       CounterService.getInstance().setForceCount();
4477 03 May 17 nicklas 315     }
4477 03 May 17 nicklas 316     catch (Throwable t)
4477 03 May 17 nicklas 317     {
4477 03 May 17 nicklas 318       t.printStackTrace();
4477 03 May 17 nicklas 319       json.clear();
4477 03 May 17 nicklas 320       json.put("status", "error");
4477 03 May 17 nicklas 321       json.put("message", t.getMessage());
4477 03 May 17 nicklas 322       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
4477 03 May 17 nicklas 323     }
4477 03 May 17 nicklas 324     finally
4477 03 May 17 nicklas 325     {
4477 03 May 17 nicklas 326       if (dc != null) dc.close();
4477 03 May 17 nicklas 327       if (sc != null) sc.setSessionSetting("linked-specimen-progress", null);
4477 03 May 17 nicklas 328       json.writeJSONString(resp.getWriter());
4477 03 May 17 nicklas 329     }
4477 03 May 17 nicklas 330     
4477 03 May 17 nicklas 331   }
4477 03 May 17 nicklas 332
4477 03 May 17 nicklas 333   
4477 03 May 17 nicklas 334   static class Counter
4477 03 May 17 nicklas 335   {
4477 03 May 17 nicklas 336     
4701 16 Mar 18 nicklas 337     final ReferenceDateSource refSource;
4477 03 May 17 nicklas 338
4701 16 Mar 18 nicklas 339     Counter(ReferenceDateSource refSource)
4477 03 May 17 nicklas 340     {
4701 16 Mar 18 nicklas 341       this.refSource = refSource;
4477 03 May 17 nicklas 342     }
4477 03 May 17 nicklas 343     
4477 03 May 17 nicklas 344     int numBefore = 0;
4477 03 May 17 nicklas 345     int numAfter = 0;
4477 03 May 17 nicklas 346   }
4477 03 May 17 nicklas 347   
4477 03 May 17 nicklas 348 }