]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/subscription/SubscriptionItemLabel.java
Merge "Reverted unintentional MANIFEST.MF change from c160c0a55f"
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / subscription / SubscriptionItemLabel.java
1 package org.simantics.modeling.subscription;\r
2 \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.exception.DatabaseException;\r
15 import org.simantics.db.layer0.exception.PendingVariableException;\r
16 import org.simantics.db.layer0.request.PossibleModel;\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
25 \r
26 public class SubscriptionItemLabel {\r
27 \r
28     private static final String NO_VARIABLE_ID = "<no variable id>";\r
29 \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
35     }\r
36 \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
39     }\r
40 \r
41     public static String resolveLabel(ReadGraph graph, Resource item, ValueFormat valueFormat, boolean synchronous, boolean tryLabel, boolean showValue) throws DatabaseException {\r
42 \r
43         Layer0 L0 = Layer0.getInstance(graph);\r
44         ModelingResources MOD = ModelingResources.getInstance(graph);\r
45 \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
49             return label;\r
50 \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
54         if (rvi == null)\r
55             return NO_VARIABLE_ID;\r
56 \r
57         Resource model = graph.syncRequest(new PossibleModel(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
62 \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
74                 }\r
75 \r
76                 if (variable != null) {\r
77                     if (!labelDefined) {\r
78                         label = relativeURI(graph, variable, resolutionContextURI);\r
79                         if (label == null)\r
80                             label = rvi.toPossibleString(graph, configurationContext);\r
81                         if (label != null) {\r
82                             label = removeVariablePrefixPath(label);\r
83                             label = URIStringUtils.unescape(label);\r
84                         }\r
85                     }\r
86 \r
87                     if (showValue && resolutionContext == experimentContext) {\r
88                         StringBuilder sb = new StringBuilder(label);\r
89 \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
93 \r
94                         boolean oldSync = graph.setSynchronous(synchronous);\r
95                         try {\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
100                         } finally {\r
101                             graph.setSynchronous(oldSync);\r
102                         }\r
103 \r
104                         label = sb.toString();\r
105                     }\r
106                 }\r
107             }\r
108         }\r
109 \r
110         return label != null ? label : NO_VARIABLE_ID;\r
111     }\r
112 \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
116             double ad = d;\r
117             if (gain != null)\r
118                 ad *= gain;\r
119             if (bias != null)\r
120                 ad += bias;\r
121             sb.append(" (").append(valueFormat.format.format(ad));\r
122         } else {\r
123             sb.append(" (").append(FormattingUtils.engineeringFormat(value));\r
124         }\r
125         if (unit != null && !unit.isEmpty()) {\r
126             sb.append(' ').append(unit);\r
127         }\r
128         return sb.append(')');\r
129     }\r
130 \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
137             return rvi;\r
138         int prevSlash = rvi.lastIndexOf('/', propIndex);\r
139         if (prevSlash == -1)\r
140             return rvi;\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
144     }\r
145 \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
149         if (isIndexed) {\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
153         }\r
154         return Pair.make(key.substring(start), null);\r
155     }\r
156 \r
157     private static boolean isNonempty(String label) {\r
158         return label != null && !label.trim().isEmpty();\r
159     }\r
160 \r
161     private static String relativeURI(ReadGraph graph, Variable variable, String contextURI) throws DatabaseException {\r
162         return relativeURI(variable.getURI(graph), contextURI);\r
163     }\r
164 \r
165     private static String relativeURI(String fullURI, String contextURI) {\r
166         return fullURI.substring(contextURI.length());\r
167     }\r
168 \r
169 }