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