package org.simantics.district.network.techtype;
import java.util.Collection;
+import java.util.HashMap;
import java.util.Map;
+import java.util.Objects;
import org.simantics.Simantics;
import org.simantics.databoard.Bindings;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.QueryIndexUtils;
import org.simantics.db.layer0.request.PossibleVariable;
+import org.simantics.db.layer0.request.PropertyInfo;
+import org.simantics.db.layer0.request.PropertyInfoRequest;
import org.simantics.db.layer0.variable.Variable;
import org.simantics.district.network.ontology.DistrictNetworkResource;
import org.simantics.district.network.techtype.requests.PossibleTechTypeItem;
import org.simantics.district.network.techtype.requests.PossibleTechTypeTable;
+import org.simantics.district.network.techtype.requests.TechTypeTableData;
import org.simantics.district.network.techtype.requests.TechTypeTableKeyName;
+import org.simantics.layer0.Layer0;
import org.simantics.scl.runtime.SCLContext;
import org.simantics.structural.stubs.StructuralResource2;
import org.slf4j.Logger;
});
}
+ /**
+ * Reset all components that address the given tech type table to the table values.
+ *
+ * @param table A tech type table
+ * @throws DatabaseException
+ */
+ public static void resetMapElements(Resource table) throws DatabaseException {
+ Simantics.getSession().syncRequest(new WriteRequest() {
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ Resource model = graph.syncRequest(new PossibleIndexRoot(table), TransientCacheListener.instance());
+ if (model == null)
+ return;
+
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ Resource type = graph.getPossibleObject(table, DN.TechType_TechTypeTable_HasComponentType);
+ if (type == null)
+ return;
+
+ Layer0 L0 = Layer0.getInstance(graph);
+ String typeName = graph.getRelatedValue2(type, L0.HasName);
+
+ Resource mapping = null;
+ for (Resource m : QueryIndexUtils.searchByType(graph, model, DN.Mapping_Base)) {
+ String name = graph.getRelatedValue2(m, DN.Mapping_ComponentType);
+ if (Objects.equals(name, typeName)) {
+ mapping = m;
+ break;
+ }
+ }
+
+ if (mapping == null) {
+ LOGGER.warn("No mapping found for component type {}", type);
+ return;
+ }
+
+ Map<String, PropertyInfo> properties = new HashMap<>();
+ Resource mappingType = graph.getSingleType(mapping, DN.Mapping_Base);
+ Collection<Resource> mappingRelations = graph.getObjects(mappingType, L0.DomainOf);
+ for (Resource r : mappingRelations) {
+ String propertyName = graph.getPossibleRelatedValue2(mapping, r);
+ if (propertyName == null)
+ continue;
+
+ Resource relation = graph.getPossibleObject(r, DN.Mapping_HasPropertyRelation);
+ if (relation == null)
+ continue;
+
+ properties.put(propertyName, graph.syncRequest(new PropertyInfoRequest(relation)));
+ }
+
+ Map<String, Map<String, String>> data = graph.syncRequest(new TechTypeTableData(table), TransientCacheListener.instance());
+ String keyName = graph.syncRequest(new TechTypeTableKeyName(table), TransientCacheListener.instance());
+ Resource keyRelation = properties.get(keyName).predicate;
+
+ if (keyRelation == null) {
+ LOGGER.warn("No relation mapped to property {} found in {} mapping", keyName, mapping);
+ return;
+ }
+
+ Resource elementType = graph.isInstanceOf(mapping, DN.Mapping_EdgeMapping) ? DN.Edge :
+ graph.isInstanceOf(mapping, DN.Mapping_VertexMapping) ? DN.Vertex :
+ DN.Element;
+
+ Collection<Resource> elements = QueryIndexUtils.searchByType(graph, model, elementType);
+ for (Resource element : elements) {
+ Resource elementMapping = graph.getPossibleObject(element, DN.HasMapping);
+ if (!mapping.equals(elementMapping))
+ continue;
+
+ String key = graph.getPossibleRelatedValue2(element, keyRelation);
+ Map<String, String> values = data.get(key);
+ if (values == null) {
+ LOGGER.info("Key {} no found in tech type table {}", key, table);
+ continue;
+ }
+
+ for (Map.Entry<String, String> entry : values.entrySet()) {
+ PropertyInfo prop = properties.get(entry.getKey());
+ if (prop == null)
+ continue;
+
+ String value = entry.getValue();
+ Datatype dt = prop.requiredDatatype;
+ if (dt instanceof NumberType) {
+ try {
+ Object num = ((NumberBinding)prop.defaultBinding).create(value.replace(",", "."));
+ graph.claimLiteral(element, prop.predicate, prop.literalRange, num, prop.defaultBinding);
+ } catch (NumberFormatException e) {
+ // Revert to asserted value
+ graph.deny(element, prop.predicate);
+ } catch (BindingException e) {
+ LOGGER.error("Failed to get binding for datatype {}", dt, e);
+ }
+ } else if (dt instanceof StringType) {
+ graph.claimLiteral(element, prop.predicate, prop.literalRange, value, Bindings.STRING);
+ } else {
+ LOGGER.warn("updateComponent: Unsupported property type {}", dt);
+ }
+ }
+ }
+ }
+ });
+ }
+
/**
* Update property values of a component based on the values in an associated tech type table, if any
*