1 package org.simantics.district.route.internal;
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.HashSet;
9 import java.util.stream.Collectors;
11 import org.eclipse.osgi.util.NLS;
12 import org.simantics.Simantics;
13 import org.simantics.databoard.Bindings;
14 import org.simantics.databoard.util.ObjectUtils;
15 import org.simantics.db.ReadGraph;
16 import org.simantics.db.Resource;
17 import org.simantics.db.WriteGraph;
18 import org.simantics.db.common.request.ObjectsWithType;
19 import org.simantics.db.common.request.ResourceRead;
20 import org.simantics.db.common.request.UniqueRead;
21 import org.simantics.db.common.utils.ListUtils;
22 import org.simantics.db.common.utils.NameUtils;
23 import org.simantics.db.exception.DatabaseException;
24 import org.simantics.db.layer0.QueryIndexUtils;
25 import org.simantics.db.layer0.request.PossibleActiveModel;
26 import org.simantics.db.layer0.request.PossibleModel;
27 import org.simantics.db.layer0.util.RemoverUtil;
28 import org.simantics.district.network.ontology.DistrictNetworkResource;
29 import org.simantics.district.route.Waypoint;
30 import org.simantics.district.route.ontology.RouteResource;
31 import org.simantics.layer0.Layer0;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
36 * @author Tuukka Lehtonen
38 public class RoutePersistence {
40 private static final Logger LOGGER = LoggerFactory.getLogger(RoutePersistence.class);
42 public static Resource getRouteFolder(ReadGraph graph, Resource model) throws DatabaseException {
43 List<Resource> diagrams = QueryIndexUtils.searchByType(graph, model, RouteResource.getInstance(graph).RouteFolder);
44 if (diagrams.size() > 0)
45 return diagrams.get(0);
49 public static Resource getOrCreateRouteFolder(WriteGraph graph, Resource model) throws DatabaseException {
50 Resource rf = getRouteFolder(graph, model);
52 Layer0 L0 = Layer0.getInstance(graph);
53 RouteResource RR = RouteResource.getInstance(graph);
54 rf = graph.newResource();
55 graph.claim(rf, L0.InstanceOf, null, RR.RouteFolder);
56 graph.claimLiteral(rf, L0.HasName, L0.NameOf, L0.String, UUID.randomUUID().toString(), Bindings.STRING);
57 graph.claim(model, L0.ConsistsOf, L0.PartOf, rf);
62 public static Resource createRoute(WriteGraph graph, Resource model, String label, List<Resource> waypoints) throws DatabaseException {
63 Resource rf = getOrCreateRouteFolder(graph, model);
65 RouteResource RR = RouteResource.getInstance(graph);
66 Layer0 L0 = Layer0.getInstance(graph);
68 Resource route = ListUtils.create(graph, RR.Route, waypoints);
69 graph.claim(rf, L0.ConsistsOf, L0.PartOf, route);
70 graph.claimLiteral(route, L0.HasName, UUID.randomUUID().toString(), Bindings.STRING);
71 graph.claimLiteral(route, L0.HasLabel, label, Bindings.STRING);
73 LOGGER.info("Persisted route {} with label {} and waypoints {}", route, label, waypoints);
78 public static void updateRoute(WriteGraph graph, Resource route, String label, List<Resource> waypoints) throws DatabaseException {
79 RouteResource RR = RouteResource.getInstance(graph);
80 Layer0 L0 = Layer0.getInstance(graph);
82 String existingLabel = graph.getPossibleRelatedValue(route, L0.HasLabel, Bindings.STRING);
83 if (!ObjectUtils.objectEquals(existingLabel, label)) {
84 graph.claimLiteral(route, L0.HasLabel, label, Bindings.STRING);
87 List<Resource> existingWaypoints = ListUtils.toList(graph, route);
88 if (!existingWaypoints.equals(waypoints)) {
89 // TODO: optimize this
90 ListUtils.removeElements(graph, route, new HashSet<>(existingWaypoints));
91 ListUtils.createExisting(graph, RR.Route, waypoints);
94 LOGGER.info("Updated route {} with label {} and waypoints {}", route, label, waypoints);
97 public static void removeRoute(WriteGraph graph, Resource route) throws DatabaseException {
98 RemoverUtil.remove(graph, route);
101 public static Waypoint toWaypoint(ReadGraph graph, Resource waypoint) throws DatabaseException {
102 DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
103 Set<Resource> types = graph.getTypes(waypoint);
104 String name = NameUtils.getSafeName(graph, waypoint);
105 if (types.contains(DN.Vertex)) {
106 String address = graph.getPossibleRelatedValue(waypoint, DN.Vertex_HasAddress, Bindings.STRING);
107 String label = address != null
108 ? NLS.bind("Node {0} - {1}", name, address).trim()
109 : NLS.bind("Node {0}", name, address).trim();
110 return new WaypointImpl(waypoint, label);
111 } else if (types.contains(DN.Edge)) {
112 return new WaypointImpl(waypoint, NLS.bind("Edge {0}", name));
114 LOGGER.warn("Tried to convert unrecognized resource {} to a route waypoint", waypoint);
118 public static List<Waypoint> toWaypoints(ReadGraph graph, List<Resource> waypoints) throws DatabaseException {
119 List<Waypoint> result = new ArrayList<>();
120 for (Resource wpr : waypoints) {
121 Waypoint wp = toWaypoint(graph, wpr);
128 public static List<RouteImpl> findRoutes(ReadGraph graph, Resource model) throws DatabaseException {
129 Resource rf = model != null ? getRouteFolder(graph, model) : null;
131 return Collections.emptyList();
133 Layer0 L0 = Layer0.getInstance(graph);
134 RouteResource RR = RouteResource.getInstance(graph);
136 List<RouteImpl> routes = new ArrayList<>();
138 for (Resource route : graph.syncRequest(new ObjectsWithType(rf, L0.ConsistsOf, RR.Route))) {
139 routes.add(getRoute(graph, model, route));
145 public static RouteImpl getRoute(ReadGraph graph, Resource model, Resource route) throws DatabaseException {
146 Layer0 L0 = Layer0.getInstance(graph);
147 RouteImpl ri = new RouteImpl(graph.getRelatedValue(route, L0.HasLabel, Bindings.STRING))
150 .waypoints(toWaypoints(graph, ListUtils.toList(graph, route)));
154 public static class RouteRequest extends ResourceRead<RouteImpl> {
155 public RouteRequest(Resource resource) {
160 public RouteImpl perform(ReadGraph graph) throws DatabaseException {
161 Resource model = graph.syncRequest(new PossibleModel(resource));
162 return model != null ? getRoute(graph, model, resource) : null;
166 public static class ModelRoutesRequest extends ResourceRead<List<RouteImpl>> {
167 public ModelRoutesRequest(Resource model) {
171 public List<RouteImpl> perform(ReadGraph graph) throws DatabaseException {
172 return findRoutes(graph, resource);
176 public static class ActiveModelRoutesRequest extends UniqueRead<List<RouteImpl>> {
178 public List<RouteImpl> perform(ReadGraph graph) throws DatabaseException {
179 return findRoutes(graph, graph.syncRequest(new PossibleActiveModel(Simantics.getProjectResource())));
183 public static List<Resource> toResources(List<Waypoint> waypoints) {
184 return waypoints.stream()
185 .<Resource>map(Waypoint::getObject)
186 .collect(Collectors.toList());