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

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