--- /dev/null
+package org.simantics.modeling.subscription;\r
+\r
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;\r
+import org.eclipse.core.runtime.preferences.InstanceScope;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.Databoard;\r
+import org.simantics.databoard.accessor.reference.ChildReference;\r
+import org.simantics.databoard.accessor.reference.IndexReference;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.util.URIStringUtils;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.exception.PendingVariableException;\r
+import org.simantics.db.layer0.request.PossibleModel;\r
+import org.simantics.db.layer0.request.PossibleVariableValue;\r
+import org.simantics.db.layer0.variable.RVI;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.utils.datastructures.Pair;\r
+import org.simantics.utils.format.FormattingUtils;\r
+import org.simantics.utils.format.ValueFormat;\r
+\r
+public class SubscriptionItemLabel {\r
+\r
+ private static final String NO_VARIABLE_ID = "<no variable id>";\r
+\r
+ public static String resolveLabel(ReadGraph graph, Resource item, boolean synchronous) throws DatabaseException {\r
+ IEclipsePreferences chartPreferenceNode = InstanceScope.INSTANCE.getNode( "org.simantics.charts" );\r
+ String s = chartPreferenceNode.get("chart.valueformat", ValueFormat.Default.name());\r
+ ValueFormat valueFormat = ValueFormat.valueOf( s );\r
+ return resolveLabel(graph, item, valueFormat, synchronous);\r
+ }\r
+\r
+ public static String resolveLabel(ReadGraph graph, Resource item, ValueFormat valueFormat, boolean synchronous) throws DatabaseException {\r
+ return resolveLabel(graph, item, valueFormat, synchronous, true, true);\r
+ }\r
+\r
+ public static String resolveLabel(ReadGraph graph, Resource item, ValueFormat valueFormat, boolean synchronous, boolean tryLabel, boolean showValue) throws DatabaseException {\r
+\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ ModelingResources MOD = ModelingResources.getInstance(graph);\r
+\r
+ String label = tryLabel ? graph.<String>getPossibleRelatedValue(item, L0.HasLabel, Bindings.STRING) : null;\r
+ boolean labelDefined = isNonempty(label);\r
+ if (!showValue && labelDefined)\r
+ return label;\r
+\r
+ // Create label from rvi\r
+ Binding rviBinding = graph.getService(Databoard.class).getBindingUnchecked( RVI.class );\r
+ RVI rvi = graph.getPossibleRelatedValue(item, MOD.Subscription_Item_VariableId, rviBinding);\r
+ if (rvi == null)\r
+ return NO_VARIABLE_ID;\r
+\r
+ Resource model = graph.syncRequest(new PossibleModel(item));\r
+ if (model != null) {\r
+ ModelContexts contexts = graph.syncRequest(new ModelContextsRequest(model), TransientCacheAsyncListener.<ModelContexts>instance());\r
+ Variable configurationContext = contexts.getConfigurationContext();\r
+ Variable experimentContext = contexts.getExperimentContext();\r
+\r
+ if (configurationContext != null) {\r
+ // Resolve variable and take note of the resolution context\r
+ Variable variable = null;\r
+ Variable resolutionContext = experimentContext;\r
+ String resolutionContextURI = contexts.getExperimentContextURI();\r
+ if (showValue && experimentContext != null)\r
+ variable = rvi.resolvePossible(graph, experimentContext);\r
+ if (variable == null) {\r
+ resolutionContext = configurationContext;\r
+ resolutionContextURI = contexts.getConfigurationContextURI();\r
+ variable = rvi.resolvePossible(graph, configurationContext);\r
+ }\r
+\r
+ if (variable != null) {\r
+ if (!labelDefined) {\r
+ label = relativeURI(graph, variable, resolutionContextURI);\r
+ if (label == null)\r
+ label = rvi.toPossibleString(graph, configurationContext);\r
+ if (label != null) {\r
+ label = removeVariablePrefixPath(label);\r
+ label = URIStringUtils.unescape(label);\r
+ }\r
+ }\r
+\r
+ if (showValue && resolutionContext == experimentContext) {\r
+ StringBuilder sb = new StringBuilder(label);\r
+\r
+ Double gain = graph.getPossibleRelatedValue(item, MOD.Subscription_Item_Gain, Bindings.DOUBLE);\r
+ Double bias = graph.getPossibleRelatedValue(item, MOD.Subscription_Item_Bias, Bindings.DOUBLE);\r
+ String unit = graph.getPossibleRelatedValue(item, MOD.Subscription_Item_Unit, Bindings.STRING);\r
+\r
+ boolean oldSync = graph.setSynchronous(synchronous);\r
+ try {\r
+ Object value = graph.syncRequest( new PossibleVariableValue<Object>(variable) );\r
+ sb = formatValue(value, gain, bias, unit, valueFormat, sb);\r
+ } catch (PendingVariableException e) {\r
+ sb.append(" (<pending>)");\r
+ } finally {\r
+ graph.setSynchronous(oldSync);\r
+ }\r
+\r
+ label = sb.toString();\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return label != null ? label : NO_VARIABLE_ID;\r
+ }\r
+\r
+ private static StringBuilder formatValue(Object value, Double gain, Double bias, String unit, ValueFormat valueFormat, StringBuilder sb) {\r
+ if (value instanceof Number) {\r
+ double d = ((Number) value).doubleValue();\r
+ double ad = d;\r
+ if (gain != null)\r
+ ad *= gain;\r
+ if (bias != null)\r
+ ad += bias;\r
+ sb.append(" (").append(valueFormat.format.format(ad));\r
+ } else {\r
+ sb.append(" (").append(FormattingUtils.engineeringFormat(value));\r
+ }\r
+ if (unit != null && !unit.isEmpty()) {\r
+ sb.append(' ').append(unit);\r
+ }\r
+ return sb.append(')');\r
+ }\r
+\r
+ public static String removeVariablePrefixPath(String rvi) {\r
+ // Apros-specific logics:\r
+ // 1. remove path prefix\r
+ // 2. change IndexReferences (i-N) into "(N+1)" Apros-style indexing\r
+ int propIndex = rvi.indexOf('#');\r
+ if (propIndex == -1)\r
+ return rvi;\r
+ int prevSlash = rvi.lastIndexOf('/', propIndex);\r
+ if (prevSlash == -1)\r
+ return rvi;\r
+ Pair<String, Integer> attrKey = attributeKey(rvi, propIndex + 1);\r
+ return rvi.substring(prevSlash + 1, propIndex + 1) + attrKey.first\r
+ + (attrKey.second != null ? "(" + (attrKey.second + 1) + ")" : "");\r
+ }\r
+\r
+ private static Pair<String, Integer> attributeKey(String key, int start) {\r
+ int iy = key.lastIndexOf('/');\r
+ boolean isIndexed = iy >= start;\r
+ if (isIndexed) {\r
+ ChildReference child = ChildReference.parsePath(key.substring(iy + 1));\r
+ if (child instanceof IndexReference)\r
+ return Pair.make(key.substring(start, iy), ((IndexReference) child).getIndex());\r
+ }\r
+ return Pair.make(key.substring(start), null);\r
+ }\r
+\r
+ private static boolean isNonempty(String label) {\r
+ return label != null && !label.trim().isEmpty();\r
+ }\r
+\r
+ private static String relativeURI(ReadGraph graph, Variable variable, String contextURI) throws DatabaseException {\r
+ return relativeURI(variable.getURI(graph), contextURI);\r
+ }\r
+\r
+ private static String relativeURI(String fullURI, String contextURI) {\r
+ return fullURI.substring(contextURI.length());\r
+ }\r
+\r
+}
\ No newline at end of file