001: /*
002: * Copyright 2004-2007 Gary Bentley
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may
005: * not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software
010: * distributed under the License is distributed on an "AS IS" BASIS,
011: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: * See the License for the specific language governing permissions and
013: * limitations under the License.
014: */
015: package org.josql.functions;
016:
017: import java.io.File;
018:
019: import java.util.Random;
020: import java.util.List;
021: import java.util.Date;
022: import java.util.Calendar;
023: import java.util.Map;
024: import java.util.HashMap;
025:
026: import com.gentlyweb.utils.Getter;
027:
028: import org.josql.QueryExecutionException;
029:
030: import org.josql.expressions.Expression;
031:
032: public class MiscellaneousFunctions extends AbstractFunctionHandler {
033:
034: public static final String HANDLER_ID = "_internal_misc";
035:
036: private Map accessorCache = new HashMap();
037:
038: private Random rand = new Random();
039:
040: /**
041: * Return the current date.
042: *
043: * @param zeroTime If set to <code>true</code> then the date returned will have it's time fields
044: * set to zero.
045: * @return A date object.
046: */
047: public Date now(boolean zeroTime) {
048:
049: Date d = null;
050:
051: if (zeroTime) {
052:
053: Calendar c = Calendar.getInstance();
054:
055: c.set(Calendar.HOUR_OF_DAY, 0);
056: c.set(Calendar.MINUTE, 0);
057: c.set(Calendar.SECOND, 0);
058: c.set(Calendar.MILLISECOND, 0);
059:
060: d = c.getTime();
061:
062: } else {
063:
064: d = new Date();
065:
066: }
067:
068: return d;
069:
070: }
071:
072: public void cache(List allobjs, Getter get)
073: throws QueryExecutionException {
074:
075: int s = allobjs.size();
076:
077: for (int i = 0; i < s; i++) {
078:
079: Object o = allobjs.get(i);
080:
081: try {
082:
083: this .q.setSaveValue(o, get.getValue(o));
084:
085: } catch (Exception e) {
086:
087: throw new QueryExecutionException(
088: "Unable to get value from accessor: " + get
089: + " from object: " + i, e);
090:
091: }
092:
093: }
094:
095: }
096:
097: public void cache(List allobjs, Expression exp)
098: throws QueryExecutionException {
099:
100: Object co = this .q.getCurrentObject();
101:
102: int s = allobjs.size();
103:
104: for (int i = 0; i < s; i++) {
105:
106: Object o = allobjs.get(i);
107:
108: this .q.setCurrentObject(o);
109:
110: try {
111:
112: this .q.setSaveValue(o, exp.getValue(o, q));
113:
114: } catch (Exception e) {
115:
116: throw new QueryExecutionException(
117: "Unable to get value from expression: " + exp
118: + " from object: " + i, e);
119:
120: }
121:
122: }
123:
124: this .q.setCurrentObject(co);
125:
126: }
127:
128: public double abs(Number d) {
129:
130: return Math.abs(d.doubleValue());
131:
132: }
133:
134: public int random() {
135:
136: return this .rand.nextInt();
137:
138: }
139:
140: public int random(Number n) {
141:
142: return this .rand.nextInt(n.intValue());
143:
144: }
145:
146: public double randomDouble() {
147:
148: return this .rand.nextDouble();
149:
150: }
151:
152: public Object saveValue(Object saveValueName) {
153:
154: return this .q.getSaveValue(saveValueName);
155:
156: }
157:
158: public Object savevalue(Object saveValueName) {
159:
160: return this .q.getSaveValue(saveValueName);
161:
162: }
163:
164: public Object save_value(Object saveValueName) {
165:
166: return this .q.getSaveValue(saveValueName);
167:
168: }
169:
170: public String fileExtension(Object f) {
171:
172: if (f == null) {
173:
174: return null;
175:
176: }
177:
178: String n = null;
179:
180: if (f instanceof String) {
181:
182: n = (String) f;
183:
184: }
185:
186: if (f instanceof File) {
187:
188: File fi = (File) f;
189:
190: if (fi.isDirectory()) {
191:
192: return null;
193:
194: }
195:
196: n = ((File) f).getName();
197:
198: }
199:
200: return n.substring(n.lastIndexOf('.') + 1);
201:
202: }
203:
204: /**
205: * Call the specified accessor on the object.
206: *
207: * @param oExp The expression to use to evaluate to get the object.
208: * @param accExp The expression that is evaluated to get the accessor.
209: * @return The value returned from the accessor.
210: * @throws Exception If there is something wrong.
211: */
212: public Object accessor(Expression oExp, Expression accExp)
213: throws Exception {
214:
215: // Get the value for the object.
216: Object o = null;
217:
218: try {
219:
220: o = oExp.getValue(this .q.getCurrentObject(), this .q);
221:
222: } catch (Exception e) {
223:
224: throw new QueryExecutionException(
225: "Unable to evaluate expression: " + oExp
226: + " to get object.");
227:
228: }
229:
230: Object a = null;
231:
232: try {
233:
234: a = accExp.getValue(this .q.getCurrentObject(), this .q);
235:
236: } catch (Exception e) {
237:
238: throw new QueryExecutionException(
239: "Unable to evaluate expression: " + accExp
240: + " to get accessor.");
241:
242: }
243:
244: if (a == null) {
245:
246: throw new QueryExecutionException("Accessor expression: "
247: + accExp + " evaluates to null for object: " + o
248: + " returned from expression: " + oExp);
249:
250: }
251:
252: // Co-erce to a string.
253: return this .accessor(o, a.toString());
254:
255: }
256:
257: /**
258: * Call the specified accessor on the object.
259: *
260: * @param o The object to call the accessor on.
261: * @param acc The accessor.
262: * @return The value returned from the accessor.
263: * @throws Exception If there is something wrong.
264: */
265: public Object accessor(Object o, String acc) throws Exception {
266:
267: if (o == null) {
268:
269: return null;
270:
271: }
272:
273: // See if we already have the getter.
274: Getter g = (Getter) this .accessorCache.get(o.getClass()
275: .getName()
276: + acc);
277:
278: if (g == null) {
279:
280: // Create a new Getter for the class of the object.
281: g = new Getter(acc, o.getClass());
282:
283: this .accessorCache.put(o.getClass().getName() + acc, g);
284:
285: }
286:
287: return g.getValue(o);
288:
289: }
290:
291: public Object ifThen(Expression ifcond, Expression thenVal)
292: throws QueryExecutionException {
293:
294: if (ifcond.isTrue(this .q.getCurrentObject(), this .q)) {
295:
296: return thenVal.getValue(this .q.getCurrentObject(), this .q);
297:
298: }
299:
300: return null;
301:
302: }
303:
304: public Object ifThenElse(Expression ifcond, Expression thenVal,
305: Expression elseVal) throws QueryExecutionException {
306:
307: Object i = this .ifThen(ifcond, thenVal);
308:
309: if (i == null) {
310:
311: return elseVal.getValue(this .q.getCurrentObject(), this .q);
312:
313: }
314:
315: return i;
316:
317: }
318:
319: public Object eval(Expression exp) throws QueryExecutionException {
320:
321: return exp.getValue(this .q.getCurrentObject(), this .q);
322:
323: }
324:
325: /**
326: * Evaluates the <b>type</b> expression to produce a object whose type
327: * should be compared against the class gained from evaluation of the
328: * <b>clazz</b> expression.
329: * In effect the following is performed:
330: * <pre>
331: * obj.getValue (q.getCurrentObject (), q)
332: * instanceof clazz.getValue (q.getCurrentObject (), q).getClass ()
333: * </pre>
334: * <p>
335: * This is really just a thin wrapper around {@link Class#isInstance(Object)}.
336: *
337: * @param obj The expression that represents the object to
338: * against.
339: * @param clazz The expression that represents the class of the type
340: * to compare against.
341: * @throws QueryExecutionException If either of the expressions can't
342: * be evaluated.
343: */
344: public Boolean instanceOf(Expression obj, Expression clazz)
345: throws QueryExecutionException {
346:
347: return Boolean.valueOf(clazz.getValue(
348: this.q.getCurrentObject(), q).getClass().isInstance(
349: obj.getValue(this.q.getCurrentObject(), q)));
350:
351: }
352:
353: }
|