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}