001package jmri.server.json;
002
003import com.fasterxml.jackson.databind.JsonNode;
004import java.io.IOException;
005import java.util.Locale;
006import javax.annotation.Nonnull;
007import jmri.JmriException;
008
009/**
010 * Interface for JSON Services provided over TCP Sockets or WebSockets.
011 *
012 * @param <H> The supporting JsonHttpService implementing class
013 * @author Randall Wood Copyright 2016, 2018
014 */
015public abstract class JsonSocketService<H extends JsonHttpService> {
016
017    protected final JsonConnection connection;
018    protected final H service;
019
020    protected JsonSocketService(@Nonnull JsonConnection connection, @Nonnull H service) {
021        this.connection = connection;
022        this.service = service;
023    }
024
025    /**
026     * Handle an inbound message.
027     *
028     * @param type    The service type; if the implementing service responds to
029     *                multiple types, it will need to use this to handle data
030     *                correctly
031     * @param data    JSON data; the contents of this will depend on the
032     *                implementing service
033     * @param request The JSON request
034     * @throws java.io.IOException Thrown if the service cannot send a response;
035     *                             this will cause the JSON Server to close its
036     *                             connection to the client if open
037     * @throws jmri.JmriException  Thrown if the request cannot be handled;
038     *                             throwing this will cause the JSON Server to
039     *                             pass a 500 UnsupportedOperation message to
040     *                             the client
041     * @throws JsonException       Thrown if the service needs to pass an error
042     *                             message back to the client
043     */
044    public abstract void onMessage(@Nonnull String type, @Nonnull JsonNode data,
045            @Nonnull JsonRequest request) throws IOException, JmriException, JsonException;
046
047    /**
048     * Handle a request for a list of objects. Note that this <strong>should
049     * not</strong> create listeners for items in the list, but should only
050     * create listeners for the object providing the list, if applicable.
051     *
052     * @param type    The service type; if the implementing service responds to
053     *                multiple types, it will need to use this to handle data
054     *                correctly
055     * @param data    JSON data; the contents of this will depend on the
056     *                implementing service
057     * @param request The JSON request
058     * @throws java.io.IOException Thrown if the service cannot send a response;
059     *                             this will cause the JSON Server to close its
060     *                             connection to the client if open
061     * @throws jmri.JmriException  Thrown if the request cannot be handled;
062     *                             throwing this will cause the JSON Server to
063     *                             pass a 500 UnsupportedOperation message to
064     *                             the client
065     * @throws JsonException       If the service needs to pass an error message
066     *                             back to the client; implementing services may
067     *                             throw a JsonException with code 400 and the
068     *                             localized message "UnlistableService" to
069     *                             indicate that {@code type} should not be
070     *                             listed
071     */
072    public abstract void onList(@Nonnull String type, @Nonnull JsonNode data, @Nonnull JsonRequest request)
073            throws IOException, JmriException, JsonException;
074
075    /**
076     * Perform any teardown required when closing a connection.
077     */
078    public abstract void onClose();
079
080    /**
081     * Get the connection to the client.
082     *
083     * @return the connection
084     */
085    @Nonnull
086    public final JsonConnection getConnection() {
087        return connection;
088    }
089
090    /**
091     * Get the supporting {@link JsonHttpService}.
092     *
093     * @return the supporting service
094     */
095    @Nonnull
096    public final H getHttpService() {
097        return service;
098    }
099
100    /**
101     * Get the in-use locale
102     *
103     * @return the locale
104     */
105    @Nonnull
106    protected final Locale getLocale() {
107        return connection.getLocale();
108    }
109
110    /**
111     * Get the JSON protocol version
112     *
113     * @return the version
114     */
115    protected final String getVersion() {
116        return connection.getVersion();
117    }
118}