private DocumentBasedSingleton(DocEventRouter router, Doc.E container, String valueTagName, Factory<Doc.E, V, I> valueFactory) { this.router = router; this.container = container; this.valueTagName = valueTagName; this.valueFactory = valueFactory; this.currentElement = findCanonicalElement(); }
@Override public void onElementRemoved(Doc.E removedElement) { if (removedElement == currentElement) { changeCurrentValue(findCanonicalElement()); } }
@Override public void onElementAdded(Doc.E newElement) { // When a deletion and insertion are composed it's possible that // recalculation from the deletion event changes the current element // to the newly inserted canonical element before this event // is fired. Thus the check that the new element is not already // the current element. // Yet another failure of the ElementListener interface. if (newElement == findCanonicalElement() && newElement != currentElement) { changeCurrentValue(newElement); } }
@Override public void clear() { // Delete non-canonical elements first so no events are generated. cleanup(); // Then delete the canonical, which will remove currentValue. Doc.E element = findCanonicalElement(); if (element != null) { getDocument().deleteNode(element); } assert currentElement == null; assert currentValue == null; }
/** * Deletes all non-canonical elements from the document. */ private void cleanup() { Doc.E canonical = findCanonicalElement(); Doc.E toDelete = DocHelper.getLastElementWithTagName(getDocument(), valueTagName, container); while (toDelete != canonical) { getDocument().deleteNode(toDelete); toDelete = DocHelper.getLastElementWithTagName(getDocument(), valueTagName, container); } }