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 org.quartz.CronExpression
42 * @author Prodromos Gerakios <pgerakios@grnet.gr>
45 case class DSLCronSpec(cronSpec: String) {
47 private val cronExpr = {
48 val e = "00 " + cronSpec.trim //IMPORTANT: WE DO NOT CARE ABOUT SECONDS!!!
50 assert(l.size == 6,"Invalid cron specification")
51 //for {ll <- l } Console.err.println(ll)
53 case ("?",_) | (_,"?") => ()
54 case (_,"*") => l.update(5,"?")
55 case ("*",_) => l.update(3,"?")
57 val e1 = l.foldLeft("") { (s,elt) => s + " " + elt}
58 //Console.err.println("e = " + e + " and e1 = " + e1)
59 new CronExpression(e1)
62 def includes(d:Date) : Boolean =
63 cronExpr isSatisfiedBy d
65 /* the next valid date cannot outlive (min,max)*/
66 def nextValidDate(min0:Date,max0:Date,d:Date) : Option[Date] =
67 (cronExpr getNextValidTimeAfter d) match {
71 val (min,max,e) = (min0.getTime,max0.getTime,d1.getTime)
75 Some({assert(d1.getTime>=d.getTime);d1})
78 /*def nextValidDate(d:Date) : Date = {
79 val ret = cronExpr getNextValidTimeAfter d
83 /*def nextContinuousValidDate(d:Date) : Date = {
84 val d1 = cronExpr getNextInvalidTimeAfter d
86 d1.setTime(d1.getTime - 1000) /* 1 sec before was valid so return this*/
91 def getMaxValidBeforeDate(min0:Date , max0:Date,d:Date) : Option[Date] ={
92 val (min,max,e) = (min0.getTime,max0.getTime,d.getTime)
93 if(min > e || max < e) None
94 else if(includes(d)) Some(d)
100 val tmp = new Date(0L)
101 val step = 10000L * 60L // 1 minute
104 val pivot = (end - start) / 2 + start
106 val next = nextValidDate(tmp)
107 if(next == null){ /* no valid time after pivot*/
108 end = pivot-step; // pivot minus one
110 val p = next.getTime()
111 if(p < e) { /* next date occurs before e*/
112 val post = next.getTime < d.getTime
113 assert(post,"BUG!!!")
116 } else if( p > e) { /* next date occurs after e*/
119 else assert(false,"This should not happen")
121 // System.err.println("Start: " + new Date(start) + " end: " + new Date(end));
123 System.err.println("Iterations " + iterations);
124 if(best!=null) Some(best) else None
131 val emptyCronSpec = new DSLCronSpec("? ? ? ? ?")