View Javadoc

1   /*
2    * Copyright 2004-2005, University Health Network.  All rights reserved. Distributed under the BSD 
3    * license (see http://opensource.org/licenses/bsd-license.php).
4    *  
5    * Created on 6-Dec-2004
6    */
7   package ca.uhn.cache.impl;
8   
9   import java.text.DateFormat;
10  import java.text.ParseException;
11  import java.text.SimpleDateFormat;
12  import java.util.Arrays;
13  import java.util.Date;
14  
15  import ca.uhn.cache.IDimension;
16  import ca.uhn.cache.IGroupQueryParam;
17  import ca.uhn.cache.IQueryParam;
18  
19  /***
20   * A <code>IQueryParam</code> encompassing a range of dates.
21   * 
22   * @author <a href="mailto:bryan.tripp@uhn.on.ca">Bryan Tripp</a>
23   * @version $Revision: 1.1 $ updated on $Date: 2005/01/24 22:52:37 $ by $Author: bryan_tripp $
24   */
25  public class DateRangeParam extends AbstractQueryParam implements IGroupQueryParam {
26      
27      private final Date myStart; 
28      private final Date myEnd;
29      
30      /***
31       * Factory method for <code>DateRangeParam</code>.
32       *  
33       * @param theDim The dimension where this parameter is difined.
34       * @param theStart Start date/time represented as a string, where the date will be represented in 
35       *                 {@link DateFormat#MEDIUM} (MMM dd, yyyy) format 
36       *                 and the time in {@link DateFormat#SHORT} ("M/d/yy h:mm a") format.
37       *                 
38       * @param theEnd End date/time represented as a string, where the date will be represented in 
39       *                 {@link DateFormat#MEDIUM} (MMM dd, yyyy) format 
40       *                 and the time in {@link DateFormat#SHORT} ("M/d/yy h:mm a") format.
41       *                 
42       * @return The created <code>DateRangeParam</code>.
43       * 
44       * @throws ParseException If either theStart or theEnd date/time could not be parsed. 
45       * 
46       * Example:
47       * <pre>
48       *  DateRangeParam.getInstance( dim, "Jan 21, 2001 12:20 am", "Feb 21, 2004 1:20 am" );
49       * </pre>
50  
51       */
52      public static final DateRangeParam getInstance( IDimension theDim, String theStart, String theEnd ) 
53          throws ParseException {
54          
55          DateRangeParam retVal;
56          
57          DateFormat df = new SimpleDateFormat("MMM d, yyyy h:mm a");
58          Date start = df.parse( theStart );
59          Date end = df.parse( theEnd );
60          
61          retVal = new DateRangeParam( theDim, start, end );
62          
63          return retVal;
64      }
65      
66      /***
67       * Creates a new <code>DateRangeParam</code>.
68       * 
69       * @param theDimension The dimension where this parameter is difined. 
70       * @param theStart The start of the date range, in UTC.
71       * @param theEnd The end of the date range, in UTC.
72       */
73      public DateRangeParam( IDimension theDimension, Date theStart, Date theEnd ) {
74          super( theDimension );
75          
76          assert theStart != null;
77          assert theEnd != null;
78          assert theStart.equals( theEnd ) || theStart.before( theEnd );
79          
80          myStart = theStart;
81          myEnd = theEnd;
82      }
83  
84      /***
85       * @return Returns the end of the range.
86       */
87      public Date getEnd() {
88          return myEnd;
89      }
90  
91      /***
92       * @return Returns the start of the range.
93       */
94      public Date getStart() {
95          return myStart;
96      }
97      
98      /***
99       * @see ca.uhn.cache.IQueryParam#intersects(ca.uhn.cache.IQueryParam)
100      */
101     public boolean intersects( IQueryParam theParam ) {
102         boolean retVal = false;
103         
104         if (super.intersects(theParam)) {
105             DateParam saturation =  new DateParam(this.getDimension(), new Date(1) );
106             if (getDistance(theParam, saturation) == 0) {
107                 retVal = true;
108             }
109         }
110         
111         return retVal;
112     }
113     
114     /***
115      * @return DateParam.class
116      */
117     public Class getPointParamClass() {
118         return DateParam.class;
119     }
120     
121     /*** 
122      * @see ca.uhn.cache.IQueryParam#getDistance(ca.uhn.cache.IQueryParam, ca.uhn.cache.IQueryParam)
123      */
124     public float getDistance(IQueryParam theParam, IQueryParam theSaturationPoint) {
125         DateParam.checkCompatibility(theParam, this.getDimension());
126         DateParam.checkCompatibility(theSaturationPoint, this.getDimension());
127         
128         if ( !(theSaturationPoint instanceof DateParam) ) {
129             throw new IllegalArgumentException("Saturation point should be a DateParam");
130         }
131         
132         float distance = 0;
133         if (theParam instanceof DateParam) {
134             distance = ((DateParam) theParam).getDistance(this, theSaturationPoint);
135         } else {
136             DateRangeParam that = (DateRangeParam) theParam;
137             long diff1 = that.getStart().getTime() - this.getEnd().getTime();
138             long diff2 = that.getEnd().getTime() - this.getStart().getTime();
139             
140             if (diff1 * diff2 == 0 || (diff1 < 0 ^ diff2 < 0)) {
141                 distance = 0;
142             } else {
143                 long saturation = ((DateParam) theSaturationPoint).getValue().getTime();
144 
145                 long diff = Math.min(Math.abs(diff1), Math.abs(diff2));
146                 distance = DateParam.getDistance(diff, saturation);                                
147             }
148         }
149         return distance; 
150     }
151 
152     /***
153      * @see ca.uhn.cache.IQueryParam#merge(ca.uhn.cache.IQueryParam)
154      */
155     public IQueryParam merge(IQueryParam theParam) {
156         DateParam.checkCompatibility(theParam, this.getDimension());
157         
158         Date[] edges = null;
159         if (theParam instanceof DateParam) {
160             DateParam that = (DateParam) theParam;
161             edges = new Date[] {this.getStart(), this.getEnd(), that.getValue()};
162         } else if (theParam instanceof DateRangeParam) {
163             DateRangeParam that = (DateRangeParam) theParam;
164             edges = new Date[] {this.getStart(), this.getEnd(), that.getStart(), that.getEnd()};
165         }         
166         
167         Arrays.sort(edges);
168         return new DateRangeParam(this.getDimension(), edges[0], edges[edges.length-1]);                
169     }
170     
171 }