package edu.uw.zookeeper.data;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.base.CharMatcher;
import edu.uw.zookeeper.common.Reference;
public final class ZNodeLabel extends AbstractZNodeLabel {
/**
* @param label to be validated
* @return label
*/
public static <T extends CharSequence> T validate(T label) {
return validate(label, 0, label.length());
}
@SuppressWarnings("unchecked")
public static <T extends CharSequence> T validate(T label, int start, int end) {
checkArgument(start < end, "empty label");
for (int i=start; i<end; ++i) {
char c = label.charAt(i);
if (c == SLASH) {
throw new IllegalArgumentException(String.format("Slash at index %d of %s", i, label));
} else if (ILLEGAL_CHARACTERS.matches(c)) {
throw new IllegalArgumentException(String.format("Illegal character at index %d of %s", i, label));
}
}
return ((start > 0) || (end < label.length() - 1)) ? (T) label.subSequence(start, end) : label;
}
public static ZNodeLabel validated(String label) {
return fromString(validate(label));
}
public static ZNodeLabel validated(String label, int start, int end) {
return fromString(validate(label, start, end));
}
@Serializes(from=String.class, to=ZNodeLabel.class)
public static ZNodeLabel fromString(String label) {
assert(! label.isEmpty());
return new ZNodeLabel(label);
}
public static ZNodeLabel zookeeper() {
return Reserved.ZOOKEEPER.get();
}
public static ZNodeLabel self() {
return Reserved.SELF.get();
}
public static ZNodeLabel parent() {
return Reserved.PARENT.get();
}
private ZNodeLabel(String label) {
super(label);
}
@Override
public boolean isEmpty() {
return false;
}
public boolean isReserved() {
return Reserved.contains(this);
}
// illegal unicode values
private static final CharMatcher ILLEGAL_CHARACTERS =
CharMatcher.inRange('\u0000', '\u001f')
.and(CharMatcher.inRange('\u007f', '\u009F'))
.and(CharMatcher.inRange('\ud800', '\uf8ff'))
.and(CharMatcher.inRange('\ufff0', '\uffff'))
.precomputed();
public static enum Reserved implements Reference<ZNodeLabel> {
ZOOKEEPER(ZNodeLabel.fromString("zookeeper")),
SELF(ZNodeLabel.fromString(".")),
PARENT(ZNodeLabel.fromString(".."));
public static boolean contains(ZNodeLabel c) {
for (ZNodeLabel.Reserved e: values()) {
if (e.get().equals(c)) {
return true;
}
}
return false;
}
private final ZNodeLabel value;
private Reserved(ZNodeLabel value) {
this.value = value;
}
@Override
public ZNodeLabel get() {
return value;
}
}
}