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.LinkedList;
007import java.util.List;
008
009import org.openstreetmap.josm.Main;
010import org.openstreetmap.josm.data.osm.PrimitiveId;
011import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
012import org.openstreetmap.josm.gui.io.DownloadPrimitivesWithReferrersTask;
013import org.openstreetmap.josm.gui.util.GuiHelper;
014import org.openstreetmap.josm.io.remotecontrol.AddTagsDialog;
015import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
016
017/**
018 * Loads OSM primitives using their ID
019 * similar to the "Download object" dialog (@see DownloadPrimitiveAction}.
020 * For instance, {@code /load_object?objects=n1,w2,r3[&new_layer=false&relation_members=true]}.
021 */
022public class LoadObjectHandler extends RequestHandler {
023
024    /**
025     * The remote control command name used to load objects using their ID.
026     */
027    public static final String command = "load_object";
028
029    private final List<PrimitiveId> ps = new LinkedList<>();
030
031    @Override
032    public String[] getMandatoryParams() {
033        return new String[]{"objects"};
034    }
035
036    @Override
037    public String[] getOptionalParams() {
038        return new String[] {"new_layer", "addtags", "relation_members", "referrers"};
039    }
040
041    @Override
042    public String getUsage() {
043        return "downloads the specified objects from the server";
044    }
045
046    @Override
047    public String[] getUsageExamples() {
048        return new String[] {"/load_object?new_layer=true&objects=w106159509",
049            "/load_object?new_layer=true&objects=r2263653&relation_members=true",
050            "/load_object?objects=n100000&referrers=false"
051        };
052    }
053
054    @Override
055    protected void handleRequest() throws RequestHandlerErrorException, RequestHandlerBadRequestException {
056        if (!PermissionPrefWithDefault.LOAD_DATA.isAllowed()) {
057            Main.info("RemoteControl: download forbidden by preferences");
058        }
059        if (!ps.isEmpty()) {
060            final boolean newLayer = isLoadInNewLayer();
061            final boolean relationMembers = Boolean.parseBoolean(args.get("relation_members"));
062            final boolean referrers = args.containsKey("referrers") ? Boolean.parseBoolean(args.get("referrers")) : true;
063            final DownloadPrimitivesWithReferrersTask task = new DownloadPrimitivesWithReferrersTask(
064                    newLayer, ps, referrers, relationMembers, null);
065            Main.worker.submit(task);
066            Main.worker.submit(new Runnable() {
067                @Override
068                public void run() {
069                    final List<PrimitiveId> downloaded = task.getDownloadedId();
070                    if(downloaded != null) {
071                        GuiHelper.runInEDT(new Runnable() {
072                            @Override
073                            public void run() {
074                                Main.main.getCurrentDataSet().setSelected(downloaded);
075                            }
076                        });
077                    }
078                    AddTagsDialog.addTags(args, sender);
079                    ps.clear();
080                }
081            });
082        }
083    }
084
085    @Override
086    public String getPermissionMessage() {
087        return tr("Remote Control has been asked to load objects (specified by their id) from the API.");
088    }
089
090    @Override
091    public PermissionPrefWithDefault getPermissionPref() {
092        return PermissionPrefWithDefault.LOAD_DATA;
093    }
094
095    @Override
096    protected void validateRequest() throws RequestHandlerBadRequestException {
097        ps.clear();
098        for (String i : args.get("objects").split(",\\s*")) {
099            try {
100                ps.add(SimplePrimitiveId.fromString(i));
101            } catch (IllegalArgumentException e) {
102                Main.warn("RemoteControl: invalid selection '"+i+"' ignored");
103            }
104        }
105    }
106}