public void onElementRemoved(E element) { if (WaveletBasedSupplement.CONVERSATION_TAG.equals(getDocument().getTagName(element))) { WaveletId waveletId = valueOf(element); if (waveletId != null) { WaveletThreadState state = waveletSupplements.remove(waveletId); if (state == null) { // Not good - there was a collapsed-state element and we weren't // tracking it... // TODO(user): this is the same problem as the read state // tracker } } } }
@Override public void onElementRemoved(E oldElement) { if (!tag.equals(getDocument().getTagName(oldElement))) { return; } redundantElements.remove(oldElement); if (oldElement == valueElement) { // Reference value is removed. Find new best value from redundant collection. changeValue(extractLastRedundant()); } }
@Override public void onElementAdded(E element) { assert getDocument().getParentElement(element).equals(parent) : "Received event for unrelated element"; if (childTag.equals(getDocument().getTagName(element))) { T child = factory.adapt(router, element); T sibling = getPreviousKnownValue(element); orderedValues.add(sibling == null ? 0 : orderedValues.indexOf(sibling) + 1, child); elementToValue.put(element, child); valueToElement.put(child, element); fireElementAdded(child); } }
@Override public void onElementRemoved(E element) { if (WaveletBasedSupplement.GADGET_TAG.equals(getDocument().getTagName(element))) { String gadgetId = valueOf(element); if (gadgetId != null) { gadgetSupplements.remove(gadgetId); } } }
/** * Handles an element being removed from the container. */ private void handleElementRemoved(E deletedElement) { // To start with though, we do a quick check to see if deletedElement has // the same tag name as value elements. if (!entryTagName.equals(getDocument().getTagName(deletedElement))) { // Exit, because deletedElement definitely isn't part of this container. return; } if (obsoleteElements.remove(deletedElement)) { // Element was obsolete, so ignore the removal event return; } T value = valueOf(deletedElement); E existingElement = valueElements.get(value); if (existingElement != deletedElement) { // deleted element was not part of the backing store for this map, so // ignore it } else { valueElements.remove(value); fireOnValueRemoved(value); } }
/** * Clears the cache reference to an entry, if the cache refers to it, in * response to an entry element being removed. */ @Override public void onElementRemoved(E entry) { if (!entryTagName.equals(getDocument().getTagName(entry))) { return; } // It is possible, in transient states, that there are multiple entries in the document for the // same key. Therefore, we can not blindly remove the entry from the cache based on key alone. if (value == entry) { C oldValue = get(); value = null; triggerOnEntryChanged(oldValue, null); } else { obsoleteEntries.remove(entry); } }
/** * Clears the cache reference to an entry, if the cache refers to it, in * response to an entry element being removed. */ @Override public void onElementRemoved(E entry) { if (!entryTagName.equals(getDocument().getTagName(entry))) { return; } K key = keyOf(entry); // It is possible, in transient states, that there are multiple entries in the document for the // same key. Therefore, we can not blindly remove the entry from the cache based on key alone. if (entries.get(key) == entry) { entries.remove(key); triggerOnEntryChanged(key, valueOf(entry), null); } if (activeCleanUp) { obsoleteEntries.remove(entry); } }
/** * Creates a document-based manifest backed by a document with existing * conversation structure. * * @param router event router for the document on which to base the manifest * @precondition {@code documentHasManifest(doc)} */ static <E> DocumentBasedManifest createOnExisting( DocumentEventRouter<? super E, E, ?> router, E top) { Preconditions.checkArgument(router.getDocument().getTagName(top).equals(MANIFEST_TOP_TAG), "Invalid manifest top tag %s", router.getDocument().getTagName(top)); return new DocumentBasedManifest( DocumentBasedManifestThread.create(router, top), DocumentBasedStructuredValue.create(router, top, Serializer.STRING, AnchorKey.class)); }
@Override public void onElementAdded(E element) { ObservableMutableDocument<? super E, E, ?> doc = getDocument(); assert container.equals(doc.getParentElement(element)); if (!WaveletBasedSupplement.CONVERSATION_TAG.equals(doc.getTagName(element))) { return; } WaveletId waveletId = valueOf(element); if (waveletId != null) { WaveletThreadState existing = waveletSupplements.get(waveletId); if (existing == null) { WaveletThreadState read = DocumentBasedWaveletThreadState.create(router, element, waveletId, listener); waveletSupplements.put(waveletId, read); } else { // // We can't mutate during callbacks yet. // Let's just ignore the latter :(. Clean up on timer? // } } else { // XML error: someone added a WAVELET element without an id. Ignore. // TODO(user): we should log this } }
/** * Handles a new element being added to the container. If it represents a new * value, that value is recorded. If it represents a value already in this * container, either the old element or the new element is marked obsolete. * The element marked obsolete is the one that appears later in the document. */ private void handleElementAdded(E newElement) { ObservableMutableDocument<? super E, E, ?> document = getDocument(); assert container.equals(document.getParentElement(newElement)); if (!entryTagName.equals(document.getTagName(newElement))) { return; } T value = valueOf(newElement); E oldEntry = valueElements.get(value); if (oldEntry == null) { // Entry is for a new value - add it to the element map and fire an event // to collection listeners valueElements.put(value, newElement); fireOnValueAdded(value); } else if (document.getLocation(oldEntry) < document.getLocation(newElement)) { // newEntry is not needed, so mark it obsolete obsoleteElements.add(newElement); } else { // oldEntry is no needed, so mark it obsoleted and use the new one instead obsoleteElements.add(oldEntry); valueElements.put(value, newElement); } }
@Override public void onElementAdded(E newElement) { ObservableMutableDocument<? super E, E, ?> document = getDocument(); assert container.equals(document.getParentElement(newElement)); if (!tag.equals(document.getTagName(newElement))) { return; } // Possibly changing an existing value? if (valueElement != null) { if (document.getLocation(newElement) < document.getLocation(valueElement)) { // New element loses. redundantElements.add(newElement); } else { // New element wins. redundantElements.add(valueElement); changeValue(newElement); } } else { // New element is the new value. changeValue(newElement); } }
/** * Updates the entry cache, if necessary, in response to an entry element * being added. * * This method also aggressively deletes any entries that are not greater * than the cached entry. */ @Override public void onElementAdded(E entry) { ObservableMutableDocument<? super E, E, ?> document = getDocument(); assert container.equals(document.getParentElement(entry)); if (!entryTagName.equals(document.getTagName(entry))) { return; } C newValue = valueOf(entry); C oldValue = get(); // If the new value should end up in the cache, delete the old one (if applicable) and update // the entry cache. // Otherwise, the new value is aggressively deleted. if (oldValue == null || oldValue.compareTo(newValue) < 0) { invalidateCacheEntry(); // This should clean up the old entry in onEntryRemoved. value = entry; triggerOnEntryChanged(oldValue, newValue); } else { invalidateEntry(entry); } }
/** * Updates the entry cache, if necessary, in response to an entry element * being added. */ @Override public void onElementAdded(E entry) { assert getDocument().getParentElement(entry).equals(container) : "Received event for unrelated element"; if (!entryTagName.equals(getDocument().getTagName(entry))) { return; } K key = keyOf(entry); V newValue = valueOf(entry); E oldEntry = entries.get(key); V oldValue = oldEntry != null ? valueOf(oldEntry) : null; // If the new value should end up in the cache, delete the old one (if applicable) and update // the entry cache. // Otherwise, the new value is aggressively deleted. if (canReplace(oldEntry, entry, oldValue, newValue)) { invalidateCurrentCacheEntry(key); entries.put(key, entry); triggerOnEntryChanged(key, oldValue, newValue); } else { invalidateEntry(entry); } }
@Override public void onElementAdded(E element) { ObservableMutableDocument<? super E, E, ?> doc = getDocument(); assert container.equals(doc.getParentElement(element)); if (!WaveletBasedSupplement.GADGET_TAG.equals(doc.getTagName(element))) { return; } String gadgetId = valueOf(element); if (gadgetId != null) { GadgetState existing = gadgetSupplements.get(gadgetId); if (existing == null) { GadgetState state = DocumentBasedGadgetState.create(router, element, gadgetId, listener); gadgetSupplements.put(gadgetId, state); // TODO(user): Follow the changes in WaveletReadStateCollection and update this class. // // NOTE(user): it is important that these events get fired after the new read-state // object is added to the map above, in order that the interface presented by this // collection object is consistent with the events being broadcast to the listener. // listener.onGadgetStateChanged(gadgetId, null, null, null); } else { // TODO(user): Follow the changes in WaveletReadStateCollection and update this class. } } else { // XML error: someone added a WAVELET element without an id. Ignore. // TODO(user): log this at error level, once loggers are injected into // these classes. // TODO(user): Follow the changes in WaveletReadStateCollection and update this class. } }
void removeEntries(K key) { N curChild = context.doc.getFirstChild(context.container); String keyString = keySerializer.toString(key); E e = DocHelper.getFirstChildElement(context.doc, context.container); while (e != null) { if (ENTRY_TAG.equals(context.doc.getTagName(e)) && keyString.equals(context.doc.getAttribute(e, KEY_ATTR))) { context.doc.deleteNode(e); } e = DocHelper.getNextSiblingElement(context.doc, e); } }
void removeEntries(K key) { N curChild = context.doc.getFirstChild(context.container); String keyString = keySerializer.toString(key); E e = DocHelper.getFirstChildElement(context.doc, context.container); while (e != null) { if (ENTRY_TAG.equals(context.doc.getTagName(e)) && keyString.equals(context.doc.getAttribute(e, KEY_ATTR))) { context.doc.deleteNode(e); } e = DocHelper.getNextSiblingElement(context.doc, e); } }
@Override public <N, E extends N, T extends N> void exec(ObservableMutableDocument<N, E, T> doc) { E container = doc.getDocumentElement(); E entry = DocHelper.getFirstChildElement(doc, container); // Skip over anything we don't care about while (entry != null && !ENTRY_TAG.equals(doc.getTagName(entry))) { entry = DocHelper.getNextSiblingElement(doc, entry); } for (Boolean b : state) { assertNotNull(entry); Attributes attrs = b != null ? new AttributesImpl(VALUE_ATTR, b.toString()) : Attributes.EMPTY_MAP; assertEquals(attrs, doc.getAttributes(entry)); entry = DocHelper.getNextSiblingElement(doc, entry); // Skip over anything we don't care about while (entry != null && !ENTRY_TAG.equals(doc.getTagName(entry))) { entry = DocHelper.getNextSiblingElement(doc, entry); } } assertNull("Unexpected element in subtrate: " + entry, entry); } });
@Override public <N, E extends N, T extends N> void exec(ObservableMutableDocument<N, E, T> doc) { E container = doc.getDocumentElement(); E entry = DocHelper.getFirstChildElement(doc, container); // Skip over anything we don't care about while (entry != null && !ENTRY_TAG.equals(doc.getTagName(entry))) { entry = DocHelper.getNextSiblingElement(doc, entry); } for (Boolean b : state) { assertNotNull(entry); Attributes attrs = b != null ? new AttributesImpl(VALUE_ATTR, b.toString()) : Attributes.EMPTY_MAP; assertEquals(attrs, doc.getAttributes(entry)); entry = DocHelper.getNextSiblingElement(doc, entry); // Skip over anything we don't care about while (entry != null && !ENTRY_TAG.equals(doc.getTagName(entry))) { entry = DocHelper.getNextSiblingElement(doc, entry); } } assertNull("Unexpected element in subtrate: " + entry, entry); } });
public void onElementRemoved(E element) { if (WaveletBasedSupplement.WAVELET_TAG.equals(getDocument().getTagName(element))) { WaveletId waveletId = valueOf(element); if (waveletId != null) {
@Override public void onElementAdded(E element) { assert container == getDocument().getParentElement(element); if (!WaveletBasedSupplement.WAVELET_TAG.equals(getDocument().getTagName(element))) { return;