@Override
public void deleteCharacters(String s) {
for (int i = 0; i < s.length(); i++) {
CharacterItem item = nextCharacter();
if (s.charAt(i) != item.character) {
throw new OpCursorException("Mismatched deleted characters: " +
s.charAt(i) + " vs " + item.character);
}
inherited = item.getAnnotations();
iterator.remove();
}
}
@Override
public void deleteElementEnd() {
ElementEndItem item = nextElementEnd();
inherited = item.getAnnotations();
iterator.remove();
}
@Override
public void deleteElementStart(String tag, Attributes attrs) {
ElementStartItem item = nextElementStart();
inherited = item.getAnnotations();
iterator.remove();
}
@Override
public void retain(int distance) {
for (int i = 0; i < distance; i++) {
inheritAndAnnotate(next());
}
}
@Override
public void replaceAttributes(Attributes oldAttrs, Attributes newAttrs) {
ElementStartItem item = nextElementStart();
item.replaceAttributes(newAttrs);
inheritAndAnnotate(item);
}
@Override
public void updateAttributes(AttributesUpdate attrUpdate) {
ElementStartItem item = nextElementStart();
item.updateAttributes(attrUpdate);
inheritAndAnnotate(item);
}
private void inheritAndAnnotate(Item item) {
inherited = item.getAnnotations();
item.updateAnnotations(annotationUpdates);
}
Item next() {
if (!iterator.hasNext()) {
throw new OpCursorException("Action past end of document, of size: " + length());
}
current = iterator.next();
return current;
}
ElementStartItem nextElementStart() {
try {
return (ElementStartItem) next();
} catch (ClassCastException e) {
throw new OpCursorException("Not at an element start, at: " + current);
}
}
ElementEndItem nextElementEnd() {
try {
return (ElementEndItem) next();
} catch (ClassCastException e) {
throw new OpCursorException("Not at an element end, at: " + current);
}
}
CharacterItem nextCharacter() {
try {
return (CharacterItem) next();
} catch (ClassCastException e) {
throw new OpCursorException("Not at a character, at: " + current);
}
}
});
if (iterator.hasNext()) {
int remainingItems = 0;