Ticket #8228: rc.patch
| File rc.patch, 20.5 KB (added by , 13 years ago) |
|---|
-
src/org/openstreetmap/josm/io/remotecontrol/RemoteControl.java
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/RemoteControl.java b/src/org/openstreetmap/josm/io/remotecontrol/RemoteControl.java index 248303e..1a89d9c 100644
a b 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.io.remotecontrol; 3 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 6 import com.sun.net.httpserver.HttpExchange; 7 import com.sun.net.httpserver.HttpHandler; 8 import com.sun.net.httpserver.HttpServer; 9 import java.io.IOException; 10 import java.io.OutputStreamWriter; 11 import java.net.BindException; 12 import java.net.InetAddress; 13 import java.net.InetSocketAddress; 14 import java.util.Arrays; 15 import java.util.HashMap; 16 import java.util.Map; 4 17 import org.openstreetmap.josm.data.preferences.BooleanProperty; 18 import org.openstreetmap.josm.io.remotecontrol.handler.AddNodeHandler; 19 import org.openstreetmap.josm.io.remotecontrol.handler.AddWayHandler; 20 import org.openstreetmap.josm.io.remotecontrol.handler.ImageryHandler; 21 import org.openstreetmap.josm.io.remotecontrol.handler.ImportHandler; 22 import org.openstreetmap.josm.io.remotecontrol.handler.LoadAndZoomHandler; 23 import org.openstreetmap.josm.io.remotecontrol.handler.LoadObjectHandler; 24 import org.openstreetmap.josm.io.remotecontrol.handler.OpenFileHandler; 5 25 import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler; 26 import org.openstreetmap.josm.io.remotecontrol.handler.VersionHandler; 27 import org.openstreetmap.josm.tools.Utils; 6 28 7 29 /** 8 30 * Manager class for remote control operations. … … import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler; 10 32 * IMPORTANT! increment the minor version on compatible API extensions 11 33 * and increment the major version and set minor to 0 on incompatible changes. 12 34 */ 13 public class RemoteControl 14 { 35 public class RemoteControl { 15 36 /** 16 37 * If the remote cotrol feature is enabled or disabled. If disabled, 17 38 * it should not start the server. … … public class RemoteControl 19 40 public static final BooleanProperty PROP_REMOTECONTROL_ENABLED = new BooleanProperty("remotecontrol.enabled", false); 20 41 21 42 /** 43 * Default port for the HTTP server 44 */ 45 public static final int DEFAULT_PORT = 8111; 46 47 /** 22 48 * RemoteControl HTTP protocol version. Change minor number for compatible 23 49 * interface extensions. Change major number in case of incompatible 24 50 * changes. … … public class RemoteControl 27 53 static final int protocolMinorVersion = 4; 28 54 29 55 /** 56 * RemoteControl protocol version. Change minor number for compatible 57 * interface extensions. Change major number in case of incompatible 58 * changes. 59 */ 60 public static final String PROTOCOLVERSION = "{\"protocolversion\": {\"major\": " + 61 RemoteControl.protocolMajorVersion + ", \"minor\": " + 62 RemoteControl.protocolMinorVersion + 63 "}, \"application\": \"JOSM RemoteControl\"}"; 64 65 private static final Map<String, Class<? extends RequestHandler>> handlers = new HashMap<String, java.lang.Class<? extends RequestHandler>>(); 66 67 public static HttpServer SERVER; 68 69 static { 70 try { 71 SERVER = HttpServer.create(new InetSocketAddress(InetAddress.getLocalHost(), DEFAULT_PORT), 0); 72 SERVER.createContext("/", new UsageHandler()); 73 addRequestHandlerClass(LoadAndZoomHandler.command, LoadAndZoomHandler.class, true); 74 addRequestHandlerClass(LoadAndZoomHandler.command2, LoadAndZoomHandler.class, true); 75 addRequestHandlerClass(ImageryHandler.command, ImageryHandler.class, true); 76 addRequestHandlerClass(AddNodeHandler.command, AddNodeHandler.class, true); 77 addRequestHandlerClass(AddWayHandler.command, AddWayHandler.class, true); 78 addRequestHandlerClass(ImportHandler.command, ImportHandler.class, true); 79 addRequestHandlerClass(VersionHandler.command, VersionHandler.class, true); 80 addRequestHandlerClass(LoadObjectHandler.command, LoadObjectHandler.class, true); 81 addRequestHandlerClass(OpenFileHandler.command, OpenFileHandler.class, true); 82 } catch (BindException ex) { 83 System.err.println(tr("Warning: Cannot start remotecontrol server on port {0}: {1}", 84 Integer.toString(DEFAULT_PORT), ex.getLocalizedMessage())); 85 } catch (IOException ioe) { 86 ioe.printStackTrace(); 87 } 88 } 89 90 /** 30 91 * Starts the remote control server 31 92 */ 32 93 public static void start() { 33 RemoteControlHttpServer.restartRemoteControlHttpServer(); 94 SERVER.start(); 95 System.out.println("RemoteControl: Accepting connections on port " + DEFAULT_PORT); 96 34 97 } 35 98 36 99 /** 37 * Adds external request handler. 38 * Can be used by plugins that want to use remote control. 39 * 40 * @param command The command name. 100 * Add external request handler. Message can be suppressed (for internal use) 101 * 102 * @param command The command to handle. 41 103 * @param handlerClass The additional request handler. 104 * @param silent Don't show message if true. 42 105 */ 43 public void addRequestHandler(String command, Class<? extends RequestHandler> handlerClass) 44 { 45 RequestProcessor.addRequestHandlerClass(command, handlerClass); 106 public static void addRequestHandlerClass(String command, final Class<? extends RequestHandler> handlerClass, boolean silent) { 107 final String commandSlash = command.startsWith("/") ? command : ("/" + command); 108 handlers.put(commandSlash, handlerClass); 109 SERVER.createContext(commandSlash, new HttpHandler() { 110 @Override 111 public void handle(HttpExchange exchange) throws IOException { 112 try { 113 System.out.println("RemoteControl received: " + exchange.getRequestURI()); 114 RequestHandler h = handlerClass.newInstance(); 115 h.setCommand(commandSlash); 116 h.setUrl(exchange.getRequestURI().toString()); 117 h.handle(); 118 sendResponse(exchange, 200, h.getContentType(), h.getContent()); 119 } catch (Exception e) { 120 throw new RuntimeException(e); 121 } 122 } 123 }); 124 if (!silent) { 125 System.out.println("RemoteControl: adding command \"" + command + "\" (handled by " + handlerClass.getSimpleName() + ")"); 126 } 127 } 128 129 private static class UsageHandler implements HttpHandler { 130 @Override 131 public void handle(HttpExchange exchange) throws IOException { 132 try { 133 StringBuilder usage = new StringBuilder(1024); 134 for (Map.Entry<String, Class<? extends RequestHandler>> handler : handlers.entrySet()) { 135 final RequestHandler handlerInstance = handler.getValue().newInstance(); 136 final String[] mandatory = handlerInstance.getMandatoryParams(); 137 usage.append("<li>"); 138 usage.append(handler.getKey()); 139 usage.append(": "); 140 usage.append(handlerInstance.getUsage()); 141 if (mandatory != null) { 142 usage.append("<br/>mandatory parameter: ").append(Utils.join(", ", Arrays.asList(mandatory))); 143 usage.append("<br/>usage examples:").append(Utils.joinAsHtmlUnorderedList(handlerInstance.getUsageExamples())); 144 } 145 usage.append("</li>"); 146 } 147 String help = "<h1>JOSM RemoteControl</h1>" 148 + "No command specified! The following commands are available:<ul>" 149 + usage.toString() 150 + "</ul>"; 151 sendResponse(exchange, 400, "text/html", help); 152 } catch (Exception e) { 153 throw new RuntimeException(e); 154 } 155 } 156 } 157 158 private static void sendResponse(HttpExchange exchange, int httpCode, String contentType, String data) throws IOException { 159 exchange.getResponseHeaders().set("Content-Type", contentType); 160 exchange.getResponseHeaders().set("Server", "JOSM RemoteControl"); 161 exchange.getResponseHeaders().set("Access-Control-Allow-Origin", "*"); 162 exchange.sendResponseHeaders(httpCode, data.length()); 163 OutputStreamWriter out = new OutputStreamWriter(exchange.getResponseBody(), "UTF-8"); 164 out.write(data); 165 out.close(); 46 166 } 47 167 } -
src/org/openstreetmap/josm/io/remotecontrol/handler/AddNodeHandler.java
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/AddNodeHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/AddNodeHandler.java index 4ed5bc6..71f6c03 100644
a b package org.openstreetmap.josm.io.remotecontrol.handler; 3 3 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.util.Arrays; 6 7 import java.util.HashMap; 8 import java.util.List; 7 9 import org.openstreetmap.josm.Main; 8 10 import org.openstreetmap.josm.actions.AutoScaleAction; 9 11 import org.openstreetmap.josm.command.AddCommand; … … public class AddNodeHandler extends RequestHandler { 30 32 } 31 33 32 34 @Override 35 public String getUsage() { 36 return "adds a node (given by its latitude and longitude) to the current dataset"; 37 } 38 39 @Override 40 public List<String> getUsageExamples() { 41 return Arrays.asList( 42 "/add_node?lat=11&lon=22" 43 ); 44 } 45 46 @Override 33 47 public String getPermissionMessage() { 34 48 return tr("Remote Control has been asked to create a new node."); 35 49 } -
src/org/openstreetmap/josm/io/remotecontrol/handler/AddWayHandler.java
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/AddWayHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/AddWayHandler.java index c1cab8c..10e7188 100644
a b package org.openstreetmap.josm.io.remotecontrol.handler; 2 2 3 3 import static org.openstreetmap.josm.tools.I18n.tr; 4 4 5 import java.util.Arrays; 5 6 import java.util.LinkedList; 6 7 import java.util.List; 7 8 import org.openstreetmap.josm.Main; … … public class AddWayHandler extends RequestHandler { 27 28 } 28 29 29 30 @Override 31 public String getUsage() { 32 return "adds a way (given by a semicolon separated sequence of lat,lon pairs) to the current dataset"; 33 } 34 35 @Override 36 public List<String> getUsageExamples() { 37 return Arrays.asList( 38 "/add_way?way=lat1,lon2;lat2,lon2" 39 ); 40 } 41 42 @Override 30 43 protected void handleRequest() throws RequestHandlerErrorException, RequestHandlerBadRequestException { 31 44 Way way = new Way(); 32 45 List<Command> commands = new LinkedList<Command>(); -
src/org/openstreetmap/josm/io/remotecontrol/handler/ImageryHandler.java
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/ImageryHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/ImageryHandler.java index 1fdf8b0..7e9807a 100644
a b import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 6 import java.io.UnsupportedEncodingException; 7 7 import java.net.URLDecoder; 8 import java.util.Arrays; 8 9 import java.util.HashMap; 10 import java.util.List; 9 11 10 12 import org.openstreetmap.josm.Main; 11 13 import org.openstreetmap.josm.data.imagery.ImageryInfo; 12 14 import org.openstreetmap.josm.gui.layer.ImageryLayer; 13 15 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault; 16 import org.openstreetmap.josm.tools.Utils; 14 17 15 18 /** 16 19 * Adds an imagery (WMS/TMS) layer. For instance, {@code /imagery?title=...&type=...&url=...}. … … public class ImageryHandler extends RequestHandler { 35 38 } 36 39 37 40 @Override 41 public String getUsage() { 42 return "adds an imagery layer (e.g. WMS, TMS))"; 43 } 44 45 @Override 46 public List<String> getUsageExamples() { 47 final String types = Utils.join("|", Utils.transform(Arrays.asList(ImageryInfo.ImageryType.values()), new Utils.Function<ImageryInfo.ImageryType, String>() { 48 @Override 49 public String apply(ImageryInfo.ImageryType x) { 50 return x.getUrlString(); 51 } 52 })); 53 return Arrays.asList( 54 "/imagery?title=...&type={"+types+"}&url=....[&cookies=...][&min_zoom=...][&max_zoom=...]" 55 ); 56 } 57 58 @Override 38 59 public PermissionPrefWithDefault getPermissionPref() { 39 60 return PermissionPrefWithDefault.LOAD_IMAGERY; 40 61 } -
src/org/openstreetmap/josm/io/remotecontrol/handler/ImportHandler.java
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/ImportHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/ImportHandler.java index 4175a51..57d436a 100644
a b import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 6 import java.io.UnsupportedEncodingException; 7 7 import java.net.URLDecoder; 8 import java.util.Arrays; 8 9 import java.util.HashMap; 9 10 11 import java.util.List; 10 12 import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask; 11 13 import org.openstreetmap.josm.actions.downloadtasks.DownloadTask; 12 14 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault; … … public class ImportHandler extends RequestHandler { 36 38 } 37 39 38 40 @Override 41 public String getUsage() { 42 return "downloads the specified OSM file and adds it to the current data set"; 43 } 44 45 @Override 46 public List<String> getUsageExamples() { 47 return Arrays.asList( 48 "/import?url=http://..." 49 ); 50 } 51 52 @Override 39 53 public String getPermissionMessage() { 40 54 return tr("Remote Control has been asked to import data from the following URL:") 41 55 + "<br>" + request; -
src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java index fce910f..d0dc92b 100644
a b import java.awt.geom.Area; 7 7 import java.awt.geom.Rectangle2D; 8 8 import java.io.UnsupportedEncodingException; 9 9 import java.net.URLDecoder; 10 import java.util.Arrays; 10 11 import java.util.HashSet; 12 import java.util.List; 11 13 import java.util.Map; 12 14 import java.util.concurrent.Future; 13 15 … … public class LoadAndZoomHandler extends RequestHandler 50 52 } 51 53 52 54 @Override 55 public String getUsage() { 56 return "download a bounding box from the API, zoom to the downloaded area and optionally select one or more objects"; 57 } 58 59 @Override 60 public List<String> getUsageExamples() { 61 return Arrays.asList( 62 "/load_and_zoom?left=...&right=...&top=...&bottom=...[&select=object[,object...][&addtags=...][&zoom_mode=(download|selection)]]", 63 "/zoom?left=...&right=...&top=...&bottom=...&select=object[,object...]" 64 ); 65 } 66 67 @Override 53 68 protected void handleRequest() throws RequestHandlerErrorException 54 69 { 55 70 DownloadTask osmTask = new DownloadOsmTask(); -
src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java index a1f25e7..3ca5edd 100644
a b package org.openstreetmap.josm.io.remotecontrol.handler; 2 2 3 3 import static org.openstreetmap.josm.tools.I18n.tr; 4 4 5 import java.util.Arrays; 5 6 import java.util.LinkedList; 6 7 import java.util.List; 7 8 import org.openstreetmap.josm.Main; … … public class LoadObjectHandler extends RequestHandler { 25 26 } 26 27 27 28 @Override 29 public String getUsage() { 30 return "downloads the specified objects from the server"; 31 } 32 33 @Override 34 public List<String> getUsageExamples() { 35 return Arrays.asList( 36 "/load_object?objects=n1,w2,r3[&new_layer=false][&relation_members=true]" 37 ); 38 } 39 40 @Override 28 41 protected void handleRequest() throws RequestHandlerErrorException, RequestHandlerBadRequestException { 29 42 if (!PermissionPrefWithDefault.LOAD_DATA.isAllowed()) { 30 43 System.out.println("RemoteControl: download forbidden by preferences"); -
src/org/openstreetmap/josm/io/remotecontrol/handler/OpenFileHandler.java
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/OpenFileHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/OpenFileHandler.java index a049045..fd68783 100644
a b package org.openstreetmap.josm.io.remotecontrol.handler; 2 2 3 3 import java.io.File; 4 4 import java.util.Arrays; 5 import java.util.List; 5 6 import org.openstreetmap.josm.actions.OpenFileAction; 6 7 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault; 7 8 import static org.openstreetmap.josm.tools.I18n.tr; … … public class OpenFileHandler extends RequestHandler { 16 17 } 17 18 18 19 @Override 20 public String getUsage() { 21 return "opens a local file in JOSM"; 22 } 23 24 @Override 25 public List<String> getUsageExamples() { 26 return Arrays.asList( 27 "/open_file?filename=/tmp/test.osm" 28 ); 29 } 30 31 @Override 19 32 public PermissionPrefWithDefault getPermissionPref() { 20 33 return PermissionPrefWithDefault.OPEN_FILES; 21 34 } -
src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java index f920001..94b96c2 100644
a b import java.text.MessageFormat; 9 9 import java.util.HashMap; 10 10 import java.util.LinkedList; 11 11 import java.util.List; 12 13 12 import javax.swing.JOptionPane; 14 15 13 import org.openstreetmap.josm.Main; 16 14 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault; 17 15 import org.openstreetmap.josm.tools.Utils; … … public abstract class RequestHandler { 91 89 92 90 abstract public String[] getMandatoryParams(); 93 91 92 abstract public String getUsage(); 93 94 abstract public List<String> getUsageExamples(); 95 94 96 /** 95 97 * Check permissions in preferences and display error message 96 98 * or ask for permission. -
src/org/openstreetmap/josm/io/remotecontrol/handler/VersionHandler.java
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/VersionHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/VersionHandler.java index baf1783..cb0e6a3 100644
a b package org.openstreetmap.josm.io.remotecontrol.handler; 3 3 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.util.Arrays; 7 import java.util.List; 6 8 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault; 7 import org.openstreetmap.josm.io.remotecontrol.Re questProcessor;9 import org.openstreetmap.josm.io.remotecontrol.RemoteControl; 8 10 9 11 /** 10 12 * Handler for version request. … … public class VersionHandler extends RequestHandler { 16 18 @Override 17 19 protected void handleRequest() throws RequestHandlerErrorException, 18 20 RequestHandlerBadRequestException { 19 content = Re questProcessor.PROTOCOLVERSION;21 content = RemoteControl.PROTOCOLVERSION; 20 22 contentType = "application/json"; 21 23 if (args.containsKey("jsonp")) { 22 24 content = args.get("jsonp") + " && " + args.get("jsonp") + "(" + content + ")"; … … public class VersionHandler extends RequestHandler { 37 39 public String[] getMandatoryParams() { 38 40 return null; 39 41 } 42 43 @Override 44 public String getUsage() { 45 return "returns the current protocol version of the installed JOSM RemoteControl"; 46 } 47 48 @Override 49 public List<String> getUsageExamples() { 50 return Arrays.asList( 51 "/version" 52 ); 53 } 40 54 } 55 No newline at end of file
