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