001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.dialogs.properties;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.event.ActionEvent;
007import java.util.Map;
008import java.util.Objects;
009import java.util.function.IntFunction;
010
011import javax.swing.JTable;
012
013import org.openstreetmap.josm.actions.JosmAction;
014import org.openstreetmap.josm.data.osm.IRelation;
015import org.openstreetmap.josm.data.preferences.StringProperty;
016import org.openstreetmap.josm.tools.OpenBrowser;
017import org.openstreetmap.josm.tools.Utils;
018
019/**
020 * Launch browser with Taginfo statistics for selected object.
021 * @since 13521
022 */
023public class TaginfoAction extends JosmAction {
024
025    private static final StringProperty TAGINFO_URL_PROP = new StringProperty("taginfo.url", "https://taginfo.openstreetmap.org/");
026
027    private final JTable tagTable;
028    private final IntFunction<String> tagKeySupplier;
029    private final IntFunction<Map<String, Integer>> tagValuesSupplier;
030
031    private final String taginfoUrl;
032    private final JTable membershipTable;
033    private final IntFunction<IRelation<?>> memberValueSupplier;
034
035    /**
036     * Constructs a new {@code TaginfoAction}.
037     * @param tagTable The tag table. Cannot be null
038     * @param tagKeySupplier Finds the key from given row of tag table. Cannot be null
039     * @param tagValuesSupplier Finds the values from given row of tag table (map of values and number of occurrences). Cannot be null
040     * @param membershipTable The membership table. Can be null
041     * @param memberValueSupplier Finds the parent relation from given row of membership table. Can be null
042     * @since 13959 (signature)
043     */
044    public TaginfoAction(JTable tagTable, IntFunction<String> tagKeySupplier, IntFunction<Map<String, Integer>> tagValuesSupplier,
045            JTable membershipTable, IntFunction<IRelation<?>> memberValueSupplier) {
046        this(tagTable, tagKeySupplier, tagValuesSupplier, membershipTable, memberValueSupplier, TAGINFO_URL_PROP.get(), null);
047    }
048
049    /**
050     * Constructs a new {@code TaginfoAction} with a given URL and optional name suffix.
051     * @param tagTable The tag table. Cannot be null
052     * @param tagKeySupplier Finds the key from given row of tag table. Cannot be null
053     * @param tagValuesSupplier Finds the values from given row of tag table (map of values and number of occurrences). Cannot be null
054     * @param membershipTable The membership table. Can be null
055     * @param memberValueSupplier Finds the parent relation from given row of membership table. Can be null
056     * @param taginfoUrl Taginfo URL. Cannot be null
057     * @param suffix Optional name suffix, can be null
058     * @since 15565
059     */
060    public TaginfoAction(JTable tagTable, IntFunction<String> tagKeySupplier, IntFunction<Map<String, Integer>> tagValuesSupplier,
061            JTable membershipTable, IntFunction<IRelation<?>> memberValueSupplier, String taginfoUrl, String suffix) {
062        super(tr("Go to Taginfo") + (suffix != null ? " " + suffix : ""), "dialogs/taginfo",
063                tr("Launch browser with Taginfo statistics for selected object"), null, false);
064        this.taginfoUrl = taginfoUrl.endsWith("/") ? taginfoUrl : taginfoUrl + '/';
065        this.tagTable = Objects.requireNonNull(tagTable);
066        this.tagKeySupplier = Objects.requireNonNull(tagKeySupplier);
067        this.tagValuesSupplier = Objects.requireNonNull(tagValuesSupplier);
068        this.membershipTable = membershipTable;
069        this.memberValueSupplier = memberValueSupplier;
070    }
071
072    @Override
073    public void actionPerformed(ActionEvent e) {
074        final String url;
075        if (tagTable.getSelectedRowCount() == 1) {
076            final int row = tagTable.getSelectedRow();
077            final String key = Utils.encodeUrl(tagKeySupplier.apply(row)).replaceAll("\\+", "%20");
078            Map<String, Integer> values = tagValuesSupplier.apply(row);
079            if (values.size() == 1) {
080                url = taginfoUrl + "tags/" + key
081                        + '=' + Utils.encodeUrl(values.keySet().iterator().next()).replaceAll("\\+", "%20");
082            } else {
083                url = taginfoUrl + "keys/" + key;
084            }
085        } else if (membershipTable != null && membershipTable.getSelectedRowCount() == 1) {
086            final String type = (memberValueSupplier.apply(membershipTable.getSelectedRow())).get("type");
087            url = taginfoUrl + "relations/" + type;
088        } else {
089            return;
090        }
091        OpenBrowser.displayUrl(url);
092    }
093}