]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.common/src/org/simantics/db/common/utils/Literals.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.common / src / org / simantics / db / common / utils / Literals.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.db.common.utils;\r
13 \r
14 import java.math.BigDecimal;\r
15 import java.math.MathContext;\r
16 import java.math.RoundingMode;\r
17 import java.util.Arrays;\r
18 import java.util.regex.Pattern;\r
19 \r
20 /**\r
21  * Common utility methods for handling and visualising literal values.\r
22  * \r
23  * @author Tuukka Lehtonen\r
24  * \r
25  * PROBLEMS:\r
26  * - ProCore does not support zero length vectors at the moment\r
27  * - String[] literals could be parsed from a String assuming a StringMemento String serialization.\r
28  */\r
29 public final class Literals {\r
30     \r
31     final private static Pattern comma = Pattern.compile(",");\r
32     \r
33     private static int precision = 8;\r
34     \r
35 //    public static final boolean[] FALSE = { false };\r
36 //\r
37 //    public static final boolean[] TRUE  = { true };\r
38 \r
39     public static int getPrecision() {\r
40         return precision;\r
41     }\r
42     \r
43     public static void setPrecision(int precision) {\r
44         Literals.precision = precision;\r
45     }\r
46 \r
47     private static String formattedDouble(double a) {\r
48         try {\r
49             BigDecimal dec = new BigDecimal(String.valueOf(a), new MathContext(precision, RoundingMode.HALF_UP));\r
50             dec = dec.stripTrailingZeros();\r
51             if(dec.scale() < 1) dec = dec.setScale(1);\r
52             return dec.toString();\r
53         } catch (NumberFormatException e) {\r
54             return "Invalid Value";\r
55         }\r
56     }\r
57     \r
58     public static String toString(double[] a) {\r
59         if (a == null)\r
60             return "null";\r
61         int iMax = a.length - 1;\r
62         if (iMax == -1)\r
63             return "[]";\r
64 \r
65         StringBuilder b = new StringBuilder();\r
66         b.append('[');\r
67         for (int i = 0; ; i++) {\r
68             b.append(formattedDouble(a[i]));\r
69         if (i == iMax)\r
70         return b.append(']').toString();\r
71             b.append(", ");\r
72         }\r
73     }\r
74 \r
75     /**\r
76      * Convert a literal object (of any allowed type) into to a String.\r
77      * \r
78      * @param literal\r
79      * @return\r
80      * @throws IllegalArgumentException\r
81      */\r
82     public static String literalToString(Object literal) throws IllegalArgumentException {\r
83         Class<?> literalClass = literal.getClass();\r
84         \r
85         if (literalClass == String.class) {\r
86             return (String)literal;\r
87         } else if (literalClass == Double.class) {\r
88             return literal.toString();\r
89         } else if (literalClass == Float.class) {\r
90             return literal.toString();\r
91         } else if (literalClass == Long.class) {\r
92             return literal.toString();\r
93         } else if (literalClass == Integer.class) {\r
94             return literal.toString();\r
95         } else if (literalClass == Byte.class) {\r
96             return literal.toString();\r
97         } else if (literalClass == Boolean.class) {\r
98             return literal.toString();\r
99         } else if (literalClass == String[].class) {\r
100             return literalToString((String[]) literal);\r
101         } else if (literalClass == double[].class) {\r
102             return literalToString((double[]) literal);\r
103         } else if (literalClass == float[].class) {\r
104             return literalToString((float[]) literal);\r
105         } else if (literalClass == long[].class) {\r
106             return literalToString((long[]) literal);\r
107         } else if (literalClass == int[].class) {\r
108             return literalToString((int[]) literal);\r
109         } else if (literalClass == byte[].class) {\r
110             return literalToString((byte[]) literal);\r
111         } else if (literalClass == boolean[].class) {\r
112             return literalToString((boolean[]) literal);\r
113         }\r
114         \r
115         throw new IllegalArgumentException(String.format("Literal object type not recognized: %s", literal.getClass().getName()));\r
116     }\r
117     \r
118     public static String shortString(Object original) {\r
119         if(original.toString().length() > 100) return original.toString().substring(0, 99) + "...";\r
120         else return original.toString();\r
121     }\r
122 \r
123     public static String literalToString(boolean[] l) throws IllegalArgumentException {\r
124         return l.length == 1 ? String.valueOf(l[0]) : Arrays.toString(l);\r
125     }\r
126 \r
127     public static String literalToString(byte[] l) throws IllegalArgumentException {\r
128         return l.length == 1 ? String.valueOf(l[0]) : Arrays.toString(l);\r
129     }\r
130 \r
131     public static String literalToString(int[] l) throws IllegalArgumentException {\r
132         return l.length == 1 ? String.valueOf(l[0]) : Arrays.toString(l);\r
133     }\r
134 \r
135     public static String literalToString(long[] l) throws IllegalArgumentException {\r
136         return l.length == 1 ? String.valueOf(l[0]) : Arrays.toString(l);\r
137     }\r
138 \r
139     public static String literalToString(float[] l) throws IllegalArgumentException {\r
140         return l.length == 1 ? String.valueOf(l[0]) : Arrays.toString(l);\r
141     }\r
142 \r
143     public static String literalToString(double[] l) throws IllegalArgumentException {\r
144         return l.length == 1 ? String.valueOf(l[0]) : Arrays.toString(l);\r
145     }\r
146 \r
147     public static String literalToString(String[] l) throws IllegalArgumentException {\r
148         // FIXME BEWARE!!! THIS BREAKS UP WITH STRINGS CONTAINING ',' CHARACTERS\r
149         return l.length == 1 ? String.valueOf(l[0]) : Arrays.toString(l);\r
150     }\r
151 \r
152 \r
153 //    /**\r
154 //     * Convert a literal object (of any allowed type) into to a String.\r
155 //     * \r
156 //     * @param literal a literal as string\r
157 //     * @return the same literal as its native type\r
158 //     * @throws IllegalArgumentException\r
159 //     */\r
160 //    public static Object stringToLiteral(Graph g, Resource property, String literal) throws IllegalArgumentException, ResourceNotFoundException {\r
161 //        if (property == null)\r
162 //            throw new IllegalArgumentException("null property");\r
163 //        if (literal == null)\r
164 //            throw new IllegalArgumentException("null literal string");\r
165 //\r
166 //        // Attempt to parse the property value by its type.\r
167 //        if (g.isInstanceOf(property, g.getBuiltins().Double)) {\r
168 //            return parseDoubleLiteral(literal);\r
169 //        } else if (g.isInstanceOf(property, g.getBuiltins().Float)) {\r
170 //            return parseFloatLiteral(literal);\r
171 //        } else if (g.isInstanceOf(property, g.getBuiltins().Long)) {\r
172 //            return parseLongLiteral(literal);\r
173 //        } else if (g.isInstanceOf(property, g.getBuiltins().Integer)) {\r
174 //            return parseIntegerLiteral(literal);\r
175 //        } else if (g.isInstanceOf(property, g.getBuiltins().Byte)) {\r
176 //            return parseByteLiteral(literal);\r
177 //        } else if (g.isInstanceOf(property, g.getBuiltins().Boolean)) {\r
178 //            return parseBooleanLiteral(literal);\r
179 //        } else if (g.isInstanceOf(property, g.getBuiltins().String)) {\r
180 //            return parseStringLiteral(literal);\r
181 //        }\r
182 //        \r
183 //        throw new IllegalArgumentException("unrecognized property type for resource");\r
184 //    }\r
185     \r
186     /**\r
187      * @param literal\r
188      * @return\r
189      * @throws IllegalArgumentException if the parsing fails\r
190      */\r
191     public static boolean[] parseBooleanLiteral(String literal) {\r
192         literal = trimLiteralString(literal);\r
193         try {\r
194             String parts[] = comma.split(literal);\r
195             boolean[] result = new boolean[parts.length];\r
196             for (int i = 0; i < parts.length; i++)\r
197                 result[i] = Boolean.parseBoolean(parts[i]);\r
198             return result;\r
199         } catch(NumberFormatException e) {\r
200             throw new IllegalArgumentException("Invalid boolean value: " + literal, e);\r
201         }\r
202     }\r
203 \r
204     /**\r
205      * @param literal\r
206      * @return\r
207      * @throws IllegalArgumentException if the parsing fails\r
208      */\r
209     public static double[] parseDoubleLiteral(String literal) {\r
210         literal = trimLiteralString(literal);\r
211         try {\r
212             String parts[] = comma.split(literal);\r
213             // " " would be more common delimiter for primitive arrays since \r
214             // it is also default delimiter in XML documents\r
215             double result[] = new double[parts.length];\r
216             for (int i = 0; i < parts.length; i++)\r
217                 result[i] = Double.parseDouble(parts[i]);\r
218             return result;\r
219         } catch (NumberFormatException e) {\r
220             throw new IllegalArgumentException("Invalid double value: " + literal, e);\r
221         }\r
222     }\r
223     \r
224     /**\r
225      * @param literal\r
226      * @return\r
227      * @throws IllegalArgumentException if the parsing fails\r
228      */\r
229     public static int[] parseIntegerLiteral(String literal) {\r
230         literal = trimLiteralString(literal);\r
231         try {\r
232             String parts[] = comma.split(literal);\r
233             int result[] = new int[parts.length];\r
234             for (int i = 0; i < parts.length; i++)\r
235                 result[i] = Integer.parseInt(parts[i]);\r
236             return result;\r
237         } catch (NumberFormatException e) {\r
238             throw new IllegalArgumentException("Invalid integer value: " + literal, e);\r
239         }\r
240     }\r
241 \r
242     public static byte[] parseByteLiteral(String literal) {\r
243         literal = trimLiteralString(literal);\r
244         try {\r
245             String parts[] = comma.split(literal);\r
246             byte result[] = new byte[parts.length];\r
247             for (int i = 0; i < parts.length; i++)\r
248                 result[i] = Byte.parseByte(parts[i]);\r
249             return result;\r
250         } catch (NumberFormatException e) {\r
251             throw new IllegalArgumentException("Invalid byte value: " + literal, e);\r
252         }\r
253     }\r
254 \r
255     public static long[] parseLongLiteral(String literal) {\r
256         literal = trimLiteralString(literal);\r
257         try {\r
258             String parts[] = comma.split(literal);\r
259             long result[] = new long[parts.length];\r
260             for (int i = 0; i < parts.length; i++)\r
261                 result[i] = Long.parseLong(parts[i]);\r
262             return result;\r
263         } catch (NumberFormatException e) {\r
264             throw new IllegalArgumentException("Invalid long value: " + literal, e);\r
265         }\r
266     }\r
267 \r
268     public static float[] parseFloatLiteral(String literal) {\r
269         literal = trimLiteralString(literal);\r
270         try {\r
271             String parts[] = comma.split(literal);\r
272             float result[] = new float[parts.length];\r
273             for (int i = 0; i < parts.length; i++)\r
274                 result[i] = Float.parseFloat(parts[i]);\r
275             return result;\r
276         } catch (NumberFormatException e) {\r
277             throw new IllegalArgumentException("Invalid float value: " + literal, e);\r
278         }\r
279     }\r
280     \r
281     private static String[] parseStringLiteral(String literal) {\r
282         // TODO: support StringMemento serialized literals!\r
283         return new String[] {literal};\r
284     }\r
285     \r
286     private static String trimLiteralString(String literal) {\r
287         // First trim the literal to make the input more canonical.\r
288         // Also remove possible '[' and ']' prefix and suffix.\r
289         literal = literal.trim();\r
290         if (literal.startsWith("["))\r
291             literal = literal.substring(1);\r
292         if (literal.endsWith("]"))\r
293             literal = literal.substring(0, literal.length() - 1);\r
294         return literal;\r
295     }\r
296 \r
297 }\r