private DocOp composeOperations(DocOp op1, DocOp op2) throws OperationException { target = defaultTarget; int op1Index = 0; int op2Index = 0; while (op1Index < op1.size()) { op1.applyComponent(op1Index++, target); while (target.isPostTarget()) { if (op2Index >= op2.size()) { throw new OperationException( "Document size mismatch: " + "op1 resulting length=" + DocOpUtil.resultingDocumentLength(op1) + ", op2 initial length=" + DocOpUtil.initialDocumentLength(op2)); } op2.applyComponent(op2Index++, target); } } if (op2Index < op2.size()) { target = new FinisherPostTarget(); while (op2Index < op2.size()) { op2.applyComponent(op2Index++, target); } } flushAnnotations(); return normalizer.finish(); }
/** * Find the size of a document in number of characters and tags. * * @param doc document mutation to find the size * @return size of the document in number of characters and tags */ public static int findDocumentSize(DocOp doc) { final AtomicInteger size = new AtomicInteger(0); doc.apply( new InitializationCursorAdapter( new DocOpCursor() { @Override public void characters(String s) { size.getAndAdd(s.length()); } @Override public void elementStart(String key, Attributes attrs) { size.incrementAndGet(); } @Override public void elementEnd() { size.incrementAndGet(); } @Override public void annotationBoundary(AnnotationBoundaryMap map) {} @Override public void retain(int itemCount) {} @Override public void deleteCharacters(String chars) {} @Override public void deleteElementStart(String type, Attributes attrs) {} @Override public void deleteElementEnd() {} @Override public void replaceAttributes(Attributes oldAttrs, Attributes newAttrs) {} @Override public void updateAttributes(AttributesUpdate attrUpdate) {} })); return size.get(); }