package org.gridkit.jvmtool.event;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.SortedMap;
import java.util.TreeMap;
public class SimpleTagCollection implements TagCollection {
private SortedMap<Tag, Tag> tags = new TreeMap<Tag, Tag>();
public SimpleTagCollection() {
}
public SimpleTagCollection(TagCollection that) {
for(String key: that) {
for(String tag: that.tagsFor(key)) {
put(key, tag);
}
}
}
protected SimpleTagCollection(Iterable<Tag> tags) {
for(Tag t: tags) {
this.tags.put(t, t);
}
}
@Override
public Iterator<String> iterator() {
return new KeyIterator(tags.keySet().iterator());
}
@Override
public Iterable<String> tagsFor(final String key) {
return new Iterable<String>() {
@Override
public Iterator<String> iterator() {
return new TagIterator(key, tags.tailMap(new Tag(key, "")).keySet().iterator());
}
};
}
@Override
public String firstTagFor(String key) {
SortedMap<Tag, Tag> tail = tags.tailMap(new Tag(key, ""));
if (!tail.isEmpty()) {
Tag f = tail.firstKey();
if (key.equals(f.tagKey)) {
return f.tagValue;
}
}
return null;
}
@Override
public boolean contains(String key, String tag) {
if (key == null) {
throw new NullPointerException("'key' is null");
}
if (tag == null) {
throw new NullPointerException("'tag' is null");
}
return tags.containsKey(new Tag(key, tag));
}
@Override
public SimpleTagCollection clone() {
return new SimpleTagCollection(tags.keySet());
}
public void put(String key, String tag) {
if (key == null) {
throw new NullPointerException("'key' is null");
}
if (tag == null) {
throw new NullPointerException("'tag' is null");
}
Tag t = new Tag(key, tag);
tags.put(t, t);
}
public void putAll(TagCollection that) {
for(String key: that) {
for(String tag: that.tagsFor(key)) {
put(key, tag);
}
}
}
public void remove(String key) {
if (key == null) {
throw new NullPointerException("'key' is null");
}
Iterator<Tag> it = tags.tailMap(new Tag(key, "")).keySet().iterator();
while(it.hasNext()) {
Tag t = it.next();
if (t.tagKey.equals(key)) {
it.remove();
}
else {
break;
}
}
}
public void remove(String key, String tag) {
if (key == null) {
throw new NullPointerException("'key' is null");
}
if (tag == null) {
throw new NullPointerException("'tag' is null");
}
Tag t = new Tag(key, tag);
tags.remove(t);
}
public void clear() {
tags.clear();
}
private static class KeyIterator implements Iterator<String> {
private final Iterator<Tag> iterator;
private String nextKey = null;
public KeyIterator(Iterator<Tag> tags) {
iterator = tags;
seekNext();
}
private void seekNext() {
while(iterator.hasNext()) {
Tag tag = iterator.next();
if (!tag.tagKey.equals(nextKey)) {
nextKey = tag.tagKey;
return;
}
}
nextKey = null;
}
public boolean hasNext() {
return nextKey != null;
}
@Override
public String next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
String tagKey = nextKey;
seekNext();
return tagKey;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
private static class TagIterator implements Iterator<String> {
private final String key;
private final Iterator<Tag> iterator;
private String nextTag;
public TagIterator(String key, Iterator<Tag> iterator) {
this.key = key;
this.iterator = iterator;
seekNext();
}
private void seekNext() {
while(iterator.hasNext()) {
Tag tag = iterator.next();
if (!key.equals(tag.tagKey)) {
break;
}
nextTag = tag.tagValue;
return;
}
nextTag = null;
}
@Override
public boolean hasNext() {
return nextTag != null;
}
@Override
public String next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
String tag = nextTag;
seekNext();
return tag;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
public String toString() {
return tags.keySet().toString();
}
private static class Tag implements Comparable<Tag> {
final String tagKey;
final String tagValue;
public Tag(String tagKey, String tagValue) {
this.tagKey = tagKey;
this.tagValue = tagValue;
}
@Override
public int compareTo(Tag that) {
int n = tagKey.compareTo(that.tagKey);
if (n == 0) {
n = tagValue.compareTo(that.tagValue);
}
return n;
}
public String toString() {
return tagKey + ":" + tagValue;
}
}
}