1 package org.simantics.modeling.subscription;
3 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
4 import org.eclipse.core.runtime.preferences.InstanceScope;
5 import org.simantics.databoard.Bindings;
6 import org.simantics.databoard.Databoard;
7 import org.simantics.databoard.accessor.reference.ChildReference;
8 import org.simantics.databoard.accessor.reference.IndexReference;
9 import org.simantics.databoard.binding.Binding;
10 import org.simantics.databoard.util.URIStringUtils;
11 import org.simantics.db.ReadGraph;
12 import org.simantics.db.Resource;
13 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
14 import org.simantics.db.common.request.PossibleIndexRoot;
15 import org.simantics.db.exception.DatabaseException;
16 import org.simantics.db.layer0.exception.PendingVariableException;
17 import org.simantics.db.layer0.request.PossibleVariableValue;
18 import org.simantics.db.layer0.variable.RVI;
19 import org.simantics.db.layer0.variable.Variable;
20 import org.simantics.layer0.Layer0;
21 import org.simantics.modeling.ModelingResources;
22 import org.simantics.utils.datastructures.Pair;
23 import org.simantics.utils.format.FormattingUtils;
24 import org.simantics.utils.format.ValueFormat;
26 public class SubscriptionItemLabel {
28 private static final String NO_VARIABLE_ID = "<no variable id>";
30 public static String resolveLabel(ReadGraph graph, Resource item, boolean synchronous) throws DatabaseException {
31 IEclipsePreferences chartPreferenceNode = InstanceScope.INSTANCE.getNode( "org.simantics.charts" );
32 String s = chartPreferenceNode.get("chart.valueformat", ValueFormat.Default.name());
33 ValueFormat valueFormat = ValueFormat.valueOf( s );
34 return resolveLabel(graph, item, valueFormat, synchronous);
37 public static String resolveLabel(ReadGraph graph, Resource item, ValueFormat valueFormat, boolean synchronous) throws DatabaseException {
38 return resolveLabel(graph, item, valueFormat, synchronous, true, true);
41 public static String resolveLabel(ReadGraph graph, Resource item, ValueFormat valueFormat, boolean synchronous, boolean tryLabel, boolean showValue) throws DatabaseException {
43 Layer0 L0 = Layer0.getInstance(graph);
44 ModelingResources MOD = ModelingResources.getInstance(graph);
46 String label = tryLabel ? graph.<String>getPossibleRelatedValue(item, L0.HasLabel, Bindings.STRING) : null;
47 boolean labelDefined = isNonempty(label);
48 if (!showValue && labelDefined)
51 // Create label from rvi
52 Binding rviBinding = graph.getService(Databoard.class).getBindingUnchecked( RVI.class );
53 RVI rvi = graph.getPossibleRelatedValue(item, MOD.Subscription_Item_VariableId, rviBinding);
55 return NO_VARIABLE_ID;
57 Resource model = graph.syncRequest(new PossibleIndexRoot(item));
59 ModelContexts contexts = graph.syncRequest(new ModelContextsRequest(model), TransientCacheAsyncListener.<ModelContexts>instance());
60 Variable configurationContext = contexts.getConfigurationContext();
61 Variable experimentContext = contexts.getExperimentContext();
63 if (configurationContext != null) {
64 // Resolve variable and take note of the resolution context
65 Variable variable = null;
66 Variable resolutionContext = experimentContext;
67 String resolutionContextURI = contexts.getExperimentContextURI();
68 if (showValue && experimentContext != null)
69 variable = rvi.resolvePossible(graph, experimentContext);
70 if (variable == null) {
71 resolutionContext = configurationContext;
72 resolutionContextURI = contexts.getConfigurationContextURI();
73 variable = rvi.resolvePossible(graph, configurationContext);
76 if (variable != null) {
78 label = relativeURI(graph, variable, resolutionContextURI);
80 label = rvi.toPossibleString(graph, configurationContext);
82 label = removeVariablePrefixPath(label);
83 label = URIStringUtils.unescape(label);
87 if (showValue && resolutionContext == experimentContext) {
88 StringBuilder sb = new StringBuilder(label);
90 Double gain = graph.getPossibleRelatedValue(item, MOD.Subscription_Item_Gain, Bindings.DOUBLE);
91 Double bias = graph.getPossibleRelatedValue(item, MOD.Subscription_Item_Bias, Bindings.DOUBLE);
92 String unit = graph.getPossibleRelatedValue(item, MOD.Subscription_Item_Unit, Bindings.STRING);
94 boolean oldSync = graph.setSynchronous(synchronous);
96 Object value = graph.syncRequest( new PossibleVariableValue<Object>(variable) );
97 sb = formatValue(value, gain, bias, unit, valueFormat, sb);
98 } catch (PendingVariableException e) {
99 sb.append(" (<pending>)");
101 graph.setSynchronous(oldSync);
104 label = sb.toString();
110 return label != null ? label : NO_VARIABLE_ID;
113 private static StringBuilder formatValue(Object value, Double gain, Double bias, String unit, ValueFormat valueFormat, StringBuilder sb) {
114 if (value instanceof Number) {
115 double d = ((Number) value).doubleValue();
121 sb.append(" (").append(valueFormat.format.format(ad));
123 sb.append(" (").append(FormattingUtils.engineeringFormat(value));
125 if (unit != null && !unit.isEmpty()) {
126 sb.append(' ').append(unit);
128 return sb.append(')');
131 public static String removeVariablePrefixPath(String rvi) {
132 // Apros-specific logics:
133 // 1. remove path prefix
134 // 2. change IndexReferences (i-N) into "(N+1)" Apros-style indexing
135 int propIndex = rvi.indexOf('#');
138 int prevSlash = rvi.lastIndexOf('/', propIndex);
141 Pair<String, Integer> attrKey = attributeKey(rvi, propIndex + 1);
142 return rvi.substring(prevSlash + 1, propIndex + 1) + attrKey.first
143 + (attrKey.second != null ? "(" + (attrKey.second + 1) + ")" : "");
146 private static Pair<String, Integer> attributeKey(String key, int start) {
147 int iy = key.lastIndexOf('/');
148 boolean isIndexed = iy >= start;
150 ChildReference child = ChildReference.parsePath(key.substring(iy + 1));
151 if (child instanceof IndexReference)
152 return Pair.make(key.substring(start, iy), ((IndexReference) child).getIndex());
154 return Pair.make(key.substring(start), null);
157 private static boolean isNonempty(String label) {
158 return label != null && !label.trim().isEmpty();
161 private static String relativeURI(ReadGraph graph, Variable variable, String contextURI) throws DatabaseException {
162 return relativeURI(variable.getURI(graph), contextURI);
165 private static String relativeURI(String fullURI, String contextURI) {
166 return fullURI.substring(contextURI.length());