]> gerrit.simantics Code Review - simantics/district.git/blobdiff - org.simantics.district.route/src/org/simantics/district/route/internal/RoutePersistence.java
Merge "Initial version of the district network Routes view."
[simantics/district.git] / org.simantics.district.route / src / org / simantics / district / route / internal / RoutePersistence.java
diff --git a/org.simantics.district.route/src/org/simantics/district/route/internal/RoutePersistence.java b/org.simantics.district.route/src/org/simantics/district/route/internal/RoutePersistence.java
new file mode 100644 (file)
index 0000000..c3ba757
--- /dev/null
@@ -0,0 +1,160 @@
+package org.simantics.district.route.internal;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+import org.eclipse.osgi.util.NLS;
+import org.simantics.Simantics;
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.util.ObjectUtils;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.ObjectsWithType;
+import org.simantics.db.common.request.UniqueRead;
+import org.simantics.db.common.utils.ListUtils;
+import org.simantics.db.common.utils.NameUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.QueryIndexUtils;
+import org.simantics.db.layer0.request.PossibleActiveModel;
+import org.simantics.db.layer0.util.RemoverUtil;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.route.Waypoint;
+import org.simantics.district.route.ontology.RouteResource;
+import org.simantics.layer0.Layer0;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class RoutePersistence {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(RoutePersistence.class);
+
+    public static Resource getRouteFolder(ReadGraph graph, Resource model) throws DatabaseException {
+        List<Resource> diagrams = QueryIndexUtils.searchByType(graph, model, RouteResource.getInstance(graph).RouteFolder);
+        if (diagrams.size() > 0)
+            return diagrams.get(0);
+        return null;
+    }
+
+    public static Resource getOrCreateRouteFolder(WriteGraph graph, Resource model) throws DatabaseException {
+        Resource rf = getRouteFolder(graph, model);
+        if (rf == null) {
+            Layer0 L0 = Layer0.getInstance(graph);
+            RouteResource RR = RouteResource.getInstance(graph);
+            rf = graph.newResource();
+            graph.claim(rf, L0.InstanceOf, null, RR.RouteFolder);
+            graph.claimLiteral(rf, L0.HasName, L0.NameOf, L0.String, UUID.randomUUID().toString(), Bindings.STRING);
+            graph.claim(model, L0.ConsistsOf, L0.PartOf, rf);
+        }
+        return rf;
+    }
+
+    public static Resource createRoute(WriteGraph graph, Resource model, String label, List<Resource> waypoints) throws DatabaseException {
+        Resource rf = getOrCreateRouteFolder(graph, model);
+
+        RouteResource RR = RouteResource.getInstance(graph);
+        Layer0 L0 = Layer0.getInstance(graph);
+
+        Resource route = ListUtils.create(graph, RR.Route, waypoints);
+        graph.claim(rf, L0.ConsistsOf, L0.PartOf, route);
+        graph.claimLiteral(route, L0.HasName, UUID.randomUUID().toString(), Bindings.STRING);
+        graph.claimLiteral(route, L0.HasLabel, label, Bindings.STRING);
+
+        LOGGER.info("Persisted route {} with label {} and waypoints {}", route, label, waypoints);
+
+        return route;
+    }
+
+    public static void updateRoute(WriteGraph graph, Resource route, String label, List<Resource> waypoints) throws DatabaseException {
+        RouteResource RR = RouteResource.getInstance(graph);
+        Layer0 L0 = Layer0.getInstance(graph);
+
+        String existingLabel = graph.getPossibleRelatedValue(route, L0.HasLabel, Bindings.STRING);
+        if (ObjectUtils.objectEquals(existingLabel, label)) {
+            graph.claimLiteral(route, L0.HasLabel, label, Bindings.STRING);
+        }
+
+        List<Resource> existingWaypoints = ListUtils.toList(graph, route);
+        if (!existingWaypoints.equals(waypoints)) {
+            // TODO: optimize this
+            ListUtils.removeElements(graph, route, new HashSet<>(existingWaypoints));
+            ListUtils.createExisting(graph, RR.Route, waypoints);
+        }
+
+        LOGGER.info("Updated route {} with label {} and waypoints {}", route, label, waypoints);
+    }
+
+    public static void removeRoute(WriteGraph graph, Resource route) throws DatabaseException {
+        RemoverUtil.remove(graph, route);
+    }
+
+    public static Waypoint toWaypoint(ReadGraph graph, Resource waypoint) throws DatabaseException {
+        DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+        Set<Resource> types = graph.getTypes(waypoint);
+        String name = NameUtils.getSafeName(graph, waypoint);
+        if (types.contains(DN.Vertex)) {
+            String address = graph.getPossibleRelatedValue(waypoint, DN.Vertex_HasAddress, Bindings.STRING);
+            String label = address != null
+                    ? NLS.bind("Node {0} - {1}", name, address).trim()
+                    : NLS.bind("Node {0}", name, address).trim();
+            return new WaypointImpl(waypoint, label);
+        } else if (types.contains(DN.Edge)) {
+            return new WaypointImpl(waypoint, NLS.bind("Edge {0}", name));
+        }
+        LOGGER.warn("Tried to convert unrecognized resource {} to a route waypoint", waypoint);
+        return null;
+    }
+
+    public static List<Waypoint> toWaypoints(ReadGraph graph, List<Resource> waypoints) throws DatabaseException {
+        List<Waypoint> result = new ArrayList<>();
+        for (Resource wpr : waypoints) {
+            Waypoint wp = toWaypoint(graph, wpr);
+            if (wp != null)
+                result.add(wp);
+        }
+        return result;
+    }
+
+    public static List<RouteImpl> findRoutes(ReadGraph graph, Resource model) throws DatabaseException {
+        Resource rf = getRouteFolder(graph, model);
+        if (rf == null)
+            return Collections.emptyList();
+
+        Layer0 L0 = Layer0.getInstance(graph);
+        RouteResource RR = RouteResource.getInstance(graph);
+
+        List<RouteImpl> routes = new ArrayList<>();
+
+        for (Resource route : graph.syncRequest(new ObjectsWithType(rf, L0.ConsistsOf, RR.Route))) {
+            RouteImpl ri = new RouteImpl(graph.getRelatedValue(route, L0.HasLabel, Bindings.STRING))
+                    .backend(route)
+                    .modelEntity(model)
+                    .waypoints(toWaypoints(graph, ListUtils.toList(graph, route)));
+            routes.add(ri);
+        }
+
+        return routes;
+    }
+
+    public static class ActiveModelRoutesRequest extends UniqueRead<List<RouteImpl>> {
+        @Override
+        public List<RouteImpl> perform(ReadGraph graph) throws DatabaseException {
+            return findRoutes(graph, graph.syncRequest(new PossibleActiveModel(Simantics.getProjectResource())));
+        }
+    }
+
+    public static List<Resource> toResources(List<Waypoint> waypoints) {
+        return waypoints.stream()
+                .<Resource>map(Waypoint::getObject)
+                .collect(Collectors.toList());
+    }
+
+}