]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.route/src/org/simantics/district/route/internal/RoutePersistence.java
c3ba7571e82c3af15c96c4534a45a3d55c3965a4
[simantics/district.git] / org.simantics.district.route / src / org / simantics / district / route / internal / RoutePersistence.java
1 package org.simantics.district.route.internal;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.HashSet;
6 import java.util.List;
7 import java.util.Set;
8 import java.util.UUID;
9 import java.util.stream.Collectors;
10
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.UniqueRead;
20 import org.simantics.db.common.utils.ListUtils;
21 import org.simantics.db.common.utils.NameUtils;
22 import org.simantics.db.exception.DatabaseException;
23 import org.simantics.db.layer0.QueryIndexUtils;
24 import org.simantics.db.layer0.request.PossibleActiveModel;
25 import org.simantics.db.layer0.util.RemoverUtil;
26 import org.simantics.district.network.ontology.DistrictNetworkResource;
27 import org.simantics.district.route.Waypoint;
28 import org.simantics.district.route.ontology.RouteResource;
29 import org.simantics.layer0.Layer0;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 /**
34  * @author Tuukka Lehtonen
35  */
36 public class RoutePersistence {
37
38     private static final Logger LOGGER = LoggerFactory.getLogger(RoutePersistence.class);
39
40     public static Resource getRouteFolder(ReadGraph graph, Resource model) throws DatabaseException {
41         List<Resource> diagrams = QueryIndexUtils.searchByType(graph, model, RouteResource.getInstance(graph).RouteFolder);
42         if (diagrams.size() > 0)
43             return diagrams.get(0);
44         return null;
45     }
46
47     public static Resource getOrCreateRouteFolder(WriteGraph graph, Resource model) throws DatabaseException {
48         Resource rf = getRouteFolder(graph, model);
49         if (rf == null) {
50             Layer0 L0 = Layer0.getInstance(graph);
51             RouteResource RR = RouteResource.getInstance(graph);
52             rf = graph.newResource();
53             graph.claim(rf, L0.InstanceOf, null, RR.RouteFolder);
54             graph.claimLiteral(rf, L0.HasName, L0.NameOf, L0.String, UUID.randomUUID().toString(), Bindings.STRING);
55             graph.claim(model, L0.ConsistsOf, L0.PartOf, rf);
56         }
57         return rf;
58     }
59
60     public static Resource createRoute(WriteGraph graph, Resource model, String label, List<Resource> waypoints) throws DatabaseException {
61         Resource rf = getOrCreateRouteFolder(graph, model);
62
63         RouteResource RR = RouteResource.getInstance(graph);
64         Layer0 L0 = Layer0.getInstance(graph);
65
66         Resource route = ListUtils.create(graph, RR.Route, waypoints);
67         graph.claim(rf, L0.ConsistsOf, L0.PartOf, route);
68         graph.claimLiteral(route, L0.HasName, UUID.randomUUID().toString(), Bindings.STRING);
69         graph.claimLiteral(route, L0.HasLabel, label, Bindings.STRING);
70
71         LOGGER.info("Persisted route {} with label {} and waypoints {}", route, label, waypoints);
72
73         return route;
74     }
75
76     public static void updateRoute(WriteGraph graph, Resource route, String label, List<Resource> waypoints) throws DatabaseException {
77         RouteResource RR = RouteResource.getInstance(graph);
78         Layer0 L0 = Layer0.getInstance(graph);
79
80         String existingLabel = graph.getPossibleRelatedValue(route, L0.HasLabel, Bindings.STRING);
81         if (ObjectUtils.objectEquals(existingLabel, label)) {
82             graph.claimLiteral(route, L0.HasLabel, label, Bindings.STRING);
83         }
84
85         List<Resource> existingWaypoints = ListUtils.toList(graph, route);
86         if (!existingWaypoints.equals(waypoints)) {
87             // TODO: optimize this
88             ListUtils.removeElements(graph, route, new HashSet<>(existingWaypoints));
89             ListUtils.createExisting(graph, RR.Route, waypoints);
90         }
91
92         LOGGER.info("Updated route {} with label {} and waypoints {}", route, label, waypoints);
93     }
94
95     public static void removeRoute(WriteGraph graph, Resource route) throws DatabaseException {
96         RemoverUtil.remove(graph, route);
97     }
98
99     public static Waypoint toWaypoint(ReadGraph graph, Resource waypoint) throws DatabaseException {
100         DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
101         Set<Resource> types = graph.getTypes(waypoint);
102         String name = NameUtils.getSafeName(graph, waypoint);
103         if (types.contains(DN.Vertex)) {
104             String address = graph.getPossibleRelatedValue(waypoint, DN.Vertex_HasAddress, Bindings.STRING);
105             String label = address != null
106                     ? NLS.bind("Node {0} - {1}", name, address).trim()
107                     : NLS.bind("Node {0}", name, address).trim();
108             return new WaypointImpl(waypoint, label);
109         } else if (types.contains(DN.Edge)) {
110             return new WaypointImpl(waypoint, NLS.bind("Edge {0}", name));
111         }
112         LOGGER.warn("Tried to convert unrecognized resource {} to a route waypoint", waypoint);
113         return null;
114     }
115
116     public static List<Waypoint> toWaypoints(ReadGraph graph, List<Resource> waypoints) throws DatabaseException {
117         List<Waypoint> result = new ArrayList<>();
118         for (Resource wpr : waypoints) {
119             Waypoint wp = toWaypoint(graph, wpr);
120             if (wp != null)
121                 result.add(wp);
122         }
123         return result;
124     }
125
126     public static List<RouteImpl> findRoutes(ReadGraph graph, Resource model) throws DatabaseException {
127         Resource rf = getRouteFolder(graph, model);
128         if (rf == null)
129             return Collections.emptyList();
130
131         Layer0 L0 = Layer0.getInstance(graph);
132         RouteResource RR = RouteResource.getInstance(graph);
133
134         List<RouteImpl> routes = new ArrayList<>();
135
136         for (Resource route : graph.syncRequest(new ObjectsWithType(rf, L0.ConsistsOf, RR.Route))) {
137             RouteImpl ri = new RouteImpl(graph.getRelatedValue(route, L0.HasLabel, Bindings.STRING))
138                     .backend(route)
139                     .modelEntity(model)
140                     .waypoints(toWaypoints(graph, ListUtils.toList(graph, route)));
141             routes.add(ri);
142         }
143
144         return routes;
145     }
146
147     public static class ActiveModelRoutesRequest extends UniqueRead<List<RouteImpl>> {
148         @Override
149         public List<RouteImpl> perform(ReadGraph graph) throws DatabaseException {
150             return findRoutes(graph, graph.syncRequest(new PossibleActiveModel(Simantics.getProjectResource())));
151         }
152     }
153
154     public static List<Resource> toResources(List<Waypoint> waypoints) {
155         return waypoints.stream()
156                 .<Resource>map(Waypoint::getObject)
157                 .collect(Collectors.toList());
158     }
159
160 }