final Map<NodeId, EventImpl> addedNodes = new HashMap<NodeId, EventImpl>();
// property events
List<EventImpl> propEvents = new ArrayList<EventImpl>();
while (events.hasNext()) {
EventImpl e = (EventImpl) events.nextEvent();
if (!isExcluded(e)) {
long type = e.getType();
if (type == Event.NODE_ADDED) {
addedNodes.put(e.getChildId(), e);
// quick'n dirty fix for JCR-905
if (e.isExternal()) {
removedNodes.add(e.getChildId());
}
if (e.isShareableChildNode()) {
// simply re-index shareable nodes
removedNodes.add(e.getChildId());
}
} else if (type == Event.NODE_REMOVED) {
removedNodes.add(e.getChildId());
if (e.isShareableChildNode()) {
// check if there is a node remaining in the shared set
if (itemMgr.hasItemState(e.getChildId())) {
addedNodes.put(e.getChildId(), e);
}
}
} else {
propEvents.add(e);
}
}
}
// sort out property events
for (EventImpl e : propEvents) {
NodeId nodeId = e.getParentId();
if (e.getType() == Event.PROPERTY_ADDED) {
if (addedNodes.put(nodeId, e) == null) {
// only property added
// need to re-index
removedNodes.add(nodeId);
} else {
// the node where this prop belongs to is also new
}
} else if (e.getType() == Event.PROPERTY_CHANGED) {
// need to re-index
addedNodes.put(nodeId, e);
removedNodes.add(nodeId);
} else {
// property removed event is only generated when node still exists
addedNodes.put(nodeId, e);
removedNodes.add(nodeId);
}
}
Iterator<NodeState> addedStates = new Iterator<NodeState>() {
private final Iterator<NodeId> iter = addedNodes.keySet().iterator();
public void remove() {
throw new UnsupportedOperationException();
}
public boolean hasNext() {
return iter.hasNext();
}
public NodeState next() {
NodeState item = null;
NodeId id = (NodeId) iter.next();
try {
item = (NodeState) itemMgr.getItemState(id);
} catch (ItemStateException ise) {
// check whether this item state change originated from
// an external event
EventImpl e = addedNodes.get(id);
if (e == null || !e.isExternal()) {
log.error("Unable to index node " + id + ": does not exist");
} else {
log.info("Node no longer available " + id + ", skipped.");
}
}