--- /dev/null
+package org.simantics.district.network.profile;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.RequestProcessor;
+import org.simantics.db.Resource;
+import org.simantics.db.common.primitiverequest.OrderedSet;
+import org.simantics.db.common.procedure.wrapper.SetListenerToSingleSetListener;
+import org.simantics.db.common.request.BinaryRead;
+import org.simantics.db.common.request.TernaryRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.procedure.SetListener;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.layer0.Layer0;
+import org.simantics.scenegraph.profile.Group;
+import org.simantics.utils.strings.StringUtils;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class DistrictNodeGroup implements Group {
+
+ private final String name;
+ private final Collection<Resource> types;
+ private final Set<String> mappedComponentTypeNames;
+
+ public DistrictNodeGroup(ReadGraph graph, Resource group) throws DatabaseException {
+ Layer0 L0 = Layer0.getInstance(graph);
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+
+ this.name = StringUtils.safeString( graph.getPossibleRelatedValue(group, L0.HasName, Bindings.STRING) );
+ this.types = graph.getObjects(group, DIA.TypeGroup_HasType);
+ Collection<Resource> names = graph.getObjects(group, DN.DistrictNodeGroup_hasComponentTypeName);
+ this.mappedComponentTypeNames = new HashSet<>(names.size());
+ for (Resource name : names) {
+ mappedComponentTypeNames.add( graph.getValue(name, Bindings.STRING) );
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + name.hashCode();
+ result = prime * result + types.hashCode();
+ result = prime * result + mappedComponentTypeNames.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ DistrictNodeGroup other = (DistrictNodeGroup) obj;
+ return name.equals(other.name) && types.equals(other.types) && mappedComponentTypeNames.equals(other.mappedComponentTypeNames);
+ }
+
+ @Override
+ public void trackItems(RequestProcessor processor, final Resource runtimeDiagram, final SetListener<Resource> listener) {
+ if (types.isEmpty()) {
+ System.out.println("DistrictNodeGroup has no types!");
+ return;
+ }
+ processor.asyncRequest(new TernaryRead<Resource, Collection<Resource>, Set<String>, Collection<Resource>>(runtimeDiagram, types, mappedComponentTypeNames) {
+ @Override
+ public Collection<Resource> perform(ReadGraph graph) throws DatabaseException {
+ return graph.syncRequest(new ElementsMappedToComponentTypes(parameter, parameter2, parameter3));
+ }
+ }, new SetListenerToSingleSetListener<Resource>(listener));
+ }
+
+ @Override
+ public String toString() {
+ return "every '" + name + "' of mapped type " + mappedComponentTypeNames;
+ }
+
+ private static class ElementsMappedToComponentTypes extends TernaryRead<Resource, Collection<Resource>, Set<String>, Set<Resource>> {
+
+ public ElementsMappedToComponentTypes(Resource runtimeDiagram, Collection<Resource> elementTypes, Set<String> componentTypeNames) {
+ super(runtimeDiagram, elementTypes, componentTypeNames);
+ }
+
+ @Override
+ public Set<Resource> perform(ReadGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ Set<Resource> result = new HashSet<>();
+ Set<Resource> elementsOfType = graph.syncRequest(new ElementsOfType(parameter, parameter2));
+ for (Resource e : elementsOfType) {
+ Resource mapping = graph.getPossibleObject(e, DN.HasMapping);
+ if (mapping != null) {
+ String ct = graph.getPossibleRelatedValue(mapping, DN.Mapping_ComponentType, Bindings.STRING);
+ if (ct != null) {
+ if (parameter3.contains(ct)) {
+ //System.out.println("GROUP: added element " + NameUtils.getSafeName(graph, e) + " of type " + ct);
+ result.add(e);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ }
+
+ private static class ElementsOfType extends BinaryRead<Resource, Collection<Resource>, Set<Resource>> {
+
+ public ElementsOfType(Resource runtimeDiagram, Collection<Resource> types) {
+ super(runtimeDiagram, types);
+ }
+
+ @Override
+ public Set<Resource> perform(ReadGraph graph) throws DatabaseException {
+ HashSet<Resource> result = new HashSet<>();
+
+ Resource realDiagram = graph.getPossibleObject(parameter, DiagramResource.getInstance(graph).RuntimeDiagram_HasConfiguration);
+ if (realDiagram == null)
+ return result;
+
+ Collection<Resource> elements = graph.syncRequest(new OrderedSet(realDiagram));
+ for (Resource element : elements) {
+ Collection<Resource> elementTypes = graph.getTypes(element);
+ if (!Collections.disjoint(parameter2, elementTypes)) {
+ result.add(element);
+ }
+ }
+
+ return result;
+ }
+
+ }
+
+}