/** * Replacement is permitted only when the newEntry is later in the document. */ @Override protected boolean canReplace(E oldEntry, E newEntry, V oldValue, V newValue) { if (oldEntry == null) { return true; } if (getDocument().getLocation(newEntry) > getDocument().getLocation(oldEntry)) { return true; } return false; }
private E extractLastRedundant() { E maxElement = null; int maxLocation = -1; for (E element : redundantElements) { // NOTE(user): there is a possible bug here, which will be fixed by // not individualising the element events in the ElementListener // interface. int location = getDocument().getLocation(element); if (location > maxLocation) { maxLocation = location; maxElement = element; } } redundantElements.remove(maxElement); return maxElement; }
@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); } }
/** * 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); } }