001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.dialogs.properties;
003
004import java.awt.event.ActionEvent;
005import java.util.Arrays;
006import java.util.Collection;
007import java.util.Objects;
008import java.util.function.IntFunction;
009import java.util.function.Supplier;
010import java.util.stream.Collectors;
011import java.util.stream.Stream;
012
013import javax.swing.AbstractAction;
014import javax.swing.JTable;
015
016import org.openstreetmap.josm.data.osm.Tagged;
017import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
018
019/**
020 * Super class of all copy actions from tag table.
021 * @since 13521
022 */
023public abstract class AbstractCopyAction extends AbstractAction {
024
025    private final JTable tagTable;
026    private final IntFunction<String> keySupplier;
027    private final Supplier<Collection<? extends Tagged>> objectSupplier;
028
029    /**
030     * Constructs a new {@code AbstractCopyAction}.
031     * @param tagTable the tag table
032     * @param keySupplier a supplier which returns the selected key for a given row index
033     * @param objectSupplier a supplier which returns the selected tagged object(s)
034     */
035    public AbstractCopyAction(JTable tagTable, IntFunction<String> keySupplier, Supplier<Collection<? extends Tagged>> objectSupplier) {
036        this.tagTable = Objects.requireNonNull(tagTable);
037        this.keySupplier = Objects.requireNonNull(keySupplier);
038        this.objectSupplier = Objects.requireNonNull(objectSupplier);
039    }
040
041    protected abstract Collection<String> getString(Tagged p, String key);
042
043    protected Stream<String> valueStream() {
044        int[] rows = tagTable.getSelectedRows();
045        Collection<? extends Tagged> sel = objectSupplier.get();
046        if (rows.length == 0 || sel == null || sel.isEmpty()) return Stream.empty();
047        return Arrays.stream(rows)
048                .mapToObj(keySupplier)
049                .flatMap(key -> sel.stream().map(p -> getString(p, key)))
050                .filter(Objects::nonNull)
051                .flatMap(Collection::stream);
052    }
053
054    @Override
055    public void actionPerformed(ActionEvent ae) {
056        final String values = valueStream()
057                .sorted()
058                .collect(Collectors.joining("\n"));
059        if (!values.isEmpty()) {
060            ClipboardUtils.copyString(values);
061        }
062    }
063}