-/*******************************************************************************\r
- * Copyright (c) 2011 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.modeling.subscription;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.Map;\r
-import java.util.TreeMap;\r
-\r
-import org.eclipse.core.runtime.MultiStatus;\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.Databoard;\r
-import org.simantics.databoard.binding.Binding;\r
-import org.simantics.databoard.type.Datatype;\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.common.procedure.adapter.TransientCacheListener;\r
-import org.simantics.db.common.request.BinaryRead;\r
-import org.simantics.db.common.request.ObjectsWithType;\r
-import org.simantics.db.common.request.ResourceRead;\r
-import org.simantics.db.common.request.TernaryRead;\r
-import org.simantics.db.common.utils.NameUtils;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.variable.RVI;\r
-import org.simantics.db.layer0.variable.Variable;\r
-import org.simantics.db.layer0.variable.Variables;\r
-import org.simantics.history.util.subscription.SubscriptionItem;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.modeling.ModelingResources;\r
-import org.simantics.scl.runtime.tuple.Tuple3;\r
-import org.simantics.simulation.experiment.IDynamicExperiment;\r
-import org.simantics.simulation.ontology.SimulationResource;\r
-import org.simantics.utils.datastructures.Pair;\r
-\r
-import gnu.trove.map.hash.THashMap;\r
-\r
-/**\r
- * @author Tuukka Lehtonen\r
- */\r
-public class CollectSubscriptions extends ResourceRead<SubscriptionCollectionResult> {\r
-\r
- private static final boolean PERF = false;\r
- private static final boolean DEBUG = false;\r
-\r
- protected Resource experiment;\r
- protected double defaultSamplingInterval;\r
- protected boolean synchronous;\r
-\r
- public CollectSubscriptions(IDynamicExperiment experiment, double defaultSamplingInterval) {\r
- this(experiment.getModel(), experiment.getResource(), defaultSamplingInterval, false);\r
- }\r
-\r
- public CollectSubscriptions(IDynamicExperiment experiment, double defaultSamplingInterval, boolean synchronous) {\r
- this(experiment.getModel(), experiment.getResource(), defaultSamplingInterval, synchronous);\r
- }\r
-\r
- public CollectSubscriptions(Resource model, Resource experiment, double defaultSamplingInterval) {\r
- this(model, experiment, defaultSamplingInterval, false);\r
- }\r
-\r
- public CollectSubscriptions(Resource model, Resource experiment, double defaultSamplingInterval, boolean synchronous) {\r
- super(model);\r
- this.experiment = experiment;\r
- this.defaultSamplingInterval = defaultSamplingInterval;\r
- }\r
-\r
- @Override\r
- public SubscriptionCollectionResult perform(ReadGraph graph) throws DatabaseException {\r
- MultiStatus status = new MultiStatus(ModelHistoryCollector.BUNDLE_ID, 0, "History collection subscription resolution problems:", null);\r
- boolean oldSync = graph.setSynchronous(synchronous);\r
- try {\r
- Map<String, SubscriptionItem> items = gatherSubscriptions(graph, resource, status, new TreeMap<String, SubscriptionItem>());\r
- return new SubscriptionCollectionResult(new ArrayList<>(items.values()), status);\r
- } finally {\r
- graph.setSynchronous(oldSync);\r
- }\r
- }\r
-\r
- /**\r
- * Scans thru a model and writes up all the variables that are to be monitored.\r
- * This includes:\r
- * Subscriptions\r
- * Charts\r
- * Spreadsheets (not in cur. impl)\r
- * Monitors on diagram (not in cur. impl)\r
- * \r
- * @param graph\r
- * @param model\r
- * @param status \r
- * @param variablesToMonitor\r
- * @throws DatabaseException\r
- */\r
- public Map<String, SubscriptionItem> gatherSubscriptions(ReadGraph graph, Resource model, MultiStatus status,\r
- Map<String, SubscriptionItem> items) throws DatabaseException {\r
- if (PERF)\r
- System.out.println("DEBUG: CollectAprosSubscriptions.gatherSubscriptions");\r
- long start = System.nanoTime();\r
-\r
- // Get active experiment context if possible to be able\r
- // to resolve the whole model, not just the configuration.\r
- Variable configuration = Variables.getPossibleConfigurationContext(graph, model);\r
- if (configuration == null)\r
- return items;\r
- Variable experimentVariable = null;\r
-\r
- SimulationResource SIMU = SimulationResource.getInstance(graph);\r
- Layer0 L0 = Layer0.getInstance(graph);\r
- for (Resource run : graph.syncRequest(new ObjectsWithType(experiment, L0.ConsistsOf, SIMU.Run))) {\r
- if (graph.hasStatement(run, SIMU.IsActive)) {\r
- try {\r
- experimentVariable = Variables.switchRealization(graph, configuration, run);\r
- } catch (DatabaseException e) {\r
- experimentVariable = Variables.switchPossibleContext(graph, configuration, run);\r
- }\r
- }\r
- }\r
-\r
- ModelingResources MOD = ModelingResources.getInstance(graph);\r
- Param constants = new Param(configuration, experimentVariable, defaultSamplingInterval);\r
- for (Resource subscription : graph.syncRequest(new ObjectsWithType(model, L0.ConsistsOf, MOD.Subscription))) {\r
- Map<String, SubscriptionItem> subscriptionItems = graph.syncRequest(\r
- new SubscriptionRequest(subscription, constants),\r
- TransientCacheAsyncListener.<Map<String, SubscriptionItem>>instance());\r
- items.putAll(subscriptionItems);\r
- }\r
-\r
- if (PERF)\r
- System.out.println("DEBUG: CollectAprosSubscriptions.gatherSubscriptions ENDS, took " + ((System.nanoTime() - start)*1e-6) + " ms with " + items.size() + " items");\r
-\r
- return items;\r
- }\r
-\r
- static class Param extends Tuple3 {\r
- public Param(Variable configurationContext, Variable experimentContext, Double defaultSamplingInterval) {\r
- super(configurationContext, experimentContext, defaultSamplingInterval);\r
- }\r
- }\r
-\r
- static class SubscriptionRequest extends BinaryRead<Resource, Param, Map<String, SubscriptionItem>> {\r
-\r
- public SubscriptionRequest(Resource subscription, Param constants) {\r
- super(subscription, constants);\r
- }\r
-\r
- @Override\r
- public Map<String, SubscriptionItem> perform(ReadGraph graph) throws DatabaseException {\r
- if (PERF)\r
- System.out.println("DEBUG: CollectSubscriptions.SubscriptionRequest(" + NameUtils.getSafeName(graph, parameter, true) + ")");\r
- long start = System.nanoTime();\r
-\r
- ModelingResources MOD = ModelingResources.getInstance(graph);\r
- Boolean v = graph.getPossibleRelatedValue(parameter, MOD.Subscription_Enabled, Bindings.BOOLEAN);\r
- if (!Boolean.TRUE.equals(v))\r
- return Collections.emptyMap();\r
-\r
- Layer0 L0 = Layer0.getInstance(graph);\r
- String groupId = graph.getPossibleRelatedValue(parameter, L0.HasName, Bindings.STRING);\r
- if (groupId == null)\r
- return Collections.emptyMap();\r
-\r
- Map<String, SubscriptionItem> items = graph.syncRequest(\r
- new SubscriptionItemsRequest(parameter, groupId, parameter2),\r
- TransientCacheAsyncListener.<Map<String, SubscriptionItem>>instance());\r
- if (PERF)\r
- System.out.println("DEBUG: CollectSubscriptions.SubscriptionRequest(" + NameUtils.getSafeName(graph, parameter, true) + ") DONE in " + ((System.nanoTime() - start)*1e-6) + " ms");\r
-\r
- return items;\r
- }\r
-\r
- }\r
-\r
- static class SubscriptionItemsRequest extends TernaryRead<Resource, String, Param, Map<String, SubscriptionItem>> {\r
-\r
- public SubscriptionItemsRequest(Resource subscription, String groupId, Param constants) {\r
- super(subscription, groupId, constants);\r
- }\r
-\r
- @Override\r
- public Map<String, SubscriptionItem> perform(ReadGraph graph) throws DatabaseException {\r
- if (PERF)\r
- System.out.println("DEBUG: CollectSubscriptions.SubscriptionItemsRequest(" + NameUtils.getSafeName(graph, parameter, true) + ")");\r
- long start = System.nanoTime();\r
-\r
- Layer0 L0 = Layer0.getInstance(graph);\r
- ModelingResources MOD = ModelingResources.getInstance(graph);\r
-\r
- Collection<Resource> subscriptionItems = graph.syncRequest(new ObjectsWithType(parameter, L0.ConsistsOf, MOD.Subscription_Item));\r
- if (subscriptionItems.isEmpty())\r
- return Collections.emptyMap();\r
-\r
- Map<String, SubscriptionItem> result = new THashMap<>(subscriptionItems.size());\r
- for (Resource subscriptionItem : subscriptionItems) {\r
- SubscriptionItem hi = graph.syncRequest(\r
- new ItemRequest(subscriptionItem, parameter2, parameter3),\r
- TransientCacheListener.<SubscriptionItem>instance());\r
- if (hi != null)\r
- result.put(hi.id, hi);\r
- }\r
-\r
- if (PERF)\r
- System.out.println("DEBUG: CollectSubscriptions.SubscriptionItemsRequest(" + NameUtils.getSafeName(graph, parameter, true) + ") DONE in " + ((System.nanoTime() - start)*1e-6) + " ms with " + result.size() + " items");\r
-\r
- return result;\r
- }\r
-\r
- }\r
-\r
- static class ItemRequest extends TernaryRead<Resource, String, Param, SubscriptionItem> {\r
-\r
- public ItemRequest(Resource item, String groupId, Param constants) {\r
- super(item, groupId, constants);\r
- }\r
-\r
- @Override\r
- public SubscriptionItem perform(ReadGraph graph) throws DatabaseException {\r
- ModelingResources MOD = ModelingResources.getInstance(graph);\r
- Resource subscriptionItem = parameter;\r
- String groupId = parameter2;\r
- Param constants = parameter3;\r
- Variable configurationContext = (Variable) constants.c0;\r
- Variable experimentContext = (Variable) constants.c1;\r
- double defaultSamplingInterval = (double) constants.c2;\r
-\r
- Binding rviBinding = graph.getService(Databoard.class).getBindingUnchecked( RVI.class );\r
- RVI rvi = graph.getPossibleRelatedValue(subscriptionItem, MOD.Subscription_Item_VariableId, rviBinding);\r
- if (rvi == null) {\r
- //status.add(new Status(IStatus.WARNING, ModelHistoryCollector.BUNDLE_ID, "Subscription Item '" + NameUtils.getSafeName(graph, subscriptionItem) + "' is missing RVI property"));\r
- return null;\r
- }\r
-\r
- Layer0 L0 = Layer0.getInstance(graph);\r
- String guid = graph.getPossibleRelatedValue(subscriptionItem, L0.HasName);\r
- if (guid == null) {\r
- //status.add(new Status(IStatus.WARNING, ModelHistoryCollector.BUNDLE_ID, "Subscription Item '" + NameUtils.getSafeName(graph, subscriptionItem) + "' has no name (ID)."));\r
- return null;\r
- }\r
- String variablePersistentId = rvi.toString();\r
- Pair<Variable, Variable> variable = Variables.resolvePossible(graph, rvi, configurationContext, experimentContext);\r
- if (variable == null) {\r
- if (DEBUG)\r
- System.out.println("DEBUG: unresolvable subscription: " + variablePersistentId);\r
- // Don't log these, these problems are conveyed to the\r
- // user through model browser UI labels.\r
- //status.add(new Status(IStatus.WARNING, ModelHistoryCollector.BUNDLE_ID, "Subscription Item '" + NameUtils.getSafeName(graph, subscriptionItem) + "' variable cannot be resolved from RVI " + rvi.toString(graph)));\r
- return null;\r
- }\r
- String variableId = rvi.asPossibleString(graph, variable.second);\r
- //System.out.println("DEBUG: " + variablePersistentId + " - " + variableId);\r
- if (variableId == null) {\r
- return null;\r
- }\r
-\r
- Datatype type = graph.getPossibleRelatedValue(subscriptionItem, MOD.Subscription_Item_Datatype, Bindings.getBindingUnchecked(Datatype.class));\r
- if (type == null && variable != null) {\r
- type = variable.first.getPossibleDatatype(graph);\r
- }\r
- if (type == null) {\r
- //status.add(new Status(IStatus.WARNING, ModelHistoryCollector.BUNDLE_ID, "Subscription Item '" + NameUtils.getSafeName(graph, subscriptionItem) + "' is missing data type"));\r
- // Can't function without a datatype.\r
- return null;\r
- }\r
-\r
- Double itemSamplingInterval = graph.getPossibleRelatedValue(subscriptionItem, MOD.Subscription_Item_SamplingInterval, Bindings.DOUBLE);\r
- Double itemDeadband = graph.getPossibleRelatedValue(subscriptionItem, MOD.Subscription_Item_Deadband, Bindings.DOUBLE);\r
-\r
- Double bias = graph.getPossibleRelatedValue(subscriptionItem, MOD.Subscription_Item_Bias, Bindings.DOUBLE);\r
- Double gain = graph.getPossibleRelatedValue(subscriptionItem, MOD.Subscription_Item_Gain, Bindings.DOUBLE);\r
- String unit = graph.getPossibleRelatedValue(subscriptionItem, MOD.Subscription_Item_Unit, Bindings.STRING);\r
-\r
- double samplingInterval = itemSamplingInterval != null ? itemSamplingInterval : defaultSamplingInterval;\r
- double deadband = itemDeadband != null ? itemDeadband : 0.0;\r
-\r
- SubscriptionItem item = new SubscriptionItem();\r
-\r
- // HACK: use id for storing the name of the item\r
- // Assumption: subscription item's name is unique within the model\r
- item.id = guid;\r
-\r
- item.variableId = variableId;\r
- item.groupId = groupId;\r
- item.groupItemId = variablePersistentId;\r
- // HACK: use format for storing the data type of the item\r
- item.format = type;\r
- // HACK: use formatId for storing the unit of the item,\r
- // empty unit is interpreted to mean "no unit" because\r
- // formatId cannot be null.\r
- item.formatId = unit == null ? "" : unit;\r
-\r
- // Subscription parameters\r
- item.deadband = deadband;\r
- item.interval = samplingInterval;\r
- if (bias != null) item.bias = bias;\r
- if (gain != null) item.gain = gain;\r
-\r
- if (DEBUG)\r
- //System.out.println("DEBUG: ItemRequest(" + parameter + ", " + parameter2.getURI(graph) + ", " + parameter3 + ")\n\t= " + item);\r
- System.out.println("DEBUG: ItemRequest(" + parameter + ", " + parameter2 + ", " + parameter3 + ")\n\t= " + item);\r
-\r
- return item;\r
- }\r
-\r
- }\r
-\r
+/*******************************************************************************
+ * Copyright (c) 2011 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.modeling.subscription;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.eclipse.core.runtime.MultiStatus;
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.Databoard;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.type.Datatype;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
+import org.simantics.db.common.procedure.adapter.TransientCacheListener;
+import org.simantics.db.common.request.BinaryRead;
+import org.simantics.db.common.request.ObjectsWithType;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.common.request.TernaryRead;
+import org.simantics.db.common.utils.NameUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.variable.RVI;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.db.layer0.variable.Variables;
+import org.simantics.history.util.subscription.SubscriptionItem;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.scl.runtime.tuple.Tuple3;
+import org.simantics.simulation.experiment.IDynamicExperiment;
+import org.simantics.simulation.ontology.SimulationResource;
+import org.simantics.utils.datastructures.Pair;
+
+import gnu.trove.map.hash.THashMap;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class CollectSubscriptions extends ResourceRead<SubscriptionCollectionResult> {
+
+ private static final boolean PERF = false;
+ private static final boolean DEBUG = false;
+
+ protected Resource experiment;
+ protected double defaultSamplingInterval;
+ protected boolean synchronous;
+
+ public CollectSubscriptions(IDynamicExperiment experiment, double defaultSamplingInterval) {
+ this(experiment.getModel(), experiment.getResource(), defaultSamplingInterval, false);
+ }
+
+ public CollectSubscriptions(IDynamicExperiment experiment, double defaultSamplingInterval, boolean synchronous) {
+ this(experiment.getModel(), experiment.getResource(), defaultSamplingInterval, synchronous);
+ }
+
+ public CollectSubscriptions(Resource model, Resource experiment, double defaultSamplingInterval) {
+ this(model, experiment, defaultSamplingInterval, false);
+ }
+
+ public CollectSubscriptions(Resource model, Resource experiment, double defaultSamplingInterval, boolean synchronous) {
+ super(model);
+ this.experiment = experiment;
+ this.defaultSamplingInterval = defaultSamplingInterval;
+ }
+
+ @Override
+ public SubscriptionCollectionResult perform(ReadGraph graph) throws DatabaseException {
+ MultiStatus status = new MultiStatus(ModelHistoryCollector.BUNDLE_ID, 0, "History collection subscription resolution problems:", null);
+ boolean oldSync = graph.setSynchronous(synchronous);
+ try {
+ Map<String, SubscriptionItem> items = gatherSubscriptions(graph, resource, status, new TreeMap<String, SubscriptionItem>());
+ return new SubscriptionCollectionResult(new ArrayList<>(items.values()), status);
+ } finally {
+ graph.setSynchronous(oldSync);
+ }
+ }
+
+ /**
+ * Scans thru a model and writes up all the variables that are to be monitored.
+ * This includes:
+ * Subscriptions
+ * Charts
+ * Spreadsheets (not in cur. impl)
+ * Monitors on diagram (not in cur. impl)
+ *
+ * @param graph
+ * @param model
+ * @param status
+ * @param variablesToMonitor
+ * @throws DatabaseException
+ */
+ public Map<String, SubscriptionItem> gatherSubscriptions(ReadGraph graph, Resource model, MultiStatus status,
+ Map<String, SubscriptionItem> items) throws DatabaseException {
+ if (PERF)
+ System.out.println("DEBUG: CollectAprosSubscriptions.gatherSubscriptions");
+ long start = System.nanoTime();
+
+ // Get active experiment context if possible to be able
+ // to resolve the whole model, not just the configuration.
+ Variable configuration = Variables.getPossibleConfigurationContext(graph, model);
+ if (configuration == null)
+ return items;
+ Variable experimentVariable = null;
+
+ SimulationResource SIMU = SimulationResource.getInstance(graph);
+ Layer0 L0 = Layer0.getInstance(graph);
+ for (Resource run : graph.syncRequest(new ObjectsWithType(experiment, L0.ConsistsOf, SIMU.Run))) {
+ if (graph.hasStatement(run, SIMU.IsActive)) {
+ try {
+ experimentVariable = Variables.switchRealization(graph, configuration, run);
+ } catch (DatabaseException e) {
+ experimentVariable = Variables.switchPossibleContext(graph, configuration, run);
+ }
+ }
+ }
+
+ ModelingResources MOD = ModelingResources.getInstance(graph);
+ Param constants = new Param(configuration, experimentVariable, defaultSamplingInterval);
+ for (Resource subscription : graph.syncRequest(new ObjectsWithType(model, L0.ConsistsOf, MOD.Subscription))) {
+ Map<String, SubscriptionItem> subscriptionItems = graph.syncRequest(
+ new SubscriptionRequest(subscription, constants),
+ TransientCacheAsyncListener.<Map<String, SubscriptionItem>>instance());
+ items.putAll(subscriptionItems);
+ }
+
+ if (PERF)
+ System.out.println("DEBUG: CollectAprosSubscriptions.gatherSubscriptions ENDS, took " + ((System.nanoTime() - start)*1e-6) + " ms with " + items.size() + " items");
+
+ return items;
+ }
+
+ static class Param extends Tuple3 {
+ public Param(Variable configurationContext, Variable experimentContext, Double defaultSamplingInterval) {
+ super(configurationContext, experimentContext, defaultSamplingInterval);
+ }
+ }
+
+ static class SubscriptionRequest extends BinaryRead<Resource, Param, Map<String, SubscriptionItem>> {
+
+ public SubscriptionRequest(Resource subscription, Param constants) {
+ super(subscription, constants);
+ }
+
+ @Override
+ public Map<String, SubscriptionItem> perform(ReadGraph graph) throws DatabaseException {
+ if (PERF)
+ System.out.println("DEBUG: CollectSubscriptions.SubscriptionRequest(" + NameUtils.getSafeName(graph, parameter, true) + ")");
+ long start = System.nanoTime();
+
+ ModelingResources MOD = ModelingResources.getInstance(graph);
+ Boolean v = graph.getPossibleRelatedValue(parameter, MOD.Subscription_Enabled, Bindings.BOOLEAN);
+ if (!Boolean.TRUE.equals(v))
+ return Collections.emptyMap();
+
+ Layer0 L0 = Layer0.getInstance(graph);
+ String groupId = graph.getPossibleRelatedValue(parameter, L0.HasName, Bindings.STRING);
+ if (groupId == null)
+ return Collections.emptyMap();
+
+ Map<String, SubscriptionItem> items = graph.syncRequest(
+ new SubscriptionItemsRequest(parameter, groupId, parameter2),
+ TransientCacheAsyncListener.<Map<String, SubscriptionItem>>instance());
+ if (PERF)
+ System.out.println("DEBUG: CollectSubscriptions.SubscriptionRequest(" + NameUtils.getSafeName(graph, parameter, true) + ") DONE in " + ((System.nanoTime() - start)*1e-6) + " ms");
+
+ return items;
+ }
+
+ }
+
+ static class SubscriptionItemsRequest extends TernaryRead<Resource, String, Param, Map<String, SubscriptionItem>> {
+
+ public SubscriptionItemsRequest(Resource subscription, String groupId, Param constants) {
+ super(subscription, groupId, constants);
+ }
+
+ @Override
+ public Map<String, SubscriptionItem> perform(ReadGraph graph) throws DatabaseException {
+ if (PERF)
+ System.out.println("DEBUG: CollectSubscriptions.SubscriptionItemsRequest(" + NameUtils.getSafeName(graph, parameter, true) + ")");
+ long start = System.nanoTime();
+
+ Layer0 L0 = Layer0.getInstance(graph);
+ ModelingResources MOD = ModelingResources.getInstance(graph);
+
+ Collection<Resource> subscriptionItems = graph.syncRequest(new ObjectsWithType(parameter, L0.ConsistsOf, MOD.Subscription_Item));
+ if (subscriptionItems.isEmpty())
+ return Collections.emptyMap();
+
+ Map<String, SubscriptionItem> result = new THashMap<>(subscriptionItems.size());
+ for (Resource subscriptionItem : subscriptionItems) {
+ SubscriptionItem hi = graph.syncRequest(
+ new ItemRequest(subscriptionItem, parameter2, parameter3),
+ TransientCacheListener.<SubscriptionItem>instance());
+ if (hi != null)
+ result.put(hi.id, hi);
+ }
+
+ if (PERF)
+ System.out.println("DEBUG: CollectSubscriptions.SubscriptionItemsRequest(" + NameUtils.getSafeName(graph, parameter, true) + ") DONE in " + ((System.nanoTime() - start)*1e-6) + " ms with " + result.size() + " items");
+
+ return result;
+ }
+
+ }
+
+ static class ItemRequest extends TernaryRead<Resource, String, Param, SubscriptionItem> {
+
+ public ItemRequest(Resource item, String groupId, Param constants) {
+ super(item, groupId, constants);
+ }
+
+ @Override
+ public SubscriptionItem perform(ReadGraph graph) throws DatabaseException {
+ ModelingResources MOD = ModelingResources.getInstance(graph);
+ Resource subscriptionItem = parameter;
+ String groupId = parameter2;
+ Param constants = parameter3;
+ Variable configurationContext = (Variable) constants.c0;
+ Variable experimentContext = (Variable) constants.c1;
+ double defaultSamplingInterval = (double) constants.c2;
+
+ Binding rviBinding = graph.getService(Databoard.class).getBindingUnchecked( RVI.class );
+ RVI rvi = graph.getPossibleRelatedValue(subscriptionItem, MOD.Subscription_Item_VariableId, rviBinding);
+ if (rvi == null) {
+ //status.add(new Status(IStatus.WARNING, ModelHistoryCollector.BUNDLE_ID, "Subscription Item '" + NameUtils.getSafeName(graph, subscriptionItem) + "' is missing RVI property"));
+ return null;
+ }
+
+ Layer0 L0 = Layer0.getInstance(graph);
+ String guid = graph.getPossibleRelatedValue(subscriptionItem, L0.HasName);
+ if (guid == null) {
+ //status.add(new Status(IStatus.WARNING, ModelHistoryCollector.BUNDLE_ID, "Subscription Item '" + NameUtils.getSafeName(graph, subscriptionItem) + "' has no name (ID)."));
+ return null;
+ }
+ String variablePersistentId = rvi.toString();
+ Pair<Variable, Variable> variable = Variables.resolvePossible(graph, rvi, configurationContext, experimentContext);
+ if (variable == null) {
+ if (DEBUG)
+ System.out.println("DEBUG: unresolvable subscription: " + variablePersistentId);
+ // Don't log these, these problems are conveyed to the
+ // user through model browser UI labels.
+ //status.add(new Status(IStatus.WARNING, ModelHistoryCollector.BUNDLE_ID, "Subscription Item '" + NameUtils.getSafeName(graph, subscriptionItem) + "' variable cannot be resolved from RVI " + rvi.toString(graph)));
+ return null;
+ }
+ String variableId = rvi.asPossibleString(graph, variable.second);
+ //System.out.println("DEBUG: " + variablePersistentId + " - " + variableId);
+ if (variableId == null) {
+ return null;
+ }
+
+ Datatype type = graph.getPossibleRelatedValue(subscriptionItem, MOD.Subscription_Item_Datatype, Bindings.getBindingUnchecked(Datatype.class));
+ if (type == null && variable != null) {
+ type = variable.first.getPossibleDatatype(graph);
+ }
+ if (type == null) {
+ //status.add(new Status(IStatus.WARNING, ModelHistoryCollector.BUNDLE_ID, "Subscription Item '" + NameUtils.getSafeName(graph, subscriptionItem) + "' is missing data type"));
+ // Can't function without a datatype.
+ return null;
+ }
+
+ Double itemSamplingInterval = graph.getPossibleRelatedValue(subscriptionItem, MOD.Subscription_Item_SamplingInterval, Bindings.DOUBLE);
+ Double itemDeadband = graph.getPossibleRelatedValue(subscriptionItem, MOD.Subscription_Item_Deadband, Bindings.DOUBLE);
+
+ Double bias = graph.getPossibleRelatedValue(subscriptionItem, MOD.Subscription_Item_Bias, Bindings.DOUBLE);
+ Double gain = graph.getPossibleRelatedValue(subscriptionItem, MOD.Subscription_Item_Gain, Bindings.DOUBLE);
+ String unit = graph.getPossibleRelatedValue(subscriptionItem, MOD.Subscription_Item_Unit, Bindings.STRING);
+
+ double samplingInterval = itemSamplingInterval != null ? itemSamplingInterval : defaultSamplingInterval;
+ double deadband = itemDeadband != null ? itemDeadband : 0.0;
+
+ SubscriptionItem item = new SubscriptionItem();
+
+ // HACK: use id for storing the name of the item
+ // Assumption: subscription item's name is unique within the model
+ item.id = guid;
+
+ item.variableId = variableId;
+ item.groupId = groupId;
+ item.groupItemId = variablePersistentId;
+ // HACK: use format for storing the data type of the item
+ item.format = type;
+ // HACK: use formatId for storing the unit of the item,
+ // empty unit is interpreted to mean "no unit" because
+ // formatId cannot be null.
+ item.formatId = unit == null ? "" : unit;
+
+ // Subscription parameters
+ item.deadband = deadband;
+ item.interval = samplingInterval;
+ if (bias != null) item.bias = bias;
+ if (gain != null) item.gain = gain;
+
+ if (DEBUG)
+ //System.out.println("DEBUG: ItemRequest(" + parameter + ", " + parameter2.getURI(graph) + ", " + parameter3 + ")\n\t= " + item);
+ System.out.println("DEBUG: ItemRequest(" + parameter + ", " + parameter2 + ", " + parameter3 + ")\n\t= " + item);
+
+ return item;
+ }
+
+ }
+
}
\ No newline at end of file