KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > outerj > daisy > query > model > functions > RelativeDateTimeFunction


1 /*
2  * Copyright 2004 Outerthought bvba and Schaubroeck nv
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.outerj.daisy.query.model.functions;
17
18 import org.outerj.daisy.query.model.AbstractFunction;
19 import org.outerj.daisy.query.model.ValueExpr;
20 import org.outerj.daisy.query.model.QValueType;
21 import org.outerj.daisy.query.model.SqlGenerationContext;
22 import org.outerj.daisy.query.QueryContext;
23 import org.outerj.daisy.repository.query.QueryException;
24 import org.outerj.daisy.repository.query.EvaluationContext;
25 import org.outerj.daisy.repository.Document;
26 import org.outerj.daisy.repository.Version;
27
28 import java.util.*;
29 import java.util.regex.Pattern JavaDoc;
30 import java.util.regex.Matcher JavaDoc;
31 import java.sql.PreparedStatement JavaDoc;
32 import java.sql.SQLException JavaDoc;
33
34
35 public class RelativeDateTimeFunction extends AbstractFunction {
36     public static final String JavaDoc NAME = "RelativeDateTime";
37
38     public String JavaDoc getFunctionName() {
39         return NAME;
40     }
41
42     public void prepare(QueryContext context) throws QueryException {
43         super.prepare(context);
44         if (params.size() != 1)
45             throw new QueryException(getFunctionName() + " takes exactly 1 parameter.");
46
47         ValueExpr param = getParam(0);
48         if ((param.getValueType() != QValueType.STRING && param.getValueType() != QValueType.UNDEFINED)
49                 || param.isMultiValue() || param.isSymbolicIdentifier())
50             throw new QueryException("Invalid argument for " + getFunctionName() + " function: " + param.getExpression());
51     }
52
53     public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) throws QueryException {
54         sql.append(" ? ");
55     }
56
57     public int bindValueExpr(PreparedStatement JavaDoc stmt, int bindPos, QValueType valueType, EvaluationContext evaluationContext) throws SQLException JavaDoc, QueryException {
58         stmt.setDate(bindPos, new java.sql.Date JavaDoc(((Date)evaluate(null, evaluationContext)).getTime()));
59         return ++bindPos;
60     }
61
62     public Object JavaDoc evaluate(QValueType valueType, EvaluationContext evaluationContext) throws QueryException {
63         return getDate((String JavaDoc)getParam(0).evaluate(QValueType.STRING, evaluationContext));
64     }
65
66     public Object JavaDoc evaluate(QValueType valueType, Document document, Version version, EvaluationContext evaluationContext) throws QueryException {
67         return getDate((String JavaDoc)getParam(0).evaluate(QValueType.STRING, document, version, evaluationContext));
68     }
69
70     public QValueType getValueType() {
71         return QValueType.DATETIME;
72     }
73
74     public String JavaDoc getTitle(Locale locale) {
75         return getExpression();
76     }
77
78     public QValueType getOutputValueType() {
79         return QValueType.DATETIME;
80     }
81
82     public Object JavaDoc getOutputValue(Document document, Version version, EvaluationContext evaluationContext) throws QueryException {
83         return evaluate(null, document, version, evaluationContext);
84     }
85
86
87     private Date getDate(String JavaDoc spec) throws QueryException {
88         Pattern JavaDoc pattern = Pattern.compile("^([a-z]+)\\s([a-z]+)\\s([a-z]+)$");
89         Matcher JavaDoc matcher = pattern.matcher(spec);
90         if (matcher.matches()) {
91             // parse start or end field
92
String JavaDoc startOrEnd = matcher.group(1);
93             boolean start;
94             if (startOrEnd.equals("start"))
95                 start = true;
96             else if (startOrEnd.equals("end"))
97                 start = false;
98             else
99                 throw new QueryException(getFunctionName() + " function: first part of expression should be 'start' or 'end', but got " + startOrEnd);
100
101             // parse this/next/last
102
String JavaDoc shiftParam = matcher.group(2);
103             int shift;
104             if (shiftParam.equals("this"))
105                 shift = 0;
106             else if (shiftParam.equals("next"))
107                 shift = 1;
108             else if (shiftParam.equals("last"))
109                 shift = -1;
110             else
111                 throw new QueryException(getFunctionName() + " function: second part of expression should be 'this', 'next' or 'last', but got " + shiftParam);
112
113             // parse week/month/year
114
String JavaDoc unitParam = matcher.group(3);
115             int shiftUnit;
116             int dayInShiftUnit;
117             if (unitParam.equals("week")) {
118                 shiftUnit = Calendar.WEEK_OF_YEAR;
119                 dayInShiftUnit = Calendar.DAY_OF_WEEK;
120             } else if (unitParam.equals("month")) {
121                 shiftUnit = Calendar.MONTH;
122                 dayInShiftUnit = Calendar.DAY_OF_MONTH;
123             } else if (unitParam.equals("year")) {
124                 shiftUnit = Calendar.YEAR;
125                 dayInShiftUnit = Calendar.DAY_OF_YEAR;
126             } else {
127                 throw new QueryException(getFunctionName() + " function: third part of expression should be 'week', 'month' or 'calendar', but got " + unitParam);
128             }
129
130             return calcDate(start, shift, shiftUnit, dayInShiftUnit).getTime();
131         } else {
132             throw new QueryException("Invalid specification for " + getFunctionName() + " function: " + spec);
133         }
134     }
135
136     protected Calendar calcDate(boolean start, int shift, int shiftUnit, int dayInShiftUnit) {
137         GregorianCalendar calendar = new GregorianCalendar();
138
139         if (shift != 0)
140             calendar.roll(shiftUnit, shift);
141
142         if (start)
143             calendar.set(dayInShiftUnit, calendar.getActualMinimum(dayInShiftUnit));
144         else
145             calendar.set(dayInShiftUnit, calendar.getActualMaximum(dayInShiftUnit));
146
147         if (start) {
148             calendar.set(Calendar.HOUR_OF_DAY, 0);
149             calendar.set(Calendar.MINUTE, 0);
150             calendar.set(Calendar.SECOND, 0);
151         } else {
152             calendar.set(Calendar.HOUR_OF_DAY, 23);
153             calendar.set(Calendar.MINUTE, 59);
154             calendar.set(Calendar.SECOND, 59);
155         }
156         // we only work up to second precision
157
calendar.set(Calendar.MILLISECOND, 0);
158
159         return calendar;
160     }
161
162 }
163
Popular Tags