001// Copyright (c) 2001 Hursh Jain (http://www.mollypages.org) 002// The Molly framework is freely distributable under the terms of an 003// MIT-style license. For details, see the molly pages web site at: 004// http://www.mollypages.org/. Use, modify, have fun ! 005 006package fc.util; 007 008import java.util.*; 009 010 011/** A set of date ranges. **/ 012public class DateRangeSet 013{ 014DateRange seedRange; 015List union; 016List intersect; 017 018/** 019Constructs a new DateRangeSet with the initial set containing 020only the specified DateRange 021 022@param cs the initial DateRange 023**/ 024public DateRangeSet(DateRange cs) 025 { 026 Argcheck.notnull(cs); 027 seedRange = cs; 028 //do _not_ lazy instantiate, otherwise have to put in 029 //null checks in other places 030 union = new ArrayList(); 031 intersect = new ArrayList(); 032 } 033 034/** 035Adds this specified range as a union to the existing set of 036ranges (for purposes of {@link inRange(char)} method). 037Overlapping ranges are ok. 038 039@param cs a DateRange to unite with 040@throws IllegalArgumentException 041 if the specified range was null 042**/ 043public void union(DateRange r) 044 { 045 Argcheck.notnull(r); 046 union.add(r); 047 } 048 049/** 050Adds the specified range as an intersection to the existing 051ranges (for purposes of {@link inRange(char)} method). 052Overlapping ranges are ok. 053 054@param r the range to add 055**/ 056public void intersection(DateRange r) 057 { 058 Argcheck.notnull(r); 059 intersect.add(r); 060 } 061 062/** 063Consider a set of ranges <tt>A</tt>, <tt>B</tt> added as a union 064(logical <tt>or</tt>) and ranges <tt>C</tt> and <tt>D</tt> added as an 065intersection (logical <tt>and</tt>). A character <tt>c</tt> is in range if 066it exists in: 067 068<blockquote> <tt> 069 070(A.inRange(c) || B.inRange(c) || ...) && C.inRange(c) && D.inRange(c) 071&& ... 072 073</tt></blockquote> 074 075This can be generalized to an arbitrary number of sub ranges. If 076intersection or union ranges don't exist, then they are not 077considered in the above expression. Note, the interaction may be 078subtle if any of the ranges (<tt>A, B, C...</tt>etc) are 079individually negated because in that case the inRange method for 080that negated range would return true if the specified character 081was <b>not</b> in that range. 082 083@return <tt>true</tt> if the passed in character is allowed by this 084 set of ranges. 085 086**/ 087public boolean inRange(Date val) 088 { 089 boolean result = seedRange.inRange(val); 090 for (int i = 0, n = union.size(); i < n; i++) { 091 DateRange item = (DateRange) union.get(i); 092 result = result || item.inRange(val); 093 } 094 for (int i = 0, n = intersect.size(); i < n; i++) { 095 DateRange item = (DateRange) intersect.get(i); 096 result = result && item.inRange(val); 097 } 098 return result; 099 } 100 101public String toString() { 102 StringBuffer buf = new StringBuffer(128); 103 buf.append("DateRangeSet:["); 104 105 if (intersect.size() > 0) 106 buf.append("("); 107 108 buf.append(seedRange); 109 110 int len = union.size(); 111 if (len > 0) 112 { 113 buf.append(" || " ); 114 for (int i = 0; i < len; i++) { 115 buf.append(union.get(i).toString()); 116 if (i < (len-1)) 117 buf.append(" || "); 118 } 119 } 120 121 len = intersect.size(); 122 if (len > 0) 123 { 124 buf.append(") && " ); 125 for (int i = 0; i < len; i++) { 126 buf.append(intersect.get(i).toString()); 127 if (i < (len-1)) 128 buf.append(" && "); 129 } 130 } 131 132 buf.append("]"); 133 return buf.toString(); 134 } 135 136 137public static void main(String[] args) 138 { 139 Date now = new Date(); 140 141 Calendar cal = Calendar.getInstance(); 142 Date d1 = cal.getTime(); 143 //back 1 month 144 cal.add(Calendar.MONTH, -1); 145 Date d2 = cal.getTime(); 146 147 DateRange r = new DateRange(d2, d1); 148 149 cal.setTime(now); 150 cal.add(Calendar.MONTH, -3); 151 Date d3 = cal.getTime(); 152 cal.setTime(now); 153 cal.add(Calendar.MONTH, -6); 154 Date d4 = cal.getTime(); 155 156 DateRange r2 = new DateRange(d4, d3); 157 158 DateRangeSet crs = new DateRangeSet(r); 159 crs.union(r2); 160 System.out.println("constructed: " + crs); 161 test(crs); 162 163 cal.setTime(now); 164 cal.add(Calendar.MONTH, -4); 165 d3 = cal.getTime(); 166 cal.setTime(now); 167 cal.add(Calendar.MONTH, -5); 168 d4 = cal.getTime(); 169 r2 = new DateRange(d4, d3); 170 crs.intersection(r2); 171 System.out.println("constructed: " + crs); 172 test(crs); 173 } 174 175private static void test(DateRangeSet crs) 176 { 177 Calendar cal = Calendar.getInstance(); 178 cal.add(Calendar.MONTH, -5); 179 Date d = cal.getTime(); 180 System.out.println("in range: " + d + "=" + crs.inRange(d)); 181 cal.setTime(new Date()); 182 cal.add(Calendar.MONTH, 3); 183 d = cal.getTime(); 184 System.out.println("in range: " + d + "=" + crs.inRange(d)); 185 } 186}