/******************************************************************************* * Copyright (c) 2010 Association for Decentralized Information Management in * Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.databoard; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import org.simantics.databoard.binding.error.BindingConstructionException; import org.simantics.databoard.binding.error.DatatypeConstructionException; import org.simantics.databoard.binding.error.RuntimeDatatypeConstructionException; import org.simantics.databoard.binding.reflection.ClassBindingFactory; import org.simantics.databoard.binding.reflection.VoidBinding; import org.simantics.databoard.parser.repository.DataTypeRepository; import org.simantics.databoard.parser.repository.DataTypeSyntaxError; import org.simantics.databoard.type.ArrayType; import org.simantics.databoard.type.BooleanType; import org.simantics.databoard.type.ByteType; import org.simantics.databoard.type.Datatype; import org.simantics.databoard.type.DoubleType; import org.simantics.databoard.type.FloatType; import org.simantics.databoard.type.IntegerType; import org.simantics.databoard.type.LongType; import org.simantics.databoard.type.OptionalType; import org.simantics.databoard.type.StringType; import org.simantics.databoard.type.VariantType; import org.simantics.databoard.util.StreamUtil; /** * This class is a facade to the data type services. * * @author Hannu Niemisto * @author Toni Kalajainen */ public class Datatypes { public static final BooleanType BOOLEAN = new BooleanType(); public static final ByteType BYTE = new ByteType(); public static final IntegerType INTEGER = new IntegerType(); public static final LongType LONG = new LongType(); public static final FloatType FLOAT = new FloatType(); public static final DoubleType DOUBLE = new DoubleType(); public static final StringType STRING = new StringType(); public static final VariantType VARIANT = new VariantType(); public static final Datatype VOID = VoidBinding.VOID_BINDING.type(); public static final ArrayType BOOLEAN_ARRAY = new ArrayType( BOOLEAN ); public static final ArrayType BYTE_ARRAY = new ArrayType( BYTE ); public static final ArrayType INTEGER_ARRAY = new ArrayType( INTEGER ); public static final ArrayType LONG_ARRAY = new ArrayType( LONG ); public static final ArrayType FLOAT_ARRAY = new ArrayType( FLOAT ); public static final ArrayType DOUBLE_ARRAY = new ArrayType( DOUBLE ); public static final ArrayType STRING_ARRAY = new ArrayType( STRING ); public static final ArrayType VARIANT_ARRAY = new ArrayType( VARIANT ); public static final DataTypeRepository datatypeRepository = new DataTypeRepository(); /** Make type optional */ public static Datatype optional( Datatype type ) { return new OptionalType( type ); } /** * Read representation from a class. DataType details and parameters * are read as annotations placed in the class. * (See org.simantics.databoard.annotations) *

* As an exception, in the subclasses of {@link Throwable}, the fields of * Throwable are omited. * * @see ClassBindingFactory * @param clazz * @return data type * @throws DatatypeConstructionException */ @SuppressWarnings("unchecked") public static T getDatatype(Class clazz) throws DatatypeConstructionException { try { return (T) Bindings.getBinding(clazz).type(); } catch (BindingConstructionException e) { throw new DatatypeConstructionException(e); } } /** * Read representation from a class. DataType details and parameters * are read as annotations placed in the class. * (See org.simantics.databoard.annotations) *

* This method is used when the caller is 100% sure that binding will be * constructed without exceptions. Such classes * are all primitive types (Double, Integer, etc, arrays, DataType, ...) * * This method is unchecked if binding construction to the clazz cannot be trusted. * If construction fails, a RuntimeException is thrown. * * @see ClassBindingFactory * @param clazz * @return data type * @throws RuntimeDatatypeConstructionException */ @SuppressWarnings("unchecked") public static T getDatatypeUnchecked(Class clazz) throws RuntimeDatatypeConstructionException { try { return (T) Bindings.getBinding(clazz).type(); } catch (BindingConstructionException e) { throw new RuntimeDatatypeConstructionException(new DatatypeConstructionException(e)); } } /** * Adds a type to the repository. * * @param name Name of the type * @param type Type to be added */ public static void addDatatype(String name, Datatype type) { datatypeRepository.add(name, type); } /** * Get data type by name. * * e.g. get("Vec2"); * * @param name * @return data type */ public static Datatype getDatatype(String name) { return datatypeRepository.get(name); } /** * Parses and adds type definitions to the repository. * * The data type can be acquired with #getType * * e.g. "type Vec2 = { x : Double, y : Double }" * * @param definitions Definitions in textual format. * @throws DataTypeSyntaxError */ public static void addDefinitions(String definitions) throws DataTypeSyntaxError { datatypeRepository.addDefinitions(definitions); } /** * Parses an unnamed data type. * * Datatype Notation * * e.g. "{ direction : Vec, vector : Vec2 }" * * @param typeString The textual representation of the type to be translated * @return Translated data type * @throws DataTypeSyntaxError */ public static Datatype translate(String typeString) throws DataTypeSyntaxError { return datatypeRepository.translate(typeString); } static { Charset UTF8 = Charset.forName("UTF-8"); // Read File InputStream is = Datatypes.class.getResourceAsStream("standardTypes.dbt"); try { String defs = StreamUtil.readString(is, UTF8); Datatypes.datatypeRepository.addDefinitions(defs); } catch (IOException e) { throw new RuntimeException( e ); } catch (DataTypeSyntaxError e) { throw new RuntimeException( e ); } finally { try { is.close(); } catch (IOException e) {} } } }