2 * Copyright 2011-2012 GRNET S.A. All rights reserved.
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the following
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
30 * The views and conclusions contained in the software and
31 * documentation are those of the authors and should not be
32 * interpreted as representing official policies, either expressed
33 * or implied, of GRNET S.A.
36 package gr.grnet.aquarium.logic.accounting.dsl
38 import java.util.{GregorianCalendar, Date, Calendar}
39 import collection.mutable
42 * Represents an instance of an expanded cronstring declaration. Enforces,
43 * at object creation time, the following conditions:
47 * - -1 < `dom` < 31 and `dom` not equal to 0
48 * - -1 < `mon` < 12 and `mon` not equal to 0
51 * A value of -1 for the fields `dom`,`mon` and `dow` means that the defined
52 * time moment can be repeated within a timeframe.
53 * `min` and `hour` fields cannot be used to define repetitive time moments.
55 * @author Georgios Gousios <gousiosg@gmail.com>
57 case class DSLTimeSpec(
64 //Preconditions to force correct values on object creation
65 assert(0 <= min && 60 > min)
66 assert(0 <= hour && 24 > hour)
67 assert(-1 <= dom && 31 > dom && dom != 0)
68 assert(-1 <= mon && 12 > mon && mon != 0)
69 assert(-1 <= dow && 7 > dow)
71 /* calendar-related methods*/
72 private val cal = new GregorianCalendar()
73 private def initDay(init:Long) {
74 cal.setTimeInMillis(init)
75 cal.set(Calendar.MINUTE,min)
76 cal.set(Calendar.HOUR_OF_DAY,hour)
77 cal.set(Calendar.SECOND,0)
79 private def nextValidDay(end:Long) (): Date = {
81 while (cal.getTimeInMillis <= end && ret == null) {
82 val valid : Boolean = (mon < 0 || cal.get(Calendar.MONTH) == getCalendarMonth()) &&
83 (dom < 0 || cal.get(Calendar.DAY_OF_MONTH) == dom) &&
84 (dow < 0 || cal.get(Calendar.DAY_OF_WEEK) == getCalendarDow())
87 cal.add(Calendar.DAY_OF_YEAR, 1)
92 def expandTimeSpec(from: Date, to: Date) : List[Date] = {
93 val result = new mutable.ListBuffer[Date]()
94 val nextDay = this.nextValidDay (to.getTime) _
97 while({d=nextDay();d}!=null) result += d
101 /** Day of week conversions to stay compatible with [[java.util.Calendar]] */
102 private def getCalendarDow(): Int = dow match {
103 case 0 => Calendar.SUNDAY
104 case 1 => Calendar.MONDAY
105 case 2 => Calendar.TUESDAY
106 case 3 => Calendar.WEDNESDAY
107 case 4 => Calendar.THURSDAY
108 case 5 => Calendar.FRIDAY
109 case 6 => Calendar.SATURDAY
110 case 7 => Calendar.SUNDAY
113 /** Month conversions to stay compatible with [[java.util.Calendar]] */
114 private def getCalendarMonth(): Int = mon match {
115 case 1 => Calendar.JANUARY
116 case 2 => Calendar.FEBRUARY
117 case 3 => Calendar.MARCH
118 case 4 => Calendar.APRIL
119 case 5 => Calendar.MAY
120 case 6 => Calendar.JUNE
121 case 7 => Calendar.JULY
122 case 8 => Calendar.AUGUST
123 case 9 => Calendar.SEPTEMBER
124 case 10 => Calendar.OCTOBER
125 case 11 => Calendar.NOVEMBER
126 case 12 => Calendar.DECEMBER
131 val emtpyTimeSpec = DSLTimeSpec(0,0, -1, -1, -1)
133 def expandTimeSpec(d0:DSLTimeSpec,d1:DSLTimeSpec, from: Date, to: Date) : List[(Date,Date)] = {
138 val result = new mutable.ListBuffer[(Date,Date)]()
139 val d0_nextDay = d0.nextValidDay (to.getTime) _ /* iterator for valid dates of d0*/
140 val d1_nextDay = d1.nextValidDay (to.getTime) _ /* iterator for valid dates of d1*/
141 var d0_d : Date = null
142 d0.initDay(from.getTime)
143 while({d0_d=d0_nextDay();d0_d}!=null){
144 val d1_d : Date = {d1.initDay(d0_d.getTime);d1_nextDay()}
145 if(d1_d!=null) result += ((d0_d,d1_d))