| 1 16 package org.outerj.daisy.query.model.functions; 17 18 import org.outerj.daisy.repository.Document; 19 import org.outerj.daisy.repository.Version; 20 import org.outerj.daisy.repository.query.QueryException; 21 import org.outerj.daisy.repository.query.EvaluationContext; 22 import org.outerj.daisy.query.QueryContext; 23 import org.outerj.daisy.query.model.AbstractFunction; 24 import org.outerj.daisy.query.model.SqlGenerationContext; 25 import org.outerj.daisy.query.model.QValueType; 26 import org.outerj.daisy.query.model.ValueExpr; 27 28 import java.util.Locale ; 29 import java.util.Date ; 30 import java.util.Calendar ; 31 import java.util.GregorianCalendar ; 32 import java.util.regex.Pattern ; 33 import java.util.regex.Matcher ; 34 import java.sql.PreparedStatement ; 35 import java.sql.SQLException ; 36 import java.sql.Timestamp ; 37 38 public class CurrentDateTimeFunction extends AbstractFunction { 39 public static final String NAME = "CurrentDateTime"; 40 41 public String getFunctionName() { 42 return NAME; 43 } 44 45 public void prepare(QueryContext context) throws QueryException { 46 super.prepare(context); 47 if (params.size() > 1) 48 throw new QueryException(getFunctionName() + " takes at most 1 (optional) parameter."); 49 50 if (params.size() == 1) { 51 ValueExpr param = getParam(0); 52 if ((param.getValueType() != QValueType.STRING && param.getValueType() != QValueType.UNDEFINED) 53 || param.isMultiValue() || param.isSymbolicIdentifier()) 54 throw new QueryException("Invalid argument for " + getFunctionName() + " function: " + param.getExpression()); 55 } 56 } 57 58 public void generateSqlValueExpr(StringBuffer sql, SqlGenerationContext context) throws QueryException { 59 sql.append(" ? "); 60 } 61 62 public int bindValueExpr(PreparedStatement stmt, int bindPos, QValueType valueType, EvaluationContext evaluationContext) throws SQLException , QueryException { 63 stmt.setTimestamp(bindPos, new Timestamp (((Date )evaluate(null, evaluationContext)).getTime())); 64 return ++bindPos; 65 } 66 67 public Object evaluate(QValueType valueType, EvaluationContext evaluationContext) throws QueryException { 68 if (params.size() == 1) 69 return getDate((String )getParam(0).evaluate(QValueType.STRING, evaluationContext)); 70 else 71 return getDate(null); 72 } 73 74 public Object evaluate(QValueType valueType, Document document, Version version, EvaluationContext evaluationContext) throws QueryException { 75 if (params.size() == 1) 76 return getDate((String )getParam(0).evaluate(QValueType.STRING, document, version, evaluationContext)); 77 else 78 return getDate(null); 79 } 80 81 public QValueType getValueType() { 82 return QValueType.DATETIME; 83 } 84 85 public String getTitle(Locale locale) { 86 return getExpression(); 87 } 88 89 public QValueType getOutputValueType() { 90 return QValueType.DATETIME; 91 } 92 93 public Object getOutputValue(Document document, Version version, EvaluationContext evaluationContext) throws QueryException { 94 return evaluate(null, document, version, evaluationContext); 95 } 96 97 protected Date getDate(String expression) throws QueryException { 98 Calendar calendar = new GregorianCalendar (); 99 calendar.setLenient(false); 100 calendar.set(Calendar.MILLISECOND, 0); 101 if (expression != null) { 102 int[] valueAndField = parseExpression(expression); 103 calendar.add(valueAndField[1], valueAndField[0]); 104 } 105 return calendar.getTime(); 106 } 107 108 protected int[] parseExpression(String expression) throws QueryException { 109 Pattern pattern = Pattern.compile("([+-])\\s*([0-9]+)\\s*(days|weeks|months|years|hours|minutes|seconds)"); 110 Matcher matcher = pattern.matcher(expression); 111 if (!matcher.matches()) 112 throw new QueryException("Invalid relative datetime expression: \"" + expression + "\""); 113 int value = Integer.parseInt(matcher.group(2)); 114 if (matcher.group(1).equals("-")) 115 value = value * -1; 116 117 String fieldName = matcher.group(3); 118 int field; 119 if (fieldName.equals("days")) 120 field = Calendar.DATE; 121 else if (fieldName.equals("weeks")) 122 field = Calendar.WEEK_OF_YEAR; 123 else if (fieldName.equals("months")) 124 field = Calendar.MONTH; 125 else if (fieldName.equals("years")) 126 field = Calendar.YEAR; 127 else if (fieldName.equals("hours")) 128 field = Calendar.HOUR_OF_DAY; 129 else if (fieldName.equals("minutes")) 130 field = Calendar.MINUTE; 131 else if (fieldName.equals("seconds")) 132 field = Calendar.SECOND; 133 else 134 throw new RuntimeException ("Unexpected value for datetime field name in " + NAME + " function: " + fieldName); 135 136 return new int[] {value, field}; 137 } 138 } 139 | Popular Tags |