001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.io.remotecontrol.handler;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.util.Arrays;
007import java.util.Collection;
008import java.util.stream.Collectors;
009
010import javax.json.Json;
011import javax.json.JsonArray;
012import javax.json.JsonArrayBuilder;
013import javax.json.JsonObject;
014import javax.json.JsonObjectBuilder;
015
016import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
017import org.openstreetmap.josm.io.remotecontrol.RequestProcessor;
018
019/**
020 * Reports available commands, their parameters and examples
021 * @since 6091
022 */
023public class FeaturesHandler extends RequestHandler {
024
025    /**
026     * The remote control command name used to reply version.
027     */
028    public static final String command = "features";
029
030    @Override
031    protected void handleRequest() throws RequestHandlerErrorException, RequestHandlerBadRequestException {
032        String q = args.get("q");
033        Collection<String> handlers = q == null ? null : Arrays.asList(q.split("[,\\s]+", -1));
034        content = getHandlersInfoAsJSON(handlers).toString();
035        contentType = "application/json";
036        if (args.containsKey("jsonp")) {
037            content = args.get("jsonp") + " && " + args.get("jsonp") + '(' + content + ')';
038        }
039    }
040
041    private static JsonArray getHandlersInfoAsJSON(Collection<String> handlers) {
042        JsonArrayBuilder json = Json.createArrayBuilder();
043        RequestProcessor.getHandlersInfo(handlers)
044                .map(FeaturesHandler::getHandlerInfoAsJSON)
045                .forEach(json::add);
046        return json.build();
047    }
048
049    private static JsonObject getHandlerInfoAsJSON(RequestHandler handler) {
050        JsonObjectBuilder json = Json.createObjectBuilder();
051        json.add("request", handler.getCommand());
052        if (handler.getUsage() != null) {
053            json.add("usage", handler.getUsage());
054        }
055        json.add("parameters", toJsonArray(handler.getMandatoryParams()));
056        json.add("optional", toJsonArray(handler.getOptionalParams()));
057        json.add("examples", toJsonArray(handler.getUsageExamples(handler.getCommand())));
058        return json.build();
059    }
060
061    private static JsonArray toJsonArray(String[] strings) {
062        return Arrays.stream(strings)
063                .collect(Collectors.collectingAndThen(Collectors.toList(), Json::createArrayBuilder))
064                .build();
065    }
066
067    @Override
068    public String getPermissionMessage() {
069        return tr("Remote Control has been asked to report its supported features. This enables web sites to guess a running JOSM version");
070    }
071
072    @Override
073    public PermissionPrefWithDefault getPermissionPref() {
074        return PermissionPrefWithDefault.READ_PROTOCOL_VERSION;
075    }
076
077    @Override
078    public String[] getMandatoryParams() {
079        return new String[0];
080    }
081
082    @Override
083    public String[] getOptionalParams() {
084        return new String[]{"jsonp", "q"};
085    }
086
087    @Override
088    protected void validateRequest() throws RequestHandlerBadRequestException {
089        // Nothing to do
090    }
091
092    @Override
093    public String getUsage() {
094        return "reports available commands, their parameters and examples";
095    }
096
097    @Override
098    public String[] getUsageExamples() {
099        return new String[] {"/features", "/features?q=import,add_node"};
100    }
101}