extensions/net.sf.basedb.meludi/trunk/src/net/sf/basedb/meludi/servlet/ReportTableUtil.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.Calendar;
2933 14 Nov 14 olle 6 import java.util.Collection;
2933 14 Nov 14 olle 7 import java.util.Collections;
2933 14 Nov 14 olle 8 import java.util.Comparator;
2933 14 Nov 14 olle 9 import java.util.Date;
2933 14 Nov 14 olle 10 import java.util.GregorianCalendar;
2933 14 Nov 14 olle 11 import java.util.HashMap;
2933 14 Nov 14 olle 12 import java.util.ArrayList;
2933 14 Nov 14 olle 13 import java.util.List;
2933 14 Nov 14 olle 14 import java.util.HashSet;
2933 14 Nov 14 olle 15 import java.util.Iterator;
2933 14 Nov 14 olle 16 import java.util.Set;
2933 14 Nov 14 olle 17
2933 14 Nov 14 olle 18 import javax.servlet.ServletException;
2933 14 Nov 14 olle 19 import net.sf.basedb.core.BioMaterial;
2933 14 Nov 14 olle 20 import net.sf.basedb.core.BioMaterialEvent;
2933 14 Nov 14 olle 21 import net.sf.basedb.core.DbControl;
3028 11 Dec 14 olle 22 import net.sf.basedb.core.ItemSubtype;
2933 14 Nov 14 olle 23 import net.sf.basedb.core.Sample;
2933 14 Nov 14 olle 24 import net.sf.basedb.core.snapshot.SnapshotManager;
2933 14 Nov 14 olle 25 import net.sf.basedb.meludi.Meludi;
2933 14 Nov 14 olle 26 import net.sf.basedb.meludi.Site;
2933 14 Nov 14 olle 27 import net.sf.basedb.meludi.converter.DateToStringConverter;
2933 14 Nov 14 olle 28 import net.sf.basedb.meludi.dao.Annotationtype;
3028 11 Dec 14 olle 29 import net.sf.basedb.meludi.dao.Subtype;
2933 14 Nov 14 olle 30
2933 14 Nov 14 olle 31 import org.json.simple.JSONArray;
2933 14 Nov 14 olle 32 import org.json.simple.JSONObject;
2933 14 Nov 14 olle 33
2933 14 Nov 14 olle 34 public class ReportTableUtil
2933 14 Nov 14 olle 35 {
2933 14 Nov 14 olle 36
2933 14 Nov 14 olle 37   public static final String weekView = "WEEK";
2933 14 Nov 14 olle 38   public static final String monthView = "MONTH";
2933 14 Nov 14 olle 39   public static final String quarterView = "QUARTER";
2933 14 Nov 14 olle 40   public static final String yearView = "YEAR";
2933 14 Nov 14 olle 41   public static final String autoView = "AUTO";
2933 14 Nov 14 olle 42   
2933 14 Nov 14 olle 43   public static final int weekViewLimit = 3;
2933 14 Nov 14 olle 44   public static final int monthViewLimit = 13;
2933 14 Nov 14 olle 45   public static final int quarterViewLimit= 3;
2933 14 Nov 14 olle 46   
2933 14 Nov 14 olle 47   public ReportTableUtil()
2933 14 Nov 14 olle 48   {}
2933 14 Nov 14 olle 49
2933 14 Nov 14 olle 50
2933 14 Nov 14 olle 51   /**
2933 14 Nov 14 olle 52    *  Returns a JSONObject with item id values for item name keys updated with a new item.
2933 14 Nov 14 olle 53    *  
2933 14 Nov 14 olle 54    *  @param jsonObject JSONObject The JSONObject with item id values for item name keys to update.
2933 14 Nov 14 olle 55    *  @param item BioMaterial The BioMaterial item to update the JSONObject with.
2933 14 Nov 14 olle 56    *  @return JSONObject The JSONObject with item id values for item name keys updated with the new item.
2933 14 Nov 14 olle 57    */
2933 14 Nov 14 olle 58   @SuppressWarnings({ "unchecked", "rawtypes" })
2933 14 Nov 14 olle 59   public JSONObject updateJSONItemnameItemid(JSONObject jsonObject, BioMaterial item)
2933 14 Nov 14 olle 60   {
2933 14 Nov 14 olle 61     // Increase the counter for current key for the site
2933 14 Nov 14 olle 62     if (jsonObject == null)
2933 14 Nov 14 olle 63     {
2933 14 Nov 14 olle 64       jsonObject = new JSONObject();
2933 14 Nov 14 olle 65     }
2933 14 Nov 14 olle 66     if (item != null)
2933 14 Nov 14 olle 67     {
2933 14 Nov 14 olle 68       int itemId = item.getId();
2933 14 Nov 14 olle 69       String itemIdStr = Integer.toString(itemId);
2933 14 Nov 14 olle 70       jsonObject.put(item.getName(), itemIdStr);
2933 14 Nov 14 olle 71     }
2933 14 Nov 14 olle 72     return jsonObject;
2933 14 Nov 14 olle 73   }
2933 14 Nov 14 olle 74
2933 14 Nov 14 olle 75   /**
2933 14 Nov 14 olle 76    *  Returns true if a given date exists in the HashMap date set for the specified string key, else false.
2933 14 Nov 14 olle 77    *
2933 14 Nov 14 olle 78    *  @param stringDateSetHashMap HashMap<String, Set<Date>> The HashMap to check.
2933 14 Nov 14 olle 79    *  @param string String The string key.
2933 14 Nov 14 olle 80    *  @param date Date The date to check if it exists in the HashMap date set for the specified string key.
2933 14 Nov 14 olle 81    *  @return Boolean Returns true if the date exists in the HashMap date set for the specified string key, else false.
2933 14 Nov 14 olle 82    */
2933 14 Nov 14 olle 83   public Boolean inStringDateSetHashMap(HashMap<String, Set<Date>> stringDateSetHashMap, String string, Date date)
2933 14 Nov 14 olle 84   {
2933 14 Nov 14 olle 85     Boolean inHashMap = false;
2933 14 Nov 14 olle 86     if (stringDateSetHashMap != null && string != null && !string.equals("") && date != null)
2933 14 Nov 14 olle 87     {
2933 14 Nov 14 olle 88       Set<Date> dateSet = stringDateSetHashMap.get(string);
2933 14 Nov 14 olle 89       if (dateSet != null)
2933 14 Nov 14 olle 90       {
2933 14 Nov 14 olle 91         for (Date d: dateSet)
2933 14 Nov 14 olle 92         {
2933 14 Nov 14 olle 93           if (date.equals(d))
2933 14 Nov 14 olle 94           {
2933 14 Nov 14 olle 95             inHashMap = true;
2933 14 Nov 14 olle 96             break;
2933 14 Nov 14 olle 97           }
2933 14 Nov 14 olle 98         }
2933 14 Nov 14 olle 99       }
2933 14 Nov 14 olle 100     }
2933 14 Nov 14 olle 101     return inHashMap;
2933 14 Nov 14 olle 102   }
2933 14 Nov 14 olle 103
2933 14 Nov 14 olle 104   /**
2933 14 Nov 14 olle 105    *  Returns a HashMap updated with the new date in the date set for the specified string key.
2933 14 Nov 14 olle 106    *
2933 14 Nov 14 olle 107    *  @param stringDateSetHashMap HashMap<String, Set<Date>> The HashMap to update.
2933 14 Nov 14 olle 108    *  @param string String The string key for the sample.
2933 14 Nov 14 olle 109    *  @param date Date The date to update the date set for the specified string key in the HashMap with.
2933 14 Nov 14 olle 110    *  @return HashMap<String, Sample> A HashMap updated with the new date in the date set for the specified string key.
2933 14 Nov 14 olle 111    */
2933 14 Nov 14 olle 112   public HashMap<String, Set<Date>> updateStringDateSetHashMap(HashMap<String, Set<Date>> stringDateSetHashMap, String string, Date date)
2933 14 Nov 14 olle 113   {
2933 14 Nov 14 olle 114     if (stringDateSetHashMap == null)
2933 14 Nov 14 olle 115     {
2933 14 Nov 14 olle 116       stringDateSetHashMap = new HashMap<String, Set<Date>>();
2933 14 Nov 14 olle 117     }
2933 14 Nov 14 olle 118     if (string != null && !string.equals("") && date != null)
2933 14 Nov 14 olle 119     {
2933 14 Nov 14 olle 120       Set<Date> dateSet = stringDateSetHashMap.get(string);
2933 14 Nov 14 olle 121       Boolean dateInSet = false;
2933 14 Nov 14 olle 122       if (dateSet != null)
2933 14 Nov 14 olle 123       {
2933 14 Nov 14 olle 124         for (Date d: dateSet)
2933 14 Nov 14 olle 125         {
2933 14 Nov 14 olle 126           if (date.equals(d))
2933 14 Nov 14 olle 127           {
2933 14 Nov 14 olle 128             dateInSet = true;
2933 14 Nov 14 olle 129             break;
2933 14 Nov 14 olle 130           }
2933 14 Nov 14 olle 131         }
2933 14 Nov 14 olle 132       }
2933 14 Nov 14 olle 133       if (!dateInSet)
2933 14 Nov 14 olle 134       {
2933 14 Nov 14 olle 135         if (dateSet == null)
2933 14 Nov 14 olle 136         {
2933 14 Nov 14 olle 137           dateSet = new HashSet<Date>();
2933 14 Nov 14 olle 138         }
2933 14 Nov 14 olle 139         dateSet.add(date);
2933 14 Nov 14 olle 140         stringDateSetHashMap.put(string,  dateSet);
2933 14 Nov 14 olle 141       }
2933 14 Nov 14 olle 142     }
2933 14 Nov 14 olle 143     return stringDateSetHashMap;
2933 14 Nov 14 olle 144   }
2933 14 Nov 14 olle 145
2933 14 Nov 14 olle 146   /**
2933 14 Nov 14 olle 147    *  Returns an updated HashMap for the sample with earliest date for specified string key.
2933 14 Nov 14 olle 148    *
2933 14 Nov 14 olle 149    *  @param stringSampleHashMap HashMap<String, Sample> The HashMap to update.
2933 14 Nov 14 olle 150    *  @param string String The string key for the sample.
2933 14 Nov 14 olle 151    *  @param sample Sample The sample to update the HashMap with, if the sample date is earlier than the stored sample for the specified key.
2933 14 Nov 14 olle 152    *  @return HashMap<String, Sample> An updated HashMap for the sample with earliest date for specified string key.
2933 14 Nov 14 olle 153    */
2933 14 Nov 14 olle 154   public HashMap<String, Sample> updateStringEarliestSampleHashMap(HashMap<String, Sample> stringSampleHashMap, String string, Sample sample)
2933 14 Nov 14 olle 155   {
2933 14 Nov 14 olle 156     if (stringSampleHashMap == null)
2933 14 Nov 14 olle 157     {
2933 14 Nov 14 olle 158       stringSampleHashMap = new HashMap<String, Sample>();
2933 14 Nov 14 olle 159     }
2933 14 Nov 14 olle 160     if (string != null && !string.equals(""))
2933 14 Nov 14 olle 161     {
2933 14 Nov 14 olle 162       // Store the sample with the earliest date for the item defined by string
2933 14 Nov 14 olle 163       Sample storedSample = stringSampleHashMap.get(string);
2933 14 Nov 14 olle 164       Date sampleDate = null;
2933 14 Nov 14 olle 165       Date storedSampleDate = null;
2933 14 Nov 14 olle 166       if (sample != null)
2933 14 Nov 14 olle 167       {
2933 14 Nov 14 olle 168         BioMaterialEvent creationEvent = sample.getCreationEvent();
2933 14 Nov 14 olle 169         sampleDate = creationEvent.getEventDate();
2933 14 Nov 14 olle 170       }
2933 14 Nov 14 olle 171       if (storedSample != null)
2933 14 Nov 14 olle 172       {
2933 14 Nov 14 olle 173         BioMaterialEvent creationEvent = storedSample.getCreationEvent();
2933 14 Nov 14 olle 174         storedSampleDate = creationEvent.getEventDate();
2933 14 Nov 14 olle 175       }
2933 14 Nov 14 olle 176       if (sampleDate != null)
2933 14 Nov 14 olle 177       {
2933 14 Nov 14 olle 178         if (storedSampleDate != null)
2933 14 Nov 14 olle 179         {
2933 14 Nov 14 olle 180           if (sampleDate.before(storedSampleDate))
2933 14 Nov 14 olle 181           {
2933 14 Nov 14 olle 182             // New sample date earlier, store that sample for patient
2933 14 Nov 14 olle 183             stringSampleHashMap.put(string, sample);
2933 14 Nov 14 olle 184           }
2933 14 Nov 14 olle 185         }
2933 14 Nov 14 olle 186         else
2933 14 Nov 14 olle 187         {
2933 14 Nov 14 olle 188           // No stored sample; store new sample for patient
2933 14 Nov 14 olle 189           stringSampleHashMap.put(string, sample);
2933 14 Nov 14 olle 190         }
2933 14 Nov 14 olle 191       }
2933 14 Nov 14 olle 192     }
2933 14 Nov 14 olle 193     return stringSampleHashMap;
2933 14 Nov 14 olle 194   }
2933 14 Nov 14 olle 195
2933 14 Nov 14 olle 196   /**
2933 14 Nov 14 olle 197    *  Creates a JSONObject with sample statistics for input data.
2933 14 Nov 14 olle 198    *
2933 14 Nov 14 olle 199    *  @param sampleIterator Iterator<Sample> An iterator for the sample data.
2933 14 Nov 14 olle 200    *  @param startDate Date The start date for the JSONObject periods.
2933 14 Nov 14 olle 201    *  @param endDate Date The end date for the JSONObject periods.
2933 14 Nov 14 olle 202    *  @param viewType String The view type to use.
2933 14 Nov 14 olle 203    *  @return JSONObject A JSONObject with sample statistics for input data.
2933 14 Nov 14 olle 204    */
2933 14 Nov 14 olle 205   @SuppressWarnings("unchecked")
2933 14 Nov 14 olle 206   public JSONObject createJSONStatistics(DbControl dc, Iterator<Sample> sampleIterator, Date startDate, Date endDate, String viewType)
2933 14 Nov 14 olle 207     throws ServletException, IOException 
2933 14 Nov 14 olle 208   {  
2933 14 Nov 14 olle 209     Date latestDate = null;
2933 14 Nov 14 olle 210     JSONObject jsonStatistics = new JSONObject();
2933 14 Nov 14 olle 211     JSONObject jsonSitesCombined = new JSONObject();
2933 14 Nov 14 olle 212     Date dataStartDate = fetchEarliestSiteStartDate();
2933 14 Nov 14 olle 213     jsonSitesCombined = initializeJSONPeriodData(jsonSitesCombined, startDate, endDate, dataStartDate, viewType);
2933 14 Nov 14 olle 214     String sitesCombinedKey = "sitesCombinedKey";
2933 14 Nov 14 olle 215     String sumSiteKey = "sumSiteKey";
2933 14 Nov 14 olle 216     String sumKey = "sumKey";
2933 14 Nov 14 olle 217     String totalSiteKey = "totalSiteKey";
2933 14 Nov 14 olle 218     String totalKey = "totalKey";
2933 14 Nov 14 olle 219     String latestDateKey = "latestDateKey";
2933 14 Nov 14 olle 220     jsonStatistics.put(sitesCombinedKey, jsonSitesCombined);
3028 11 Dec 14 olle 221     // Get item subtype constants for later use
3028 11 Dec 14 olle 222     ItemSubtype subtypeSpecimen = Subtype.SPECIMEN.load(dc);
3028 11 Dec 14 olle 223     ItemSubtype subtypeCase = Subtype.CASE.load(dc);
2933 14 Nov 14 olle 224     // Use stored annotation snapshots for performance reasons
2933 14 Nov 14 olle 225     SnapshotManager manager = new SnapshotManager();        
2933 14 Nov 14 olle 226     // Create HashMap to keep track of latest sample date for each site
2933 14 Nov 14 olle 227     HashMap<String, Date> sitePrefixDateHashMap = new HashMap<String, Date>();
2933 14 Nov 14 olle 228     while (sampleIterator.hasNext())
2933 14 Nov 14 olle 229     {
2933 14 Nov 14 olle 230       Sample s = sampleIterator.next();
2933 14 Nov 14 olle 231       BioMaterialEvent creationEvent = s.getCreationEvent();
2933 14 Nov 14 olle 232       Date creationDate = creationEvent.getEventDate();
2933 14 Nov 14 olle 233
3028 11 Dec 14 olle 234       Site site = fetchSite(dc, manager, subtypeCase, subtypeSpecimen, s);
2933 14 Nov 14 olle 235       if (site == Site.UNKNOWN)
2933 14 Nov 14 olle 236       {
2933 14 Nov 14 olle 237         String key = "unknownSite";
2933 14 Nov 14 olle 238         jsonStatistics = updateJSONObjectCounter(jsonStatistics, key);
2933 14 Nov 14 olle 239         // Change site to be able to add the unknown site to statistics
2933 14 Nov 14 olle 240         site = Site.UNKNOWN_RPT;
2933 14 Nov 14 olle 241       }
2933 14 Nov 14 olle 242       // Get site info            
2933 14 Nov 14 olle 243       JSONObject jsonSite = (JSONObject)jsonStatistics.get(site.getPrefix());
2933 14 Nov 14 olle 244       if (jsonSite == null)
2933 14 Nov 14 olle 245       {
2933 14 Nov 14 olle 246         jsonSite = new JSONObject();
2933 14 Nov 14 olle 247         jsonStatistics.put(site.getPrefix(), jsonSite);
2933 14 Nov 14 olle 248       }
2933 14 Nov 14 olle 249               
2933 14 Nov 14 olle 250       if (creationDate != null)
2933 14 Nov 14 olle 251       {
2933 14 Nov 14 olle 252         if ((creationDate.after(startDate) || creationDate.equals(startDate)) &&
2933 14 Nov 14 olle 253             (creationDate.before(endDate) || creationDate.equals(endDate)))
2933 14 Nov 14 olle 254         {
2933 14 Nov 14 olle 255           // Increase the counter for current period on the site
2933 14 Nov 14 olle 256           String currentPeriod = getCurrentPeriod(creationDate, viewType);                        
2933 14 Nov 14 olle 257           jsonSite = updateJSONObjectCounter(jsonSite, currentPeriod);
2933 14 Nov 14 olle 258           jsonSitesCombined = updateJSONObjectCounter(jsonSitesCombined, currentPeriod);
2933 14 Nov 14 olle 259                     
2933 14 Nov 14 olle 260           // Increase the counter for samples for the site for the selected time period
2933 14 Nov 14 olle 261           jsonSite = updateJSONObjectCounter(jsonSite, sumSiteKey);
2933 14 Nov 14 olle 262
2933 14 Nov 14 olle 263           // Increase the counter for samples for all sites for the selected time period
2933 14 Nov 14 olle 264           jsonStatistics = updateJSONObjectCounter(jsonStatistics, sumKey);
2933 14 Nov 14 olle 265
2933 14 Nov 14 olle 266           // Find out if current creation-date is the latest so far.
2933 14 Nov 14 olle 267           if (latestDate == null || latestDate.before(creationDate)) 
2933 14 Nov 14 olle 268           {
2933 14 Nov 14 olle 269             latestDate = creationDate;
2933 14 Nov 14 olle 270           }
2933 14 Nov 14 olle 271         }
2933 14 Nov 14 olle 272
2933 14 Nov 14 olle 273         // Keep track of latest sample date for site
2933 14 Nov 14 olle 274         Date siteLatestDate = sitePrefixDateHashMap.get(site.getPrefix());
2933 14 Nov 14 olle 275         if (siteLatestDate == null || siteLatestDate.before(creationDate))
2933 14 Nov 14 olle 276         {
2933 14 Nov 14 olle 277           sitePrefixDateHashMap.put(site.getPrefix(), creationDate);
2933 14 Nov 14 olle 278         }
2933 14 Nov 14 olle 279       }
2933 14 Nov 14 olle 280       else
2933 14 Nov 14 olle 281       {
2933 14 Nov 14 olle 282         String noDateKey = "noDate";
2933 14 Nov 14 olle 283         jsonStatistics = updateJSONObjectCounter(jsonStatistics, noDateKey);
2933 14 Nov 14 olle 284       }
2933 14 Nov 14 olle 285
2933 14 Nov 14 olle 286       // Increase the counter for total samples for the site, regardless of creation date
2933 14 Nov 14 olle 287       jsonSite = updateJSONObjectCounter(jsonSite, totalSiteKey);
2933 14 Nov 14 olle 288
2933 14 Nov 14 olle 289       // Increase the counter for total samples for all sites
2933 14 Nov 14 olle 290       jsonStatistics = updateJSONObjectCounter(jsonStatistics, totalKey);
2933 14 Nov 14 olle 291     }
2933 14 Nov 14 olle 292     // Add latest sample date for site to site JSON object
2933 14 Nov 14 olle 293     DateToStringConverter date2StringConverter = Meludi.CONVERTER_DATE_TO_STRING;
2933 14 Nov 14 olle 294     for (Site s: Site.getAllReportSites())
2933 14 Nov 14 olle 295     {
2933 14 Nov 14 olle 296         JSONObject jsonSite = (JSONObject) jsonStatistics.get(s.getPrefix());
2933 14 Nov 14 olle 297         if (jsonSite == null)
2933 14 Nov 14 olle 298         {
2933 14 Nov 14 olle 299           jsonSite = new JSONObject();
2933 14 Nov 14 olle 300           jsonStatistics.put(s.getPrefix(), jsonSite);
2933 14 Nov 14 olle 301         }
2933 14 Nov 14 olle 302         Date siteLatestDate = sitePrefixDateHashMap.get(s.getPrefix());
2933 14 Nov 14 olle 303         jsonSite.put(latestDateKey, date2StringConverter.convert(siteLatestDate));
2933 14 Nov 14 olle 304     }
2933 14 Nov 14 olle 305     // Add latest date for further transfer to other JSON object
2933 14 Nov 14 olle 306     jsonStatistics.put(latestDateKey, date2StringConverter.convert(latestDate));
2933 14 Nov 14 olle 307     return jsonStatistics;        
2933 14 Nov 14 olle 308   }
2933 14 Nov 14 olle 309
2933 14 Nov 14 olle 310   /**
2933 14 Nov 14 olle 311    * Returns the site for the sample, based on the latter's site annotation.
2933 14 Nov 14 olle 312    * 
2933 14 Nov 14 olle 313    * @param dc DbControl The DbControl to use.
2933 14 Nov 14 olle 314    * @param manager SnapshotManager The SnapshotManager to use for speeding up annotation retrieval.
3028 11 Dec 14 olle 315    * @param subtypeCase ItemSubtype The item subtype for case items.
3028 11 Dec 14 olle 316    * @param subtypeSpecimen ItemSubtype The item subtype for specimen items.
2933 14 Nov 14 olle 317    * @param s Sample The sample to find the site for.
2933 14 Nov 14 olle 318    * @return Site The site object found for the sample or UNKNOWN.
2933 14 Nov 14 olle 319    */
3028 11 Dec 14 olle 320   private Site fetchSite(DbControl dc, SnapshotManager manager, ItemSubtype subtypeCase, ItemSubtype subtypeSpecimen, Sample s)
2933 14 Nov 14 olle 321   {
2933 14 Nov 14 olle 322     Site site = Site.UNKNOWN;
3028 11 Dec 14 olle 323     // Find parent case item for sample
3028 11 Dec 14 olle 324     String prefix = null;
3046 16 Dec 14 olle 325     if (s != null)
3028 11 Dec 14 olle 326     {
3046 16 Dec 14 olle 327       if (s.getItemSubtype().equals(subtypeCase))
3046 16 Dec 14 olle 328       {
3046 16 Dec 14 olle 329         prefix = (String) Annotationtype.SITE.getAnnotationValue(dc, manager, s);
3046 16 Dec 14 olle 330       }
3046 16 Dec 14 olle 331       else if (s.getItemSubtype().equals(subtypeSpecimen))
3046 16 Dec 14 olle 332       {
3046 16 Dec 14 olle 333         Sample theCase = (Sample) s.getParent();
3046 16 Dec 14 olle 334         if (theCase != null)
3046 16 Dec 14 olle 335         {
3046 16 Dec 14 olle 336           prefix = (String) Annotationtype.SITE.getAnnotationValue(dc, manager, theCase);
3046 16 Dec 14 olle 337         }
3046 16 Dec 14 olle 338       }
3028 11 Dec 14 olle 339     }
2933 14 Nov 14 olle 340     if (prefix != null)
2933 14 Nov 14 olle 341     {
2933 14 Nov 14 olle 342       site = Site.findByPrefix(prefix);
2933 14 Nov 14 olle 343     }
2933 14 Nov 14 olle 344     return site;
2933 14 Nov 14 olle 345   }
2933 14 Nov 14 olle 346
2933 14 Nov 14 olle 347
2933 14 Nov 14 olle 348   /**
2933 14 Nov 14 olle 349    *  Returns JSONObject with incremented integer value counter for specified key.
2933 14 Nov 14 olle 350    *
2933 14 Nov 14 olle 351    *  @param jsonObject JSONObject The JSONObject with integer value counter for specified key.
2933 14 Nov 14 olle 352    *  @param key String The JSON key for the integer value counter.
2933 14 Nov 14 olle 353    *  @return JSONObject The JSONObject with incremented integer value counter for specified key.
2933 14 Nov 14 olle 354    */
2933 14 Nov 14 olle 355   @SuppressWarnings("unchecked")
2933 14 Nov 14 olle 356   public JSONObject updateJSONObjectCounter(JSONObject jsonObject, String key)
2933 14 Nov 14 olle 357   {
2933 14 Nov 14 olle 358     // Increase the counter for current key for the site
2933 14 Nov 14 olle 359     Integer counter = (Integer)jsonObject.get(key);
2933 14 Nov 14 olle 360     if (counter == null)
2933 14 Nov 14 olle 361     {
2933 14 Nov 14 olle 362       counter = 0;
2933 14 Nov 14 olle 363     }
2933 14 Nov 14 olle 364     counter++;
2933 14 Nov 14 olle 365     jsonObject.put(key, counter);
2933 14 Nov 14 olle 366     return jsonObject;
2933 14 Nov 14 olle 367   }
2933 14 Nov 14 olle 368
2933 14 Nov 14 olle 369   /**
2933 14 Nov 14 olle 370    *  Returns container JSONObject with site JSONObjects having values for specified key being initialized to 0.
2933 14 Nov 14 olle 371    *
2933 14 Nov 14 olle 372    *  @param jsonSiteContainerObject JSONObject The optional JSONObject to use (if null, a new JSONObject will be created).
2933 14 Nov 14 olle 373    *  @param key String The JSON key for which the site JSONObject values will be initialized to 0.
2933 14 Nov 14 olle 374    *  @return JSONObject A container JSONObject with site JSONObjects having values for specified key being initialized to 0.
2933 14 Nov 14 olle 375    */
2933 14 Nov 14 olle 376   @SuppressWarnings("unchecked")
2933 14 Nov 14 olle 377   public JSONObject initializeJSONSiteData(JSONObject jsonSiteContainerObject, String key)
2933 14 Nov 14 olle 378   {
2933 14 Nov 14 olle 379     if (jsonSiteContainerObject == null)
2933 14 Nov 14 olle 380     {
2933 14 Nov 14 olle 381       jsonSiteContainerObject = new JSONObject();
2933 14 Nov 14 olle 382     }
2933 14 Nov 14 olle 383     for (Site site: Site.getAllReportSites())
2933 14 Nov 14 olle 384     {
2933 14 Nov 14 olle 385       // Get JSON site object
2933 14 Nov 14 olle 386       JSONObject jsonSite = (JSONObject)jsonSiteContainerObject.get(site.getPrefix());
2933 14 Nov 14 olle 387       if (jsonSite == null)
2933 14 Nov 14 olle 388       {
2933 14 Nov 14 olle 389         jsonSite = new JSONObject();
2933 14 Nov 14 olle 390         jsonSiteContainerObject.put(site.getPrefix(), jsonSite);
2933 14 Nov 14 olle 391       }
2933 14 Nov 14 olle 392       // Set site data for key to 0
2933 14 Nov 14 olle 393       jsonSite.put(key, 0);
2933 14 Nov 14 olle 394     }
2933 14 Nov 14 olle 395     return jsonSiteContainerObject;
2933 14 Nov 14 olle 396   }
2933 14 Nov 14 olle 397
2933 14 Nov 14 olle 398   /**
2933 14 Nov 14 olle 399    *  Returns a JSONObject with period strings as keys and values set to 0 for periods after a given data start date.
2933 14 Nov 14 olle 400    *
2933 14 Nov 14 olle 401    *  @param jsonObject JSONObject The optional JSONObject to use (if null, a new JSONObject will be created).
2933 14 Nov 14 olle 402    *  @param startDate Date The start date for the JSONObject periods.
2933 14 Nov 14 olle 403    *  @param endDate Date The end date for the JSONObject periods.
2933 14 Nov 14 olle 404    *  @param dataStartDate Date The first date after which period date values will be initialized to 0. 
2933 14 Nov 14 olle 405    *  @param viewType String The view type to use.
2933 14 Nov 14 olle 406    *  @return JSONObject A JSONObject with period strings as keys and values set to 0.
2933 14 Nov 14 olle 407    */
2933 14 Nov 14 olle 408   @SuppressWarnings("unchecked")
2933 14 Nov 14 olle 409   public JSONObject initializeJSONPeriodData(JSONObject jsonObject, Date startDate, Date endDate, Date dataStartDate, String viewType)
2933 14 Nov 14 olle 410   {
2933 14 Nov 14 olle 411     if (jsonObject == null)
2933 14 Nov 14 olle 412     {
2933 14 Nov 14 olle 413       jsonObject = new JSONObject();
2933 14 Nov 14 olle 414     }
2933 14 Nov 14 olle 415     if (startDate != null && endDate != null)
2933 14 Nov 14 olle 416     {
2933 14 Nov 14 olle 417       // Fill period slots with zeroes beginning with the dataStartDate
2933 14 Nov 14 olle 418       List<Date> sortedPeriodEndDateList = createSortedPeriodEndDateList(startDate, endDate, viewType);
2933 14 Nov 14 olle 419       for (Date d: sortedPeriodEndDateList)
2933 14 Nov 14 olle 420       {
2933 14 Nov 14 olle 421         if (dataStartDate != null)
2933 14 Nov 14 olle 422         {
2933 14 Nov 14 olle 423           if (d.after(dataStartDate))
2933 14 Nov 14 olle 424           {
2933 14 Nov 14 olle 425             // Set data for period to 0
2933 14 Nov 14 olle 426             String currentPeriod = getCurrentPeriod(d, viewType);
2933 14 Nov 14 olle 427             jsonObject.put(currentPeriod, 0);
2933 14 Nov 14 olle 428           }
2933 14 Nov 14 olle 429         }
2933 14 Nov 14 olle 430       }
2933 14 Nov 14 olle 431     }
2933 14 Nov 14 olle 432     return jsonObject;
2933 14 Nov 14 olle 433   }
2933 14 Nov 14 olle 434
2933 14 Nov 14 olle 435   /**
2933 14 Nov 14 olle 436    *  Returns a JSONArray with all sites 
2933 14 Nov 14 olle 437    * 
2933 14 Nov 14 olle 438    *  @return String A JSONObject with site prefix as key and site JSON data as value.
2933 14 Nov 14 olle 439    */
2933 14 Nov 14 olle 440   @SuppressWarnings("unchecked")
2933 14 Nov 14 olle 441   public static JSONArray getJSONSites(Comparator<Site> comparator)
2933 14 Nov 14 olle 442   {
2933 14 Nov 14 olle 443     Collection<Site> sites = Site.getAllSites();
2933 14 Nov 14 olle 444     if (comparator != null)
2933 14 Nov 14 olle 445     {
2933 14 Nov 14 olle 446       List<Site> list = new ArrayList<Site>(sites);
2933 14 Nov 14 olle 447       Collections.sort(list, comparator);
2933 14 Nov 14 olle 448       sites = list;
2933 14 Nov 14 olle 449     }
2933 14 Nov 14 olle 450
2933 14 Nov 14 olle 451     JSONArray jsonSites = new JSONArray();
2933 14 Nov 14 olle 452     for (Site s : sites)
2933 14 Nov 14 olle 453     {
2933 14 Nov 14 olle 454       jsonSites.add(s.asJSONObject());
2933 14 Nov 14 olle 455     }
2933 14 Nov 14 olle 456     return jsonSites;
2933 14 Nov 14 olle 457   }
2933 14 Nov 14 olle 458
2933 14 Nov 14 olle 459
2933 14 Nov 14 olle 460   /**
2933 14 Nov 14 olle 461    *  Gets period string given date and view type.
2933 14 Nov 14 olle 462    *
2933 14 Nov 14 olle 463    *  @param currentDate Date The date to get period string for.
2933 14 Nov 14 olle 464    *  @param viewType String The view type to use.
2933 14 Nov 14 olle 465    *  @return String The period string for the given date and view type.
2933 14 Nov 14 olle 466    */
2933 14 Nov 14 olle 467   public String getCurrentPeriod(Date currentDate, String viewType) 
2933 14 Nov 14 olle 468   {    
2933 14 Nov 14 olle 469     String currentPeriod = null;
2933 14 Nov 14 olle 470     if (viewType.equals(quarterView))
2933 14 Nov 14 olle 471     {
2933 14 Nov 14 olle 472       DateToStringConverter converter = new DateToStringConverter(new SimpleDateFormat("yyyy"));
2933 14 Nov 14 olle 473       currentPeriod = converter.convert(currentDate);
2933 14 Nov 14 olle 474       Calendar cal = GregorianCalendar.getInstance();
2933 14 Nov 14 olle 475       cal.setTime(currentDate);
2933 14 Nov 14 olle 476       int month = cal.get(Calendar.MONTH);
2933 14 Nov 14 olle 477       if (month < 3) 
2933 14 Nov 14 olle 478       {
2933 14 Nov 14 olle 479         currentPeriod += "1";
2933 14 Nov 14 olle 480       }
2933 14 Nov 14 olle 481       else if (month < 6) 
2933 14 Nov 14 olle 482       {
2933 14 Nov 14 olle 483         currentPeriod += "2";
2933 14 Nov 14 olle 484       }
2933 14 Nov 14 olle 485       else if (month < 9) 
2933 14 Nov 14 olle 486       {
2933 14 Nov 14 olle 487         currentPeriod +="3";
2933 14 Nov 14 olle 488       }
2933 14 Nov 14 olle 489       else
2933 14 Nov 14 olle 490       {
2933 14 Nov 14 olle 491         currentPeriod += "4";
2933 14 Nov 14 olle 492       }
2933 14 Nov 14 olle 493     }
2933 14 Nov 14 olle 494     else if (viewType.equals(weekView))
2933 14 Nov 14 olle 495     {
2933 14 Nov 14 olle 496       // Get year number
2933 14 Nov 14 olle 497       DateToStringConverter converter = new DateToStringConverter(new SimpleDateFormat("yyyy"));
2933 14 Nov 14 olle 498       currentPeriod = converter.convert(currentDate);
2933 14 Nov 14 olle 499       // Use Calendar to get ISO week number
2933 14 Nov 14 olle 500       Calendar cal = GregorianCalendar.getInstance();
2933 14 Nov 14 olle 501       cal.setFirstDayOfWeek(Calendar.MONDAY);
2933 14 Nov 14 olle 502       cal.setMinimalDaysInFirstWeek(4);
2933 14 Nov 14 olle 503       cal.setTime(currentDate);
2933 14 Nov 14 olle 504       int week = cal.get(Calendar.WEEK_OF_YEAR);
2933 14 Nov 14 olle 505       // Add week number to year number to get week in "yyyyww" format  with leading 0 if needed
2933 14 Nov 14 olle 506       if (week < 10)
2933 14 Nov 14 olle 507       {
2933 14 Nov 14 olle 508         currentPeriod += "0" + Integer.toString(week);
2933 14 Nov 14 olle 509       }
2933 14 Nov 14 olle 510       else
2933 14 Nov 14 olle 511       {
2933 14 Nov 14 olle 512         currentPeriod += Integer.toString(week);
2933 14 Nov 14 olle 513       }
2933 14 Nov 14 olle 514     }
2933 14 Nov 14 olle 515     else
2933 14 Nov 14 olle 516     {      
2933 14 Nov 14 olle 517       String dateFormat = null;
2933 14 Nov 14 olle 518       if (viewType.equals(monthView)) 
2933 14 Nov 14 olle 519       {
2933 14 Nov 14 olle 520         dateFormat = "yyyyMM";
2933 14 Nov 14 olle 521       }
2933 14 Nov 14 olle 522       else 
2933 14 Nov 14 olle 523       {
2933 14 Nov 14 olle 524         dateFormat = "yyyy";
2933 14 Nov 14 olle 525       }
2933 14 Nov 14 olle 526       DateToStringConverter converter = new DateToStringConverter(new SimpleDateFormat(dateFormat));
2933 14 Nov 14 olle 527       currentPeriod = converter.convert(currentDate);
2933 14 Nov 14 olle 528     }
2933 14 Nov 14 olle 529     
2933 14 Nov 14 olle 530     return currentPeriod;
2933 14 Nov 14 olle 531   }
2933 14 Nov 14 olle 532
2933 14 Nov 14 olle 533   /**
2933 14 Nov 14 olle 534    *  Gets view type string for given start and end dates.
2933 14 Nov 14 olle 535    *  The view type is determined by the first of the following conditions, that is true:<BR>
2933 14 Nov 14 olle 536    *  1. Period shorter than 3 months - week view.<BR>
2933 14 Nov 14 olle 537    *  2. Period shorter than 13 months - month view.<BR>
2933 14 Nov 14 olle 538    *  3. Period shorter than 3 years - quarter view.<BR>
2933 14 Nov 14 olle 539    *  4. Period is 3 years or greater - year view.<BR>
2933 14 Nov 14 olle 540    *
2933 14 Nov 14 olle 541    *  @param start Date The start date.
2933 14 Nov 14 olle 542    *  @param end Date The end date.
2933 14 Nov 14 olle 543    *  @return String The view type string for the given start and end dates.
2933 14 Nov 14 olle 544    */
2933 14 Nov 14 olle 545   public String getViewType(Date start, Date end)
2933 14 Nov 14 olle 546   {
2933 14 Nov 14 olle 547     String viewType = null;
2933 14 Nov 14 olle 548     
2933 14 Nov 14 olle 549     Calendar cal = GregorianCalendar.getInstance();
2933 14 Nov 14 olle 550     cal.setTime(start);
2933 14 Nov 14 olle 551     
2933 14 Nov 14 olle 552     Calendar endCal = GregorianCalendar.getInstance();
2933 14 Nov 14 olle 553     endCal.setTime(end);
2933 14 Nov 14 olle 554     
2933 14 Nov 14 olle 555     Calendar limitWeekView = (Calendar)cal.clone();    
2933 14 Nov 14 olle 556     limitWeekView.add(Calendar.MONTH, weekViewLimit);
2933 14 Nov 14 olle 557     int daysToWeekend = 9-limitWeekView.get(Calendar.DAY_OF_WEEK);
2933 14 Nov 14 olle 558     limitWeekView.add(Calendar.DATE, daysToWeekend);
2933 14 Nov 14 olle 559     
2933 14 Nov 14 olle 560     Calendar limitMonthView = (Calendar)cal.clone();
2933 14 Nov 14 olle 561     limitMonthView.add(Calendar.MONTH, monthViewLimit+1);
2933 14 Nov 14 olle 562     limitMonthView.add(Calendar.DATE, -1);
2933 14 Nov 14 olle 563     
2933 14 Nov 14 olle 564     Calendar limitQuarterView = (Calendar)cal.clone();    
2933 14 Nov 14 olle 565     limitQuarterView.add(Calendar.YEAR, quarterViewLimit);
2933 14 Nov 14 olle 566     int currentQuarter = limitQuarterView.get(Calendar.MONTH)/3;
2933 14 Nov 14 olle 567     limitQuarterView.add(Calendar.MONTH, (3*currentQuarter)-limitQuarterView.get(Calendar.MONTH));
2933 14 Nov 14 olle 568                 
2933 14 Nov 14 olle 569     if (limitWeekView.after(endCal)) 
2933 14 Nov 14 olle 570     {
2933 14 Nov 14 olle 571       viewType = weekView;
2933 14 Nov 14 olle 572     }
2933 14 Nov 14 olle 573     else if (limitMonthView.after(endCal)) 
2933 14 Nov 14 olle 574     {
2933 14 Nov 14 olle 575       viewType = monthView;
2933 14 Nov 14 olle 576     }
2933 14 Nov 14 olle 577     else if (limitQuarterView.after(endCal)) 
2933 14 Nov 14 olle 578     {
2933 14 Nov 14 olle 579       viewType = quarterView;
2933 14 Nov 14 olle 580     }
2933 14 Nov 14 olle 581     else 
2933 14 Nov 14 olle 582     {
2933 14 Nov 14 olle 583       viewType = yearView;
2933 14 Nov 14 olle 584     }
2933 14 Nov 14 olle 585     
2933 14 Nov 14 olle 586     return viewType;
2933 14 Nov 14 olle 587   }
2933 14 Nov 14 olle 588
2933 14 Nov 14 olle 589   /**
2933 14 Nov 14 olle 590    *  Creates a sorted list of period start dates for given start date, end date, and view type.
2933 14 Nov 14 olle 591    *  The returned start dates will have its time set to midnight 00:00:00.
2933 14 Nov 14 olle 592    *
2933 14 Nov 14 olle 593    *  @param startDate Date The start date.
2933 14 Nov 14 olle 594    *  @param endDate Date The end date.
2933 14 Nov 14 olle 595    *  @param viewType String The view type to use.
2933 14 Nov 14 olle 596    *  @return List<Date> A sorted list of period start dates for given start date, end date, and view type.
2933 14 Nov 14 olle 597    */
2933 14 Nov 14 olle 598   public List<Date> createSortedPeriodStartDateList(Date startDate, Date endDate, String viewType)
2933 14 Nov 14 olle 599   {
2933 14 Nov 14 olle 600     List<Date> sortedPeriodStartDateList = new ArrayList<Date>();
2933 14 Nov 14 olle 601     Date periodStartDate = calculatePeriodStartDate(startDate, viewType);
2933 14 Nov 14 olle 602     Calendar cal = GregorianCalendar.getInstance();
2933 14 Nov 14 olle 603     cal.setTime(periodStartDate);
2933 14 Nov 14 olle 604     Calendar endCal = GregorianCalendar.getInstance();
2933 14 Nov 14 olle 605     endCal.setTime(endDate);
2933 14 Nov 14 olle 606     while (cal.before(endCal) || cal.equals(endCal))
2933 14 Nov 14 olle 607     {
2933 14 Nov 14 olle 608       sortedPeriodStartDateList.add(cal.getTime());
2933 14 Nov 14 olle 609       // Advance to start of next time period
2933 14 Nov 14 olle 610       int year = cal.get(Calendar.YEAR);
2933 14 Nov 14 olle 611       int month = cal.get(Calendar.MONTH);
2933 14 Nov 14 olle 612       int day = cal.get(Calendar.DAY_OF_MONTH);
2933 14 Nov 14 olle 613       if (viewType.equals(yearView))
2933 14 Nov 14 olle 614       {
2933 14 Nov 14 olle 615         cal.set(year+1, month, day);
2933 14 Nov 14 olle 616       }
2933 14 Nov 14 olle 617       else if (viewType.equals(quarterView))
2933 14 Nov 14 olle 618       {
2933 14 Nov 14 olle 619         cal.set(year, month+3, day);
2933 14 Nov 14 olle 620       }
2933 14 Nov 14 olle 621       else if (viewType.equals(monthView))
2933 14 Nov 14 olle 622       {
2933 14 Nov 14 olle 623         cal.set(year, month+1, day);
2933 14 Nov 14 olle 624       }
2933 14 Nov 14 olle 625       else if (viewType.equals(weekView))
2933 14 Nov 14 olle 626       {
2933 14 Nov 14 olle 627         cal.set(year, month, day+7);
2933 14 Nov 14 olle 628       }
2933 14 Nov 14 olle 629     }
2933 14 Nov 14 olle 630     return sortedPeriodStartDateList;
2933 14 Nov 14 olle 631   }
2933 14 Nov 14 olle 632   
2933 14 Nov 14 olle 633   /**
2933 14 Nov 14 olle 634    *  Creates a sorted list of period end dates for given start date, end date, and view type.
2933 14 Nov 14 olle 635    *  The returned end dates will have its time set to one second before midnight 23:59:59.
2933 14 Nov 14 olle 636    *
2933 14 Nov 14 olle 637    *  @param startDate Date The start date.
2933 14 Nov 14 olle 638    *  @param endDate Date The end date.
2933 14 Nov 14 olle 639    *  @param viewType String The view type to use.
2933 14 Nov 14 olle 640    *  @return List<Date> A sorted list of period start dates for given start date, end date, and view type.
2933 14 Nov 14 olle 641    */
2933 14 Nov 14 olle 642   public List<Date> createSortedPeriodEndDateList(Date startDate, Date endDate, String viewType)
2933 14 Nov 14 olle 643   {
2933 14 Nov 14 olle 644     List<Date> sortedPeriodEndDateList = new ArrayList<Date>();
2933 14 Nov 14 olle 645     Date periodStartDate = calculatePeriodStartDate(startDate, viewType);
2933 14 Nov 14 olle 646     Calendar cal = GregorianCalendar.getInstance();
2933 14 Nov 14 olle 647     cal.setTime(periodStartDate);
2933 14 Nov 14 olle 648     Calendar endCal = GregorianCalendar.getInstance();
2933 14 Nov 14 olle 649     endCal.setTime(endDate);
2933 14 Nov 14 olle 650     while (cal.before(endCal) || cal.equals(endCal))
2933 14 Nov 14 olle 651     {
2933 14 Nov 14 olle 652       // Advance to start of next time period
2933 14 Nov 14 olle 653       int year = cal.get(Calendar.YEAR);
2933 14 Nov 14 olle 654       int month = cal.get(Calendar.MONTH);
2933 14 Nov 14 olle 655       int day = cal.get(Calendar.DAY_OF_MONTH);
2933 14 Nov 14 olle 656       if (viewType.equals(yearView))
2933 14 Nov 14 olle 657       {
2933 14 Nov 14 olle 658         cal.set(year+1, month, day);
2933 14 Nov 14 olle 659       }
2933 14 Nov 14 olle 660       else if (viewType.equals(quarterView))
2933 14 Nov 14 olle 661       {
2933 14 Nov 14 olle 662         cal.set(year, month+3, day);
2933 14 Nov 14 olle 663       }
2933 14 Nov 14 olle 664       else if (viewType.equals(monthView))
2933 14 Nov 14 olle 665       {
2933 14 Nov 14 olle 666         cal.set(year, month+1, day);
2933 14 Nov 14 olle 667       }
2933 14 Nov 14 olle 668       else if (viewType.equals(weekView))
2933 14 Nov 14 olle 669       {
2933 14 Nov 14 olle 670         cal.set(year, month, day+7);
2933 14 Nov 14 olle 671       }
2933 14 Nov 14 olle 672       // Get original period end date by subtracting one second from start of next period
2933 14 Nov 14 olle 673       long timeInMs = cal.getTimeInMillis();
2933 14 Nov 14 olle 674       Calendar periodEndCal = GregorianCalendar.getInstance();
2933 14 Nov 14 olle 675       periodEndCal.setTimeInMillis(timeInMs - 1000);      
2933 14 Nov 14 olle 676       sortedPeriodEndDateList.add(periodEndCal.getTime());
2933 14 Nov 14 olle 677     }
2933 14 Nov 14 olle 678     return sortedPeriodEndDateList;
2933 14 Nov 14 olle 679   }
2933 14 Nov 14 olle 680   
2933 14 Nov 14 olle 681   /**
2933 14 Nov 14 olle 682    *  Calculates the first date in a period for given date and view type.
2933 14 Nov 14 olle 683    *  The returned start date will have its time reset to midnight 00:00:00.
2933 14 Nov 14 olle 684    *
2933 14 Nov 14 olle 685    *  @param date Date The date.
2933 14 Nov 14 olle 686    *  @param viewType String The view type to use.
2933 14 Nov 14 olle 687    *  @return Date The first date in a period for given date and view type, with time reset to midnight 00:00:00.
2933 14 Nov 14 olle 688    */
2933 14 Nov 14 olle 689   public Date calculatePeriodStartDate(Date date, String viewType)
2933 14 Nov 14 olle 690   {
2933 14 Nov 14 olle 691     Date tmpDate = null;
2933 14 Nov 14 olle 692     if (viewType.equals(weekView)) 
2933 14 Nov 14 olle 693     {
2933 14 Nov 14 olle 694       tmpDate = mondayInISOWeek(date);
2933 14 Nov 14 olle 695     }
2933 14 Nov 14 olle 696     else if (viewType.equals(monthView))
2933 14 Nov 14 olle 697     {
2933 14 Nov 14 olle 698       tmpDate = firstDayInMonth(date);
2933 14 Nov 14 olle 699     }
2933 14 Nov 14 olle 700     else if (viewType.equals(quarterView))
2933 14 Nov 14 olle 701     {
2933 14 Nov 14 olle 702       tmpDate = firstDayInQuarter(date);
2933 14 Nov 14 olle 703     }
2933 14 Nov 14 olle 704     else if (viewType.equals(yearView))
2933 14 Nov 14 olle 705     {
2933 14 Nov 14 olle 706       tmpDate = firstDayInYear(date);
2933 14 Nov 14 olle 707     }
2933 14 Nov 14 olle 708     Date periodDate = adjustDayTime(tmpDate, 0, 0, 0);
2933 14 Nov 14 olle 709     return periodDate;
2933 14 Nov 14 olle 710   }
2933 14 Nov 14 olle 711
2933 14 Nov 14 olle 712   /**
2933 14 Nov 14 olle 713    *  Returns the date for the Monday in the ISO week containing the given date.
2933 14 Nov 14 olle 714    *  The time of day of the returned date is equal to that of the input date.
2933 14 Nov 14 olle 715    *
2933 14 Nov 14 olle 716    *  @param date Date The date.
2933 14 Nov 14 olle 717    *  @return Date The date for the Monday in the ISO week containing the given date, with retained time of day.
2933 14 Nov 14 olle 718    */
2933 14 Nov 14 olle 719   public Date mondayInISOWeek(Date date)
2933 14 Nov 14 olle 720   {
2933 14 Nov 14 olle 721     // Get weekday number; 1 => Sunday, 2 => Monday, ... , 7 => Saturday
2933 14 Nov 14 olle 722     Calendar cal = GregorianCalendar.getInstance();
2933 14 Nov 14 olle 723     cal.setTime(date);
2933 14 Nov 14 olle 724     int weekdayNumber = cal.get(Calendar.DAY_OF_WEEK);
2933 14 Nov 14 olle 725     // Get weekday offset from Monday; 6 => Sunday, 0 => Monday, ... , 5 => Saturday
2933 14 Nov 14 olle 726     int offset = weekdayNumber - 2;
2933 14 Nov 14 olle 727     if (offset < 0)
2933 14 Nov 14 olle 728     {
2933 14 Nov 14 olle 729       offset = offset + 7;
2933 14 Nov 14 olle 730     }
2933 14 Nov 14 olle 731     // Get date for Monday in ISO week
2933 14 Nov 14 olle 732     long msSince19700101 = date.getTime() - offset*24*60*60*1000;
2933 14 Nov 14 olle 733     Date dateMondayInWeek = new Date(msSince19700101);
2933 14 Nov 14 olle 734     return dateMondayInWeek;
2933 14 Nov 14 olle 735   }
2933 14 Nov 14 olle 736
2933 14 Nov 14 olle 737   /**
2933 14 Nov 14 olle 738    *  Returns the date for the first day of the month containing the given date.
2933 14 Nov 14 olle 739    *  The time of day of the returned date is equal to that of the input date.
2933 14 Nov 14 olle 740    *
2933 14 Nov 14 olle 741    *  @param date Date The date.
2933 14 Nov 14 olle 742    *  @return Date The date for the first day of the month containing the given date, with retained time of day.
2933 14 Nov 14 olle 743    */
2933 14 Nov 14 olle 744   public Date firstDayInMonth(Date date)
2933 14 Nov 14 olle 745   {
2933 14 Nov 14 olle 746     // Get year and month;
2933 14 Nov 14 olle 747     Calendar cal = GregorianCalendar.getInstance();
2933 14 Nov 14 olle 748     cal.setTime(date);
2933 14 Nov 14 olle 749     int year = cal.get(Calendar.YEAR);
2933 14 Nov 14 olle 750     int month = cal.get(Calendar.MONTH);
2933 14 Nov 14 olle 751     // Get date for first day in month
2933 14 Nov 14 olle 752     cal.set(year, month, 1);
2933 14 Nov 14 olle 753     Date dateFirstDayInMonth = cal.getTime();
2933 14 Nov 14 olle 754     return dateFirstDayInMonth;
2933 14 Nov 14 olle 755   }
2933 14 Nov 14 olle 756
2933 14 Nov 14 olle 757   /**
2933 14 Nov 14 olle 758    *  Returns the date for the first day of the quarter containing the given date.
2933 14 Nov 14 olle 759    *  The time of day of the returned date is equal to that of the input date.
2933 14 Nov 14 olle 760    *
2933 14 Nov 14 olle 761    *  @param date Date The date.
2933 14 Nov 14 olle 762    *  @return Date The date for the first day of the quarter containing the given date, with retained time of day.
2933 14 Nov 14 olle 763    */
2933 14 Nov 14 olle 764   public Date firstDayInQuarter(Date date)
2933 14 Nov 14 olle 765   {
2933 14 Nov 14 olle 766     // Get year and month;
2933 14 Nov 14 olle 767     Calendar cal = GregorianCalendar.getInstance();
2933 14 Nov 14 olle 768     cal.setTime(date);
2933 14 Nov 14 olle 769     int year = cal.get(Calendar.YEAR);
2933 14 Nov 14 olle 770     int month = cal.get(Calendar.MONTH);
2933 14 Nov 14 olle 771     // Get first month of quarter;  0 => January, 1 => February, ... , 11 => December
2933 14 Nov 14 olle 772     if (month < 3)
2933 14 Nov 14 olle 773     {
2933 14 Nov 14 olle 774       month = 0;
2933 14 Nov 14 olle 775     }
2933 14 Nov 14 olle 776     else if (month < 6)
2933 14 Nov 14 olle 777     {
2933 14 Nov 14 olle 778       month = 3;
2933 14 Nov 14 olle 779     }
2933 14 Nov 14 olle 780     else if (month < 9)
2933 14 Nov 14 olle 781     {
2933 14 Nov 14 olle 782       month = 6;
2933 14 Nov 14 olle 783     }
2933 14 Nov 14 olle 784     else
2933 14 Nov 14 olle 785     {
2933 14 Nov 14 olle 786       month = 9;
2933 14 Nov 14 olle 787     }
2933 14 Nov 14 olle 788     // Get date for first day in quarter
2933 14 Nov 14 olle 789     cal.set(year, month, 1);
2933 14 Nov 14 olle 790     Date dateFirstDayInQuarter = cal.getTime();
2933 14 Nov 14 olle 791     return dateFirstDayInQuarter;
2933 14 Nov 14 olle 792   }
2933 14 Nov 14 olle 793
2933 14 Nov 14 olle 794   /**
2933 14 Nov 14 olle 795    *  Returns the date for the first day of the year containing the given date.
2933 14 Nov 14 olle 796    *  The time of day of the returned date is equal to that of the input date.
2933 14 Nov 14 olle 797    *
2933 14 Nov 14 olle 798    *  @param date Date The date.
2933 14 Nov 14 olle 799    *  @return Date The date for the first day of the year containing the given date, with retained time of day.
2933 14 Nov 14 olle 800    */
2933 14 Nov 14 olle 801   public Date firstDayInYear(Date date)
2933 14 Nov 14 olle 802   {
2933 14 Nov 14 olle 803     // Get year;
2933 14 Nov 14 olle 804     Calendar cal = GregorianCalendar.getInstance();
2933 14 Nov 14 olle 805     cal.setTime(date);
2933 14 Nov 14 olle 806     int year = cal.get(Calendar.YEAR);
2933 14 Nov 14 olle 807     // Get date for first day in year
2933 14 Nov 14 olle 808     cal.set(year, 1, 1);
2933 14 Nov 14 olle 809     Date dateFirstDayInYear = cal.getTime();
2933 14 Nov 14 olle 810     return dateFirstDayInYear;
2933 14 Nov 14 olle 811   }
2933 14 Nov 14 olle 812
2933 14 Nov 14 olle 813   /**
2933 14 Nov 14 olle 814    *  Returns a date equal to the input date, but with time of day set to given time.
2933 14 Nov 14 olle 815    *
2933 14 Nov 14 olle 816    *  @param date Date The input Date object to get year, month, and day from.  
2933 14 Nov 14 olle 817    *  @param hour int The hour of day to use. 
2933 14 Nov 14 olle 818    *  @param min int The minute to use. 
2933 14 Nov 14 olle 819    *  @param sec int The second to use.
2933 14 Nov 14 olle 820    *  @return A date equal to the input date, but with time of day set to given time.
2933 14 Nov 14 olle 821    */
2933 14 Nov 14 olle 822   public Date adjustDayTime(Date date, int hour, int min, int sec)
2933 14 Nov 14 olle 823   {
2933 14 Nov 14 olle 824     // Get year, month, and date
2933 14 Nov 14 olle 825     Calendar cal = GregorianCalendar.getInstance();
2933 14 Nov 14 olle 826     cal.setTime(date);
2933 14 Nov 14 olle 827     int year = cal.get(Calendar.YEAR);
2933 14 Nov 14 olle 828     int month = cal.get(Calendar.MONTH);
2933 14 Nov 14 olle 829     int dateInMonth = cal.get(Calendar.DATE);
2933 14 Nov 14 olle 830     // Adjust time of day for date
2933 14 Nov 14 olle 831     cal.clear();
2933 14 Nov 14 olle 832     cal.set(year, month, dateInMonth, hour, min, sec);
2933 14 Nov 14 olle 833     Date adjustedDate = cal.getTime();
2933 14 Nov 14 olle 834     return adjustedDate;
2933 14 Nov 14 olle 835   }
2933 14 Nov 14 olle 836
2933 14 Nov 14 olle 837   /**
2933 14 Nov 14 olle 838    *  Returns the earliest of the site start dates.
2933 14 Nov 14 olle 839    *
2933 14 Nov 14 olle 840    *  @return Date The earliest of the site start dates.
2933 14 Nov 14 olle 841    */
2933 14 Nov 14 olle 842   public Date fetchEarliestSiteStartDate()
2933 14 Nov 14 olle 843   {
2933 14 Nov 14 olle 844     Calendar calEarliest = GregorianCalendar.getInstance();
2933 14 Nov 14 olle 845     for (Site s : Site.getAllReportSites())
2933 14 Nov 14 olle 846     {
2933 14 Nov 14 olle 847       // Site start date is stored in yyyy-mm-dd format
2933 14 Nov 14 olle 848       String siteStartString = s.getStartDate();
2933 14 Nov 14 olle 849       if (siteStartString != null && !siteStartString.equals(""))
2933 14 Nov 14 olle 850       {
2933 14 Nov 14 olle 851         String yearStr = siteStartString.substring(0,4);
2933 14 Nov 14 olle 852         String monthStr = siteStartString.substring(5,7);
2933 14 Nov 14 olle 853         String dayStr = siteStartString.substring(8,10);
2933 14 Nov 14 olle 854         int year = Integer.parseInt(yearStr, 10);
2933 14 Nov 14 olle 855         int month = Integer.parseInt(monthStr, 10);
2933 14 Nov 14 olle 856         int date = Integer.parseInt(dayStr, 10);
2933 14 Nov 14 olle 857         Calendar cal = GregorianCalendar.getInstance();
2933 14 Nov 14 olle 858         cal.clear();
2933 14 Nov 14 olle 859         cal.set(year, month-1, date);
2933 14 Nov 14 olle 860         if (cal.before(calEarliest))
2933 14 Nov 14 olle 861         {
2933 14 Nov 14 olle 862           calEarliest = cal;
2933 14 Nov 14 olle 863         }
2933 14 Nov 14 olle 864       }
2933 14 Nov 14 olle 865     }
2933 14 Nov 14 olle 866     return calEarliest.getTime();
2933 14 Nov 14 olle 867   }
2933 14 Nov 14 olle 868
2933 14 Nov 14 olle 869 }