Changeset 9465 in osm for applications
- Timestamp:
- 2008-08-05T02:28:44+02:00 (16 years ago)
- Location:
- applications/editors/josm/plugins/remotecontrol
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/remotecontrol/README
r9417 r9465 1 A plugin for JOSM that listens for commands on a TCP port. It can be used to 2 tell JOSM to zoom to an area and download data. 1 A plugin for JOSM that listens for commands on a TCP port (8111). 2 It can be used to tell JOSM to zoom to an area and download data. 3 Details are found on the Wiki page, 4 5 http://wiki.openstreetmap.org/index.php/JOSM/Plugins/RemoteControl 6 7 Initially written by Frederik Ramm <frederik@remote.org>. License: 8 GPL V2 or later. Incorporates code taken from YWMS plugin by frsantos. 9 -
applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/HttpServer.java
r9417 r9465 8 8 9 9 /** 10 * Simple HTTP server that spawns a {@link RequestProcessor} for every connection. 11 * 12 * @author frsantos 13 */ 14 public class HttpServer extends Thread 15 { 10 * Simple HTTP server that spawns a {@link RequestProcessor} for every 11 * connection. 12 * 13 * Taken from YWMS plugin by frsantos. 14 */ 15 16 public class HttpServer extends Thread { 17 16 18 /** Default port for the HTTP server */ 17 19 public static final int DEFAULT_PORT = 8111; -
applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/RemoteControlPreferences.java
r9417 r9465 3 3 import static org.openstreetmap.josm.tools.I18n.tr; 4 4 5 import java.awt.Color; 6 import java.awt.GridBagLayout; 5 7 import java.awt.event.*; 6 8 7 9 import javax.swing.*; 8 10 11 import org.openstreetmap.josm.Main; 9 12 import org.openstreetmap.josm.gui.preferences.PreferenceDialog; 10 13 import org.openstreetmap.josm.gui.preferences.PreferenceSetting; 11 14 import org.openstreetmap.josm.plugins.remotecontrol.Util.Version; 15 import org.openstreetmap.josm.tools.GBC; 12 16 import org.openstreetmap.josm.tools.I18n; 13 17 … … 19 23 public class RemoteControlPreferences implements PreferenceSetting 20 24 { 21 22 23 public void addGui( final PreferenceDialog gui ) 25 private JCheckBox permissionLoadData = new JCheckBox(tr("load data from API")); 26 private JCheckBox permissionChangeSelection = new JCheckBox(tr("change the selection")); 27 private JCheckBox permissionChangeViewport = new JCheckBox(tr("change the viewport")); 28 private JCheckBox alwaysAskUserConfirm = new JCheckBox(tr("confirm all Remote Control actions manually")); 29 30 public void addGui(final PreferenceDialog gui) 24 31 { 25 26 32 Version ver = Util.getVersion(); 27 33 String description = tr("A plugin that allows JOSM to be controlled from other applications."); 28 if ( ver != null)34 if (ver != null) 29 35 description += "<br><br>" + tr("Version: {0}<br>Last change at {1}", ver.revision, ver.time) + "<br><br>"; 30 JPanel ywms = gui.createPreferenceTab("remotecontrol.gif", I18n.tr("Remote Control"), description + I18n.tr("Settings for the Remote Control plugin.")); 31 ywms.add(new JLabel("no prefs yet.")); 36 JPanel remote = gui.createPreferenceTab("remotecontrol.gif", tr("Remote Control"), tr("Settings for the Remote Control plugin.")); 37 remote.add(new JLabel("<html>"+tr("The Remote Control plugin will always listen on port 8111 on localhost." + 38 "The port is not variable because it is referenced by external applications talking to the plugin.") + "</html>"), GBC.eol().insets(0,5,0,10).fill(GBC.HORIZONTAL)); 39 40 JPanel perms = new JPanel(); 41 perms.setLayout(new GridBagLayout()); 42 perms.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.gray), tr("Permitted actions"))); 43 perms.add(permissionLoadData, GBC.eol().insets(0,5,0,0).fill(GBC.HORIZONTAL)); 44 perms.add(permissionChangeSelection, GBC.eol().insets(0,5,0,0).fill(GBC.HORIZONTAL)); 45 perms.add(permissionChangeViewport, GBC.eol().insets(0,5,0,0).fill(GBC.HORIZONTAL)); 46 remote.add(perms, GBC.eol().fill(GBC.HORIZONTAL)); 47 48 remote.add(alwaysAskUserConfirm, GBC.eol().insets(0,5,0,0).fill(GBC.HORIZONTAL)); 49 remote.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL)); 50 51 52 permissionLoadData.setSelected(Main.pref.getBoolean("remotecontrol.permission.load-data", true)); 53 permissionChangeSelection.setSelected(Main.pref.getBoolean("remotecontrol.permission.change-selection", true)); 54 permissionChangeViewport.setSelected(Main.pref.getBoolean("remotecontrol.permission.change-viewport", true)); 55 alwaysAskUserConfirm.setSelected(Main.pref.getBoolean("remotecontrol.always-confirm", false)); 56 32 57 } 33 58 34 59 public void ok() { 35 } 36 37 /** 38 * ActionListener for the configuration of WMS plugin 39 * @author frsantos 40 */ 41 private final class RemoteControlConfigurationActionListener implements ActionListener, FocusListener 42 { 43 /** If the action is already handled */ 44 boolean alreadyHandled = false; 45 public void actionPerformed(ActionEvent e) { 46 if(!alreadyHandled) 47 configureRemoteControlPluginPreferences(); 48 alreadyHandled = true; 49 } 50 51 public void focusGained(FocusEvent e) { 52 alreadyHandled = false; 53 } 54 55 public void focusLost(FocusEvent e) { 56 if(!alreadyHandled) 57 configureRemoteControlPluginPreferences(); 58 alreadyHandled = true; 59 } 60 } 61 62 63 /** 64 * Configures Remote Control 65 */ 66 private void configureRemoteControlPluginPreferences() 67 { 60 Main.pref.put("remotecontrol.permission.load-data", permissionLoadData.isSelected()); 61 Main.pref.put("remotecontrol.permission.change-selection", permissionChangeSelection.isSelected()); 62 Main.pref.put("remotecontrol.permission.change-viewport", permissionChangeViewport.isSelected()); 63 Main.pref.put("remotecontrol.always-confirm", alwaysAskUserConfirm.isSelected()); 64 68 65 } 69 66 } -
applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/RequestProcessor.java
r9417 r9465 1 1 package org.openstreetmap.josm.plugins.remotecontrol; 2 2 3 import static org.openstreetmap.josm.tools.I18n.tr; 4 5 import java.awt.geom.Area; 6 import java.awt.geom.Rectangle2D; 3 7 import java.io.*; 4 8 import java.net.Socket; … … 8 12 import java.util.StringTokenizer; 9 13 14 import javax.swing.JOptionPane; 15 10 16 import org.openstreetmap.josm.Main; 17 import org.openstreetmap.josm.actions.AutoScaleAction; 11 18 import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask; 19 import org.openstreetmap.josm.data.coor.EastNorth; 20 import org.openstreetmap.josm.data.coor.LatLon; 12 21 import org.openstreetmap.josm.data.osm.Node; 13 22 import org.openstreetmap.josm.data.osm.OsmPrimitive; 14 23 import org.openstreetmap.josm.data.osm.Relation; 15 24 import org.openstreetmap.josm.data.osm.Way; 25 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor; 16 26 import org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask; 17 27 … … 23 33 /** The socket this processor listens on */ 24 34 private Socket request; 35 36 private class AlreadyLoadedException extends Exception {}; 37 private class DeniedException extends Exception {}; 38 private class LoadDeniedException extends Exception {}; 25 39 26 40 /** … … 73 87 String url = st.nextToken(); 74 88 75 if( !method.equals("GET") ) 76 { 89 if(!method.equals("GET")) { 77 90 sendNotImplemented(out); 78 91 return; … … 85 98 { 86 99 String param = st.nextToken(); 87 if (command == null) 88 { 100 if (command == null) { 89 101 command = param; 90 } 91 else 92 { 102 } else { 93 103 int eq = param.indexOf("="); 94 if (eq>-1) 95 args.put(param.substring(0,eq), param.substring(eq+1)); 104 if (eq>-1) args.put(param.substring(0,eq), param.substring(eq+1)); 96 105 } 97 106 } 98 107 99 108 if (command.equals("/load_and_zoom")) { 100 DownloadTask osmTask = new DownloadOsmTask(); 109 if (Main.pref.getBoolean("remotecontrol.always-confirm", false)) { 110 if (JOptionPane.showConfirmDialog(Main.parent, 111 tr("Remote Control has been asked to load data from the API. Request details: {0}. Do you want to allow this?", url), 112 tr("Confirm Remote Control action"), 113 JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) { 114 sendForbidden(out); 115 return; 116 } 117 } 118 DownloadTask osmTask = new DownloadOsmTask(); 101 119 if (!(args.containsKey("bottom") && args.containsKey("top") && 102 120 args.containsKey("left") && args.containsKey("right"))) { 103 send Error(out);121 sendBadRequest(out); 104 122 System.out.println("load_and_zoom remote control request must have bottom,top,left,right parameters"); 105 123 return; 106 124 } 125 double minlat = 0; 126 double maxlat = 0; 127 double minlon = 0; 128 double maxlon = 0; 107 129 try { 108 double minlat = Double.parseDouble(args.get("bottom")); 109 double maxlat = Double.parseDouble(args.get("top")); 110 double minlon = Double.parseDouble(args.get("left")); 111 double maxlon = Double.parseDouble(args.get("right")); 112 osmTask.download(Main.main.menu.download, minlat,minlon,maxlat,maxlon); 113 } 114 catch (Exception ex) 115 { 130 minlat = Double.parseDouble(args.get("bottom")); 131 maxlat = Double.parseDouble(args.get("top")); 132 minlon = Double.parseDouble(args.get("left")); 133 maxlon = Double.parseDouble(args.get("right")); 134 135 if (!Main.pref.getBoolean("remotecontrol.permission.load-data", true)) 136 throw new LoadDeniedException(); 137 138 // find out whether some data has already been downloaded 139 Area present = Main.ds.getDataSourceArea(); 140 if (present != null && !present.isEmpty()) { 141 Area toDownload = new Area(new Rectangle2D.Double(minlon,minlat,maxlon-minlon,maxlat-minlat)); 142 toDownload.subtract(present); 143 if (toDownload.isEmpty()) throw new AlreadyLoadedException(); 144 // the result might not be a rectangle (L shaped etc) 145 Rectangle2D downloadBounds = toDownload.getBounds2D(); 146 minlat = downloadBounds.getMinY(); 147 minlon = downloadBounds.getMinX(); 148 maxlat = downloadBounds.getMaxY(); 149 maxlon = downloadBounds.getMaxX(); 150 } 151 osmTask.download(null, minlat,minlon,maxlat,maxlon); 152 } catch (AlreadyLoadedException ex) { 153 System.out.println("RemoteControl: no download necessary"); 154 } catch (LoadDeniedException ex) { 155 System.out.println("RemoteControl: download forbidden by preferences"); 156 } catch (Exception ex) { 116 157 sendError(out); 117 158 System.out.println("RemoteControl: Error parsing load_and_zoom remote control request:"); … … 119 160 return; 120 161 } 121 if (args.containsKey("select")) { 162 if (args.containsKey("select") && Main.pref.getBoolean("remotecontrol.permission.change-selection", true)) { 163 // select objects after downloading, zoom to selection. 122 164 final String selection = args.get("select"); 123 165 Main.worker.execute(new Runnable() { … … 142 184 for (Relation r : Main.ds.relations) if (relations.contains(r.id)) newSel.add(r); 143 185 Main.ds.setSelected(newSel); 186 if (Main.pref.getBoolean("remotecontrol.permission.change-viewport", true)) 187 new AutoScaleAction("selection").actionPerformed(null); 144 188 } 145 189 }); 146 }; 190 } else if (Main.pref.getBoolean("remotecontrol.permission.change-viewport", true)) { 191 // after downloading, zoom to downloaded area. 192 final LatLon min = new LatLon(minlat, minlon); 193 final LatLon max = new LatLon(maxlat, maxlon); 194 195 Main.worker.execute(new Runnable() { 196 public void run() { 197 BoundingXYVisitor bbox = new BoundingXYVisitor(); 198 bbox.min = Main.proj.latlon2eastNorth(min); 199 bbox.max = Main.proj.latlon2eastNorth(max); 200 Main.map.mapView.recalculateCenterScale(bbox); 201 } 202 }); 203 } 147 204 } 148 205 sendHeader(out, "200 OK", "text/plain", false); … … 153 210 } 154 211 catch (IOException ioe) { } 155 catch(Exception e) 156 { 212 catch(Exception e) { 157 213 e.printStackTrace(); 158 try 159 { 214 try { 160 215 sendError(out); 161 } 162 catch (IOException e1) { } 163 } 164 finally 165 { 166 try 167 { 216 } catch (IOException e1) { } 217 } finally { 218 try { 168 219 request.close(); 169 } 170 catch (IOException e) {} 220 } catch (IOException e) {} 171 221 } 172 222 } … … 205 255 out.flush(); 206 256 } 257 258 /** 259 * Sends a 403 error: forbidden 260 * @param out The writer where the error is written 261 * @throws IOException If the error can not be written 262 */ 263 private void sendForbidden(Writer out) throws IOException 264 { 265 sendHeader(out, "403 Forbidden", "text/html", true); 266 out.write("<HTML>\r\n"); 267 out.write("<HEAD><TITLE>Forbidden</TITLE>\r\n"); 268 out.write("</HEAD>\r\n"); 269 out.write("<BODY>"); 270 out.write("<H1>HTTP Error 403: Forbidden</h2>\r\n"); 271 out.write("</BODY></HTML>\r\n"); 272 out.flush(); 273 } 274 /** 275 * Sends a 403 error: forbidden 276 * @param out The writer where the error is written 277 * @throws IOException If the error can not be written 278 */ 279 private void sendBadRequest(Writer out) throws IOException 280 { 281 sendHeader(out, "400 Bad Request", "text/html", true); 282 out.write("<HTML>\r\n"); 283 out.write("<HEAD><TITLE>Bad Request</TITLE>\r\n"); 284 out.write("</HEAD>\r\n"); 285 out.write("<BODY>"); 286 out.write("<H1>HTTP Error 400: Bad Request</h2>\r\n"); 287 out.write("</BODY></HTML>\r\n"); 288 out.flush(); 289 } 207 290 208 291 /** -
applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/Util.java
r9417 r9465 18 18 * Utility class 19 19 * 20 * @author frsantos21 20 */ 22 21 public class Util 23 22 { 24 25 23 /** 26 24 * Utility method to retrieve the plugin for classes that can't access to the plugin object directly. … … 34 32 for (PluginProxy plugin : Main.plugins) 35 33 { 36 if( plugin.info.className.equals(classname))34 if(plugin.info.className.equals(classname)) 37 35 { 38 36 return (Plugin)plugin.plugin; 39 37 } 40 38 } 41 42 39 return null; 43 40 } … … 54 51 55 52 /** 56 * Utility method for creating buttons57 * @param name The name of the button58 * @param icon Icon of the button59 * @param tooltip Tooltip60 * @param action The action performed when clicking the button61 * @return The created button62 */63 public static JButton createButton(String name, String icon, String tooltip, ActionListener action)64 {65 JButton button = new JButton(tr(name), ImageProvider.get(icon));66 button.setActionCommand(name);67 button.addActionListener(action);68 button.setToolTipText(tr(tooltip));69 button.putClientProperty("help", "Dialog/SelectionList/" + name);70 return button;71 }72 73 74 /**75 53 * Returns the version 76 54 * @return The version of the application … … 79 57 { 80 58 PluginInformation info = PluginInformation.getLoaded("ywms"); 81 if ( info == null )59 if (info == null) 82 60 return null; 83 61 … … 108 86 } 109 87 } 110 111 112 /**113 * Loads a text file in a String114 *115 * @param resource The URL of the file116 * @return A String with the file contents117 * @throws IOException when error reading the file118 */119 public static String loadFile(URL resource) throws IOException120 {121 BufferedReader in = null;122 try123 {124 in = new BufferedReader(new InputStreamReader(resource.openStream()));125 StringBuilder sb = new StringBuilder();126 for (String line = in.readLine(); line != null; line = in.readLine())127 {128 sb.append(line);129 sb.append('\n');130 }131 return sb.toString();132 }133 finally134 {135 if( in != null )136 {137 try {138 in.close();139 } catch (IOException e) {140 e.printStackTrace();141 }142 }143 }144 }145 146 /**147 * Mirrors a file to a local file.148 * <p>149 * The file mirrored is only downloaded if it has been more than one day since last download150 *151 * @param url The URL of the remote file152 * @param destDir The destionation dir of the mirrored file153 * @param maxTime The time interval, in seconds, to check if the file changed. If less than 0, it defaults to 1 week154 * @return The local file155 */156 public static File mirror(URL url, String destDir, long maxTime)157 {158 if( url.getProtocol().equals("file") )159 return new File(url.toString() ) ;160 161 String localPath = Main.pref.get("tests.mirror." + url);162 File oldFile = null;163 if( localPath != null && localPath.length() > 0)164 {165 StringTokenizer st = new StringTokenizer(localPath, ";");166 long checkDate = Long.parseLong(st.nextToken());167 localPath = st.nextToken();168 oldFile = new File(localPath);169 maxTime = (maxTime <= 0) ? 7 * 24 * 60 * 60 * 1000 : maxTime * 1000;170 if( System.currentTimeMillis() - checkDate < maxTime )171 {172 if( oldFile.exists() )173 return oldFile;174 }175 }176 177 File destDirFile = new File(destDir);178 if( !destDirFile.exists() )179 destDirFile.mkdirs();180 181 localPath = destDir + System.currentTimeMillis() + "-" + new File(url.getPath()).getName();182 BufferedOutputStream bos = null;183 BufferedInputStream bis = null;184 try185 {186 URLConnection conn = url.openConnection();187 conn.setConnectTimeout(5000);188 bis = new BufferedInputStream(conn.getInputStream());189 bos = new BufferedOutputStream( new FileOutputStream(localPath) );190 byte[] buffer = new byte[4096];191 int length;192 while( (length = bis.read( buffer )) > -1 )193 {194 bos.write( buffer, 0, length );195 }196 }197 catch(IOException ioe)198 {199 if( oldFile != null )200 return oldFile;201 else202 return null;203 }204 finally205 {206 if( bis != null )207 {208 try {209 bis.close();210 } catch (IOException e) {211 e.printStackTrace();212 }213 }214 if( bos != null )215 {216 try {217 bos.close();218 } catch (IOException e) {219 e.printStackTrace();220 }221 }222 }223 224 Main.pref.put("tests.mirror." + url, System.currentTimeMillis() + ";" + localPath);225 226 if( oldFile != null )227 oldFile.delete();228 229 return new File(localPath);230 }231 232 /**233 * Copies the ressource 'from' to the file in the plugin directory named 'to'.234 * @param from The source directory235 * @param to The destination directory236 * @throws FileNotFoundException237 * @throws IOException238 */239 public static void copy(String from, String to) throws FileNotFoundException, IOException {240 File pluginDir = new File(getPluginDir());241 if (!pluginDir.exists())242 pluginDir.mkdirs();243 FileOutputStream out = new FileOutputStream(getPluginDir()+to);244 InputStream in = Util.class.getResourceAsStream(from);245 byte[] buffer = new byte[8192];246 for(int len = in.read(buffer); len > 0; len = in.read(buffer))247 out.write(buffer, 0, len);248 in.close();249 out.close();250 }251 88 }
Note:
See TracChangeset
for help on using the changeset viewer.