X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.district.route%2Fsrc%2Forg%2Fsimantics%2Fdistrict%2Froute%2Finternal%2FRoutePersistence.java;fp=org.simantics.district.route%2Fsrc%2Forg%2Fsimantics%2Fdistrict%2Froute%2Finternal%2FRoutePersistence.java;h=c3ba7571e82c3af15c96c4534a45a3d55c3965a4;hb=716ce6c9abe27be04635922ad437f242c4bd7dfc;hp=0000000000000000000000000000000000000000;hpb=cb14c9e0dfd0b7179c11f0a54af87e2b7fe16113;p=simantics%2Fdistrict.git 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 index 00000000..c3ba7571 --- /dev/null +++ b/org.simantics.district.route/src/org/simantics/district/route/internal/RoutePersistence.java @@ -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 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 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 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 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 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 toWaypoints(ReadGraph graph, List waypoints) throws DatabaseException { + List result = new ArrayList<>(); + for (Resource wpr : waypoints) { + Waypoint wp = toWaypoint(graph, wpr); + if (wp != null) + result.add(wp); + } + return result; + } + + public static List 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 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> { + @Override + public List perform(ReadGraph graph) throws DatabaseException { + return findRoutes(graph, graph.syncRequest(new PossibleActiveModel(Simantics.getProjectResource()))); + } + } + + public static List toResources(List waypoints) { + return waypoints.stream() + .map(Waypoint::getObject) + .collect(Collectors.toList()); + } + +}