extensions/net.sf.basedb.meludi/trunk/src/net/sf/basedb/meludi/servlet/SampleReportServlet.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.Date;
2933 14 Nov 14 olle 6 import java.util.HashMap;
2933 14 Nov 14 olle 7 import java.util.ArrayList;
2933 14 Nov 14 olle 8 import java.util.List;
2933 14 Nov 14 olle 9 import java.util.HashSet;
2933 14 Nov 14 olle 10 import java.util.Set;
2933 14 Nov 14 olle 11
2933 14 Nov 14 olle 12 import javax.servlet.ServletException;
2933 14 Nov 14 olle 13 import javax.servlet.http.HttpServlet;
2933 14 Nov 14 olle 14 import javax.servlet.http.HttpServletRequest;
2933 14 Nov 14 olle 15 import javax.servlet.http.HttpServletResponse;
2933 14 Nov 14 olle 16
2933 14 Nov 14 olle 17 import net.sf.basedb.core.Application;
2933 14 Nov 14 olle 18 import net.sf.basedb.core.BioMaterial;
2933 14 Nov 14 olle 19 import net.sf.basedb.core.BioMaterialEvent;
2933 14 Nov 14 olle 20 import net.sf.basedb.core.DbControl;
2933 14 Nov 14 olle 21 import net.sf.basedb.core.ItemQuery;
2933 14 Nov 14 olle 22 import net.sf.basedb.core.ItemResultIterator;
2933 14 Nov 14 olle 23 import net.sf.basedb.core.ItemSubtype;
2933 14 Nov 14 olle 24 import net.sf.basedb.core.MeasuredBioMaterial;
4174 24 Oct 16 olle 25 import net.sf.basedb.core.Project;
2933 14 Nov 14 olle 26 import net.sf.basedb.core.Sample;
2933 14 Nov 14 olle 27 import net.sf.basedb.core.SessionControl;
3504 23 Sep 15 olle 28 import net.sf.basedb.core.query.Expressions;
2933 14 Nov 14 olle 29 import net.sf.basedb.core.query.Hql;
2933 14 Nov 14 olle 30 import net.sf.basedb.core.query.Orders;
2933 14 Nov 14 olle 31 import net.sf.basedb.core.query.Restrictions;
2933 14 Nov 14 olle 32 import net.sf.basedb.core.snapshot.SnapshotManager;
2933 14 Nov 14 olle 33 import net.sf.basedb.meludi.JsonUtil;
2933 14 Nov 14 olle 34 import net.sf.basedb.meludi.Meludi;
2933 14 Nov 14 olle 35 import net.sf.basedb.meludi.Site;
2933 14 Nov 14 olle 36 import net.sf.basedb.meludi.converter.DateToStringConverter;
2933 14 Nov 14 olle 37 import net.sf.basedb.meludi.dao.Annotationtype;
3028 11 Dec 14 olle 38 import net.sf.basedb.meludi.dao.Case;
2933 14 Nov 14 olle 39 import net.sf.basedb.meludi.dao.Subtype;
2933 14 Nov 14 olle 40 import net.sf.basedb.meludi.servlet.ReportTableUtil;
2933 14 Nov 14 olle 41 import net.sf.basedb.util.Values;
2933 14 Nov 14 olle 42 import net.sf.basedb.util.error.ThrowableUtil;
2933 14 Nov 14 olle 43
2933 14 Nov 14 olle 44 import org.json.simple.JSONArray;
2933 14 Nov 14 olle 45 import org.json.simple.JSONObject;
2933 14 Nov 14 olle 46
2933 14 Nov 14 olle 47 public class SampleReportServlet 
2933 14 Nov 14 olle 48   extends HttpServlet 
2933 14 Nov 14 olle 49 {
2933 14 Nov 14 olle 50   private static final long serialVersionUID = 9211971419478625406L;
2933 14 Nov 14 olle 51
2933 14 Nov 14 olle 52   private ReportTableUtil tableUtil;
2933 14 Nov 14 olle 53   private final static String TABLE_ALTERNATIVE_FULL = "full_blood_sample_tables";
3060 19 Dec 14 olle 54   private ItemSubtype subtypeSpecimen;
3060 19 Dec 14 olle 55   private ItemSubtype subtypeCase;
3060 19 Dec 14 olle 56   
3060 19 Dec 14 olle 57   private ItemSubtype getSubtypeSpecimen()
3060 19 Dec 14 olle 58   {
3060 19 Dec 14 olle 59     return this.subtypeSpecimen;
3060 19 Dec 14 olle 60   }
2933 14 Nov 14 olle 61
3060 19 Dec 14 olle 62   private void setSubtypeSpecimen(ItemSubtype subtypeSpecimen)
3060 19 Dec 14 olle 63   {
3060 19 Dec 14 olle 64     this.subtypeSpecimen = subtypeSpecimen;
3060 19 Dec 14 olle 65   }
3060 19 Dec 14 olle 66
3060 19 Dec 14 olle 67   private ItemSubtype getSubtypeCase()
3060 19 Dec 14 olle 68   {
3060 19 Dec 14 olle 69     return this.subtypeCase;
3060 19 Dec 14 olle 70   }
3060 19 Dec 14 olle 71
3060 19 Dec 14 olle 72   private void setSubtypeCase(ItemSubtype subtypeCase)
3060 19 Dec 14 olle 73   {
3060 19 Dec 14 olle 74     this.subtypeCase = subtypeCase;
3060 19 Dec 14 olle 75   }
3060 19 Dec 14 olle 76
2933 14 Nov 14 olle 77   public SampleReportServlet()
2933 14 Nov 14 olle 78   {
2933 14 Nov 14 olle 79     // Create new instance of ReportTableUtilServlet for common report table utilities
2933 14 Nov 14 olle 80     tableUtil = new ReportTableUtil();
2933 14 Nov 14 olle 81   }
2933 14 Nov 14 olle 82     
2933 14 Nov 14 olle 83   @SuppressWarnings("unchecked")
2933 14 Nov 14 olle 84   @Override
2933 14 Nov 14 olle 85   protected void doGet(HttpServletRequest req, HttpServletResponse resp)
2933 14 Nov 14 olle 86     throws ServletException, IOException 
2933 14 Nov 14 olle 87   {  
2933 14 Nov 14 olle 88     String ID = req.getParameter("ID");
2933 14 Nov 14 olle 89     String cmd = req.getParameter("cmd");
2933 14 Nov 14 olle 90     JsonUtil.setJsonResponseHeaders(resp);
2933 14 Nov 14 olle 91     
2933 14 Nov 14 olle 92     JSONObject json = new JSONObject();
2933 14 Nov 14 olle 93     json.put("status", "ok");
2933 14 Nov 14 olle 94     
5468 04 Jun 19 olle 95     //final SessionControl sc = Application.getSessionControl(ID, req.getRemoteAddr());
5744 20 Nov 19 olle 96     //final SessionControl sc  = Application.getSessionControl(ID, "", req.getRemoteAddr(), true);
5744 20 Nov 19 olle 97     final SessionControl sc  = Application.getSessionControl(ID, null, req.getRemoteAddr(), true);
2933 14 Nov 14 olle 98     DbControl dc = null;    
2933 14 Nov 14 olle 99     dc = sc.newDbControl();        
3060 19 Dec 14 olle 100     // Set item subtype constants for later use
3060 19 Dec 14 olle 101     setSubtypeSpecimen(Subtype.SPECIMEN.load(dc));
3060 19 Dec 14 olle 102     setSubtypeCase(Subtype.CASE.load(dc));
3060 19 Dec 14 olle 103
2933 14 Nov 14 olle 104     try
2933 14 Nov 14 olle 105     {
2933 14 Nov 14 olle 106       if ("samplecount".equals(cmd))
2933 14 Nov 14 olle 107       {        
2933 14 Nov 14 olle 108         String startDateParameter = Values.getString(req.getParameter("fdate"), null);
2933 14 Nov 14 olle 109         String endDateParameter = Values.getString(req.getParameter("tdate"), null);
2933 14 Nov 14 olle 110
2933 14 Nov 14 olle 111         Date startDate = Meludi.CONVERTER_STRING_TO_DATE.convert(startDateParameter);
2933 14 Nov 14 olle 112         Date endDate = Meludi.CONVERTER_STRING_TO_DATE.convert(endDateParameter);
2933 14 Nov 14 olle 113         
2933 14 Nov 14 olle 114         if (startDate == null)
2933 14 Nov 14 olle 115         {
2933 14 Nov 14 olle 116           // Get the when the first site started
2933 14 Nov 14 olle 117           for (Site s : Site.getAllReportSites())
2933 14 Nov 14 olle 118           {
2933 14 Nov 14 olle 119             Date siteDate = Meludi.CONVERTER_STRING_TO_DATE.convert(s.getStartDate().replaceAll("-", ""));
2933 14 Nov 14 olle 120             if (siteDate != null && (startDate == null || startDate.after(siteDate))) 
2933 14 Nov 14 olle 121             {
2933 14 Nov 14 olle 122               startDate = siteDate;            
2933 14 Nov 14 olle 123             }
2933 14 Nov 14 olle 124           }
2933 14 Nov 14 olle 125         }
2933 14 Nov 14 olle 126         if (endDate == null) 
2933 14 Nov 14 olle 127         {
2933 14 Nov 14 olle 128           // Get the date for today
2933 14 Nov 14 olle 129           endDate = new Date();
2933 14 Nov 14 olle 130         }
2933 14 Nov 14 olle 131
2933 14 Nov 14 olle 132         String viewType = null;
2933 14 Nov 14 olle 133         String viewTypeParameter = Values.getString(req.getParameter("vtype"), null);
2933 14 Nov 14 olle 134         if (viewTypeParameter != null && !viewTypeParameter.equals(ReportTableUtil.autoView))
2933 14 Nov 14 olle 135         {
2933 14 Nov 14 olle 136           viewType = viewTypeParameter;
2933 14 Nov 14 olle 137         }
2933 14 Nov 14 olle 138         else
2933 14 Nov 14 olle 139         {
2933 14 Nov 14 olle 140           viewType = tableUtil.getViewType(startDate, endDate);
2933 14 Nov 14 olle 141         }
2933 14 Nov 14 olle 142         String sampleType = "specimen";
2933 14 Nov 14 olle 143         String sampleTypeParameter = Values.getString(req.getParameter("stype"), null);
2933 14 Nov 14 olle 144         if (sampleTypeParameter != null)
2933 14 Nov 14 olle 145         {
2933 14 Nov 14 olle 146           sampleType = sampleTypeParameter;
2933 14 Nov 14 olle 147         }
2933 14 Nov 14 olle 148         String tableAlternatives = TABLE_ALTERNATIVE_FULL;
2933 14 Nov 14 olle 149         String tableAlternativesParameter = Values.getString(req.getParameter("tablealternatives"), null);
2933 14 Nov 14 olle 150         if (tableAlternativesParameter != null)
2933 14 Nov 14 olle 151         {
2933 14 Nov 14 olle 152           tableAlternatives = tableAlternativesParameter;
2933 14 Nov 14 olle 153         }
3058 19 Dec 14 olle 154         String projectFocusFilter = InstallServlet.PROJECTFOCUS_NONE;
2933 14 Nov 14 olle 155         String projectFocusFilterParameter = Values.getString(req.getParameter("projectfocusfilter"), null);
2933 14 Nov 14 olle 156         if (projectFocusFilterParameter != null)
2933 14 Nov 14 olle 157         {
2933 14 Nov 14 olle 158           projectFocusFilter = projectFocusFilterParameter;
2933 14 Nov 14 olle 159         }
2933 14 Nov 14 olle 160
2933 14 Nov 14 olle 161         json = createSampleCountReport(dc, json, startDate, endDate, viewType, sampleType, tableAlternatives, projectFocusFilter);
2933 14 Nov 14 olle 162       }
2933 14 Nov 14 olle 163       else if ("patientcount".equals(cmd))
2933 14 Nov 14 olle 164       {        
2933 14 Nov 14 olle 165         String startDateParameter = Values.getString(req.getParameter("fdate"), null);
2933 14 Nov 14 olle 166         String endDateParameter = Values.getString(req.getParameter("tdate"), null);
2933 14 Nov 14 olle 167
2933 14 Nov 14 olle 168         Date startDate = Meludi.CONVERTER_STRING_TO_DATE.convert(startDateParameter);
2933 14 Nov 14 olle 169         Date endDate = Meludi.CONVERTER_STRING_TO_DATE.convert(endDateParameter);
2933 14 Nov 14 olle 170         
2933 14 Nov 14 olle 171         if (startDate == null)
2933 14 Nov 14 olle 172         {
2933 14 Nov 14 olle 173           // Get the date when the first site started
2933 14 Nov 14 olle 174           for (Site s : Site.getAllReportSites())
2933 14 Nov 14 olle 175           {
2933 14 Nov 14 olle 176             Date siteDate = Meludi.CONVERTER_STRING_TO_DATE.convert(s.getStartDate().replaceAll("-", ""));
2933 14 Nov 14 olle 177             if (siteDate != null && (startDate == null || startDate.after(siteDate))) 
2933 14 Nov 14 olle 178             {
2933 14 Nov 14 olle 179               startDate = siteDate;            
2933 14 Nov 14 olle 180             }
2933 14 Nov 14 olle 181           }
2933 14 Nov 14 olle 182         }
2933 14 Nov 14 olle 183         if (endDate == null) 
2933 14 Nov 14 olle 184         {
2933 14 Nov 14 olle 185           // Get the date for today
2933 14 Nov 14 olle 186           endDate = new Date();
2933 14 Nov 14 olle 187         }
2933 14 Nov 14 olle 188
2933 14 Nov 14 olle 189         String viewType = null;
2933 14 Nov 14 olle 190         String viewTypeParameter = Values.getString(req.getParameter("vtype"), null);
2933 14 Nov 14 olle 191         if (viewTypeParameter != null && !viewTypeParameter.equals(ReportTableUtil.autoView))
2933 14 Nov 14 olle 192         {
2933 14 Nov 14 olle 193           viewType = viewTypeParameter;
2933 14 Nov 14 olle 194         }
2933 14 Nov 14 olle 195         else
2933 14 Nov 14 olle 196         {
2933 14 Nov 14 olle 197           viewType = tableUtil.getViewType(startDate, endDate);
2933 14 Nov 14 olle 198         }
2933 14 Nov 14 olle 199
2933 14 Nov 14 olle 200         json = createPatientCountReport(dc, json, startDate, endDate, viewType);
2933 14 Nov 14 olle 201       }
2933 14 Nov 14 olle 202       else if ("overviewreport".equals(cmd))
2933 14 Nov 14 olle 203       {
2933 14 Nov 14 olle 204         String startDateParameter = Values.getString(req.getParameter("fdate"), null);
2933 14 Nov 14 olle 205         String endDateParameter = Values.getString(req.getParameter("tdate"), null);
2933 14 Nov 14 olle 206
2933 14 Nov 14 olle 207         Date startDate = Meludi.CONVERTER_STRING_TO_DATE.convert(startDateParameter);
2933 14 Nov 14 olle 208         Date endDate = Meludi.CONVERTER_STRING_TO_DATE.convert(endDateParameter);
2933 14 Nov 14 olle 209         
2933 14 Nov 14 olle 210         if (startDate == null)
2933 14 Nov 14 olle 211         {
2933 14 Nov 14 olle 212           // Get the date when the first site started
2933 14 Nov 14 olle 213           for (Site s : Site.getAllReportSites())
2933 14 Nov 14 olle 214           {
4731 04 Apr 18 olle 215             System.out.println("SampleReport::doGet(): cmd = \"" + cmd + "\" s = " + s);
2933 14 Nov 14 olle 216             Date siteDate = Meludi.CONVERTER_STRING_TO_DATE.convert(s.getStartDate().replaceAll("-", ""));
2933 14 Nov 14 olle 217             if (siteDate != null && (startDate == null || startDate.after(siteDate))) 
2933 14 Nov 14 olle 218             {
2933 14 Nov 14 olle 219               startDate = siteDate;            
2933 14 Nov 14 olle 220             }
2933 14 Nov 14 olle 221           }
2933 14 Nov 14 olle 222         }
2933 14 Nov 14 olle 223         if (endDate == null) 
2933 14 Nov 14 olle 224         {
2933 14 Nov 14 olle 225           // Get the date for today
2933 14 Nov 14 olle 226           endDate = new Date();
2933 14 Nov 14 olle 227         }
2933 14 Nov 14 olle 228
3058 19 Dec 14 olle 229         String projectFocusFilter = InstallServlet.PROJECTFOCUS_NONE;
2933 14 Nov 14 olle 230         String projectFocusFilterParameter = Values.getString(req.getParameter("projectfocusfilter"), null);
2933 14 Nov 14 olle 231         if (projectFocusFilterParameter != null)
2933 14 Nov 14 olle 232         {
2933 14 Nov 14 olle 233           projectFocusFilter = projectFocusFilterParameter;
2933 14 Nov 14 olle 234         }
2933 14 Nov 14 olle 235
2933 14 Nov 14 olle 236         json = createOverviewReport(dc, json, startDate, endDate, projectFocusFilter);
2933 14 Nov 14 olle 237       }
2933 14 Nov 14 olle 238       else if ("missingsampledatareport".equals(cmd))
2933 14 Nov 14 olle 239       {
2933 14 Nov 14 olle 240         String startDateParameter = Values.getString(req.getParameter("fdate"), null);
2933 14 Nov 14 olle 241         String endDateParameter = Values.getString(req.getParameter("tdate"), null);
2933 14 Nov 14 olle 242
2933 14 Nov 14 olle 243         Date startDate = Meludi.CONVERTER_STRING_TO_DATE.convert(startDateParameter);
2933 14 Nov 14 olle 244         Date endDate = Meludi.CONVERTER_STRING_TO_DATE.convert(endDateParameter);
2933 14 Nov 14 olle 245         
2933 14 Nov 14 olle 246         if (startDate == null)
2933 14 Nov 14 olle 247         {
2933 14 Nov 14 olle 248           // Get the date when the first site started
2933 14 Nov 14 olle 249           for (Site s : Site.getAllReportSites())
2933 14 Nov 14 olle 250           {
2933 14 Nov 14 olle 251             Date siteDate = Meludi.CONVERTER_STRING_TO_DATE.convert(s.getStartDate().replaceAll("-", ""));
2933 14 Nov 14 olle 252             if (siteDate != null && (startDate == null || startDate.after(siteDate))) 
2933 14 Nov 14 olle 253             {
2933 14 Nov 14 olle 254               startDate = siteDate;            
2933 14 Nov 14 olle 255             }
2933 14 Nov 14 olle 256           }
2933 14 Nov 14 olle 257         }
2933 14 Nov 14 olle 258         if (endDate == null) 
2933 14 Nov 14 olle 259         {
2933 14 Nov 14 olle 260           // Get the date for today
2933 14 Nov 14 olle 261           endDate = new Date();
2933 14 Nov 14 olle 262         }
2933 14 Nov 14 olle 263
2933 14 Nov 14 olle 264         String sampleType = "specimen";
3058 19 Dec 14 olle 265         String projectFocusFilter = InstallServlet.PROJECTFOCUS_NONE;
2933 14 Nov 14 olle 266         String projectFocusFilterParameter = Values.getString(req.getParameter("projectfocusfilter"), null);
2933 14 Nov 14 olle 267         if (projectFocusFilterParameter != null)
2933 14 Nov 14 olle 268         {
2933 14 Nov 14 olle 269           projectFocusFilter = projectFocusFilterParameter;
2933 14 Nov 14 olle 270         }
2933 14 Nov 14 olle 271         json = createMissingSampleDataReport(dc, json, startDate, endDate, sampleType, projectFocusFilter);
2933 14 Nov 14 olle 272       }
2933 14 Nov 14 olle 273     }
2933 14 Nov 14 olle 274     catch (Throwable t)
2933 14 Nov 14 olle 275     {
2933 14 Nov 14 olle 276       t.printStackTrace();
2933 14 Nov 14 olle 277       json.clear();
2933 14 Nov 14 olle 278       json.put("status", "error");
2933 14 Nov 14 olle 279       json.put("message", t.getMessage());
2933 14 Nov 14 olle 280       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
2933 14 Nov 14 olle 281     }
2933 14 Nov 14 olle 282     finally
2933 14 Nov 14 olle 283     {
2933 14 Nov 14 olle 284       if (dc != null) dc.close();
2933 14 Nov 14 olle 285       json.writeJSONString(resp.getWriter());
2933 14 Nov 14 olle 286     }
2933 14 Nov 14 olle 287   }
4174 24 Oct 16 olle 288
2933 14 Nov 14 olle 289   @SuppressWarnings("unchecked")
4174 24 Oct 16 olle 290   private JSONObject fetchJsonReportPrimer(DbControl dc)
2933 14 Nov 14 olle 291     throws ServletException, IOException 
2933 14 Nov 14 olle 292   {  
2933 14 Nov 14 olle 293     JSONObject jsonReport = new JSONObject();
4174 24 Oct 16 olle 294     // Add project name
4174 24 Oct 16 olle 295     Project project = Project.getById(dc, dc.getSessionControl().getActiveProjectId());
4174 24 Oct 16 olle 296     jsonReport.put("projectName", project.getName());
2933 14 Nov 14 olle 297     // Add extra row for unknown site
2933 14 Nov 14 olle 298     JSONArray siteJsonArr = ReportTableUtil.getJSONSites(Site.SORT_BY_NAME);
2933 14 Nov 14 olle 299     siteJsonArr.add(Site.UNKNOWN_RPT.asJSONObject());
2933 14 Nov 14 olle 300     jsonReport.put("sites", siteJsonArr);
4174 24 Oct 16 olle 301     return jsonReport;
4174 24 Oct 16 olle 302   }
4174 24 Oct 16 olle 303
4174 24 Oct 16 olle 304   @SuppressWarnings("unchecked")
4174 24 Oct 16 olle 305   private JSONObject createSampleCountReport(DbControl dc, JSONObject json, Date startDate, Date endDate, String viewType, String sampleType, String tableAlternatives, String projectFocusFilter)
4174 24 Oct 16 olle 306     throws ServletException, IOException 
4174 24 Oct 16 olle 307   {  
4174 24 Oct 16 olle 308     JSONObject jsonReport = fetchJsonReportPrimer(dc);
2933 14 Nov 14 olle 309     
2933 14 Nov 14 olle 310     //List<Restriction> restrictions = new ArrayList<Restriction>();
2933 14 Nov 14 olle 311     ItemQuery<Sample> sampleQuery = Sample.getQuery();
2933 14 Nov 14 olle 312     sampleQuery.joinPermanent(Hql.innerJoin(null, "creationEvent", "ce", true));
2933 14 Nov 14 olle 313     Subtype.SPECIMEN.addFilter(dc, sampleQuery);
2933 14 Nov 14 olle 314     sampleQuery.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
4163 19 Oct 16 olle 315     // Only include samples for active project
5255 21 Jan 19 olle 316     String specimenItemPrefix = Meludi.fetchSpecimenItemPrefix(dc.getSessionControl().getActiveProjectId());
5255 21 Jan 19 olle 317     String sampleQueryNameRestriction = specimenItemPrefix + "%";
4163 19 Oct 16 olle 318     sampleQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.string(sampleQueryNameRestriction)));
2933 14 Nov 14 olle 319     sampleQuery.order(Orders.asc(Hql.property("name")));
2933 14 Nov 14 olle 320     sampleQuery.order(Orders.asc(Hql.property("ce", "eventDate")));
2933 14 Nov 14 olle 321     sampleQuery.setCacheResult(true);
2933 14 Nov 14 olle 322     ItemResultIterator<Sample> sampleIterator = sampleQuery.iterate(dc);        
2933 14 Nov 14 olle 323     // Use stored annotation snapshots for performance reasons
2933 14 Nov 14 olle 324     SnapshotManager manager = new SnapshotManager();        
2933 14 Nov 14 olle 325     // Store samples that should be processed for report table in list 
2933 14 Nov 14 olle 326     List<Sample> rawSampleList = new ArrayList<Sample>();
2933 14 Nov 14 olle 327     while (sampleIterator.hasNext())
2933 14 Nov 14 olle 328     {
2933 14 Nov 14 olle 329       Sample s = sampleIterator.next();
2933 14 Nov 14 olle 330       rawSampleList.add(s);
2933 14 Nov 14 olle 331     }
2933 14 Nov 14 olle 332     String latestDateStr = null;
3028 11 Dec 14 olle 333     List<Sample> sampleList = createSampleCountSampleList(dc, manager, rawSampleList, projectFocusFilter);
2933 14 Nov 14 olle 334       
3028 11 Dec 14 olle 335     JSONObject jsonStatistics = tableUtil.createJSONStatistics(dc, sampleList.iterator(), startDate, endDate, viewType);
2933 14 Nov 14 olle 336
3028 11 Dec 14 olle 337     jsonReport.put("statistics", jsonStatistics);
3028 11 Dec 14 olle 338     latestDateStr = (String) jsonStatistics.get("latestDateKey");
2933 14 Nov 14 olle 339     if (viewType == null)
2933 14 Nov 14 olle 340     {
2933 14 Nov 14 olle 341       viewType = tableUtil.getViewType(startDate, endDate);
2933 14 Nov 14 olle 342     }
2933 14 Nov 14 olle 343     DateToStringConverter date2StringConverter = Meludi.CONVERTER_DATE_TO_STRING;
2933 14 Nov 14 olle 344     Date periodStartDate = tableUtil.calculatePeriodStartDate(startDate, viewType);
2933 14 Nov 14 olle 345     jsonReport.put("viewType", viewType);
2933 14 Nov 14 olle 346     jsonReport.put("sampleType", sampleType);
2933 14 Nov 14 olle 347     jsonReport.put("tableAlternatives", tableAlternatives);
2933 14 Nov 14 olle 348     jsonReport.put("projectFocusFilter", projectFocusFilter);        
2933 14 Nov 14 olle 349     jsonReport.put("beginDate", date2StringConverter.convert(startDate));
2933 14 Nov 14 olle 350     jsonReport.put("endDate", date2StringConverter.convert(endDate));
2933 14 Nov 14 olle 351     jsonReport.put("periodBeginDate", date2StringConverter.convert(periodStartDate));
2933 14 Nov 14 olle 352     // Transfer latest date from jsonStatistics to jsonReport
2933 14 Nov 14 olle 353     jsonReport.put("latestDate", latestDateStr);
2933 14 Nov 14 olle 354     json.put("report", jsonReport);
2933 14 Nov 14 olle 355     return json;
2933 14 Nov 14 olle 356   }
2933 14 Nov 14 olle 357     
2933 14 Nov 14 olle 358   @SuppressWarnings("unchecked")
2933 14 Nov 14 olle 359   private JSONObject createSampleCountReport(DbControl dc, List<Sample> sampleList, Date startDate, Date endDate, String viewType, String sampleType, String tableAlternatives, String projectFocusFilter)
2933 14 Nov 14 olle 360     throws ServletException, IOException 
2933 14 Nov 14 olle 361   {  
4174 24 Oct 16 olle 362     JSONObject jsonReport = fetchJsonReportPrimer(dc);
2933 14 Nov 14 olle 363     
2933 14 Nov 14 olle 364     String latestDateStr = null;
2933 14 Nov 14 olle 365     JSONObject jsonStatistics = tableUtil.createJSONStatistics(dc, sampleList.iterator(), startDate, endDate, viewType);
2933 14 Nov 14 olle 366     jsonReport.put("statistics", jsonStatistics);
2933 14 Nov 14 olle 367     latestDateStr = (String) jsonStatistics.get("latestDateKey");
2933 14 Nov 14 olle 368     if (viewType == null)
2933 14 Nov 14 olle 369     {
2933 14 Nov 14 olle 370       viewType = tableUtil.getViewType(startDate, endDate);
2933 14 Nov 14 olle 371     }
2933 14 Nov 14 olle 372     DateToStringConverter date2StringConverter = Meludi.CONVERTER_DATE_TO_STRING;
2933 14 Nov 14 olle 373     Date periodStartDate = tableUtil.calculatePeriodStartDate(startDate, viewType);
2933 14 Nov 14 olle 374     jsonReport.put("viewType", viewType);
2933 14 Nov 14 olle 375     jsonReport.put("sampleType", sampleType);
2933 14 Nov 14 olle 376     jsonReport.put("tableAlternatives", tableAlternatives);
2933 14 Nov 14 olle 377     jsonReport.put("projectFocusFilter", projectFocusFilter);        
2933 14 Nov 14 olle 378     jsonReport.put("beginDate", date2StringConverter.convert(startDate));
2933 14 Nov 14 olle 379     jsonReport.put("endDate", date2StringConverter.convert(endDate));
2933 14 Nov 14 olle 380     jsonReport.put("periodBeginDate", date2StringConverter.convert(periodStartDate));
2933 14 Nov 14 olle 381     // Transfer latest date from jsonStatistics to jsonReport
2933 14 Nov 14 olle 382     jsonReport.put("latestDate", latestDateStr);
2933 14 Nov 14 olle 383     return jsonReport;
2933 14 Nov 14 olle 384   }
2933 14 Nov 14 olle 385     
2933 14 Nov 14 olle 386   private List<Sample> createSampleCountSampleList(DbControl dc, SnapshotManager manager, List<Sample> rawSampleList, String projectFocusFilter)
2933 14 Nov 14 olle 387     throws ServletException, IOException 
2933 14 Nov 14 olle 388   {  
2933 14 Nov 14 olle 389     // Store samples that should be processed for report table in list 
2933 14 Nov 14 olle 390     List<Sample> sampleList = new ArrayList<Sample>();
2933 14 Nov 14 olle 391     for (Sample s: rawSampleList)
2933 14 Nov 14 olle 392     {
2933 14 Nov 14 olle 393       // Optional project focus filter (true if no filter, or sample passes filter)
2933 14 Nov 14 olle 394       boolean passedProjectFocusFilter = passProjectFocusFilter(dc, manager, projectFocusFilter, s);
2933 14 Nov 14 olle 395       if (passedProjectFocusFilter)
2933 14 Nov 14 olle 396       {
2933 14 Nov 14 olle 397         // Add sample to list
2933 14 Nov 14 olle 398         sampleList.add(s);
2933 14 Nov 14 olle 399       }
2933 14 Nov 14 olle 400     }
2933 14 Nov 14 olle 401     return sampleList;
2933 14 Nov 14 olle 402   }
2933 14 Nov 14 olle 403     
2933 14 Nov 14 olle 404   @SuppressWarnings({ "unchecked", "rawtypes" })
2933 14 Nov 14 olle 405   private JSONObject createPatientCountReport(DbControl dc, JSONObject json, Date startDate, Date endDate, String viewType)
2933 14 Nov 14 olle 406     throws ServletException, IOException 
2933 14 Nov 14 olle 407   {  
4174 24 Oct 16 olle 408     JSONObject jsonReport = fetchJsonReportPrimer(dc);
2933 14 Nov 14 olle 409     
2933 14 Nov 14 olle 410     ItemQuery<Sample> sampleQuery = Sample.getQuery();
2933 14 Nov 14 olle 411     sampleQuery.joinPermanent(Hql.innerJoin(null, "creationEvent", "ce", true));
2933 14 Nov 14 olle 412     // ...only include 'Specimen' items
2933 14 Nov 14 olle 413     sampleQuery.restrict(
2933 14 Nov 14 olle 414       Restrictions.or(
2933 14 Nov 14 olle 415         Subtype.SPECIMEN.restriction(dc, null)
2933 14 Nov 14 olle 416       ));
2933 14 Nov 14 olle 417     sampleQuery.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
4163 19 Oct 16 olle 418     // Only include samples for active project
5255 21 Jan 19 olle 419     String specimenItemPrefix = Meludi.fetchSpecimenItemPrefix(dc.getSessionControl().getActiveProjectId());
5255 21 Jan 19 olle 420     String sampleQueryNameRestriction = specimenItemPrefix + "%";
4163 19 Oct 16 olle 421     sampleQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.string(sampleQueryNameRestriction)));
2933 14 Nov 14 olle 422     sampleQuery.order(Orders.asc(Hql.property("name")));
2933 14 Nov 14 olle 423     sampleQuery.order(Orders.asc(Hql.property("ce", "eventDate")));
2933 14 Nov 14 olle 424     sampleQuery.setCacheResult(true);
2933 14 Nov 14 olle 425     ItemResultIterator<Sample> sampleIterator = sampleQuery.iterate(dc);        
2933 14 Nov 14 olle 426                   
2933 14 Nov 14 olle 427     // Store samples that should be processed for report table in list 
2933 14 Nov 14 olle 428     List<Sample> sampleList = new ArrayList<Sample>();
2933 14 Nov 14 olle 429     // Create HashMap to keep track of sample with earliest date for each patient
2933 14 Nov 14 olle 430     HashMap<String, Sample>patientSampleHashMap = new HashMap<String, Sample>();
2933 14 Nov 14 olle 431     // Create HashMap to keep track of sample with unknown date for each patient
2933 14 Nov 14 olle 432     HashMap<String, Sample>patientSampleNoDateHashMap = new HashMap<String, Sample>();
2933 14 Nov 14 olle 433     // Find earliest sample dates for each patient
2933 14 Nov 14 olle 434     while (sampleIterator.hasNext())
2933 14 Nov 14 olle 435     {
2933 14 Nov 14 olle 436       Sample s = sampleIterator.next();
2933 14 Nov 14 olle 437       BioMaterialEvent creationEvent = s.getCreationEvent();
2933 14 Nov 14 olle 438       Date creationDate = creationEvent.getEventDate();
2933 14 Nov 14 olle 439
2933 14 Nov 14 olle 440       // Find patient id
2933 14 Nov 14 olle 441       BioMaterial patient = null;
2933 14 Nov 14 olle 442       // The grandparent is the 'Patient' for specimens
2933 14 Nov 14 olle 443       MeasuredBioMaterial parent = (MeasuredBioMaterial) s.getParent();
2933 14 Nov 14 olle 444       if (parent != null)
2933 14 Nov 14 olle 445       {
2933 14 Nov 14 olle 446         patient = parent.getParent();
2933 14 Nov 14 olle 447       }
2933 14 Nov 14 olle 448       if (patient != null)
2933 14 Nov 14 olle 449       {
2933 14 Nov 14 olle 450         String patientName = patient.getName();
2933 14 Nov 14 olle 451         if (creationDate != null)
2933 14 Nov 14 olle 452         {
2933 14 Nov 14 olle 453           patientSampleHashMap = tableUtil.updateStringEarliestSampleHashMap(patientSampleHashMap, patientName, s);
2933 14 Nov 14 olle 454         }
2933 14 Nov 14 olle 455         else
2933 14 Nov 14 olle 456         {
2933 14 Nov 14 olle 457           patientSampleNoDateHashMap.put(patientName, s);
2933 14 Nov 14 olle 458         }
2933 14 Nov 14 olle 459       }
2933 14 Nov 14 olle 460     }
2933 14 Nov 14 olle 461     // Create list of samples for report
2933 14 Nov 14 olle 462     // Add sample with earliest date for patient
2933 14 Nov 14 olle 463     for (String key: patientSampleHashMap.keySet())
2933 14 Nov 14 olle 464     {
2933 14 Nov 14 olle 465       if (key != null && !key.equals(""))
2933 14 Nov 14 olle 466       {
2933 14 Nov 14 olle 467         Sample s = patientSampleHashMap.get(key);
2933 14 Nov 14 olle 468         // Include sample in list of samples for report
2933 14 Nov 14 olle 469         sampleList.add(s);
2933 14 Nov 14 olle 470       }
2933 14 Nov 14 olle 471     }
2933 14 Nov 14 olle 472     // Add sample with unknown date if no sample with date exists for patient
2933 14 Nov 14 olle 473     for (String key: patientSampleNoDateHashMap.keySet())
2933 14 Nov 14 olle 474     {
2933 14 Nov 14 olle 475       if (key != null && !key.equals(""))
2933 14 Nov 14 olle 476       {
2933 14 Nov 14 olle 477         // If no sample with date exists for sample, include sample without date
2933 14 Nov 14 olle 478         if (!patientSampleHashMap.containsKey(key))
2933 14 Nov 14 olle 479         {
2933 14 Nov 14 olle 480           Sample s = patientSampleNoDateHashMap.get(key);
2933 14 Nov 14 olle 481           // Include sample in list of samples for report
2933 14 Nov 14 olle 482           sampleList.add(s);
2933 14 Nov 14 olle 483         }
2933 14 Nov 14 olle 484       }
2933 14 Nov 14 olle 485     }
2933 14 Nov 14 olle 486
2933 14 Nov 14 olle 487     JSONObject jsonStatistics = tableUtil.createJSONStatistics(dc, sampleList.iterator(), startDate, endDate, viewType);
2933 14 Nov 14 olle 488     jsonReport.put("statistics", jsonStatistics);        
2933 14 Nov 14 olle 489     if (viewType == null)
2933 14 Nov 14 olle 490     {
2933 14 Nov 14 olle 491       viewType = tableUtil.getViewType(startDate, endDate);
2933 14 Nov 14 olle 492     }
2933 14 Nov 14 olle 493     DateToStringConverter date2StringConverter = Meludi.CONVERTER_DATE_TO_STRING;
2933 14 Nov 14 olle 494     Date periodStartDate = tableUtil.calculatePeriodStartDate(startDate, viewType);
2933 14 Nov 14 olle 495     jsonReport.put("viewType", viewType);
2933 14 Nov 14 olle 496     jsonReport.put("beginDate", date2StringConverter.convert(startDate));
2933 14 Nov 14 olle 497     jsonReport.put("endDate", date2StringConverter.convert(endDate));
2933 14 Nov 14 olle 498     jsonReport.put("periodBeginDate", date2StringConverter.convert(periodStartDate));
2933 14 Nov 14 olle 499     // Transfer latest date from jsonStatistics to jsonReport
2933 14 Nov 14 olle 500     String latestDateStr = (String) jsonStatistics.get("latestDateKey");
2933 14 Nov 14 olle 501     jsonReport.put("latestDate", latestDateStr);
2933 14 Nov 14 olle 502     json.put("report", jsonReport);
2933 14 Nov 14 olle 503     return json;
2933 14 Nov 14 olle 504   }
2933 14 Nov 14 olle 505     
2933 14 Nov 14 olle 506   @SuppressWarnings({ "unchecked", "rawtypes" })
2933 14 Nov 14 olle 507   private JSONObject createOverviewReport(DbControl dc, JSONObject json, Date startDate, Date endDate, String projectFocusFilter)
2933 14 Nov 14 olle 508       throws ServletException, IOException 
2933 14 Nov 14 olle 509   {  
4174 24 Oct 16 olle 510     JSONObject jsonReport = fetchJsonReportPrimer(dc);
2933 14 Nov 14 olle 511     
2933 14 Nov 14 olle 512     ItemQuery<Sample> sampleQuery = Sample.getQuery();
2933 14 Nov 14 olle 513     sampleQuery.joinPermanent(Hql.innerJoin(null, "creationEvent", "ce", true));
2933 14 Nov 14 olle 514     // ...only include 'Specimen' or 'Case' items
2933 14 Nov 14 olle 515     sampleQuery.restrict(
2933 14 Nov 14 olle 516         Restrictions.or(
2933 14 Nov 14 olle 517           Subtype.SPECIMEN.restriction(dc, null),
2933 14 Nov 14 olle 518           Subtype.CASE.restriction(dc, null)
2933 14 Nov 14 olle 519         ));
2933 14 Nov 14 olle 520     sampleQuery.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
4163 19 Oct 16 olle 521     // Only include samples for active project
5255 21 Jan 19 olle 522     String specimenItemPrefix = Meludi.fetchSpecimenItemPrefix(dc.getSessionControl().getActiveProjectId());
5255 21 Jan 19 olle 523     String sampleQueryNameRestriction = specimenItemPrefix + "%";
4163 19 Oct 16 olle 524     sampleQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.string(sampleQueryNameRestriction)));
2933 14 Nov 14 olle 525     sampleQuery.order(Orders.asc(Hql.property("name")));
2933 14 Nov 14 olle 526     sampleQuery.order(Orders.asc(Hql.property("ce", "eventDate")));
2933 14 Nov 14 olle 527     sampleQuery.setCacheResult(true);
2933 14 Nov 14 olle 528     ItemResultIterator<Sample> sampleIterator = sampleQuery.iterate(dc);        
2933 14 Nov 14 olle 529     // Use stored annotation snapshots for performance reasons
2933 14 Nov 14 olle 530     SnapshotManager manager = new SnapshotManager();        
2933 14 Nov 14 olle 531
2933 14 Nov 14 olle 532     // Create sample list
2933 14 Nov 14 olle 533     List<Sample> sampleList = new ArrayList<Sample>();
2933 14 Nov 14 olle 534     while (sampleIterator != null && sampleIterator.hasNext())
2933 14 Nov 14 olle 535     {
2933 14 Nov 14 olle 536       Sample s = sampleIterator.next();
2933 14 Nov 14 olle 537       // Optional project focus filter (true if no filter, or sample passes filter)
2933 14 Nov 14 olle 538       boolean passedProjectFocusFilter = passProjectFocusFilter(dc, manager, projectFocusFilter, s);
2933 14 Nov 14 olle 539       if (passedProjectFocusFilter)
2933 14 Nov 14 olle 540       {
2933 14 Nov 14 olle 541         // Add sample to list
2933 14 Nov 14 olle 542         sampleList.add(s);
2933 14 Nov 14 olle 543       }
2933 14 Nov 14 olle 544     }
2933 14 Nov 14 olle 545     JSONObject jsonStatistics = new JSONObject();
2933 14 Nov 14 olle 546     JSONObject jsonSitesCombined = new JSONObject();
2933 14 Nov 14 olle 547     String patientKey = "patient";
2933 14 Nov 14 olle 548     String specimenKey = "specimen";
2933 14 Nov 14 olle 549     String patientWithSpecimenKey = "patientWithSpecimen";
2933 14 Nov 14 olle 550     String patientWithOneSpecimenKey = "patientWithOneSpecimen";
2933 14 Nov 14 olle 551     String patientWithTwoSpecimenKey = "patientWithTwoSpecimen";
2933 14 Nov 14 olle 552     String patientWithThreeOrMoreSpecimenKey = "patientWithThreeOrMoreSpecimen";
2933 14 Nov 14 olle 553     String patientNoSamplesKey = "patientNoSamples";
2933 14 Nov 14 olle 554     String sitesCombinedKey = "sitesCombinedKey";
2933 14 Nov 14 olle 555     String sumKey = "sumKey";
2933 14 Nov 14 olle 556     String latestDateKey = "latestDateKey";
2933 14 Nov 14 olle 557     String duplicateKey = "duplicateKey";
2933 14 Nov 14 olle 558     String specimenNoDateKey = "specimenNoDate";
2933 14 Nov 14 olle 559     jsonStatistics.put(sitesCombinedKey, jsonSitesCombined);
2933 14 Nov 14 olle 560     // Initialize site data to 0 for the different keys
2933 14 Nov 14 olle 561     jsonStatistics = tableUtil.initializeJSONSiteData(jsonStatistics, patientKey);
2933 14 Nov 14 olle 562     jsonStatistics = tableUtil.initializeJSONSiteData(jsonStatistics, specimenKey);
2933 14 Nov 14 olle 563     jsonStatistics = tableUtil.initializeJSONSiteData(jsonStatistics, patientWithSpecimenKey);
2933 14 Nov 14 olle 564     jsonStatistics = tableUtil.initializeJSONSiteData(jsonStatistics, patientWithOneSpecimenKey);
2933 14 Nov 14 olle 565     jsonStatistics = tableUtil.initializeJSONSiteData(jsonStatistics, patientWithTwoSpecimenKey);
2933 14 Nov 14 olle 566     jsonStatistics = tableUtil.initializeJSONSiteData(jsonStatistics, patientWithThreeOrMoreSpecimenKey);
2933 14 Nov 14 olle 567     jsonStatistics = tableUtil.initializeJSONSiteData(jsonStatistics, patientNoSamplesKey);
2933 14 Nov 14 olle 568     jsonStatistics = tableUtil.initializeJSONSiteData(jsonStatistics, specimenNoDateKey);
2933 14 Nov 14 olle 569     jsonStatistics = tableUtil.initializeJSONSiteData(jsonStatistics, sumKey);
2933 14 Nov 14 olle 570     // Initialize combined data to 0 for the different keys
2933 14 Nov 14 olle 571     jsonSitesCombined.put(patientKey, 0);
2933 14 Nov 14 olle 572     jsonSitesCombined.put(specimenKey, 0);
2933 14 Nov 14 olle 573     jsonSitesCombined.put(patientWithSpecimenKey, 0);
2933 14 Nov 14 olle 574     jsonSitesCombined.put(patientWithOneSpecimenKey, 0);
2933 14 Nov 14 olle 575     jsonSitesCombined.put(patientWithTwoSpecimenKey, 0);
2933 14 Nov 14 olle 576     jsonSitesCombined.put(patientWithThreeOrMoreSpecimenKey, 0);
2933 14 Nov 14 olle 577     jsonSitesCombined.put(patientNoSamplesKey, 0);
2933 14 Nov 14 olle 578     jsonSitesCombined.put(specimenNoDateKey, 0);
2933 14 Nov 14 olle 579     jsonSitesCombined.put(sumKey, 0);
2933 14 Nov 14 olle 580     // Initialize other data to 0 for different keys
2933 14 Nov 14 olle 581     jsonStatistics.put(duplicateKey, 0);
2933 14 Nov 14 olle 582     Date latestDate = null;
2933 14 Nov 14 olle 583     // Create HashMap to keep track of processed dates for each patient
2933 14 Nov 14 olle 584     HashMap<String, Set<Date>>patientDateSetHashMap = new HashMap<String, Set<Date>>();
2933 14 Nov 14 olle 585     //JSONObject jsonPatientnamePatientid = new JSONObject();
2933 14 Nov 14 olle 586     // HashMap of patient id's and site prefixes
2933 14 Nov 14 olle 587     HashMap<String, String> patientHashMap = new HashMap<String, String>();
2933 14 Nov 14 olle 588     // Set of patient id's for patients with blood samples
2933 14 Nov 14 olle 589     Set<String> patientsWithBloodSamplesSet = new HashSet<String>();
2933 14 Nov 14 olle 590     // Set of patient id's for patients with follow-up blood samples
2933 14 Nov 14 olle 591     Set<String> patientsWithFollowUpBloodSamplesSet = new HashSet<String>();
2933 14 Nov 14 olle 592     // Set of patient id's for patients with specimens
2933 14 Nov 14 olle 593     Set<String> patientsWithSpecimensSet = new HashSet<String>();
2933 14 Nov 14 olle 594     // Set of patient id's for patients with no specimens
2933 14 Nov 14 olle 595     Set<String> patientsWithNoSpecimensSet = new HashSet<String>();
2933 14 Nov 14 olle 596     // HashMap of patient id's and site prefixes
2933 14 Nov 14 olle 597     HashMap<String, Integer> patientNoOfSpecimensHashMap = new HashMap<String, Integer>();
2933 14 Nov 14 olle 598     // Create HashMap to keep track of latest item date for each site
2933 14 Nov 14 olle 599     HashMap<String, Date> sitePrefixDateHashMap = new HashMap<String, Date>();
2933 14 Nov 14 olle 600     // Get item subtype constants for later use
3060 19 Dec 14 olle 601     ItemSubtype subtypeSpecimen = getSubtypeSpecimen();
3060 19 Dec 14 olle 602     ItemSubtype subtypeCase = getSubtypeSpecimen();
2933 14 Nov 14 olle 603     //
2933 14 Nov 14 olle 604 /*
2933 14 Nov 14 olle 605     while (sampleIterator != null && sampleIterator.hasNext())
2933 14 Nov 14 olle 606     {
2933 14 Nov 14 olle 607       Sample s = sampleIterator.next();
2933 14 Nov 14 olle 608 */
2933 14 Nov 14 olle 609     for (Sample s: sampleList)
2933 14 Nov 14 olle 610     {
2933 14 Nov 14 olle 611       BioMaterialEvent creationEvent = s.getCreationEvent();
2933 14 Nov 14 olle 612       Date creationDate = creationEvent.getEventDate();
2933 14 Nov 14 olle 613
2933 14 Nov 14 olle 614       // Replace unknown creation date with registration date in overview report
2933 14 Nov 14 olle 615       if (creationDate == null)
2933 14 Nov 14 olle 616       {
2933 14 Nov 14 olle 617         creationDate = s.getEntryDate();
2933 14 Nov 14 olle 618         // Update unknown date counter
3060 19 Dec 14 olle 619         Site sampleSite = fetchSite(dc, manager, s);
2933 14 Nov 14 olle 620         if (sampleSite == Site.UNKNOWN)
2933 14 Nov 14 olle 621         {
2933 14 Nov 14 olle 622           String key = "unknownSite";
2933 14 Nov 14 olle 623           jsonStatistics = tableUtil.updateJSONObjectCounter(jsonStatistics, key);
2933 14 Nov 14 olle 624           // Change site to be able to add the unknown site to statistics
2933 14 Nov 14 olle 625           sampleSite = Site.UNKNOWN_RPT;
2933 14 Nov 14 olle 626         }
2933 14 Nov 14 olle 627         String sampleNoDateKey = null;
2933 14 Nov 14 olle 628         JSONObject jsonSite = (JSONObject)jsonStatistics.get(sampleSite.getPrefix());
2933 14 Nov 14 olle 629         if (jsonSite == null)
2933 14 Nov 14 olle 630         {
2933 14 Nov 14 olle 631           jsonSite = new JSONObject();
2933 14 Nov 14 olle 632           jsonStatistics.put(sampleSite.getPrefix(), jsonSite);
2933 14 Nov 14 olle 633         }
2933 14 Nov 14 olle 634         if (s.getItemSubtype().equals(subtypeSpecimen))
2933 14 Nov 14 olle 635         {
2933 14 Nov 14 olle 636           sampleNoDateKey = specimenNoDateKey;
2933 14 Nov 14 olle 637         }
2933 14 Nov 14 olle 638         // Update unknown date counter
2933 14 Nov 14 olle 639         jsonSite = tableUtil.updateJSONObjectCounter(jsonSite, sampleNoDateKey);
2933 14 Nov 14 olle 640         jsonSitesCombined = tableUtil.updateJSONObjectCounter(jsonSitesCombined, sampleNoDateKey);
2933 14 Nov 14 olle 641         jsonStatistics = tableUtil.updateJSONObjectCounter(jsonStatistics, sampleNoDateKey);
2933 14 Nov 14 olle 642       }
2933 14 Nov 14 olle 643       // Skip item if date is outside selected time period
2933 14 Nov 14 olle 644       if (creationDate.before(startDate) || creationDate.after(endDate))
2933 14 Nov 14 olle 645       {
2933 14 Nov 14 olle 646         continue;
2933 14 Nov 14 olle 647       }
2933 14 Nov 14 olle 648
2933 14 Nov 14 olle 649       // Find patient id
2933 14 Nov 14 olle 650       BioMaterial patient = null;
2933 14 Nov 14 olle 651       if (s.getItemSubtype().equals(subtypeSpecimen))
2933 14 Nov 14 olle 652       {
2933 14 Nov 14 olle 653         // The grandparent is the 'Patient' for specimens and no specimens
2933 14 Nov 14 olle 654         MeasuredBioMaterial parent = (MeasuredBioMaterial) s.getParent();
2933 14 Nov 14 olle 655         if (parent != null)
2933 14 Nov 14 olle 656         {
2933 14 Nov 14 olle 657           patient = parent.getParent();
2933 14 Nov 14 olle 658         }
2933 14 Nov 14 olle 659       }
2933 14 Nov 14 olle 660
2933 14 Nov 14 olle 661       // Update statistics for specimens
3060 19 Dec 14 olle 662       Site site = fetchSite(dc, manager, s);
2933 14 Nov 14 olle 663       if (site == Site.UNKNOWN)
2933 14 Nov 14 olle 664       {
2933 14 Nov 14 olle 665         String key = "unknownSite";
2933 14 Nov 14 olle 666         jsonStatistics = tableUtil.updateJSONObjectCounter(jsonStatistics, key);
2933 14 Nov 14 olle 667         if (patient != null)
2933 14 Nov 14 olle 668         {
2933 14 Nov 14 olle 669           key = "unknownPatientSite";
2933 14 Nov 14 olle 670           jsonStatistics = tableUtil.updateJSONObjectCounter(jsonStatistics, key);
2933 14 Nov 14 olle 671         }
2933 14 Nov 14 olle 672         // Change site to be able to add the unknown site to statistics
2933 14 Nov 14 olle 673         site = Site.UNKNOWN_RPT;
2933 14 Nov 14 olle 674       }
2933 14 Nov 14 olle 675       // Get site info            
2933 14 Nov 14 olle 676       JSONObject jsonSite = (JSONObject)jsonStatistics.get(site.getPrefix());
2933 14 Nov 14 olle 677       if (jsonSite == null)
2933 14 Nov 14 olle 678       {
2933 14 Nov 14 olle 679         jsonSite = new JSONObject();
2933 14 Nov 14 olle 680         jsonStatistics.put(site.getPrefix(), jsonSite);
2933 14 Nov 14 olle 681       }
2933 14 Nov 14 olle 682
2933 14 Nov 14 olle 683       // Store patient data for later processing
2933 14 Nov 14 olle 684       String patientId = null;
2933 14 Nov 14 olle 685       if (patient != null)
2933 14 Nov 14 olle 686       {
2933 14 Nov 14 olle 687         patientId = patient.getName();
2933 14 Nov 14 olle 688         if (patientId != null && !patientId.equals(""))
2933 14 Nov 14 olle 689         {
2933 14 Nov 14 olle 690           // Add patient id to patient HashMap for site
2933 14 Nov 14 olle 691           patientHashMap.put(patientId, site.getPrefix());
2933 14 Nov 14 olle 692
2933 14 Nov 14 olle 693           if (s.getItemSubtype().equals(subtypeSpecimen))
2933 14 Nov 14 olle 694           {
2933 14 Nov 14 olle 695             // Add patient to patients with specimens set
2933 14 Nov 14 olle 696             patientsWithSpecimensSet.add(patientId);
2933 14 Nov 14 olle 697             // Update patient/No of specimens hash map
2933 14 Nov 14 olle 698             Integer numSpecimens = patientNoOfSpecimensHashMap.get(patientId);
2933 14 Nov 14 olle 699             if (numSpecimens == null)
2933 14 Nov 14 olle 700             {
2933 14 Nov 14 olle 701               numSpecimens = 0;
2933 14 Nov 14 olle 702             }
2933 14 Nov 14 olle 703             numSpecimens++;
2933 14 Nov 14 olle 704             patientNoOfSpecimensHashMap.put(patientId, numSpecimens);
2933 14 Nov 14 olle 705           }
2933 14 Nov 14 olle 706         }
2933 14 Nov 14 olle 707       }
2933 14 Nov 14 olle 708
2933 14 Nov 14 olle 709       // Update specimen data
2933 14 Nov 14 olle 710       if (s.getItemSubtype().equals(subtypeSpecimen))
2933 14 Nov 14 olle 711       {
2933 14 Nov 14 olle 712         jsonSite = tableUtil.updateJSONObjectCounter(jsonSite, specimenKey);
2933 14 Nov 14 olle 713         jsonSitesCombined = tableUtil.updateJSONObjectCounter(jsonSitesCombined, specimenKey);
2933 14 Nov 14 olle 714       }
2933 14 Nov 14 olle 715
2933 14 Nov 14 olle 716       // Keep track of latest item date for site
2933 14 Nov 14 olle 717       if (creationDate != null)
2933 14 Nov 14 olle 718       {
2933 14 Nov 14 olle 719         Date siteLatestDate = sitePrefixDateHashMap.get(site.getPrefix());
2933 14 Nov 14 olle 720         if (siteLatestDate == null || siteLatestDate.before(creationDate))
2933 14 Nov 14 olle 721         {
2933 14 Nov 14 olle 722           sitePrefixDateHashMap.put(site.getPrefix(), creationDate);
2933 14 Nov 14 olle 723         }
2933 14 Nov 14 olle 724         // Keep track of latest item date so far
2933 14 Nov 14 olle 725         if (latestDate == null || latestDate.before(creationDate)) 
2933 14 Nov 14 olle 726         {
2933 14 Nov 14 olle 727           latestDate = creationDate;
2933 14 Nov 14 olle 728         }
2933 14 Nov 14 olle 729       }
2933 14 Nov 14 olle 730     }
2933 14 Nov 14 olle 731
2933 14 Nov 14 olle 732     // Process patients
2933 14 Nov 14 olle 733     for (String patId: patientHashMap.keySet())
2933 14 Nov 14 olle 734     {
2933 14 Nov 14 olle 735       if (patId != null && !patId.equals(""))
2933 14 Nov 14 olle 736       {
2933 14 Nov 14 olle 737         // Get site info
2933 14 Nov 14 olle 738         String sitePrefix = patientHashMap.get(patId);
2933 14 Nov 14 olle 739         JSONObject jsonSite = (JSONObject)jsonStatistics.get(sitePrefix);
2933 14 Nov 14 olle 740         if (jsonSite == null)
2933 14 Nov 14 olle 741         {
2933 14 Nov 14 olle 742           jsonSite = new JSONObject();
2933 14 Nov 14 olle 743           jsonStatistics.put(sitePrefix, jsonSite);
2933 14 Nov 14 olle 744         }
2933 14 Nov 14 olle 745         // Update patient data
2933 14 Nov 14 olle 746         jsonSite = tableUtil.updateJSONObjectCounter(jsonSite, patientKey);
2933 14 Nov 14 olle 747         jsonSitesCombined = tableUtil.updateJSONObjectCounter(jsonSitesCombined, patientKey);
2933 14 Nov 14 olle 748         // Update data for patients having different kinds of samples
2933 14 Nov 14 olle 749         if (patientsWithSpecimensSet.contains(patId))
2933 14 Nov 14 olle 750         {
2933 14 Nov 14 olle 751           // Patient with at least one specimen
2933 14 Nov 14 olle 752           jsonSite = tableUtil.updateJSONObjectCounter(jsonSite, patientWithSpecimenKey);
2933 14 Nov 14 olle 753           jsonSitesCombined = tableUtil.updateJSONObjectCounter(jsonSitesCombined, patientWithSpecimenKey);
2933 14 Nov 14 olle 754           // Update data for number of specimens per patient
2933 14 Nov 14 olle 755           Integer numSpecimens = patientNoOfSpecimensHashMap.get(patId);
2933 14 Nov 14 olle 756           if (numSpecimens != null && numSpecimens > 0)
2933 14 Nov 14 olle 757           {
2933 14 Nov 14 olle 758             if (numSpecimens == 1)
2933 14 Nov 14 olle 759             {
2933 14 Nov 14 olle 760               // Patient with one specimen
2933 14 Nov 14 olle 761               jsonSite = tableUtil.updateJSONObjectCounter(jsonSite, patientWithOneSpecimenKey);
2933 14 Nov 14 olle 762               jsonSitesCombined = tableUtil.updateJSONObjectCounter(jsonSitesCombined, patientWithOneSpecimenKey);
2933 14 Nov 14 olle 763             }
2933 14 Nov 14 olle 764             if (numSpecimens == 2)
2933 14 Nov 14 olle 765             {
2933 14 Nov 14 olle 766               // Patient with two specimens
2933 14 Nov 14 olle 767               jsonSite = tableUtil.updateJSONObjectCounter(jsonSite, patientWithTwoSpecimenKey);
2933 14 Nov 14 olle 768               jsonSitesCombined = tableUtil.updateJSONObjectCounter(jsonSitesCombined, patientWithTwoSpecimenKey);
2933 14 Nov 14 olle 769             }
2933 14 Nov 14 olle 770             if (numSpecimens >= 3)
2933 14 Nov 14 olle 771             {
2933 14 Nov 14 olle 772               // Patient with three or more specimens
2933 14 Nov 14 olle 773               jsonSite = tableUtil.updateJSONObjectCounter(jsonSite, patientWithThreeOrMoreSpecimenKey);
2933 14 Nov 14 olle 774               jsonSitesCombined = tableUtil.updateJSONObjectCounter(jsonSitesCombined, patientWithThreeOrMoreSpecimenKey);
2933 14 Nov 14 olle 775             }
2933 14 Nov 14 olle 776           }
2933 14 Nov 14 olle 777         }
2933 14 Nov 14 olle 778         // Update summed patient data
2933 14 Nov 14 olle 779         jsonSite = tableUtil.updateJSONObjectCounter(jsonSite, sumKey);
2933 14 Nov 14 olle 780         jsonSitesCombined = tableUtil.updateJSONObjectCounter(jsonSitesCombined, sumKey);
2933 14 Nov 14 olle 781       }
2933 14 Nov 14 olle 782     }
2933 14 Nov 14 olle 783
2933 14 Nov 14 olle 784     // Add latest item date for site to site JSON object
2933 14 Nov 14 olle 785     DateToStringConverter date2StringConverter = Meludi.CONVERTER_DATE_TO_STRING;
2933 14 Nov 14 olle 786     for (Site s: Site.getAllReportSites())
2933 14 Nov 14 olle 787     {
2933 14 Nov 14 olle 788       JSONObject jsonSite = (JSONObject) jsonStatistics.get(s.getPrefix());
2933 14 Nov 14 olle 789       if (jsonSite == null)
2933 14 Nov 14 olle 790       {
2933 14 Nov 14 olle 791         jsonSite = new JSONObject();
2933 14 Nov 14 olle 792         jsonStatistics.put(s.getPrefix(), jsonSite);
2933 14 Nov 14 olle 793       }
2933 14 Nov 14 olle 794       Date siteLatestDate = sitePrefixDateHashMap.get(s.getPrefix());
2933 14 Nov 14 olle 795       jsonSite.put(latestDateKey, date2StringConverter.convert(siteLatestDate));
2933 14 Nov 14 olle 796     }
2933 14 Nov 14 olle 797     // Add latest date for further transfer to other JSON object
2933 14 Nov 14 olle 798     jsonStatistics.put(latestDateKey, date2StringConverter.convert(latestDate));
2933 14 Nov 14 olle 799     // Add number of patients with no samples
2933 14 Nov 14 olle 800     Integer numPatientsNoSamples = (Integer) jsonSitesCombined.get(patientNoSamplesKey);
2933 14 Nov 14 olle 801     if (numPatientsNoSamples == null)
2933 14 Nov 14 olle 802     {
2933 14 Nov 14 olle 803       numPatientsNoSamples = 0;
2933 14 Nov 14 olle 804     }
2933 14 Nov 14 olle 805     jsonStatistics.put(patientNoSamplesKey, numPatientsNoSamples);
2933 14 Nov 14 olle 806     //
2933 14 Nov 14 olle 807     jsonReport.put("statistics", jsonStatistics);        
2933 14 Nov 14 olle 808     jsonReport.put("projectFocusFilter", projectFocusFilter);        
2933 14 Nov 14 olle 809     jsonReport.put("beginDate", date2StringConverter.convert(startDate));
2933 14 Nov 14 olle 810     jsonReport.put("endDate", date2StringConverter.convert(endDate));
2933 14 Nov 14 olle 811     // Transfer latest date from jsonStatistics to jsonReport
2933 14 Nov 14 olle 812     String latestDateStr = (String) jsonStatistics.get("latestDateKey");
2933 14 Nov 14 olle 813     jsonReport.put("latestDate", latestDateStr);
2933 14 Nov 14 olle 814     json.put("report", jsonReport);
2933 14 Nov 14 olle 815     return json;
2933 14 Nov 14 olle 816   }
2933 14 Nov 14 olle 817
2933 14 Nov 14 olle 818   @SuppressWarnings({ "unchecked", "rawtypes" })
2933 14 Nov 14 olle 819   private JSONObject createMissingSampleDataReport(DbControl dc, JSONObject json, Date startDate, Date endDate, String sampleType, String projectFocusFilter)
2933 14 Nov 14 olle 820       throws ServletException, IOException 
2933 14 Nov 14 olle 821   {
2933 14 Nov 14 olle 822     List<Sample> sampleList = createSampleListForMissingSampleDataReport(dc, sampleType, projectFocusFilter);
2933 14 Nov 14 olle 823     // Use stored annotation snapshots for performance reasons
2933 14 Nov 14 olle 824     SnapshotManager manager = new SnapshotManager();        
2933 14 Nov 14 olle 825
4174 24 Oct 16 olle 826     JSONObject jsonReport = fetchJsonReportPrimer(dc);
2933 14 Nov 14 olle 827     
2933 14 Nov 14 olle 828     JSONObject jsonStatistics = new JSONObject();
2933 14 Nov 14 olle 829     JSONObject jsonSitesCombined = new JSONObject();
2933 14 Nov 14 olle 830     String missingPatientKey = "missingPatient";
2933 14 Nov 14 olle 831     String missingPatientNameKey = "missingPatientName";
2933 14 Nov 14 olle 832     String missingPadReferenceKey = "missingPadReference";
2933 14 Nov 14 olle 833     String missingSamplingDateTimeKey = "missingSamplingDateTime";
2933 14 Nov 14 olle 834     String permissionDeniedForPatientNameKey = "permissionDeniedForPatientName";
2933 14 Nov 14 olle 835     String permissionDeniedForPadKey = "permissionDeniedForPad";
2933 14 Nov 14 olle 836     String sitesCombinedKey = "sitesCombinedKey";
2933 14 Nov 14 olle 837     String latestDateKey = "latestDateKey";
2933 14 Nov 14 olle 838     String duplicateKey = "duplicateKey";
2933 14 Nov 14 olle 839     jsonStatistics.put(sitesCombinedKey, jsonSitesCombined);
2933 14 Nov 14 olle 840     // Initialize site data to 0 for the different keys
2933 14 Nov 14 olle 841     jsonStatistics = tableUtil.initializeJSONSiteData(jsonStatistics, missingPatientKey);
2933 14 Nov 14 olle 842     jsonStatistics = tableUtil.initializeJSONSiteData(jsonStatistics, missingPatientNameKey);
2933 14 Nov 14 olle 843     jsonStatistics = tableUtil.initializeJSONSiteData(jsonStatistics, missingPadReferenceKey);
2933 14 Nov 14 olle 844     jsonStatistics = tableUtil.initializeJSONSiteData(jsonStatistics, missingSamplingDateTimeKey);
2933 14 Nov 14 olle 845     // Initialize combined data to 0 for the different keys
2933 14 Nov 14 olle 846     jsonSitesCombined.put(missingPatientKey, 0);
2933 14 Nov 14 olle 847     jsonSitesCombined.put(missingPatientNameKey, 0);
2933 14 Nov 14 olle 848     jsonSitesCombined.put(missingPadReferenceKey, 0);
2933 14 Nov 14 olle 849     jsonSitesCombined.put(missingSamplingDateTimeKey, 0);
2933 14 Nov 14 olle 850     // Initialize other data to 0 for different keys
2933 14 Nov 14 olle 851     jsonStatistics.put(duplicateKey, 0);
2933 14 Nov 14 olle 852     Date latestDate = null;
2933 14 Nov 14 olle 853     // Create HashMap to keep track of latest item date for each site
2933 14 Nov 14 olle 854     HashMap<String, Date> sitePrefixDateHashMap = new HashMap<String, Date>();
2933 14 Nov 14 olle 855     boolean permissionDeniedForPatientName = false;
2933 14 Nov 14 olle 856     try
2933 14 Nov 14 olle 857     {
2933 14 Nov 14 olle 858       Annotationtype.ALL_FIRST_NAMES.load(dc);
2933 14 Nov 14 olle 859       Annotationtype.FAMILY_NAME.load(dc);
2933 14 Nov 14 olle 860     }
2933 14 Nov 14 olle 861     catch (RuntimeException ex)
2933 14 Nov 14 olle 862     {
2933 14 Nov 14 olle 863       permissionDeniedForPatientName = true;
2933 14 Nov 14 olle 864     }
2933 14 Nov 14 olle 865     boolean permissionDeniedForPad = false;
2933 14 Nov 14 olle 866     try
2933 14 Nov 14 olle 867     {
2933 14 Nov 14 olle 868       Annotationtype.PAD.load(dc);
2933 14 Nov 14 olle 869     }
2933 14 Nov 14 olle 870     catch (RuntimeException ex)
2933 14 Nov 14 olle 871     {
2933 14 Nov 14 olle 872       permissionDeniedForPad = true;
2933 14 Nov 14 olle 873     }
2933 14 Nov 14 olle 874     
2933 14 Nov 14 olle 875     //
2933 14 Nov 14 olle 876     for (Sample s: sampleList)
2933 14 Nov 14 olle 877     {
2933 14 Nov 14 olle 878       BioMaterialEvent creationEvent = s.getCreationEvent();
2933 14 Nov 14 olle 879       Date creationDate = creationEvent.getEventDate();
2933 14 Nov 14 olle 880
2933 14 Nov 14 olle 881       // Find patient id
2933 14 Nov 14 olle 882       BioMaterial patient = null;
2933 14 Nov 14 olle 883       // The grandparent is the 'Patient' for specimens
2933 14 Nov 14 olle 884       MeasuredBioMaterial parent = (MeasuredBioMaterial) s.getParent();
2933 14 Nov 14 olle 885       if (parent != null)
2933 14 Nov 14 olle 886       {
2933 14 Nov 14 olle 887         patient = parent.getParent();
2933 14 Nov 14 olle 888       }
2933 14 Nov 14 olle 889
2933 14 Nov 14 olle 890       // Initialize sample data
2933 14 Nov 14 olle 891       String allFirstNames = null;
2933 14 Nov 14 olle 892       String familyName = null;
2933 14 Nov 14 olle 893       String pad = null;
2933 14 Nov 14 olle 894       Date samplingDate = null;
2933 14 Nov 14 olle 895
2933 14 Nov 14 olle 896       if (patient != null)
2933 14 Nov 14 olle 897       {
2933 14 Nov 14 olle 898         if (!permissionDeniedForPatientName)
2933 14 Nov 14 olle 899         {
2933 14 Nov 14 olle 900           // Get patient all first names
2933 14 Nov 14 olle 901           allFirstNames = (String) Annotationtype.ALL_FIRST_NAMES.getAnnotationValue(dc, manager, patient);
2933 14 Nov 14 olle 902           // Get patient family name
2933 14 Nov 14 olle 903           familyName = (String) Annotationtype.FAMILY_NAME.getAnnotationValue(dc, manager, patient);
2933 14 Nov 14 olle 904         }
2933 14 Nov 14 olle 905       }
2933 14 Nov 14 olle 906       if (sampleType.equals("specimen"))
2933 14 Nov 14 olle 907       {
2933 14 Nov 14 olle 908         // Get PAD reference
2933 14 Nov 14 olle 909         if (!permissionDeniedForPad)
2933 14 Nov 14 olle 910         {
2933 14 Nov 14 olle 911           pad = (String) Annotationtype.PAD.getAnnotationValue(dc, manager, s);
2933 14 Nov 14 olle 912         }
2933 14 Nov 14 olle 913         // Get sampling date
3028 11 Dec 14 olle 914         samplingDate = (Date) Annotationtype.SAMPLING_DATE.getAnnotationValue(dc, manager, s);
2933 14 Nov 14 olle 915       }
2933 14 Nov 14 olle 916       // Update statistics for sample type
3060 19 Dec 14 olle 917       Site site = fetchSite(dc, manager, s);
2933 14 Nov 14 olle 918       if (site == Site.UNKNOWN)
2933 14 Nov 14 olle 919       {
2933 14 Nov 14 olle 920         String key = "unknownSite";
2933 14 Nov 14 olle 921         jsonStatistics = tableUtil.updateJSONObjectCounter(jsonStatistics, key);
2933 14 Nov 14 olle 922         // Change site to be able to add the unknown site to statistics
2933 14 Nov 14 olle 923         site = Site.UNKNOWN_RPT;
2933 14 Nov 14 olle 924       }
2933 14 Nov 14 olle 925       // Get site info            
2933 14 Nov 14 olle 926       JSONObject jsonSite = (JSONObject)jsonStatistics.get(site.getPrefix());
2933 14 Nov 14 olle 927       if (jsonSite == null)
2933 14 Nov 14 olle 928       {
2933 14 Nov 14 olle 929         jsonSite = new JSONObject();
2933 14 Nov 14 olle 930         jsonStatistics.put(site.getPrefix(), jsonSite);
2933 14 Nov 14 olle 931       }
2933 14 Nov 14 olle 932
2933 14 Nov 14 olle 933       if (patient == null)
2933 14 Nov 14 olle 934       {
2933 14 Nov 14 olle 935         // Update missing patient data
2933 14 Nov 14 olle 936         jsonSite = tableUtil.updateJSONObjectCounter(jsonSite, missingPatientKey);
2933 14 Nov 14 olle 937         jsonSitesCombined = tableUtil.updateJSONObjectCounter(jsonSitesCombined, missingPatientKey);
2933 14 Nov 14 olle 938       }
2933 14 Nov 14 olle 939       if (patient != null && !permissionDeniedForPatientName)
2933 14 Nov 14 olle 940       {
2933 14 Nov 14 olle 941         // Update missing patient name data, provided the user has permission to check it
2933 14 Nov 14 olle 942         if (allFirstNames == null || allFirstNames.equals("")
2933 14 Nov 14 olle 943             || familyName == null || familyName.equals(""))
2933 14 Nov 14 olle 944         {
2933 14 Nov 14 olle 945           jsonSite = tableUtil.updateJSONObjectCounter(jsonSite, missingPatientNameKey);
2933 14 Nov 14 olle 946           jsonSitesCombined = tableUtil.updateJSONObjectCounter(jsonSitesCombined, missingPatientNameKey);
2933 14 Nov 14 olle 947         }
2933 14 Nov 14 olle 948       }
2933 14 Nov 14 olle 949       if (sampleType.equals("specimen"))
2933 14 Nov 14 olle 950       {
2933 14 Nov 14 olle 951         // Update missing PAD reference data
2933 14 Nov 14 olle 952         if (!permissionDeniedForPad)
2933 14 Nov 14 olle 953         {
2933 14 Nov 14 olle 954           if (pad == null || pad.equals(""))
2933 14 Nov 14 olle 955           {
2933 14 Nov 14 olle 956             jsonSite = tableUtil.updateJSONObjectCounter(jsonSite, missingPadReferenceKey);
2933 14 Nov 14 olle 957             jsonSitesCombined = tableUtil.updateJSONObjectCounter(jsonSitesCombined, missingPadReferenceKey);
2933 14 Nov 14 olle 958           }
2933 14 Nov 14 olle 959         }
2933 14 Nov 14 olle 960         // Update missing sampling date data
2933 14 Nov 14 olle 961         if (samplingDate == null)
2933 14 Nov 14 olle 962         {
2933 14 Nov 14 olle 963           jsonSite = tableUtil.updateJSONObjectCounter(jsonSite, missingSamplingDateTimeKey);
2933 14 Nov 14 olle 964           jsonSitesCombined = tableUtil.updateJSONObjectCounter(jsonSitesCombined, missingSamplingDateTimeKey);
2933 14 Nov 14 olle 965         }
2933 14 Nov 14 olle 966       }
2933 14 Nov 14 olle 967
2933 14 Nov 14 olle 968       // Keep track of latest item date for site
2933 14 Nov 14 olle 969       if (creationDate != null)
2933 14 Nov 14 olle 970       {
2933 14 Nov 14 olle 971         Date siteLatestDate = sitePrefixDateHashMap.get(site.getPrefix());
2933 14 Nov 14 olle 972         if (siteLatestDate == null || siteLatestDate.before(creationDate))
2933 14 Nov 14 olle 973         {
2933 14 Nov 14 olle 974           sitePrefixDateHashMap.put(site.getPrefix(), creationDate);
2933 14 Nov 14 olle 975         }
2933 14 Nov 14 olle 976         // Keep track of latest item date so far
2933 14 Nov 14 olle 977         if (latestDate == null || latestDate.before(creationDate)) 
2933 14 Nov 14 olle 978         {
2933 14 Nov 14 olle 979           latestDate = creationDate;
2933 14 Nov 14 olle 980         }
2933 14 Nov 14 olle 981       }
2933 14 Nov 14 olle 982     }
2933 14 Nov 14 olle 983     // Add latest item date for site to site JSON object
2933 14 Nov 14 olle 984     DateToStringConverter date2StringConverter = Meludi.CONVERTER_DATE_TO_STRING;
2933 14 Nov 14 olle 985     for (Site s: Site.getAllReportSites())
2933 14 Nov 14 olle 986     {
2933 14 Nov 14 olle 987       JSONObject jsonSite = (JSONObject) jsonStatistics.get(s.getPrefix());
2933 14 Nov 14 olle 988       if (jsonSite == null)
2933 14 Nov 14 olle 989       {
2933 14 Nov 14 olle 990         jsonSite = new JSONObject();
2933 14 Nov 14 olle 991         jsonStatistics.put(s.getPrefix(), jsonSite);
2933 14 Nov 14 olle 992       }
2933 14 Nov 14 olle 993       Date siteLatestDate = sitePrefixDateHashMap.get(s.getPrefix());
2933 14 Nov 14 olle 994       jsonSite.put(latestDateKey, date2StringConverter.convert(siteLatestDate));
2933 14 Nov 14 olle 995     }
2933 14 Nov 14 olle 996     // Add latest date for further transfer to other JSON object
2933 14 Nov 14 olle 997     jsonStatistics.put(latestDateKey, date2StringConverter.convert(latestDate));
2933 14 Nov 14 olle 998     //
2933 14 Nov 14 olle 999     jsonReport.put("statistics", jsonStatistics);        
2933 14 Nov 14 olle 1000     jsonReport.put("sampleType", sampleType);
2933 14 Nov 14 olle 1001     jsonReport.put("projectFocusFilter", projectFocusFilter);        
2933 14 Nov 14 olle 1002     jsonReport.put("beginDate", date2StringConverter.convert(startDate));
2933 14 Nov 14 olle 1003     jsonReport.put("endDate", date2StringConverter.convert(endDate));
2933 14 Nov 14 olle 1004     // Transfer latest date from jsonStatistics to jsonReport
2933 14 Nov 14 olle 1005     String latestDateStr = (String) jsonStatistics.get("latestDateKey");
2933 14 Nov 14 olle 1006     jsonReport.put("latestDate", latestDateStr);
2933 14 Nov 14 olle 1007     jsonReport.put(permissionDeniedForPatientNameKey, permissionDeniedForPatientName);
2933 14 Nov 14 olle 1008     jsonReport.put(permissionDeniedForPadKey, permissionDeniedForPad);
2933 14 Nov 14 olle 1009     json.put("report", jsonReport);
2933 14 Nov 14 olle 1010     return json;
2933 14 Nov 14 olle 1011   }
2933 14 Nov 14 olle 1012
2933 14 Nov 14 olle 1013   /**
2933 14 Nov 14 olle 1014    * Creates sample list for missing sample data report.
2933 14 Nov 14 olle 1015    * 
2933 14 Nov 14 olle 1016    * @param dc DbControl The DbControl to use.
2933 14 Nov 14 olle 1017    * @param sampleType String The sample type for included samples.
2933 14 Nov 14 olle 1018    * @param projectFocusFilter String Optional blood sample filter.
2933 14 Nov 14 olle 1019    * @return List<Sample> Sample list for missing sample data report.
2933 14 Nov 14 olle 1020    * @throws ServletException
2933 14 Nov 14 olle 1021    * @throws IOException
2933 14 Nov 14 olle 1022    */
2933 14 Nov 14 olle 1023   private List<Sample> createSampleListForMissingSampleDataReport(DbControl dc, String sampleType, String projectFocusFilter)
2933 14 Nov 14 olle 1024       throws ServletException, IOException 
2933 14 Nov 14 olle 1025   {  
2933 14 Nov 14 olle 1026     ItemQuery<Sample> sampleQuery = Sample.getQuery();
2933 14 Nov 14 olle 1027     sampleQuery.joinPermanent(Hql.innerJoin(null, "creationEvent", "ce", true));
2933 14 Nov 14 olle 1028     // Select what sample subtype to include in database search 
2933 14 Nov 14 olle 1029     // Fetch Joining parent CASE and PATIENT should improve performance
2933 14 Nov 14 olle 1030     Subtype.SPECIMEN.addFilter(dc, sampleQuery);
2933 14 Nov 14 olle 1031     sampleQuery.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
4163 19 Oct 16 olle 1032     // Only include samples for active project
5255 21 Jan 19 olle 1033     String specimenItemPrefix = Meludi.fetchSpecimenItemPrefix(dc.getSessionControl().getActiveProjectId());
5255 21 Jan 19 olle 1034     String sampleQueryNameRestriction = specimenItemPrefix + "%";
4163 19 Oct 16 olle 1035     sampleQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.string(sampleQueryNameRestriction)));
2933 14 Nov 14 olle 1036     sampleQuery.order(Orders.asc(Hql.property("name")));
2933 14 Nov 14 olle 1037     sampleQuery.order(Orders.asc(Hql.property("ce", "eventDate")));
2933 14 Nov 14 olle 1038     sampleQuery.setCacheResult(true);
2933 14 Nov 14 olle 1039     ItemResultIterator<Sample> sampleIterator = sampleQuery.iterate(dc);
2933 14 Nov 14 olle 1040     
2933 14 Nov 14 olle 1041     // Create sample list
2933 14 Nov 14 olle 1042     List<Sample> sampleList = new ArrayList<Sample>();
2933 14 Nov 14 olle 1043     // Use stored annotation snapshots for performance reasons
2933 14 Nov 14 olle 1044     SnapshotManager manager = new SnapshotManager();        
2933 14 Nov 14 olle 1045     while (sampleIterator != null && sampleIterator.hasNext())
2933 14 Nov 14 olle 1046     {
2933 14 Nov 14 olle 1047       Sample s = sampleIterator.next();
2933 14 Nov 14 olle 1048       // Optional project focus filter (true if no filter, or sample passes filter)
2933 14 Nov 14 olle 1049       boolean passedProjectFocusFilter = passProjectFocusFilter(dc, manager, projectFocusFilter, s);
2933 14 Nov 14 olle 1050       if (passedProjectFocusFilter)
2933 14 Nov 14 olle 1051       {
2933 14 Nov 14 olle 1052         // Add sample to list
2933 14 Nov 14 olle 1053         sampleList.add(s);
2933 14 Nov 14 olle 1054       }
2933 14 Nov 14 olle 1055     }
2933 14 Nov 14 olle 1056     return sampleList;
2933 14 Nov 14 olle 1057   }
2933 14 Nov 14 olle 1058
2933 14 Nov 14 olle 1059   /**
2933 14 Nov 14 olle 1060    * Optional project focus filter. Returns 'true' if no filter,
2933 14 Nov 14 olle 1061    * or sample passes filter.
2933 14 Nov 14 olle 1062    * 
2933 14 Nov 14 olle 1063    * @param dc DbControl The DbControl to use.
2933 14 Nov 14 olle 1064    * @param manager SnapshotManager The annotation snapshot manager to use.
2933 14 Nov 14 olle 1065    * @param projectFocusFilter String Optional project focus filter.
2933 14 Nov 14 olle 1066    * @param s Sample The sample to test.
2933 14 Nov 14 olle 1067    * @return boolean Returns 'true' if no filter, or sample passes filter.
2933 14 Nov 14 olle 1068    */
2933 14 Nov 14 olle 1069   private boolean passProjectFocusFilter(DbControl dc, SnapshotManager manager, String projectFocusFilter, Sample s)
2933 14 Nov 14 olle 1070   {
2933 14 Nov 14 olle 1071     boolean passedFilter = true;
2933 14 Nov 14 olle 1072     // Optional project focus filter
3058 19 Dec 14 olle 1073     if (projectFocusFilter != null && !projectFocusFilter.equals(InstallServlet.PROJECTFOCUS_NONE))
2933 14 Nov 14 olle 1074     {
2933 14 Nov 14 olle 1075       // Get project focus annotation
3060 19 Dec 14 olle 1076       String projectFocus = fetchProjectFocus(dc, manager, s);
3058 19 Dec 14 olle 1077       if (projectFocusFilter.equals(InstallServlet.PROJECTFOCUS_UNKNOWN))
2933 14 Nov 14 olle 1078       {
2933 14 Nov 14 olle 1079         // Sample project focus unknown (project focus == null should be included)
2933 14 Nov 14 olle 1080         if (projectFocus != null && !projectFocus.equals(projectFocusFilter))
2933 14 Nov 14 olle 1081         {
2933 14 Nov 14 olle 1082           passedFilter = false;
2933 14 Nov 14 olle 1083         }
2933 14 Nov 14 olle 1084       }
2933 14 Nov 14 olle 1085       else
2933 14 Nov 14 olle 1086       {
2933 14 Nov 14 olle 1087         // Specific project focus (project focus == null should not be included)
2933 14 Nov 14 olle 1088         if (projectFocus == null || !projectFocus.equals(projectFocusFilter))
2933 14 Nov 14 olle 1089         {
2933 14 Nov 14 olle 1090           passedFilter = false;
2933 14 Nov 14 olle 1091         }
2933 14 Nov 14 olle 1092       }
2933 14 Nov 14 olle 1093     }
2933 14 Nov 14 olle 1094     return passedFilter;
2933 14 Nov 14 olle 1095   }
2933 14 Nov 14 olle 1096
2933 14 Nov 14 olle 1097   @SuppressWarnings("unchecked")
2933 14 Nov 14 olle 1098   private JSONObject createJSONPatientsWithMultipleDates(HashMap<String, Set<Date>> stringDateSetHashMap)
2933 14 Nov 14 olle 1099   {
2933 14 Nov 14 olle 1100     JSONObject jsonPatientsWithMultipleDates = new JSONObject();
2933 14 Nov 14 olle 1101     if (stringDateSetHashMap != null)
2933 14 Nov 14 olle 1102     {
2933 14 Nov 14 olle 1103       Set<String> patientNameSet = stringDateSetHashMap.keySet();
2933 14 Nov 14 olle 1104       if (patientNameSet != null)
2933 14 Nov 14 olle 1105       {
2933 14 Nov 14 olle 1106         for (String patient: patientNameSet)
2933 14 Nov 14 olle 1107         {
2933 14 Nov 14 olle 1108           Set<Date> dateSet = stringDateSetHashMap.get(patient);
2933 14 Nov 14 olle 1109           if (dateSet != null && dateSet.size() > 1)
2933 14 Nov 14 olle 1110           {
2933 14 Nov 14 olle 1111             // More than one date
2933 14 Nov 14 olle 1112             JSONObject jsonMultipleDates = new JSONObject();
2933 14 Nov 14 olle 1113             int dateCounter = 0;
2933 14 Nov 14 olle 1114             for (Date date: dateSet)
2933 14 Nov 14 olle 1115             {
2933 14 Nov 14 olle 1116               if (date != null)
2933 14 Nov 14 olle 1117               {
2933 14 Nov 14 olle 1118                 DateToStringConverter converter = new DateToStringConverter(new SimpleDateFormat("yyyy-MM-dd"));
2933 14 Nov 14 olle 1119                 String dateStr = converter.convert(date);
2933 14 Nov 14 olle 1120                 jsonMultipleDates.put(dateCounter, dateStr);
2933 14 Nov 14 olle 1121                 dateCounter++;
2933 14 Nov 14 olle 1122               }
2933 14 Nov 14 olle 1123             }
2933 14 Nov 14 olle 1124             jsonPatientsWithMultipleDates.put(patient, jsonMultipleDates);
2933 14 Nov 14 olle 1125           }
2933 14 Nov 14 olle 1126         }
2933 14 Nov 14 olle 1127       }
2933 14 Nov 14 olle 1128     }
2933 14 Nov 14 olle 1129     return jsonPatientsWithMultipleDates;
2933 14 Nov 14 olle 1130   }
2933 14 Nov 14 olle 1131
2933 14 Nov 14 olle 1132   /**
3060 19 Dec 14 olle 1133    * Returns the site for the sample, based on the site annotation for the case.
2933 14 Nov 14 olle 1134    * 
2933 14 Nov 14 olle 1135    * @param dc DbControl The DbControl to use.
2933 14 Nov 14 olle 1136    * @param manager SnapshotManager The SnapshotManager to use for speeding up annotation retrieval.
2933 14 Nov 14 olle 1137    * @param s Sample The sample to find the site for.
2933 14 Nov 14 olle 1138    * @return Site The site object found for the sample or UNKNOWN.
2933 14 Nov 14 olle 1139    */
3060 19 Dec 14 olle 1140   private Site fetchSite(DbControl dc, SnapshotManager manager, Sample s)
2933 14 Nov 14 olle 1141   {
2933 14 Nov 14 olle 1142     Site site = Site.UNKNOWN;
3028 11 Dec 14 olle 1143     // Find parent case item for sample
3028 11 Dec 14 olle 1144     String prefix = null;
3046 16 Dec 14 olle 1145     if (s != null)
3028 11 Dec 14 olle 1146     {
3060 19 Dec 14 olle 1147       if (s.getItemSubtype().equals(getSubtypeCase()))
3046 16 Dec 14 olle 1148       {
3046 16 Dec 14 olle 1149         prefix = (String) Annotationtype.SITE.getAnnotationValue(dc, manager, s);
3046 16 Dec 14 olle 1150       }
3060 19 Dec 14 olle 1151       else if (s.getItemSubtype().equals(getSubtypeSpecimen()))
3046 16 Dec 14 olle 1152       {
3046 16 Dec 14 olle 1153         Sample theCase = (Sample) s.getParent();
3046 16 Dec 14 olle 1154         if (theCase != null)
3046 16 Dec 14 olle 1155         {
3046 16 Dec 14 olle 1156           prefix = (String) Annotationtype.SITE.getAnnotationValue(dc, manager, theCase);
3046 16 Dec 14 olle 1157         }
3046 16 Dec 14 olle 1158       }
3028 11 Dec 14 olle 1159     }
2933 14 Nov 14 olle 1160     if (prefix != null)
2933 14 Nov 14 olle 1161     {
2933 14 Nov 14 olle 1162       site = Site.findByPrefix(prefix);
2933 14 Nov 14 olle 1163     }
2933 14 Nov 14 olle 1164     return site;
2933 14 Nov 14 olle 1165   }
3060 19 Dec 14 olle 1166
3060 19 Dec 14 olle 1167
3060 19 Dec 14 olle 1168   /**
3060 19 Dec 14 olle 1169    * Returns project focus for the sample, based on the ProjectFocus annotation for the case.
3060 19 Dec 14 olle 1170    * 
3060 19 Dec 14 olle 1171    * @param dc DbControl The DbControl to use.
3060 19 Dec 14 olle 1172    * @param manager SnapshotManager The SnapshotManager to use for speeding up annotation retrieval.
3060 19 Dec 14 olle 1173    * @param s Sample The sample to find the project focus for.
3060 19 Dec 14 olle 1174    * @return String The project focus for the sample, or `null`.
3060 19 Dec 14 olle 1175    */
3060 19 Dec 14 olle 1176   private String fetchProjectFocus(DbControl dc, SnapshotManager manager, Sample s)
3060 19 Dec 14 olle 1177   {
3060 19 Dec 14 olle 1178     String projectFocus = null;
3060 19 Dec 14 olle 1179     // Find parent case item for sample
3060 19 Dec 14 olle 1180     if (s != null)
3060 19 Dec 14 olle 1181     {
3060 19 Dec 14 olle 1182       if (s.getItemSubtype().equals(getSubtypeCase()))
3060 19 Dec 14 olle 1183       {
3060 19 Dec 14 olle 1184         projectFocus = (String) Annotationtype.PROJECT_FOCUS.getAnnotationValue(dc, manager, s);
3060 19 Dec 14 olle 1185       }
3060 19 Dec 14 olle 1186       else if (s.getItemSubtype().equals(getSubtypeSpecimen()))
3060 19 Dec 14 olle 1187       {
3060 19 Dec 14 olle 1188         Sample theCase = (Sample) s.getParent();
3060 19 Dec 14 olle 1189         if (theCase != null)
3060 19 Dec 14 olle 1190         {
3060 19 Dec 14 olle 1191           projectFocus = (String) Annotationtype.PROJECT_FOCUS.getAnnotationValue(dc, manager, theCase);
3060 19 Dec 14 olle 1192         }
3060 19 Dec 14 olle 1193       }
3060 19 Dec 14 olle 1194     }
3060 19 Dec 14 olle 1195     return projectFocus;
3060 19 Dec 14 olle 1196   }
2933 14 Nov 14 olle 1197 }