001package jmri.server.json.route;
002
003import static jmri.server.json.route.JsonRouteServiceFactory.ROUTE;
004import static jmri.server.json.route.JsonRouteServiceFactory.ROUTES;
005
006import com.fasterxml.jackson.databind.JsonNode;
007import com.fasterxml.jackson.databind.ObjectMapper;
008import com.fasterxml.jackson.databind.node.ObjectNode;
009import javax.servlet.http.HttpServletResponse;
010import jmri.InstanceManager;
011import jmri.NamedBean;
012import jmri.ProvidingManager;
013import jmri.Route;
014import jmri.RouteManager;
015import jmri.Sensor;
016import jmri.server.json.JSON;
017import jmri.server.json.JsonException;
018import jmri.server.json.JsonNamedBeanHttpService;
019import jmri.server.json.JsonRequest;
020
021/**
022 * Provide JSON HTTP services for managing {@link jmri.Route}s.
023 *
024 * @author Randall Wood Copyright 2016, 2018
025 */
026public class JsonRouteHttpService extends JsonNamedBeanHttpService<Route> {
027
028    public JsonRouteHttpService(ObjectMapper mapper) {
029        super(mapper);
030    }
031
032    @Override
033    public ObjectNode doGet(Route route, String name, String type, JsonRequest request) throws JsonException {
034        ObjectNode root = this.getNamedBean(route, name, getType(), request); // throws JsonException if route == null
035        ObjectNode data = root.with(JSON.DATA);
036        if (route != null) {
037            switch (route.getState()) {
038                case Sensor.ACTIVE:
039                    data.put(JSON.STATE, JSON.ACTIVE);
040                    break;
041                case Sensor.INACTIVE:
042                    data.put(JSON.STATE, JSON.INACTIVE);
043                    break;
044                case NamedBean.INCONSISTENT:
045                    data.put(JSON.STATE, JSON.INCONSISTENT);
046                    break;
047                case NamedBean.UNKNOWN:
048                default:
049                    data.put(JSON.STATE, JSON.UNKNOWN);
050                    break;
051            }
052        }
053        return root;
054    }
055
056    /**
057     * Respond to an HTTP POST request for the requested route.
058     * <p>
059     * This method throws a 404 Not Found error if the named route does not
060     * exist.
061     * <p>
062     * <strong>Note:</strong> attempting to set a state of
063     * {@link jmri.server.json.JSON#INACTIVE} or
064     * {@link jmri.server.json.JSON#UNKNOWN} has no effect. Setting a state of
065     * {@link jmri.server.json.JSON#TOGGLE} has the same effect as setting a
066     * state of {@link jmri.server.json.JSON#ACTIVE}. Any other states throw a
067     * 400 Invalid Request error.
068     *
069     * @param type   one of
070     *               {@link jmri.server.json.route.JsonRouteServiceFactory#ROUTE}
071     *               or
072     *               {@link jmri.server.json.route.JsonRouteServiceFactory#ROUTES}
073     * @param name   the name of the requested route
074     * @param data   JSON data set of attributes of the requested route to be
075     *               updated
076     * @param request the JSON request
077     * @return a JSON description of the requested route. Since a route changes
078     *         state on a separate thread, this may return a route in the state
079     *         prior to this call, the target state, or an intermediate state.
080     */
081    @Override
082    public ObjectNode doPost(Route route, String name, String type, JsonNode data, JsonRequest request) throws JsonException {
083        int state = data.path(JSON.STATE).asInt(JSON.UNKNOWN);
084        switch (state) {
085            case JSON.ACTIVE:
086            case JSON.TOGGLE:
087                route.setRoute();
088                break;
089            case JSON.INACTIVE:
090            case JSON.UNKNOWN:
091                // leave state alone in this case
092                break;
093            default:
094                throw new JsonException(400, Bundle.getMessage(request.locale, "ErrorUnknownState", ROUTE, state), request.id); // NOI18N
095        }
096        return this.doGet(route, name, type, request);
097    }
098
099    @Override
100    public JsonNode doPut(String type, String name, JsonNode data, JsonRequest request) throws JsonException {
101        throw new JsonException(HttpServletResponse.SC_METHOD_NOT_ALLOWED, Bundle.getMessage(request.locale, "PutNotAllowed", type), request.id);
102    }
103
104    @Override
105    public JsonNode doSchema(String type, boolean server, JsonRequest request) throws JsonException {
106        switch (type) {
107            case ROUTE:
108            case ROUTES:
109                return doSchema(type,
110                        server,
111                        "jmri/server/json/route/route-server.json",
112                        "jmri/server/json/route/route-client.json",
113                        request.id);
114            default:
115                throw new JsonException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, Bundle.getMessage(request.locale, JsonException.ERROR_UNKNOWN_TYPE, type), request.id);
116        }
117    }
118
119    @Override
120    protected String getType() {
121        return ROUTE;
122    }
123
124    @Override
125    protected ProvidingManager<Route> getProvidingManager() {
126        return InstanceManager.getDefault(RouteManager.class);
127    }
128}