/******************************************************************************* * Copyright (c) 2016 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: * THTH ry - initial API and implementation *******************************************************************************/ package org.simantics.debug.browser.utils; import java.io.IOException; import java.lang.reflect.Array; import java.util.Arrays; import org.simantics.databoard.Bindings; import org.simantics.databoard.Databoard; import org.simantics.databoard.binding.ArrayBinding; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.error.BindingException; import org.simantics.databoard.serialization.Serializer; import org.simantics.databoard.type.ArrayType; import org.simantics.databoard.type.Datatype; import org.simantics.databoard.util.ObjectUtils; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.utils.CommonDBUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.variable.RVI; import org.simantics.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.Variables; import org.simantics.layer0.Layer0; public class Values { private static int RESOURCE_NAME_MAX_LENGTH = 1000; private static int RESOURCE_VALUE_MAX_SIZE = 16384; public static ValueInfo getPossibleValueInfo(ReadGraph graph, Resource r) { try { if (!graph.hasValue(r)) return null; String value = null; String datatype = null; Layer0 L0 = Layer0.getInstance(graph); Datatype type = graph.getPossibleRelatedValue(r, L0.HasDataType, Bindings.getBindingUnchecked(Datatype.class)); if (type != null) { if (graph.isInstanceOf(r, L0.RVI)) { try { RVI rvi = graph.getPossibleValue(r, graph.getService(Databoard.class).getBindingUnchecked(RVI.class)); Resource owner = CommonDBUtils.getPossibleOwner(graph, r); if (owner != null) { Variable context = Variables.getPossibleConfigurationContext(graph, owner); if (context != null) value = rvi.asPossibleString(graph, context); } if (value == null) value = rvi.toString( graph ); if (value != null) datatype = "Relative Variable Identifier (RVI)"; } catch (DatabaseException e) { // Fall through to more generic mechanisms } } // Generic datatype-based fallback method if (value == null) { Binding b = Bindings.getBinding(type); Object v = graph.getPossibleValue(r, b); Serializer s = Bindings.getSerializerUnchecked(b); int size = s.getSize(v); if (size > RESOURCE_VALUE_MAX_SIZE) { value = "Approx. " + size + " byte literal"; } else { if (b instanceof ArrayBinding) { // Manipulate data type to contain actual array // length for printing purposes. int arraySize = ((ArrayBinding) b).size(v); ArrayType atype = (ArrayType) type; atype.setLength(Integer.toString(arraySize)); } value = b.toString(v, false); } // datatype = type.toSingleLineString(); // datatype = type.toString(); // datatype = DataTypePrinter2.print(type); datatype = Bindings.getBindingUnchecked(Datatype.class).toString(type, false); } } // Final fallback if there's no datatype specified ValueInfo info = null; if (value != null) info = new ValueInfo(r, value, datatype); if (info == null) info = toSimpleValueInfo(r, graph.getValue(r)); return info; } catch (DatabaseException e) { return null; } catch (IOException e) { return null; } catch (BindingException e) { return null; } } private static ValueInfo toSimpleValueInfo(Resource r, Object value) { Class clazz = value.getClass(); if (clazz.isArray()) { int length = Array.getLength(value); if (length > RESOURCE_NAME_MAX_LENGTH) { if (value instanceof byte[]) { byte[] arr = (byte[]) value; byte[] arr2 = Arrays.copyOf(arr, RESOURCE_NAME_MAX_LENGTH); return truncated(r, "byte", Arrays.toString(arr2), arr.length); } else if (value instanceof int[]) { int[] arr = (int[]) value; int[] arr2 = Arrays.copyOf(arr, RESOURCE_NAME_MAX_LENGTH); return truncated(r, "int", Arrays.toString(arr2), arr.length); } else if (value instanceof long[]) { long[] arr = (long[]) value; long[] arr2 = Arrays.copyOf(arr, RESOURCE_NAME_MAX_LENGTH); return truncated(r, "long", Arrays.toString(arr2), arr.length); } else if (value instanceof float[]) { float[] arr = (float[]) value; float[] arr2 = Arrays.copyOf(arr, RESOURCE_NAME_MAX_LENGTH); return truncated(r, "float", Arrays.toString(arr2), arr.length); } else if (value instanceof double[]) { double[] arr = (double[]) value; double[] arr2 = Arrays.copyOf(arr, RESOURCE_NAME_MAX_LENGTH); return truncated(r, "double", Arrays.toString(arr2), arr.length); } else if (value instanceof boolean[]) { boolean[] arr = (boolean[]) value; boolean[] arr2 = Arrays.copyOf(arr, RESOURCE_NAME_MAX_LENGTH); return truncated(r, "boolean", Arrays.toString(arr2), arr.length); } else if (value instanceof Object[]) { Object[] arr = (Object[]) value; Object[] arr2 = Arrays.copyOf(arr, RESOURCE_NAME_MAX_LENGTH); return truncated(r, "Object", Arrays.toString(arr2), arr.length); } else { return new ValueInfo(r, "", "Unknown big array " + clazz.getCanonicalName()); } } else { return new ValueInfo(r, ObjectUtils.toString(value), clazz.getComponentType() + "[" + length + "]"); } } return new ValueInfo(r, ObjectUtils.toString(value), clazz.getCanonicalName()); } private static ValueInfo truncated(Resource r, String type, String value, int originalLength) { return new ValueInfo(r, value, type + "[" + RESOURCE_NAME_MAX_LENGTH + "/" + originalLength + "]"); } }