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