// Copyright 2009 Google Inc. All Rights Reserved.
package org.waveprotocol.wave.model.document.util;
import org.waveprotocol.wave.model.document.AnnotationBehaviour;
import org.waveprotocol.wave.model.document.AnnotationMutationHandler;
import org.waveprotocol.wave.model.util.CollectionUtils;
import org.waveprotocol.wave.model.util.StringMap;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* StringMap based implementation
*
* @author danilatos@google.com (Daniel Danilatos)
*
*/
public class AnnotationRegistryImpl implements AnnotationRegistry {
private final StringMap<AnnotationMutationHandler> handlers = CollectionUtils.createStringMap();
private final StringMap<AnnotationBehaviour> behaviours = CollectionUtils.createStringMap();
private final List<AnnotationRegistryImpl> children =
new ArrayList<AnnotationRegistryImpl>();
public AnnotationRegistryImpl(AnnotationRegistryImpl copyFrom) {
if (copyFrom != null) {
handlers.putAll(copyFrom.handlers);
behaviours.putAll(copyFrom.behaviours);
}
}
/**
* Create a copy of this registry for further extension.
*
* TODO(user): Consider more efficient propagation of changes to children.
*/
@Override
public AnnotationRegistryImpl createExtension() {
AnnotationRegistryImpl child = new AnnotationRegistryImpl(this);
children.add(child);
return child;
}
@Override
public void registerHandler(String prefix, AnnotationMutationHandler handler) {
Util.validatePrefix(prefix);
handlers.put(prefix, handler);
for (AnnotationRegistryImpl child : children) {
child.registerHandler(prefix, handler);
}
}
@Override
public void registerBehaviour(String prefix, AnnotationBehaviour behaviour) {
Util.validatePrefix(prefix);
behaviours.put(prefix, behaviour);
for (AnnotationRegistryImpl child : children) {
child.registerBehaviour(prefix, behaviour);
}
}
@Override
public Iterator<AnnotationMutationHandler> getHandlers(final String prefix) {
final String parts = prefix + "/";
return new Iterator<AnnotationMutationHandler>() {
int fromIndex = -1;
AnnotationMutationHandler next;
{
getNext();
}
@Override
public boolean hasNext() {
return next != null;
}
@Override
public AnnotationMutationHandler next() {
AnnotationMutationHandler ret = next;
getNext();
return ret;
}
private void getNext() {
while ((fromIndex = parts.indexOf('/', fromIndex + 1)) != -1) {
AnnotationMutationHandler handler = handlers.get(parts.substring(0, fromIndex));
if (handler != null) {
next = handler;
return;
}
}
next = null;
}
@Override
public void remove() {
throw new UnsupportedOperationException("getHandlers iterator: remove");
}
};
}
@Override
public Iterator<AnnotationBehaviour> getBehaviours(final String prefix) {
final String parts = prefix + "/";
return new Iterator<AnnotationBehaviour>() {
int fromIndex = -1;
AnnotationBehaviour next;
{
getNext();
}
@Override
public boolean hasNext() {
return next != null;
}
@Override
public AnnotationBehaviour next() {
AnnotationBehaviour ret = next;
getNext();
return ret;
}
private void getNext() {
while ((fromIndex = parts.indexOf('/', fromIndex + 1)) != -1) {
AnnotationBehaviour behaviour = behaviours.get(parts.substring(0, fromIndex));
if (behaviour != null) {
next = behaviour;
return;
}
}
next = null;
}
@Override
public void remove() {
throw new UnsupportedOperationException("getBehaviours iterator: remove");
}
};
}
}