]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/Datatypes.java
Improved Bindings.getBinding(Class) caching for Datatype.class
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / Datatypes.java
1 /*******************************************************************************
2  *  Copyright (c) 2010 Association for Decentralized Information Management in
3  *  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.databoard;
13
14 import java.io.IOException;
15 import java.io.InputStream;
16 import java.nio.charset.Charset;
17
18 import org.simantics.databoard.binding.error.BindingConstructionException;
19 import org.simantics.databoard.binding.error.DatatypeConstructionException;
20 import org.simantics.databoard.binding.error.RuntimeDatatypeConstructionException;
21 import org.simantics.databoard.binding.reflection.ClassBindingFactory;
22 import org.simantics.databoard.binding.reflection.VoidBinding;
23 import org.simantics.databoard.parser.repository.DataTypeRepository;
24 import org.simantics.databoard.parser.repository.DataTypeSyntaxError;
25 import org.simantics.databoard.type.ArrayType;
26 import org.simantics.databoard.type.BooleanType;
27 import org.simantics.databoard.type.ByteType;
28 import org.simantics.databoard.type.Datatype;
29 import org.simantics.databoard.type.DoubleType;
30 import org.simantics.databoard.type.FloatType;
31 import org.simantics.databoard.type.IntegerType;
32 import org.simantics.databoard.type.LongType;
33 import org.simantics.databoard.type.OptionalType;
34 import org.simantics.databoard.type.StringType;
35 import org.simantics.databoard.type.VariantType;
36 import org.simantics.databoard.util.StreamUtil;
37
38 /**
39  * This class is a facade to the data type services. 
40  * 
41  * @author Hannu Niemisto
42  * @author Toni Kalajainen
43  */
44 public class Datatypes {
45         
46         public static final BooleanType   BOOLEAN = new BooleanType();
47         public static final ByteType      BYTE    = new ByteType();
48         public static final IntegerType   INTEGER = new IntegerType();
49         public static final LongType      LONG    = new LongType();
50         public static final FloatType     FLOAT   = new FloatType();
51         public static final DoubleType    DOUBLE  = new DoubleType();
52         public static final StringType    STRING  = new StringType();
53         public static final VariantType   VARIANT = new VariantType();
54         
55         public static final Datatype      VOID    = VoidBinding.VOID_BINDING.type();
56
57         public static final ArrayType     BOOLEAN_ARRAY = new ArrayType( BOOLEAN );
58         public static final ArrayType     BYTE_ARRAY    = new ArrayType( BYTE );
59         public static final ArrayType     INTEGER_ARRAY = new ArrayType( INTEGER );
60         public static final ArrayType     LONG_ARRAY    = new ArrayType( LONG );
61         public static final ArrayType     FLOAT_ARRAY   = new ArrayType( FLOAT );
62         public static final ArrayType     DOUBLE_ARRAY  = new ArrayType( DOUBLE );
63         public static final ArrayType     STRING_ARRAY  = new ArrayType( STRING );
64         public static final ArrayType     VARIANT_ARRAY  = new ArrayType( VARIANT );
65         
66         public static final DataTypeRepository datatypeRepository = new DataTypeRepository();
67
68         /** Make type optional */
69         public static Datatype optional( Datatype type ) { return new OptionalType( type ); }
70         
71         /**
72          * Read representation from a class. DataType details and parameters
73          * are read as annotations placed in the class.  
74          * (See org.simantics.databoard.annotations)  
75          * <p>
76          * As an exception, in the subclasses of {@link Throwable}, the fields of
77          * Throwable are omited.
78          * 
79          * @see ClassBindingFactory  
80          * @param clazz
81          * @return data type
82          * @throws DatatypeConstructionException 
83          */
84         @SuppressWarnings("unchecked")
85         public static <T extends Datatype> T getDatatype(Class<?> clazz) 
86         throws DatatypeConstructionException {
87                 try {
88                         return (T) Bindings.getBinding(clazz).type();
89                 } catch (BindingConstructionException e) {
90                         throw new DatatypeConstructionException(e);
91                 }
92         }
93         
94         /**
95          * Read representation from a class. DataType details and parameters
96          * are read as annotations placed in the class.  
97          * (See org.simantics.databoard.annotations)  
98          * <p>
99          * This method is used when the caller is 100% sure that binding will be 
100          * constructed without exceptions. Such classes
101          * are all primitive types (Double, Integer, etc, arrays, DataType, ...)
102          * 
103          * This method is unchecked if binding construction to the clazz cannot be trusted.
104          * If construction fails, a RuntimeException is thrown.
105          * 
106          * @see ClassBindingFactory  
107          * @param clazz
108          * @return data type
109          * @throws RuntimeDatatypeConstructionException 
110          */
111         @SuppressWarnings("unchecked")
112         public static <T extends Datatype> T getDatatypeUnchecked(Class<?> clazz) 
113         throws RuntimeDatatypeConstructionException {
114                 try {
115                         return (T) Bindings.getBinding(clazz).type();
116                 } catch (BindingConstructionException e) {
117                         throw new RuntimeDatatypeConstructionException(new DatatypeConstructionException(e));
118                 }
119         }       
120         
121         /**
122          * Adds a type to the repository.
123          * 
124          * @param name Name of the type
125          * @param type Type to be added
126          */
127         public static void addDatatype(String name, Datatype type) {
128                 datatypeRepository.add(name, type);
129         }
130         
131         /**
132          * Get data type by name.
133          * 
134          * e.g. get("Vec2");
135          * 
136          * @param name
137          * @return data type
138          */
139         public static Datatype getDatatype(String name) {
140                 return datatypeRepository.get(name);
141         }       
142         
143         /**
144          * Parses and adds type definitions to the repository.
145          * 
146          * The data type can be acquired with #getType
147          * 
148          * e.g. "type Vec2 = { x : Double, y : Double }"
149          * 
150          * @param definitions Definitions in textual format.
151          * @throws DataTypeSyntaxError 
152          */
153         public static void addDefinitions(String definitions) throws DataTypeSyntaxError {
154                 datatypeRepository.addDefinitions(definitions);
155         }
156         
157         /**
158          * Parses an unnamed data type.
159          * 
160          * <a href="http://dev.simantics.org/index.php/Data_type_notation">Datatype Notation</a>
161          * 
162          * e.g. "{ direction : Vec, vector : Vec2 }" 
163          * 
164          * @param typeString The textual representation of the type to be translated
165          * @return Translated data type
166          * @throws DataTypeSyntaxError 
167          */
168         public static Datatype translate(String typeString) throws DataTypeSyntaxError {
169                 return datatypeRepository.translate(typeString);
170         }       
171
172         static {
173                 Charset UTF8        = Charset.forName("UTF-8");
174                 
175                 // Read File
176                 InputStream is = Datatypes.class.getResourceAsStream("standardTypes.dbt");
177                 try {
178                         String defs = StreamUtil.readString(is, UTF8);
179                         Datatypes.datatypeRepository.addDefinitions(defs);                      
180                 } catch (IOException e) {
181                         throw new RuntimeException( e );
182                 } catch (DataTypeSyntaxError e) {
183                         throw new RuntimeException( e );
184                 } finally {
185                         try { is.close(); } catch (IOException e) {}
186                 }
187                 
188         }
189         
190 }
191
192