001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.io.remotecontrol.handler;
003    
004    import static org.openstreetmap.josm.tools.I18n.tr;
005    
006    import java.io.UnsupportedEncodingException;
007    import java.net.URLDecoder;
008    import java.util.HashMap;
009    
010    import org.openstreetmap.josm.Main;
011    import org.openstreetmap.josm.data.imagery.ImageryInfo;
012    import org.openstreetmap.josm.gui.layer.ImageryLayer;
013    import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
014    
015    /**
016     * Adds an imagery (WMS/TMS) layer. For instance, {@code /imagery?title=...&type=...&url=...}.
017     * @since 3715
018     */
019    public class ImageryHandler extends RequestHandler {
020    
021        /**
022         * The remote control command name used to add an imagery layer.
023         */
024        public static final String command = "imagery";
025    
026        @Override
027        public String getPermissionMessage() {
028            return tr("Remote Control has been asked to load an imagery layer from the following URL:")
029                    + "<br>" + args.get("url");
030        }
031    
032        @Override
033        public String[] getMandatoryParams() {
034            return new String[]{"url"};
035        }
036    
037        @Override
038        public PermissionPrefWithDefault getPermissionPref() {
039            return PermissionPrefWithDefault.LOAD_IMAGERY;
040        }
041    
042        @Override
043        protected void handleRequest() throws RequestHandlerErrorException {
044            if (Main.map == null) //Avoid exception when creating ImageryLayer with null MapFrame
045            {
046                throw new RequestHandlerErrorException();
047            }
048            String url = args.get("url");
049            String title = args.get("title");
050            String type = args.get("type");
051            if ((title == null) || (title.isEmpty())) {
052                title = tr("Remote imagery");
053            }
054            String cookies = args.get("cookies");
055            ImageryInfo imgInfo = new ImageryInfo(title, url, type, null, cookies);
056            String min_zoom = args.get("min_zoom");
057            if (min_zoom != null && !min_zoom.isEmpty()) {
058                try {
059                    imgInfo.setDefaultMinZoom(Integer.parseInt(min_zoom));
060                } catch (NumberFormatException e) {
061                    System.err.println(e.getMessage());
062                }
063            }
064            String max_zoom = args.get("max_zoom");
065            if (max_zoom != null && !max_zoom.isEmpty()) {
066                try {
067                    imgInfo.setDefaultMaxZoom(Integer.parseInt(max_zoom));
068                } catch (NumberFormatException e) {
069                    System.err.println(e.getMessage());
070                }
071            }
072            Main.main.addLayer(ImageryLayer.create(imgInfo));
073        }
074    
075        @Override
076        protected void parseArgs() {
077            HashMap<String, String> args = new HashMap<String, String>();
078            if (request.indexOf('?') != -1) {
079                String query = request.substring(request.indexOf('?') + 1);
080                if (query.indexOf("url=") == 0) {
081                    args.put("url", decodeParam(query.substring(4)));
082                } else {
083                    int urlIdx = query.indexOf("&url=");
084                    if (urlIdx != -1) {
085                        args.put("url", decodeParam(query.substring(urlIdx + 5)));
086                        query = query.substring(0, urlIdx);
087                    } else {
088                        if (query.indexOf('#') != -1) {
089                            query = query.substring(0, query.indexOf('#'));
090                        }
091                    }
092                    String[] params = query.split("&", -1);
093                    for (String param : params) {
094                        int eq = param.indexOf('=');
095                        if (eq != -1) {
096                            args.put(param.substring(0, eq), decodeParam(param.substring(eq + 1)));
097                        }
098                    }
099                }
100            }
101            this.args = args;
102        }
103    
104        private String decodeParam(String param) {
105            try {
106                return URLDecoder.decode(param, "UTF-8");
107            } catch (UnsupportedEncodingException e) {
108                throw new RuntimeException();
109            }
110        }
111    }