1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.healthmarketscience.jackcess.impl.expr;
18
19 import java.math.BigDecimal;
20 import java.text.DecimalFormatSymbols;
21
22 import com.healthmarketscience.jackcess.expr.EvalException;
23 import com.healthmarketscience.jackcess.expr.LocaleContext;
24 import com.healthmarketscience.jackcess.expr.Value;
25 import org.apache.commons.lang3.StringUtils;
26
27
28
29
30
31 public class StringValue extends BaseValue
32 {
33 private static final Object NOT_A_NUMBER = new Object();
34
35 private final String _val;
36 private Object _num;
37
38 public StringValue(String val)
39 {
40 _val = val;
41 }
42
43 @Override
44 public Type getType() {
45 return Type.STRING;
46 }
47
48 @Override
49 public Object get() {
50 return _val;
51 }
52
53 @Override
54 public boolean getAsBoolean(LocaleContext ctx) {
55
56 return true;
57 }
58
59 @Override
60 public String getAsString(LocaleContext ctx) {
61 return _val;
62 }
63
64 @Override
65 public Integer getAsLongInt(LocaleContext ctx) {
66 return roundToLongInt(ctx);
67 }
68
69 @Override
70 public Double getAsDouble(LocaleContext ctx) {
71 return getNumber(ctx).doubleValue();
72 }
73
74 @Override
75 public BigDecimal getAsBigDecimal(LocaleContext ctx) {
76 return getNumber(ctx);
77 }
78
79 @Override
80 public Value getAsDateTimeValue(LocaleContext ctx) {
81 Value dateValue = DefaultDateFunctions.stringToDateValue(ctx, _val);
82
83 if(dateValue == null) {
84
85
86 try {
87 dateValue = DefaultDateFunctions.numberToDateValue(
88 getNumber(ctx).doubleValue());
89 } catch(EvalException ignored) {
90
91 }
92
93 if(dateValue == null) {
94 throw invalidConversion(Type.DATE_TIME);
95 }
96 }
97
98
99
100 return dateValue;
101 }
102
103 protected BigDecimal getNumber(LocaleContext ctx) {
104 if(_num instanceof BigDecimal) {
105 return (BigDecimal)_num;
106 }
107 if(_num == null) {
108
109 try {
110
111
112 String tmpVal = _val.trim();
113 if(tmpVal.length() > 0) {
114
115 if(tmpVal.charAt(0) != ValueSupport.NUMBER_BASE_PREFIX) {
116
117 tmpVal = toCanonicalNumberFormat(ctx, tmpVal);
118 _num = ValueSupport.normalize(new BigDecimal(tmpVal));
119 return (BigDecimal)_num;
120 }
121
122
123 if(ValueSupport.HEX_PAT.matcher(tmpVal).matches()) {
124 return parseIntegerString(tmpVal, 16);
125 } else if(ValueSupport.OCTAL_PAT.matcher(tmpVal).matches()) {
126 return parseIntegerString(tmpVal, 8);
127 }
128
129
130 }
131 } catch(NumberFormatException nfe) {
132
133 }
134 _num = NOT_A_NUMBER;
135 }
136 throw invalidConversion(Type.DOUBLE);
137 }
138
139 private BigDecimal parseIntegerString(String tmpVal, int radix) {
140 _num = new BigDecimal(ValueSupport.parseIntegerString(tmpVal, radix));
141 return (BigDecimal)_num;
142 }
143
144 private static String toCanonicalNumberFormat(LocaleContext ctx, String tmpVal)
145 {
146
147
148
149 DecimalFormatSymbols syms = ctx.getNumericConfig().getDecimalFormatSymbols();
150 char groupSepChar = syms.getGroupingSeparator();
151 tmpVal = StringUtils.remove(tmpVal, groupSepChar);
152
153 char decSepChar = syms.getDecimalSeparator();
154 if((decSepChar != ValueSupport.CANON_DEC_SEP) && (tmpVal.indexOf(decSepChar) >= 0)) {
155 tmpVal = tmpVal.replace(decSepChar, ValueSupport.CANON_DEC_SEP);
156 }
157
158 return tmpVal;
159 }
160 }