@Override
public void notify( Changes changes ) {
Map<String, Map<Location, NetChangeDetails>> detailsByLocationByWorkspace = new HashMap<String, Map<Location, NetChangeDetails>>();
// Process each of the events, extracting the node path and property details for each ...
for (ChangeRequest change : changes.getChangeRequests()) {
Location location = change.changedLocation();
assert (location.getPath() != null);
// Find or create the NetChangeDetails for this node ...
String workspace = change.changedWorkspace();
NetChangeDetails details = findDetailsByLocation(workspace, location, detailsByLocationByWorkspace);
// Process the specific kind of change ...
if (change instanceof CreateNodeRequest) {
CreateNodeRequest create = (CreateNodeRequest)change;
details.addEventType(ChangeType.NODE_ADDED);
for (Property property : create) {
details.addProperty(property);
}
} else if (change instanceof UpdatePropertiesRequest) {
UpdatePropertiesRequest update = (UpdatePropertiesRequest)change;
for (Map.Entry<Name, Property> entry : update.properties().entrySet()) {
Name propName = entry.getKey();
Property property = entry.getValue();
if (property != null) {
if (update.isNewProperty(propName)) {
details.addProperty(property);
} else {
details.changeProperty(property);
}
} else {
details.removeProperty(propName);
}
}
} else if (change instanceof SetPropertyRequest) {
SetPropertyRequest set = (SetPropertyRequest)change;
if (set.isNewProperty()) {
details.addProperty(set.property());
} else {
details.changeProperty(set.property());
}
} else if (change instanceof RemovePropertyRequest) {
RemovePropertyRequest remove = (RemovePropertyRequest)change;
details.removeProperty(remove.propertyName());
} else if (change instanceof DeleteBranchRequest) {
// if the node was previously added than a remove results in a net no change
if (details.getEventTypes().contains(ChangeType.NODE_ADDED)) {
deleteLocationDetails(workspace, location, detailsByLocationByWorkspace);
} else {
details.addEventType(ChangeType.NODE_REMOVED);
}
} else if (change instanceof DeleteChildrenRequest) {
DeleteChildrenRequest delete = (DeleteChildrenRequest)change;
for (Location deletedChild : delete.getActualChildrenDeleted()) {
NetChangeDetails childDetails = findDetailsByLocation(workspace, deletedChild, detailsByLocationByWorkspace);
// if a child node was previously added than a remove results in a net no change
if (childDetails.getEventTypes().contains(ChangeType.NODE_ADDED)) {
deleteLocationDetails(workspace, deletedChild, detailsByLocationByWorkspace);
} else {
childDetails.addEventType(ChangeType.NODE_REMOVED);
}
}
} else if (change instanceof LockBranchRequest) {
details.setLockAction(LockAction.LOCKED);
} else if (change instanceof UnlockBranchRequest) {
details.setLockAction(LockAction.UNLOCKED);
} else if (change instanceof CopyBranchRequest) {
details.addEventType(ChangeType.NODE_ADDED);
} else if (change instanceof MoveBranchRequest) {
// the old location is a removed node event and if it is the same location as the original location it is a
// reorder
Location original = ((MoveBranchRequest)change).getActualLocationBefore();
NetChangeDetails originalDetails = findDetailsByLocation(workspace, original, detailsByLocationByWorkspace);
originalDetails.addEventType(ChangeType.NODE_REMOVED);
// the new location is a new node event
details.addEventType(ChangeType.NODE_ADDED);
} else if (change instanceof CloneBranchRequest) {
CloneBranchRequest cloneRequest = (CloneBranchRequest)change;
// create event details for any nodes that were removed
for (Location removed : cloneRequest.getRemovedNodes()) {
NetChangeDetails removedDetails = findDetailsByLocation(workspace, removed, detailsByLocationByWorkspace);
removedDetails.addEventType(ChangeType.NODE_REMOVED);
}
// create event details for new node
details.addEventType(ChangeType.NODE_ADDED);
} else if (change instanceof RenameNodeRequest) {
// the old location is a removed node event
Location original = ((RenameNodeRequest)change).getActualLocationBefore();
NetChangeDetails originalDetails = findDetailsByLocation(workspace, original, detailsByLocationByWorkspace);
originalDetails.addEventType(ChangeType.NODE_REMOVED);
// the new location is a new node event
details.addEventType(ChangeType.NODE_ADDED);
} else if (change instanceof UpdateValuesRequest) {
UpdateValuesRequest updateValuesRequest = (UpdateValuesRequest)change;
if (!updateValuesRequest.addedValues().isEmpty() || !updateValuesRequest.removedValues().isEmpty()) {
assert (updateValuesRequest.getActualProperty() != null);
if (updateValuesRequest.isNewProperty()) {
details.addEventType(ChangeType.PROPERTY_ADDED);
details.addProperty(updateValuesRequest.getActualProperty());
} else {
details.addEventType(ChangeType.PROPERTY_CHANGED);
details.changeProperty(updateValuesRequest.getActualProperty());
}
} else if (details.getEventTypes().isEmpty()) {
// details was just created for this request and now it is not needed
deleteLocationDetails(workspace, location, detailsByLocationByWorkspace);
}
} else if (change instanceof CreateWorkspaceRequest) {
details.addEventType(ChangeType.NODE_ADDED);
} else if (change instanceof DestroyWorkspaceRequest) {
details.addEventType(ChangeType.NODE_REMOVED);
} else if (change instanceof CloneWorkspaceRequest) {
details.addEventType(ChangeType.NODE_ADDED);
}
}
// Walk through the net changes ...
List<NetChange> netChanges = new LinkedList<NetChange>();
for (Map.Entry<String, Map<Location, NetChangeDetails>> byWorkspaceEntry : detailsByLocationByWorkspace.entrySet()) {
String workspaceName = byWorkspaceEntry.getKey();
// Iterate over the entries. Since we've used a TreeSet, we'll get these with the lower paths first ...
for (Map.Entry<Location, NetChangeDetails> entry : byWorkspaceEntry.getValue().entrySet()) {
Location location = entry.getKey();
NetChangeDetails details = entry.getValue();
netChanges.add(new NetChange(workspaceName, location, details.getEventTypes(), details.getAddedProperties(),
details.getModifiedProperties(), details.getRemovedProperties()));
}
}