--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.databoard.binding.util;
+
+import java.util.Map;\r
+import java.util.WeakHashMap;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.binding.ArrayBinding;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.binding.Binding.Visitor;\r
+import org.simantics.databoard.binding.BooleanBinding;\r
+import org.simantics.databoard.binding.ByteBinding;\r
+import org.simantics.databoard.binding.DoubleBinding;\r
+import org.simantics.databoard.binding.FloatBinding;\r
+import org.simantics.databoard.binding.IntegerBinding;\r
+import org.simantics.databoard.binding.LongBinding;\r
+import org.simantics.databoard.binding.MapBinding;\r
+import org.simantics.databoard.binding.OptionalBinding;\r
+import org.simantics.databoard.binding.RecordBinding;\r
+import org.simantics.databoard.binding.StringBinding;\r
+import org.simantics.databoard.binding.UnionBinding;\r
+import org.simantics.databoard.binding.VariantBinding;\r
+import org.simantics.databoard.binding.error.BindingException;\r
+import org.simantics.databoard.binding.error.RuntimeBindingException;\r
+import org.simantics.databoard.type.ArrayType;\r
+import org.simantics.databoard.type.ByteType;\r
+import org.simantics.databoard.type.DoubleType;\r
+import org.simantics.databoard.type.FloatType;\r
+import org.simantics.databoard.type.IntegerType;\r
+import org.simantics.databoard.type.LongType;\r
+import org.simantics.databoard.type.StringType;\r
+import org.simantics.databoard.util.Range;\r
+
+/**
+ * Visitor that creates a default instance of a DataType.
+ * This visitor may throw RuntimeBindingException.
+ *
+ * Type Value
+ * ------------------------------------------------------
+ * Boolean false
+ * Byte, Integer, Long 0 or min limit
+ * Float, Double 0.0 or min limit
+ * String ""
+ * Optional *novalue*
+ * Union tag 0
+ * Record each field with default value
+ * Array min range number of elements
+ * Map no entries
+ * Variant {} : void
+ *
+ *
+ * TODO Create String according to the pattern
+ * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
+ */
+public class DefaultValue implements Visitor<Object> {
+
+ /** Map of default values already created. Used to link back to recursive records */
+ Map<Binding, Object> map = new WeakHashMap<Binding, Object>(1);
+
+ @Override
+ public Object visit(ArrayBinding b) {
+ Object result = null;
+
+ ArrayType at = b.type();
+ Range r = at.getLength();
+ int min = (r!=null) ? r.getLower().getValue().intValue() : 0;
+
+ if (min>0) {
+ Binding componentBinding = b.getComponentBinding();
+ Object[] array = new Object[min];
+ for (int i=0; i<min; i++) {
+ array[i] = componentBinding.accept(this);
+ }
+ result = b.createUnchecked(array);
+ } else {
+ result = b.createUnchecked();
+ }
+ return result;
+ }
+
+ @Override
+ public Object visit(BooleanBinding b) {
+ Object result = b.createUnchecked(Boolean.FALSE);
+ return result;
+ }
+
+ @Override
+ public Object visit(DoubleBinding b) {
+ DoubleType type = b.type();
+ Range range = type.getRange();
+ Number lowValue = range==null ? null : range.getLower().getValue();\r
+ return b.createUnchecked( lowValue == null ? 0 : lowValue.doubleValue() );\r
+ }
+
+ @Override
+ public Object visit(FloatBinding b) {
+ FloatType type = b.type();
+ Range range = type.getRange();
+ Number lowValue = range==null ? null : range.getLower().getValue();\r
+ return b.createUnchecked( lowValue == null ? 0 : lowValue.floatValue() );\r
+ }
+
+ @Override
+ public Object visit(IntegerBinding b) {
+ IntegerType type = b.type();
+ Range range = type.getRange();\r
+ Number lowValue = range==null ? null : range.getLower().getValue();\r
+ return b.createUnchecked( lowValue == null ? 0 : lowValue.intValue() );\r
+ }
+
+ @Override
+ public Object visit(ByteBinding b) {
+ ByteType type = b.type();
+ Range range = type.getRange();
+ Number lowValue = range==null ? null : range.getLower().getValue();\r
+ return b.createUnchecked( lowValue == null ? 0 : lowValue.intValue() );\r
+ }
+
+ @Override
+ public Object visit(LongBinding b) {
+ LongType type = b.type();
+ Range range = type.getRange();
+ Number lowValue = range==null ? null : range.getLower().getValue();\r
+ return b.createUnchecked( lowValue == null ? 0 : lowValue.longValue() );\r
+ }
+
+ @Override
+ public Object visit(OptionalBinding b) {
+ return b.createNoValueUnchecked();
+ }
+
+ @Override
+ public Object visit(RecordBinding b) {
+ try {\r
+ Object result = null;\r
+ if (b.type().isReferable()) {
+ result = map.get(b);
+ if (result!=null) return result;\r
+ }
+ Object[] values = new Object[ b.getComponentCount() ];
+ result = b.createPartial();\r
+ if (b.type().isReferable()) map.put(b, result);
+ for (int i=0; i<values.length; i++) {
+ Binding cb = b.getComponentBinding(i);
+ values[i] = cb.accept(this);
+ }
+ b.setComponents(result, values);
+ return result;
+ } catch (BindingException e) {
+ throw new RuntimeBindingException(e);
+ }
+ }
+
+ @Override
+ public Object visit(StringBinding b) {
+ Object result = null;
+ StringType st = b.type();
+ if (st.getPattern() != null) {
+ // TODO Create a string that is valid to the pattern
+ result = b.createUnchecked("");
+ } else {
+ result = b.createUnchecked("");
+ }
+ return result;
+ }
+
+ @Override
+ public Object visit(UnionBinding b) {
+ int tag = 0;
+ Binding componentBinding = b.getComponentBinding(tag);
+ Object tag0defaultValue = componentBinding.accept(this);
+ return b.createUnchecked(tag, tag0defaultValue);
+ }
+
+
+ @Override
+ public Object visit(VariantBinding b) {
+ Binding voidBinding = Bindings.getBindingUnchecked(void.class);
+ Object voidValue = null;
+ return b.createUnchecked(voidBinding, voidValue);
+ }
+
+ @Override
+ public Object visit(MapBinding b) {
+ return b.createUnchecked();
+ }
+
+}
+