/** * Copies a document from one wavelet to another, appending the contents if the * destination document already exists. * * @param sourceWavelet the source wavelet * @param destWavelet the destination wavelet * @param docId the id of the document to copy */ public static void copyDocument(Wavelet sourceWavelet, Wavelet destWavelet, String docId) { Document document = sourceWavelet.getDocument(docId); DocInitialization docInit = document.toInitialization(); // TODO(user): add a createDocument method to Wavelet so that we can push this ugliness // down the stack. ObservableDocument destDoc = destWavelet.getDocument(docId); destDoc.hackConsume(Nindo.fromDocOp(docInit, false /* don't remove skip */)); }
private void verifyMutationsLC(String opString, RichTextTokenizer tokens) { Pair<Nindo, IndexedDocument<Node, Element, Text>> result = applyTokensToEmptyDoc(tokens); Nindo nindo = Nindo.shift(-3, result.first); if (!opString.equals(nindo.toString())) { System.out.println("ACTUAL: " + nindo); System.out.println("EXPECT: " + opString); throw new AssertionError(opString + ", " + nindo); } assertEquals(opString, nindo.toString()); }
/** * Obtains a DocumentMutation from the builder. * * This method may do some error checking on the mutation and throw an * exception if it is ill-formed. * * @return The built DocumentMutation. */ public Nindo build() { return new Nindo(mutationList); }
@Override public void setAnnotation(int start, int end, String key, String value) { Annotations.checkPersistentKey(key); Preconditions.checkPositionIndexes(start, end, doc.size()); if (start == end) { return; } try { begin(); consume(Nindo.setAnnotation(start, end, key, value)); } finally { end(); } }
/** * {@link #testOperationFailure} specialised to InsertText operation * * @param startContent * @param insertionPoint * @param insertString */ private void testInsertTextFailure( String startContent, int insertionPoint, String insertString) { // Fix to wrap in line container body startContent = "<body>" + abbreviations.expand(startContent) + "</body>"; testOperationFailure( startContent, Nindo.insertCharacters(insertionPoint, insertString)); }
doc.consumeAndReturnInvertible(Nindo.deleteElement(0));
apply(new NindoCursor() { public void begin() { builder.append("{");
/** * Addes a skip of the given size to the start of the nindo if distance is * positive, reduces initial skips if the distance is negative. * * @return a new nindo */ public static Nindo shift(final int distance, Nindo nindo) { int remaining = Math.max(0, -distance); Builder b = builder(); if (distance > 0) { b.skip(distance); } for (MutationComponent c : nindo.mutationList) { if (remaining > 0) { if (c instanceof Skip) { int skipSize = ((Skip) c).skipSize; int diff = Math.min(remaining, skipSize); remaining -= diff; if (diff < skipSize) { b.skip(skipSize - diff); } } else { Preconditions.illegalArgument("Not enough initial skips in nindo to take off"); } } else { c.apply(b); } } return b.build(); }
doc.consumeAndReturnInvertible(Nindo.setAnnotation(1, 5, "a", "1")); annotations.begin(); annotations.skip(1);
/** * {@link #testOperationFailure} specialised to InsertText operation * * @param startContent * @param insertionPoint * @param insertString */ private void testInsertTextFailure( String startContent, int insertionPoint, String insertString) { // Fix to wrap in line container body startContent = "<body>" + abbreviations.expand(startContent) + "</body>"; testOperationFailure( startContent, Nindo.insertCharacters(insertionPoint, insertString)); }
doc.consumeAndReturnInvertible(Nindo.deleteElement(0));
public DocOp consumeAndReturnInvertible(Nindo op, boolean validate) throws OperationException { checkConsistent(); if (validate) { maybeThrowOperationExceptionFor(op); } nindoCursor.begin2(); try { op.apply(nindoCursor); } catch (OpCursorException e) { throw new OperationException(e.getMessage(), e); } return nindoCursor.finish2(); }
/** * Creates and initialises a blip object in the wavelet. * * @param content initial content for the new blip, or {@code null} for * default content */ Blip createBlip(DocInitialization content) { Blip blip = wavelet.createBlip(idGenerator.newBlipId()); if (content != null) { blip.getContent().hackConsume(Nindo.fromDocOp(content, false)); } else { Document doc = blip.getContent(); doc.insertXml(Point.<Doc.N> end(doc.getDocumentElement()), Blips.INITIAL_CONTENT); } return blip; }
doc.consumeAndReturnInvertible(Nindo.setAnnotation(1, 5, "a", "1")); annotations.begin(); annotations.skip(1);
private void verifyMutationsLC(String opString, RichTextTokenizer tokens) { Pair<Nindo, IndexedDocument<Node, Element, Text>> result = applyTokensToEmptyDoc(tokens); Nindo nindo = Nindo.shift(-3, result.first); if (!opString.equals(nindo.toString())) { System.out.println("ACTUAL: " + nindo); System.out.println("EXPECT: " + opString); throw new AssertionError(opString + ", " + nindo); } assertEquals(opString, nindo.toString()); }
private WaveletOperation makeBlipContentOp(String id, long timestamp) throws OperationException { if (!docs.containsKey(id)) { docs.put(id, DocProviders.POJO.parse("<x></x>")); } Nindo nindo = Nindo.insertCharacters(1, "hi"); DocOp op = docs.get(id).consumeAndReturnInvertible(nindo); return new WaveletBlipOperation(id, new BlipContentOperation(getContext(timestamp), op)); }
/** * Creates a document mutation that deletes an empty element at a given * location. * * @param elementLocation The location of the empty element to delete. * @return The document mutation. */ public static Nindo deleteElement(int elementLocation) { List<MutationComponent> mutationList = new ArrayList<MutationComponent>(2); // It may be impossible to delete the root element, but let's check // that elsewhere. if (elementLocation > 0) { mutationList.add(new Skip(elementLocation)); } mutationList.add(DeleteElementStart.INSTANCE); mutationList.add(DeleteElementEnd.INSTANCE); return new Nindo(mutationList); }
final ViolationCollector v = new ViolationCollector(); try { m.apply(new NindoCursor() {
private void restore(Document doc) { // No comment. UncheckedDocOpBuffer builder = new UncheckedDocOpBuffer(); doc.toInitialization().apply(builder); DocOp state = builder.finish(); DocOp erasure = DocOpInverter.invert(state); DocOp restoration; try { restoration = Composer.compose(erasure, state); } catch (OperationException e) { // If the code above fails, then there is a bug in the operation code, not // these tests. Fail with an exception, not with a JUnit fail(). throw new RuntimeException(e); } doc.hackConsume(Nindo.fromDocOp(restoration, false)); } }
doc.consumeAndReturnInvertible(Nindo.setAnnotation(1, 5, "a", "1")); doc.consumeAndReturnInvertible(Nindo.setAnnotation(5, 6, "a", "2")); doc.consumeAndReturnInvertible(Nindo.setAnnotation(3, 8, "b", "1")); doc.consumeAndReturnInvertible(Nindo.setAnnotation(1, 8, "c", "1"));