1 30 31 34 package com.nightlabs.util.timepattern; 35 36 import java.io.Serializable ; 37 import java.util.ArrayList ; 38 import java.util.Collection ; 39 import java.util.Date ; 40 import java.util.GregorianCalendar ; 41 import java.util.Iterator ; 42 import java.util.List ; 43 import java.util.Set ; 44 45 import com.nightlabs.util.timepattern.TimePattern.TimePeriod; 46 47 60 public abstract class TimePatternSet 61 implements Serializable 62 { 63 64 public abstract Set getTimePatterns(); 65 66 public TimePatternSet() { } 67 68 public abstract TimePattern createTimePattern(); 69 public abstract TimePattern createTimePattern(String _year, String _month, String _day, String _dayOfWeek, String _hour, String _minute) throws TimePatternFormatException; 70 71 public void addTimePattern(TimePattern pattern) 72 { 73 if (pattern.getTimePatternSet() != null) 74 throw new IllegalStateException ("Given TimePattern "+pattern+" is already associated with a TimePatternSet "+pattern.getTimePatternSet()); 75 pattern.setTimePatternSet(this); 76 getTimePatterns().add(pattern); 77 } 78 79 87 public boolean matches(long timeStamp, byte maxInclude) 88 { 89 for (Iterator it = getTimePatterns().iterator(); it.hasNext(); ) { 90 TimePattern pattern = (TimePattern) it.next(); 91 if (pattern.matches(timeStamp,maxInclude)) 92 return true; 93 } 94 return false; 95 } 96 97 public boolean matches(long timeStamp) { 98 return matches(timeStamp,TimePattern.MINUTE); 99 } 100 101 public static class CondensedPeriod 102 { 103 public CondensedPeriod() { } 104 public CondensedPeriod(Date _fromDT, Date _toDT) 105 { 106 this.fromDT = _fromDT; 107 this.toDT = _toDT; 108 } 109 110 private Date fromDT; 111 private Date toDT; 112 113 116 public Date getFromDT() { 117 return fromDT; 118 } 119 122 public void setFromDT(Date fromDT) { 123 this.fromDT = fromDT; 124 } 125 128 public Date getToDT() { 129 return toDT; 130 } 131 134 public void setToDT(Date toDT) { 135 this.toDT = toDT; 136 } 137 } 138 139 protected static final int[] CALFIELDS = { 140 GregorianCalendar.MINUTE, 141 GregorianCalendar.HOUR_OF_DAY, 142 GregorianCalendar.DAY_OF_MONTH, 143 GregorianCalendar.MONTH, 144 GregorianCalendar.YEAR 145 }; 146 147 public static int S_MIN = 0; 148 public static int S_HOUR = 1; 149 public static int S_DAY = 2; 150 public static int S_MONTH = 3; 151 public static int S_YEAR = 4; 152 153 protected static final int CPCOMP_MODE_UP = 1; 154 protected static final int CPCOMP_MODE_DOWN = -1; 155 156 protected static class SimpleCalendar 157 { 158 protected GregorianCalendar cal; 159 160 public SimpleCalendar() 161 { 162 cal = new GregorianCalendar (); 163 } 164 165 public int get(int fieldIdx) 166 { 167 int value = cal.get(CALFIELDS[fieldIdx]); 168 if (fieldIdx == S_MONTH) 169 ++value; 170 return value; 171 } 172 173 public void set(int fieldIdx, int value) 174 { 175 if (fieldIdx == S_MONTH) 176 --value; 177 178 cal.set(CALFIELDS[fieldIdx], value); 179 thisString = null; 180 } 181 182 public int getActualMinimum(int fieldIdx) 183 { 184 if (fieldIdx == S_MONTH) 185 return 1; 186 187 if (fieldIdx == S_YEAR) 188 return 1000; 189 190 return cal.getActualMinimum(CALFIELDS[fieldIdx]); 191 } 192 public int getActualMaximum(int fieldIdx) 193 { 194 if (fieldIdx == S_MONTH) 195 return 12; 196 197 if (fieldIdx == S_YEAR) 198 return 3000; 199 200 return cal.getActualMaximum(CALFIELDS[fieldIdx]); 201 } 202 203 public void setTime(Date date) 204 { 205 cal.setTime(date); 206 thisString = null; 207 } 208 209 public long getTimeInMillis() 210 { 211 return cal.getTimeInMillis(); 212 } 213 public void setTimeInMillis(long millis) 214 { 215 cal.setTimeInMillis(millis); 216 thisString = null; 217 } 218 219 String thisString = null; 220 223 public String toString() { 224 if (thisString == null) { 225 StringBuffer sb = new StringBuffer (this.getClass().getName()); 226 sb.append('{'); 227 sb.append(get(S_YEAR)); 228 sb.append('-'); 229 sb.append(get(S_MONTH)); 230 sb.append('-'); 231 sb.append(get(S_DAY)); 232 sb.append(' '); 233 sb.append(get(S_HOUR)); 234 sb.append(':'); 235 sb.append(get(S_MIN)); 236 sb.append('}'); 237 thisString = sb.toString(); 238 } 239 return thisString; 240 } 241 } 242 243 public static final int YEAR_MIN = 1700; 244 public static final int YEAR_MAX = 2900; 245 246 247 253 protected void addCondensedPeriod(CondensedPeriod cp) 254 { 255 if (cp.getFromDT().compareTo(cp.getToDT()) > 0) 256 throw new IllegalArgumentException ("cp.fromDT > cp.toDT!!!"); 257 258 SimpleCalendar calFromDT = new SimpleCalendar(); 259 calFromDT.setTime(cp.getFromDT()); 260 SimpleCalendar calToDT = new SimpleCalendar(); 261 calToDT.setTime(cp.getToDT()); 262 SimpleCalendar calWork = new SimpleCalendar(); 263 264 if (calFromDT.get(S_YEAR) > YEAR_MAX) 265 throw new IllegalArgumentException ("cp.fromDT.year > "+YEAR_MAX+"!"); 266 267 if (calFromDT.get(S_YEAR) < YEAR_MIN) 268 throw new IllegalArgumentException ("cp.fromDT.year < "+YEAR_MIN+"!"); 269 270 if (calToDT.get(S_YEAR) > YEAR_MAX) 271 throw new IllegalArgumentException ("cp.toDT.year > "+YEAR_MAX+"!"); 272 273 if (calToDT.get(S_YEAR) < YEAR_MIN) 274 throw new IllegalArgumentException ("cp.toDT.year < "+YEAR_MIN+"!"); 275 276 277 List periodsModeUp = new ArrayList (); 278 List periodsModeDown = new ArrayList (); 279 boolean isFirstFieldIdx = true; 280 int diffFieldIdx = 0; boolean exitMode = false; 281 int mode = CPCOMP_MODE_UP; 282 int highestFieldIdxModeUp = 0; 283 boolean addPeriod = true; 284 while (diffFieldIdx <= CALFIELDS.length) { 286 addPeriod = true; 288 SimpleCalendar calSource; 289 SimpleCalendar calDest; 290 291 if (mode == CPCOMP_MODE_UP) { 292 calSource = calFromDT; 293 calDest = calToDT; 294 } 295 else { 296 calSource = calToDT; 297 calDest = calFromDT; 298 } 299 300 calWork.setTimeInMillis(calSource.getTimeInMillis()); 301 302 TimePeriod[] fieldPeriods = new TimePeriod[CALFIELDS.length]; 303 for (int fieldIdx = 0; fieldIdx < CALFIELDS.length; ++fieldIdx) { 304 if (fieldIdx < diffFieldIdx) { 305 fieldPeriods[fieldIdx] = new TimePattern.TimePeriod(-1, -1); calWork.set(fieldIdx, calDest.get(fieldIdx)); 307 } 308 else if (fieldIdx > diffFieldIdx) { 309 int i = calWork.get(fieldIdx); 310 fieldPeriods[fieldIdx] = new TimePattern.TimePeriod(i, i); 311 } 312 else { 313 int from = calWork.get(fieldIdx); 314 boolean currFieldIsComplete = false; 315 316 if (isFirstFieldIdx) { 317 isFirstFieldIdx = false; 319 } 320 else 321 from += mode; 322 323 if (from == (mode == CPCOMP_MODE_UP ? calWork.getActualMinimum(fieldIdx) : calWork.getActualMaximum(fieldIdx))) 324 { 325 calWork.set(fieldIdx, calSource.get(fieldIdx)); 326 currFieldIsComplete = true; 330 } 331 332 int to = mode == CPCOMP_MODE_UP ? calWork.getActualMaximum(fieldIdx) : calWork.getActualMinimum(fieldIdx); 333 if (mode * from > mode * to) { 334 addPeriod = false; 335 fieldPeriods = null; 336 break; 337 } 338 calWork.set(fieldIdx, to); 339 if (mode * calWork.getTimeInMillis() >= mode * calDest.getTimeInMillis()) 340 { 341 to = calDest.get(fieldIdx) - mode; 342 exitMode = true; 343 } 344 345 if (mode * from > mode * to) { 346 addPeriod = false; 347 fieldPeriods = null; 348 break; 349 } 350 351 if (mode == CPCOMP_MODE_DOWN) { 352 int i = from; 353 from = to; 354 to = i; 355 } 356 if (currFieldIsComplete) { 357 currFieldIsComplete = false; 358 fieldPeriods[fieldIdx] = new TimePattern.TimePeriod(-1, -1); } 360 else { 361 fieldPeriods[fieldIdx] = new TimePattern.TimePeriod(from, to); 362 } 363 } 364 } 365 366 if (addPeriod && fieldPeriods != null) { 367 StringBuffer sb = new StringBuffer (); 369 for (int i = 0; i < fieldPeriods.length; ++i) { 370 sb.append('['); 371 sb.append(fieldPeriods[i].getFrom()); 372 sb.append(','); 373 sb.append(fieldPeriods[i].getTo()); 374 sb.append(']'); 375 sb.append(' '); 376 } 377 System.out.println(sb.toString()); 378 380 if (mode == CPCOMP_MODE_UP) 381 periodsModeUp.add(0, fieldPeriods); 382 else 383 periodsModeDown.add(0, fieldPeriods); 384 } 385 386 if (mode == CPCOMP_MODE_UP && exitMode) { 387 exitMode = false; 388 mode = CPCOMP_MODE_DOWN; 389 highestFieldIdxModeUp = diffFieldIdx; 390 diffFieldIdx = -1; 391 isFirstFieldIdx = true; 392 } 393 394 ++diffFieldIdx; 395 if (mode == CPCOMP_MODE_DOWN && diffFieldIdx >= highestFieldIdxModeUp) 396 break; 397 398 } 400 for (int m = 0; m < 2; ++m) { 401 List srcPeriods = m == 0 ? periodsModeUp : periodsModeDown; 402 403 for (int periodIdx = 0; periodIdx < srcPeriods.size(); ++periodIdx) { 404 TimePeriod[] fieldPeriods0 = (TimePeriod[])srcPeriods.get(periodIdx); 405 if (periodIdx + 1 < srcPeriods.size()) { 406 TimePeriod[] fieldPeriods1 = (TimePeriod[])srcPeriods.get(periodIdx + 1); 407 DoubleWildCardCount wcc = countWildCards(fieldPeriods0, fieldPeriods1); 408 if (wcc.wildCardCount0 == wcc.wildCardCount1) { 409 if (fieldPeriods0[wcc.wildCardCount0].getTo() + 1 == fieldPeriods1[wcc.wildCardCount1].getFrom()) { 410 fieldPeriods0[wcc.wildCardCount0].setTo(fieldPeriods1[wcc.wildCardCount1].getTo()); 411 makeWildCards(fieldPeriods0); 412 srcPeriods.remove(periodIdx + 1); 413 } 414 if (fieldPeriods0[wcc.wildCardCount0].getFrom() == fieldPeriods1[wcc.wildCardCount1].getTo() + 1) { 415 fieldPeriods0[wcc.wildCardCount0].setFrom(fieldPeriods1[wcc.wildCardCount1].getFrom()); 416 makeWildCards(fieldPeriods1); 417 srcPeriods.remove(periodIdx + 1); 418 } 419 } 420 } 421 } 422 } 423 424 if (!periodsModeUp.isEmpty() && !periodsModeDown.isEmpty()) { 425 TimePeriod[] fieldPeriods0 = (TimePeriod[])periodsModeUp.get(0); 426 TimePeriod[] fieldPeriods1 = (TimePeriod[])periodsModeDown.get(0); 427 DoubleWildCardCount wcc = countWildCards(fieldPeriods0, fieldPeriods1); 428 if (wcc.wildCardCount0 == wcc.wildCardCount1) { 429 if (fieldPeriods0[wcc.wildCardCount0].getTo() + 1 == fieldPeriods1[wcc.wildCardCount1].getFrom()) { 430 fieldPeriods0[wcc.wildCardCount0].setTo(fieldPeriods1[wcc.wildCardCount1].getTo()); 431 makeWildCards(fieldPeriods0); 432 periodsModeDown.remove(0); 433 } 434 if (fieldPeriods0[wcc.wildCardCount0].getFrom() == fieldPeriods1[wcc.wildCardCount1].getTo() + 1) { 435 fieldPeriods0[wcc.wildCardCount0].setFrom(fieldPeriods1[wcc.wildCardCount1].getFrom()); 436 makeWildCards(fieldPeriods0); 437 periodsModeDown.remove(0); 438 } 439 } 440 } 441 442 445 System.out.println("TimePeriods in mode UP:"); 446 for (Iterator it = periodsModeUp.iterator(); it.hasNext(); ) 447 createTimePatternFromFieldPeriods((TimePeriod[]) it.next()); 448 449 System.out.println("TimePeriods in mode DOWN:"); 450 for (Iterator it = periodsModeDown.iterator(); it.hasNext(); ) 451 createTimePatternFromFieldPeriods((TimePeriod[]) it.next()); 452 } 453 454 protected static void makeWildCards(TimePeriod[] periods) 455 { 456 SimpleCalendar cal = new SimpleCalendar(); 457 int diffFieldIdx = -1; 458 for (int i = CALFIELDS.length - 1; i >= 0; --i) { 459 if (periods[i].getFrom() >= 0) { 460 cal.set(i, periods[i].getFrom()); 461 if (periods[i].getFrom() != periods[i].getTo()) 462 diffFieldIdx = i; 463 } 464 else 465 cal.set(i, cal.getActualMinimum(i)); 466 } 467 if (diffFieldIdx >= 0) { 468 if (periods[diffFieldIdx].getFrom() == cal.getActualMinimum(diffFieldIdx) && 469 periods[diffFieldIdx].getTo() == cal.getActualMaximum(diffFieldIdx)) { 470 periods[diffFieldIdx].setFrom(-1); 471 periods[diffFieldIdx].setTo(-1); 472 } 473 } 474 } 475 476 protected static class DoubleWildCardCount 477 { 478 public DoubleWildCardCount(int _wildCardCount0, int _wildCardCount1) 479 { 480 wildCardCount0 = _wildCardCount0; 481 wildCardCount1 = _wildCardCount1; 482 } 483 public int wildCardCount0; 484 public int wildCardCount1; 485 } 486 487 protected static DoubleWildCardCount countWildCards(TimePeriod[] periods0, TimePeriod[] periods1) 488 { 489 int wildCardCount0 = 0; 490 int wildCardCount1 = 0; 491 for (int i = 0; i < CALFIELDS.length; ++i) { 492 if (periods0[i].getFrom() < 0) 493 wildCardCount0 = i + 1; 494 if (periods1[i].getFrom() < 0) 495 wildCardCount1 = i + 1; 496 497 if (periods0[i].getFrom() >= 0 && periods1[i].getFrom() >= 0) 498 break; 499 } 500 return new DoubleWildCardCount(wildCardCount0, wildCardCount1); 501 } 502 503 protected void createTimePatternFromFieldPeriods(TimePeriod[] fieldPeriods) 504 { 505 String [] fieldPeriodsStr = new String [fieldPeriods.length]; 506 507 for (int i = 0; i < fieldPeriods.length; ++i) { 508 int from = fieldPeriods[i].getFrom(); 509 if (from < 0) 510 fieldPeriodsStr[i] = "*"; 511 else { 512 int to = fieldPeriods[i].getTo(); 513 if (from == to) 514 fieldPeriodsStr[i] = Integer.toString(from); 515 else { 516 StringBuffer sb = new StringBuffer (Integer.toString(from)); 517 if (from != to) 518 sb.append('-').append(Integer.toString(to)); 519 fieldPeriodsStr[i] = sb.toString(); 520 } 521 } 522 } 523 524 try { 525 System.out.println( 526 createTimePattern( 527 fieldPeriodsStr[S_YEAR], 528 fieldPeriodsStr[S_MONTH], 529 fieldPeriodsStr[S_DAY], 530 "*", 531 fieldPeriodsStr[S_HOUR], 532 fieldPeriodsStr[S_MIN])); 533 } catch (TimePatternFormatException e) { 534 throw new RuntimeException ("Something within the method \"addCondensedPeriod(...)\" went really wrong!", e); 535 } 536 } 537 538 public void setCondensedPeriod(CondensedPeriod condensedPeriod) 539 { 540 setCondensedPeriods(new CondensedPeriod[] {condensedPeriod}); 541 } 542 543 public void setCondensedPeriods(CondensedPeriod[] condensedPeriods) 544 { 545 getTimePatterns().clear(); 546 547 for (int i = 0; i < condensedPeriods.length; ++i) { 548 addCondensedPeriod(condensedPeriods[i]); 549 } 550 } 551 552 public void setCondensedPeriods(Collection condensedPeriods) 553 { 554 getTimePatterns().clear(); 555 556 for (Iterator it = condensedPeriods.iterator(); it.hasNext(); ) { 557 CondensedPeriod cp = (CondensedPeriod)it.next(); 558 addCondensedPeriod(cp); 559 } 560 } 561 562 public Collection getCondensedPeriods() 563 { 564 ArrayList periods = new ArrayList (); 565 566 return periods; 567 } 568 } 569 | Popular Tags |