1
2
3
4
5
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 }