1   package com.atlassian.bonnie.search;
2   
3   import com.atlassian.core.util.DateUtils;
4   import com.atlassian.core.util.InvalidDurationException;
5   import com.atlassian.bonnie.LuceneUtils;
6   import org.apache.lucene.index.Term;
7   import org.apache.lucene.search.Query;
8   import org.apache.lucene.search.RangeQuery;
9   import org.apache.lucene.search.ConstantScoreRangeQuery;
10  
11  import java.util.Calendar;
12  import java.util.Date;
13  
14  public class SinceDateQueryFactory
15  {
16      public static final String TODAY = "today";
17      public static final String YESTERDAY = "yesterday";
18      public static final String LAST_WEEK = "lastweek";
19      public static final String LAST_MONTH = "lastmonth";
20  
21      private String period;
22      protected String field;
23  
24      public static SinceDateQueryFactory getInstance(String period, String field)
25      {
26          return new SinceDateQueryFactory(period, field);
27      }
28  
29      SinceDateQueryFactory(String period, String field)
30      {
31          this.period = period;
32          this.field = field;
33      }
34  
35      public Query toQuery()
36      {
37          Calendar c = Calendar.getInstance();
38  //        c.setTime(new Date());
39          c.set(Calendar.HOUR_OF_DAY, 0);
40          c.set(Calendar.MINUTE, 0);
41          c.set(Calendar.SECOND, 0);
42          c.set(Calendar.MILLISECOND, 0);
43          Date startOfToday = c.getTime();
44  
45          if (TODAY.equals(period))
46          {
47              return new RangeQuery(new Term(field, LuceneUtils.dateToString(startOfToday)), null, true);
48          }
49          if (YESTERDAY.equals(period))
50          {
51              c.add(Calendar.DAY_OF_YEAR, -1);
52              Date startOfYesterday = c.getTime();
53              Date beforeMidnightYesterday = new Date(startOfToday.getTime() - 1);
54  
55              return createQuery(startOfYesterday, beforeMidnightYesterday);
56          }
57          else if (LAST_WEEK.equals(period)) // as in past 7 days
58          {
59              c.add(Calendar.DAY_OF_YEAR, -7);
60              Date lastWeekStart = c.getTime();
61  
62              return createQuery(lastWeekStart, null);
63          }
64          else if (LAST_MONTH.equals(period))
65          {
66              c.add(Calendar.DAY_OF_YEAR, -30);
67              Date lastMonthStart = c.getTime();
68  
69              return createQuery(lastMonthStart, null);
70          }
71          else
72          {
73              long duration = 0;
74              try
75              {
76                  duration = DateUtils.getDuration(period);
77                  return createQuery(new Date(new Date().getTime() - duration * 1000), new Date());
78              }
79              catch (InvalidDurationException e)
80              {
81                  throw new IllegalArgumentException("Invalid date period: " + period);
82              }
83          }
84      }
85  
86      private Query createQuery(Date startOfRange, Date endOfRange)
87      {
88          // leave the range query open ended if no date is specified.
89          String lower = (startOfRange != null) ? LuceneUtils.dateToString(startOfRange) : null;
90          String upper = (endOfRange != null) ? LuceneUtils.dateToString(endOfRange) : null;
91          return new ConstantScoreRangeQuery(field, lower, upper, true, true);
92      }
93  }