throws ItemStateException {
// delete bundles
HashSet<ItemId> deleted = new HashSet<ItemId>();
for (ItemState state : changeLog.deletedStates()) {
if (state.isNode()) {
NodePropBundle bundle = getBundle((NodeId) state.getId());
if (bundle == null) {
throw new NoSuchItemStateException(state.getId().toString());
}
deleteBundle(bundle);
deleted.add(state.getId());
}
}
// gather added node states
HashMap<ItemId, NodePropBundle> modified = new HashMap<ItemId, NodePropBundle>();
for (ItemState state : changeLog.addedStates()) {
if (state.isNode()) {
NodePropBundle bundle = new NodePropBundle(getBinding(), (NodeState) state);
modified.put(state.getId(), bundle);
}
}
// gather modified node states
for (ItemState state : changeLog.modifiedStates()) {
if (state.isNode()) {
NodeId nodeId = (NodeId) state.getId();
NodePropBundle bundle = (NodePropBundle) modified.get(nodeId);
if (bundle == null) {
bundle = getBundle(nodeId);
if (bundle == null) {
throw new NoSuchItemStateException(nodeId.toString());
}
modified.put(nodeId, bundle);
}
bundle.update((NodeState) state);
} else {
PropertyId id = (PropertyId) state.getId();
// skip redundant primaryType, mixinTypes and uuid properties
if (id.getName().equals(NameConstants.JCR_PRIMARYTYPE)
|| id.getName().equals(NameConstants.JCR_MIXINTYPES)
|| id.getName().equals(NameConstants.JCR_UUID)) {
continue;
}
NodeId nodeId = id.getParentId();
NodePropBundle bundle = (NodePropBundle) modified.get(nodeId);
if (bundle == null) {
bundle = getBundle(nodeId);
if (bundle == null) {
throw new NoSuchItemStateException(nodeId.toString());
}
modified.put(nodeId, bundle);
}
bundle.addProperty((PropertyState) state);
}
}
// add removed properties
for (ItemState state : changeLog.deletedStates()) {
if (state.isNode()) {
// check consistency
NodeId parentId = state.getParentId();
if (!modified.containsKey(parentId) && !deleted.contains(parentId)) {
log.warn("Deleted node state's parent is not modified or deleted: " + parentId + "/" + state.getId());
}
} else {
PropertyId id = (PropertyId) state.getId();
NodeId nodeId = id.getParentId();
if (!deleted.contains(nodeId)) {
NodePropBundle bundle = (NodePropBundle) modified.get(nodeId);
if (bundle == null) {
// should actually not happen
log.warn("deleted property state's parent not modified!");
bundle = getBundle(nodeId);
if (bundle == null) {
throw new NoSuchItemStateException(nodeId.toString());
}
modified.put(nodeId, bundle);
}
bundle.removeProperty(id.getName());
}
}
}
// add added properties
for (ItemState state : changeLog.addedStates()) {
if (!state.isNode()) {
PropertyId id = (PropertyId) state.getId();
// skip primaryType pr mixinTypes properties
if (id.getName().equals(NameConstants.JCR_PRIMARYTYPE)
|| id.getName().equals(NameConstants.JCR_MIXINTYPES)
|| id.getName().equals(NameConstants.JCR_UUID)) {
continue;
}
NodeId nodeId = id.getParentId();
NodePropBundle bundle = (NodePropBundle) modified.get(nodeId);
if (bundle == null) {
// should actually not happen
log.warn("added property state's parent not modified!");
bundle = getBundle(nodeId);
if (bundle == null) {
throw new NoSuchItemStateException(nodeId.toString());
}
modified.put(nodeId, bundle);
}
bundle.addProperty((PropertyState) state);
}
}
// now store all modified bundles
for (NodePropBundle bundle : modified.values()) {