package org.simantics.district.route.internal; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.simantics.Simantics; import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; import org.simantics.db.request.Read; import org.simantics.district.route.Route; import org.simantics.district.route.RouteEvent; import org.simantics.district.route.Waypoint; import org.simantics.utils.threads.ThreadUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class RouteImpl implements Route { private static final Logger LOGGER = LoggerFactory.getLogger(RouteImpl.class); private String name; private Resource model; private Resource backend; private RouteServiceImpl rs; private List waypoints; private List unmodifiableWaypoints; public RouteImpl(String name) { this.name = name; routeService(rs); waypoints(new ArrayList<>()); } public RouteImpl modelEntity(Resource model) { this.model = model; return this; } public Resource modelEntity() { return model; } public RouteImpl backend(Resource backend) { this.backend = backend; return this; } public Resource backend() { return backend; } public RouteImpl waypoints(List waypoints) { this.waypoints = waypoints; this.unmodifiableWaypoints = Collections.unmodifiableList(waypoints); return this; } public RouteImpl routeService(RouteServiceImpl rs) { this.rs = rs; return this; } @Override public String getName() { return name; } @Override public void setName(String name) { this.name = name; fireEvent(RouteEvent.TYPE_ROUTE_RENAMED); } @Override public Waypoint createWaypoint(Object backend) { if (backend instanceof Resource) { Resource waypoint = (Resource) backend; WaypointImpl wp = new WaypointImpl(waypoint, ""); // Read real label in background ThreadUtils.getBlockingWorkExecutor().submit(() -> { try { Waypoint p = Simantics.getSession().syncRequest( (Read) graph -> RoutePersistence.toWaypoint(graph, waypoint)); if (p != null) { wp.setLabel(p.getLabel()); rs.fireEvent(RouteEvent.TYPE_ROUTE_MODIFIED, RouteImpl.this); } } catch (DatabaseException e) { LOGGER.error("Failed to read waypoint {} label", backend, e); } }); return wp; } throw new IllegalArgumentException("only Resource type waypoints supported, got " + backend); //$NON-NLS-1$ } @Override public void addWaypoint(int index, Waypoint r) { waypoints.add(index, r); fireEvent(RouteEvent.TYPE_ROUTE_MODIFIED); } @Override public void removeWaypoint(Waypoint r) { waypoints.remove(r); fireEvent(RouteEvent.TYPE_ROUTE_MODIFIED); } @Override public List waypoints() { return unmodifiableWaypoints; } @Override public String toString() { return String.format("%s@%x [%s, waypoints=%s]", getClass().getName(), System.identityHashCode(this), name, waypoints.toString()); } private void fireEvent(int type) { if (rs != null) rs.fireEvent(type, this); } }