001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.validation.util;
003
004import static org.openstreetmap.josm.tools.I18n.trn;
005
006import java.util.Collection;
007import java.util.Optional;
008
009import javax.swing.Icon;
010import javax.swing.JLabel;
011
012import org.openstreetmap.josm.data.osm.OsmPrimitive;
013import org.openstreetmap.josm.tools.ImageProvider;
014
015/**
016 * Able to create a name and an icon for a collection of elements.
017 *
018 * @author frsantos
019 */
020public class MultipleNameVisitor extends NameVisitor {
021
022    /**
023     * Maximum displayed length, in characters.
024     */
025    public static final int MULTIPLE_NAME_MAX_LENGTH = 80;
026
027    /** The class name of the combined primitives */
028    private String multipleClassname;
029    /** Name to be displayed */
030    private String displayName;
031    /** Size of the collection */
032    private int size;
033
034    /**
035     * Visits a collection of primitives
036     * @param data The collection of primitives
037     */
038    public void visit(Collection<? extends OsmPrimitive> data) {
039        StringBuilder multipleName = new StringBuilder();
040        String multiplePluralClassname = null;
041        size = data.size();
042
043        multipleClassname = null;
044        for (OsmPrimitive osm : data) {
045            String name = Optional.ofNullable(osm.get("name")).orElseGet(() -> osm.get("ref"));
046            if (name != null && !name.isEmpty() && multipleName.length() <= MULTIPLE_NAME_MAX_LENGTH) {
047                if (multipleName.length() > 0) {
048                    multipleName.append(", ");
049                }
050                multipleName.append(name);
051            }
052
053            osm.accept(this);
054            if (multipleClassname == null) {
055                multipleClassname = className;
056                multiplePluralClassname = classNamePlural;
057            } else if (!multipleClassname.equals(className)) {
058                multipleClassname = "object";
059                multiplePluralClassname = trn("object", "objects", 2);
060            }
061        }
062
063        if (size <= 1) {
064            displayName = name;
065        } else {
066            StringBuilder sb = new StringBuilder().append(size).append(' ').append(trn(multipleClassname, multiplePluralClassname, size));
067            if (multipleName.length() > 0) {
068                sb.append(": ");
069                if (multipleName.length() <= MULTIPLE_NAME_MAX_LENGTH) {
070                    sb.append(multipleName);
071                } else {
072                    sb.append(multipleName.substring(0, MULTIPLE_NAME_MAX_LENGTH)).append("...");
073                }
074            }
075            displayName = sb.toString();
076        }
077    }
078
079    @Override
080    public JLabel toLabel() {
081        return new JLabel(getText(), getIcon(), JLabel.HORIZONTAL);
082    }
083
084    /**
085     * Gets the name of the items
086     * @return the name of the items
087     */
088    public String getText() {
089        return displayName;
090    }
091
092    /**
093     * Gets the icon of the items
094     * @return the icon of the items
095     */
096    public Icon getIcon() {
097        if (size <= 1)
098            return icon;
099        else
100            return ImageProvider.get("data", multipleClassname);
101    }
102
103    @Override
104    public String toString() {
105        return getText();
106    }
107}