com.day.cq.replication.DefaultAggregateHandler Maven / Gradle / Ivy
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2011 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package com.day.cq.replication;
import java.util.LinkedList;
import java.util.List;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.nodetype.NodeType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Implements an aggregate handler that detects hierarchy nodes as aggregate root.
*/
public class DefaultAggregateHandler implements AggregateHandler {
/**
* default logger
*/
private static final Logger log = LoggerFactory.getLogger(DefaultAggregateHandler.class);
/**
* flag that controls if this handler should remove the nodes.
*/
private boolean removeNodes;
/**
* Checks if this handler removes the nodes in the {@link #processForReplication(javax.jcr.Session, ReplicationAction)}
* for a delete replication.
* @return the remove nodes flag.
*/
public boolean isRemoveNodes() {
return removeNodes;
}
/**
* Sets the flag that controls if this handler should remove the node in the
* {@link #processForReplication(javax.jcr.Session, ReplicationAction)}. the default is false
.
* @param removeNodes the flag
*/
public void setRemoveNodes(boolean removeNodes) {
this.removeNodes = removeNodes;
}
/**
* {@inheritDoc}
*
* @return true
if the node is a hierarchy node.
*/
public boolean isAggregateRoot(Node node) {
try {
return node.isNodeType(NodeType.NT_HIERARCHY_NODE);
} catch (RepositoryException e) {
log.warn("Unable to determine aggregate root.", e);
return false;
}
}
/**
* {@inheritDoc}
*
* Returns the all aggregate roots that match {@link #isAggregateRoot(javax.jcr.Node)} recursively, but only
* for DELETE and DEACTIVATE action types.
*/
public List prepareForReplication(Session session, ReplicationActionType type, String path)
throws ReplicationException {
LinkedList paths = new LinkedList();
// only return full tree for delete and deactivate requests
if (type == ReplicationActionType.DELETE || type == ReplicationActionType.DEACTIVATE) {
try {
if (session.nodeExists(path)) {
collectAggregatePaths(session.getNode(path), paths);
} else {
paths.add(path);
}
} catch (RepositoryException e) {
// abort at this stage
throw new ReplicationException("Unable to prepare aggregate roots.", e);
}
} else {
paths.add(path);
}
return paths;
}
/**
* Recursively collects the aggregate roots
* @param root start node
* @param paths list for the paths
* @throws RepositoryException if an error occurrs
*/
protected void collectAggregatePaths(Node root, List paths) throws RepositoryException {
// assume give node is an aggregate root
paths.add(root.getPath());
NodeIterator iter = root.getNodes();
while (iter.hasNext()) {
Node node = iter.nextNode();
if (isAggregateRoot(node)) {
collectAggregatePaths(node, paths);
}
}
}
/**
* {@inheritDoc}
*
* Deletes all paths passed by the action. but only for DELETE actions. The changes are not saved.
*/
public void processForReplication(Session session, ReplicationAction action) throws ReplicationException {
if (action.getType() == ReplicationActionType.DELETE && isRemoveNodes()) {
for (String path: action.getPaths()) {
try {
if (session.nodeExists(path)) {
session.getNode(path).remove();
}
} catch (RepositoryException e) {
log.warn("Unable to remove aggregate at {}: {}", path, e.toString());
}
}
}
}
}