View Javadoc

1   /*
2    * Copyright (c) 2011.  The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.expreval.expr.function;
22  
23  import org.apache.expreval.client.NullColumnValueException;
24  import org.apache.expreval.client.ResultMissingColumnException;
25  import org.apache.expreval.expr.literal.DateLiteral;
26  import org.apache.expreval.expr.node.DateValue;
27  import org.apache.expreval.expr.node.GenericValue;
28  import org.apache.hadoop.hbase.hbql.client.HBqlException;
29  import org.apache.hadoop.hbase.hbql.impl.HConnectionImpl;
30  
31  import java.text.ParseException;
32  import java.text.SimpleDateFormat;
33  import java.util.List;
34  
35  public class DateFunction extends GenericFunction implements DateValue {
36  
37      public enum ConstantType {
38          NOW(0),
39          MINDATE(0),
40          MAXDATE(Long.MAX_VALUE);
41  
42          final long value;
43  
44          ConstantType(final long value) {
45              this.value = value;
46          }
47  
48          public long getValue() {
49              return this.value;
50          }
51  
52          public static GenericFunction getFunction(final String functionName) {
53  
54              try {
55                  final ConstantType type = ConstantType.valueOf(functionName.toUpperCase());
56                  return new DateFunction(type);
57              }
58              catch (IllegalArgumentException e) {
59                  return null;
60              }
61          }
62      }
63  
64      public enum IntervalType {
65          MILLI(1),
66          SECOND(1000 * MILLI.getIntervalMillis()),
67          MINUTE(60 * SECOND.getIntervalMillis()),
68          HOUR(60 * MINUTE.getIntervalMillis()),
69          DAY(24 * HOUR.getIntervalMillis()),
70          WEEK(7 * DAY.getIntervalMillis()),
71          YEAR(52 * WEEK.getIntervalMillis());
72  
73          private final long intervalMillis;
74  
75          IntervalType(final long intervalMillis) {
76              this.intervalMillis = intervalMillis;
77          }
78  
79          public long getIntervalMillis() {
80              return intervalMillis;
81          }
82  
83          public static GenericFunction getFunction(final String functionName, final List<GenericValue> exprList) {
84  
85              try {
86                  final IntervalType type = IntervalType.valueOf(functionName.toUpperCase());
87                  return new DateFunction(type, exprList);
88              }
89              catch (IllegalArgumentException e) {
90                  return null;
91              }
92          }
93      }
94  
95      private ConstantType constantType;
96      private IntervalType intervalType;
97      private DateLiteral  dateValue;
98  
99      public DateFunction(final FunctionType functionType, final List<GenericValue> exprs) {
100         super(functionType, exprs);
101     }
102 
103     public DateFunction(final ConstantType constantType) {
104         super(FunctionType.DATECONSTANT, null);
105         this.constantType = constantType;
106         switch (this.getConstantType()) {
107             case NOW:
108                 this.dateValue = new DateLiteral(DateLiteral.getNow());
109                 break;
110             case MINDATE:
111             case MAXDATE:
112                 this.dateValue = new DateLiteral(constantType.getValue());
113                 break;
114         }
115     }
116 
117     public DateFunction(final IntervalType intervalType, final List<GenericValue> exprs) {
118         super(FunctionType.DATEINTERVAL, exprs);
119         this.intervalType = intervalType;
120     }
121 
122     private ConstantType getConstantType() {
123         return this.constantType;
124     }
125 
126     private IntervalType getIntervalType() {
127         return this.intervalType;
128     }
129 
130     public Long getValue(final HConnectionImpl conn, final Object object) throws HBqlException,
131                                                                                  ResultMissingColumnException,
132                                                                                  NullColumnValueException {
133         switch (this.getFunctionType()) {
134 
135             case DATE: {
136                 final String datestr = (String)this.getExprArg(0).getValue(conn, object);
137                 final String pattern = (String)this.getExprArg(1).getValue(conn, object);
138                 final SimpleDateFormat formatter = new SimpleDateFormat(pattern);
139 
140                 try {
141                     return formatter.parse(datestr).getTime();
142                 }
143                 catch (ParseException e) {
144                     throw new HBqlException(e.getMessage());
145                 }
146             }
147 
148             case DATEINTERVAL: {
149                 final Number num = (Number)this.getExprArg(0).getValue(conn, object);
150                 final long val = num.longValue();
151                 return val * this.getIntervalType().getIntervalMillis();
152             }
153 
154             case DATECONSTANT: {
155                 return this.dateValue.getValue(conn, object);
156             }
157 
158             case RANDOMDATE: {
159                 return Math.abs(GenericFunction.randomVal.nextLong());
160             }
161 
162             case LONGTODATE: {
163                 final Number num = (Number)this.getExprArg(0).getValue(conn, object);
164                 final long val = num.longValue();
165                 this.dateValue = new DateLiteral(val);
166                 return this.dateValue.getValue(conn, object);
167             }
168 
169             default:
170                 throw new HBqlException("Invalid function: " + this.getFunctionType());
171         }
172     }
173 
174     protected String getFunctionName() {
175         if (this.isIntervalDate())
176             return this.getIntervalType().name();
177         else if (this.isConstantDate())
178             return this.getConstantType().name();
179         else
180             return super.getFunctionName();
181     }
182 
183     public String asString() {
184         if (this.isIntervalDate())
185             return this.getIntervalType().name() + "(" + this.getExprArg(0).asString() + ")";
186         else if (this.isConstantDate())
187             return this.getConstantType().name() + "()";
188         else
189             return super.asString();
190     }
191 }