1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.expreval.expr;
22
23 import org.apache.expreval.client.InternalErrorException;
24 import org.apache.expreval.expr.literal.BooleanLiteral;
25 import org.apache.expreval.expr.literal.ByteLiteral;
26 import org.apache.expreval.expr.literal.DateLiteral;
27 import org.apache.expreval.expr.literal.DoubleLiteral;
28 import org.apache.expreval.expr.literal.FloatLiteral;
29 import org.apache.expreval.expr.literal.IntegerLiteral;
30 import org.apache.expreval.expr.literal.LongLiteral;
31 import org.apache.expreval.expr.literal.ShortLiteral;
32 import org.apache.expreval.expr.literal.StringLiteral;
33 import org.apache.expreval.expr.node.BooleanValue;
34 import org.apache.expreval.expr.node.ByteValue;
35 import org.apache.expreval.expr.node.DateValue;
36 import org.apache.expreval.expr.node.DoubleValue;
37 import org.apache.expreval.expr.node.FloatValue;
38 import org.apache.expreval.expr.node.GenericValue;
39 import org.apache.expreval.expr.node.IntegerValue;
40 import org.apache.expreval.expr.node.LongValue;
41 import org.apache.expreval.expr.node.NumberValue;
42 import org.apache.expreval.expr.node.ShortValue;
43 import org.apache.expreval.expr.node.StringValue;
44 import org.apache.hadoop.hbase.hbql.client.HBqlException;
45 import org.apache.hadoop.hbase.hbql.util.Lists;
46
47 import java.io.Serializable;
48 import java.lang.reflect.Constructor;
49 import java.lang.reflect.InvocationTargetException;
50 import java.util.Arrays;
51 import java.util.Date;
52 import java.util.List;
53
54 public abstract class TypeSignature implements Serializable {
55
56 private static final long serialVersionUID = 1L;
57
58 private Class<? extends GenericValue> returnType;
59 private List<Class<? extends GenericValue>> argsTypeSignature = Lists.newArrayList();
60
61 private Class literalCastClass;
62 private transient Constructor literalConstructor;
63
64 public TypeSignature() {
65 }
66
67 public TypeSignature(final Class<? extends GenericValue> returnType,
68 final Class<? extends GenericValue>... argsTypeSignature) {
69 this.returnType = returnType;
70 this.argsTypeSignature.addAll(Arrays.asList(argsTypeSignature));
71
72 this.literalCastClass = this.getLiteralCastClass(this.getReturnType());
73 this.literalConstructor = this.getLiteralConstructor(this.getReturnType(), this.getLiteralCastClass());
74 }
75
76 public Class<? extends GenericValue> getReturnType() {
77 return this.returnType;
78 }
79
80 public List<Class<? extends GenericValue>> getArgTypeList() {
81 return this.argsTypeSignature;
82 }
83
84 private Constructor getLiteralConstructor() {
85 return this.literalConstructor;
86 }
87
88 private Class getLiteralCastClass() {
89 return this.literalCastClass;
90 }
91
92 public Class<? extends GenericValue> getArg(final int i) {
93 return this.getArgTypeList().get(i);
94 }
95
96 public int getArgCount() {
97 return this.getArgTypeList().size();
98 }
99
100 private Class getLiteralCastClass(final Class<? extends GenericValue> clazz) {
101
102 if (clazz == null)
103 return null;
104 else if (clazz == BooleanValue.class)
105 return Boolean.class;
106 else if (clazz == ByteValue.class)
107 return Byte.class;
108 else if (clazz == ShortValue.class)
109 return Short.class;
110 else if (clazz == IntegerValue.class)
111 return Integer.class;
112 else if (clazz == LongValue.class)
113 return Long.class;
114 else if (clazz == FloatValue.class)
115 return Float.class;
116 else if (clazz == DoubleValue.class)
117 return Double.class;
118 else if (clazz == NumberValue.class)
119 return Number.class;
120 else if (clazz == StringValue.class)
121 return String.class;
122 else if (clazz == DateValue.class)
123 return Long.class;
124 else {
125 throw new RuntimeException("Invalid return type in signature: " + clazz.getName());
126 }
127 }
128
129 private Constructor getLiteralConstructor(final Class clazz, final Class aLiteralCastClass) {
130
131 final Class retval;
132
133 try {
134 if (clazz == null)
135 return null;
136 else if (clazz == BooleanValue.class || clazz == Boolean.class)
137 retval = BooleanLiteral.class;
138 else if (NumericType.isAByte(clazz))
139 retval = ByteLiteral.class;
140 else if (NumericType.isAShort(clazz))
141 retval = ShortLiteral.class;
142 else if (NumericType.isAnInteger(clazz))
143 retval = IntegerLiteral.class;
144 else if (NumericType.isALong(clazz))
145 retval = LongLiteral.class;
146 else if (NumericType.isAFloat(clazz))
147 retval = FloatLiteral.class;
148 else if (NumericType.isADouble(clazz))
149 retval = DoubleLiteral.class;
150 else if (clazz == NumberValue.class || clazz == Number.class)
151 return null;
152 else if (clazz == StringValue.class || clazz == String.class)
153 retval = StringLiteral.class;
154 else if (clazz == DateValue.class || clazz == Date.class)
155 retval = DateLiteral.class;
156 else
157 throw new RuntimeException("Invalid return type in signature: " + clazz.getName());
158
159 return retval.getConstructor(aLiteralCastClass);
160 }
161 catch (NoSuchMethodException e) {
162 throw new RuntimeException("Invalid literal constructor in signature: " + clazz.getName());
163 }
164 }
165
166 public GenericValue newLiteral(final Object val) throws HBqlException {
167 try {
168
169 final Constructor constructor;
170 final Object castedObject;
171
172 if (this.getReturnType() == NumberValue.class) {
173 constructor = this.getLiteralConstructor(val.getClass(), val.getClass());
174 castedObject = val;
175 }
176 else {
177 constructor = this.getLiteralConstructor();
178 castedObject = this.getLiteralCastClass().cast(val);
179 }
180
181 return (GenericValue)constructor.newInstance(castedObject);
182 }
183 catch (InstantiationException e) {
184 throw new InternalErrorException(e.getMessage());
185 }
186 catch (IllegalAccessException e) {
187 throw new InternalErrorException(e.getMessage());
188 }
189 catch (InvocationTargetException e) {
190 throw new InternalErrorException(e.getMessage());
191 }
192 }
193 }