/******************************************************************************* * Copyright (c) 2007, 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.browsing.ui.graph.impl; import java.lang.reflect.Array; import java.util.Collection; import org.simantics.browsing.ui.NodeContext; import org.simantics.browsing.ui.common.NodeContextUtil; import org.simantics.browsing.ui.common.property.IArrayProperty; import org.simantics.browsing.ui.common.property.IProperty; import org.simantics.browsing.ui.common.property.IPropertyFactory; import org.simantics.browsing.ui.common.property.PropertyUtil; import org.simantics.browsing.ui.common.property.PropertyUtil.ValueType; import org.simantics.databoard.Bindings; import org.simantics.databoard.adapter.AdaptException; import org.simantics.databoard.binding.error.RuntimeBindingConstructionException; import org.simantics.databoard.type.ArrayType; import org.simantics.databoard.type.Datatype; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.utils.OrderedSetUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.DoesNotContainValueException; import org.simantics.layer0.Layer0; import org.simantics.utils.datastructures.slice.ValueRange; /** * A utility on top of the generic {@link PropertyUtil} for working with graph * database properties. * * @author Tuukka Lehtonen */ public class GraphPropertyUtil { /** * @param graph * @param resource * @param sizeHint * @return * @throws DatabaseException */ public static String tryGetValueTypeString(ReadGraph graph, Resource resource, int sizeHint) throws DatabaseException { Layer0 l0 = Layer0.getInstance(graph); if (graph.isInstanceOf(resource, l0.OrderedSet)) return "list"; // FIXME try { Resource literalType = graph.getSingleType(resource, l0.Literal); String literalTypeName = graph.getRelatedValue(literalType, l0.HasName, Bindings.STRING); Datatype dt = graph.getDataType(resource); String typeString = null; if (dt instanceof ArrayType) { ArrayType at = (ArrayType) dt; at = (ArrayType) Bindings.getBindingUnchecked(Datatype.class).clone(at); at.setLength("" + sizeHint); typeString = at.toSingleLineString(); } else { typeString = dt.toSingleLineString(); } return literalTypeName + " : " + typeString; } catch (RuntimeBindingConstructionException e) { // Shouldn't happen } catch (AdaptException e) { // Shouldn't happen } catch (DatabaseException e) { } // Fallback to OLD logic for some kind of backwards compatibility if (!graph.isInstanceOf(resource, l0.Literal)) return ValueType.toString(ValueType.NoValue); try { Object value = graph.getValue(resource); return ValueType.toString(ValueType.convert(value)); } catch (DoesNotContainValueException ee) { return ValueType.toString(ValueType.NoValue); } } public static T createProperty(ReadGraph graph, Resource resource, IPropertyFactory propertyFactory) throws DatabaseException { // System.out.println("createProperty: " + GraphUtils.getReadableName(graph, resource)); T t = tryCreateProperty(graph, resource, propertyFactory); if (t != null) return t; return propertyFactory.create(null); } /** * @param * @param graph * @param resource * @param propertyFactory * @return null if the specified resource is neither an * enumerated value or an L0.Value instance * @throws DatabaseException */ public static T tryCreateProperty(ReadGraph graph, Resource resource, IPropertyFactory propertyFactory) throws DatabaseException { // System.out.println("tryCreateProperty: " + GraphUtils.getReadableName(graph, resource)); boolean isEnum = IsEnumeratedValue.isEnumeratedValue(graph, resource); if (isEnum) { //System.out.println("isEnum: " + GraphUtils.getReadableName(graph, resource)); return propertyFactory.create(null); } Layer0 l0 = Layer0.getInstance(graph); boolean isLiteral = graph.isInstanceOf(resource, l0.Literal); if (isLiteral) { //System.out.println("isValue: " + GraphUtils.getReadableName(graph, resource)); try { Object value = graph.getValue(resource); //System.out.println(" VALUE: " + value); if(value.getClass().isArray()) { //System.out.println(" IS ARRAY"); int size = Array.getLength(value); if (size > 1) return propertyFactory.create(ValueRange.make(0, size)); if (size == 0) return propertyFactory.create(ValueRange.make(0, 0)); } return propertyFactory.create(null); } catch (DoesNotContainValueException e) { } } else { // Check if is list.. boolean isList = graph.isInstanceOf(resource, l0.OrderedSet); //System.out.println("IS LIST ? "+isList); if(isList) { int size = OrderedSetUtils.toList(graph, resource).size(); //System.out.println("list size "+size); return propertyFactory.create(ValueRange.make(0, size)); } } return null; } public static NodeContext[] tryValueGetChildren(ReadGraph graph, Resource resource, IPropertyFactory propertyFactory) throws DatabaseException { T property = tryCreateProperty(graph, resource, propertyFactory); if (property == null) return null; if (property instanceof IArrayProperty) { IArrayProperty array = (IArrayProperty) property; ValueRange range = array.getRange(); Collection children = PropertyUtil.subnodify(array, 0, range.size()); return NodeContextUtil.toContextsWithInput(children); } // Plain properties do not have children. return NodeContext.NONE; } /** * @param graph * @param r * @return null if this is not a value, * Boolean.FALSE if this is a scalar value and * Boolean.TRUE if this is a vector value. */ public static Boolean tryValueHasChildren(ReadGraph graph, Resource r) throws DatabaseException { Layer0 l0 = Layer0.getInstance(graph); if (graph.isInstanceOf(r, l0.Literal)) { try { Object o = graph.getValue(r); return Boolean.valueOf(Array.getLength(o) > 1); } catch (DoesNotContainValueException e) { return Boolean.FALSE; } } return null; } }