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