package jackrabbit.node; import jackrabbit.util.NodeUtils; import java.util.Map.Entry; import java.util.AbstractMap; import java.util.Comparator; import java.util.Map; import java.util.Set; import java.util.TreeSet; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.RepositoryException; public class NodeSizePartitioner implements NodePartitioner { private long limit; public NodeSizePartitioner(long limit) { this.limit=limit; } /** * Partition a node based on the size of a node (and its descendants) * @param node * @param limit * @return a sorted set of Map.Entry with key being the path of a node in the partition and value a Boolean indicating whether the node size * exceeds the limit or not * @throws RepositoryException */ public Set<Entry<String, Boolean>> partition(Node node) throws RepositoryException { Set<Map.Entry<String, Boolean>> descendants = new TreeSet<Map.Entry<String, Boolean>>(new Comparator<Map.Entry<String, Boolean>>() { public int compare(Map.Entry<String, Boolean> a, Map.Entry<String, Boolean> b) { if (a.getValue()==b.getValue()) return (a.getKey().toString().toLowerCase()).compareTo(b.getKey().toString().toLowerCase()); else return -(a.getValue().toString().toLowerCase()).compareTo(b.getValue().toString().toLowerCase()); } }); long size=NodeUtils.getPropertiesSize(node); NodeIterator children = node.getNodes(); while (children.hasNext()) { Node child=children.nextNode(); long descendantsSize=NodeUtils.getDescendantsSize(child); if (descendantsSize < limit) { descendants.add(new AbstractMap.SimpleEntry<String, Boolean>(child.getPath(), false)); } else { descendants.addAll(partition(child)); } size+=descendantsSize; } if (size < limit){ descendants.clear(); descendants.add(new AbstractMap.SimpleEntry<String, Boolean>(node.getPath(), false)); } else { descendants.add(new AbstractMap.SimpleEntry<String, Boolean>(node.getPath(), true)); } return descendants; } }