// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.gui.dialogs.properties;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Map.Entry;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
import org.openstreetmap.josm.data.osm.event.DataSetListener;
import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;
import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
public class ListOfUsedTags implements DataSetListener {
final TreeMap<String, TreeSet<String>> allData = new TreeMap<String, TreeSet<String>>();
private boolean dirty;
public Collection<String> getUsedKeys() {
if (dirty) {
rebuild();
}
return allData.keySet();
}
/**
*
* @param key
* @return List of used values or empty list if key is not used
*/
public Collection<String> getUsedValues(String key) {
if (dirty) {
rebuild();
}
Collection<String> values = allData.get(key);
if (values == null)
return Collections.emptyList();
else
return values;
}
public void rebuildNecessary() {
dirty = true;
}
private void rebuild() {
dirty = false;
allData.clear();
DataSet currentDataset = Main.main.getCurrentDataSet();
if (currentDataset != null) {
addPrimitives(currentDataset.allNonDeletedPrimitives());
}
}
private void addPrimitives(Collection<? extends OsmPrimitive> primitives) {
for (OsmPrimitive osm : primitives) {
addPrimitive(osm);
}
}
private void addPrimitive(OsmPrimitive primitive) {
for (String key: primitive.keySet()) {
addKey(key, primitive.get(key));
}
}
private void addKey(String key, String value) {
TreeSet<String> values = allData.get(key);
if (values == null) {
values = new TreeSet<String>();
allData.put(key, values);
}
values.add(value);
}
public void dataChanged(DataChangedEvent event) {
rebuild();
}
public void nodeMoved(NodeMovedEvent event) {/* ignored */}
public void otherDatasetChange(AbstractDatasetChangedEvent event) {/* ignored */}
public void primtivesAdded(PrimitivesAddedEvent event) {
addPrimitives(event.getPrimitives());
}
public void primtivesRemoved(PrimitivesRemovedEvent event) {
dirty = true;
}
public void relationMembersChanged(RelationMembersChangedEvent event) {/* ignored */}
public void tagsChanged(TagsChangedEvent event) {
Map<String, String> newKeys = event.getPrimitive().getKeys();
Map<String, String> oldKeys = event.getOriginalKeys();
if (!newKeys.keySet().containsAll(oldKeys.keySet())) {
// Some keys removed, might be the last instance of key, rebuild necessary
dirty = true;
} else {
for (Entry<String, String> oldEntry: oldKeys.entrySet()) {
if (!oldEntry.getValue().equals(newKeys.get(oldEntry.getKey()))) {
// Value changed, might be last instance of value, rebuild necessary
dirty = true;
return;
}
}
addPrimitive(event.getPrimitive());
}
}
public void wayNodesChanged(WayNodesChangedEvent event) {/* ignored */}
}