package edu.uw.zookeeper;
import static com.google.common.base.Preconditions.checkArgument;
import java.util.Collection;
import java.util.Comparator;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ForwardingSortedSet;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import edu.uw.zookeeper.data.Serializers;
import edu.uw.zookeeper.data.Serializes;
public class EnsembleView<E> extends ForwardingSortedSet<E> {
protected static final char TOKEN_SEP = ',';
protected static final char TOKEN_START = '[';
protected static final char TOKEN_END = ']';
protected static final Joiner JOINER = Joiner.on(TOKEN_SEP);
protected static final Splitter SPLITTER = Splitter.on(TOKEN_SEP).trimResults();
@Serializes(from=EnsembleView.class, to=String.class)
public static String toString(Collection<?> input) {
return toStringBuilder(new StringBuilder(), input).toString();
}
public static StringBuilder toStringBuilder(StringBuilder sb, Iterable<?> members) {
return JOINER.appendTo(sb, Iterables.transform(members, Serializers.ToString.getInstance()));
}
public static String toDelimitedString(Iterable<?> members) {
return toStringBuilder(new StringBuilder().append(TOKEN_START), members).append(TOKEN_END).toString();
}
public static <E> Comparator<E> comparator(Class<E> type) {
return new Comparator<E>() {
@Override
public int compare(E arg0, E arg1) {
return Serializers.ToString.getInstance().apply(arg0).compareTo(Serializers.ToString.getInstance().apply(arg1));
}};
}
public static <E> ImmutableSortedSet<E> fromString(String input, Class<E> type) {
ImmutableList.Builder<E> members = ImmutableList.builder();
input = input.trim();
if (input.length() > 0) {
if (input.charAt(0) == TOKEN_START) {
checkArgument(input.charAt(input.length() - 1) == TOKEN_END);
input = input.substring(1, input.length() - 1).trim();
}
String[] fields = Iterables.toArray(SPLITTER.split(input), String.class);
for (String field : fields) {
E member = Serializers.getInstance().toClass(field, type);
members.add(member);
}
}
return ImmutableSortedSet.copyOf(comparator(type), members.build());
}
public static <E> EnsembleView<E> empty() {
return create(ImmutableSortedSet.<E>of());
}
public static <E> EnsembleView<E> copyOf(Comparator<E> comparator, E...members) {
return copyOf(comparator, ImmutableList.copyOf(members));
}
public static <E> EnsembleView<E> copyOf(Comparator<E> comparator, Collection<E> members) {
return create(ImmutableSortedSet.copyOf(comparator, members));
}
public static <E extends Comparable<E>> EnsembleView<E> copyOf(E...members) {
return create(ImmutableSortedSet.copyOf(members));
}
public static <E extends Comparable<E>> EnsembleView<E> copyOf(Collection<E> members) {
return create(ImmutableSortedSet.copyOf(members));
}
public static <E> EnsembleView<E> create(ImmutableSortedSet<E> members) {
return new EnsembleView<E>(members);
}
private final ImmutableSortedSet<E> delegate;
protected EnsembleView(ImmutableSortedSet<E> delegate) {
this.delegate = delegate;
}
@Serializes(from=EnsembleView.class, to=String.class)
@Override
public String toString() {
return toString(delegate());
}
@Override
protected ImmutableSortedSet<E> delegate() {
return delegate;
}
}