diff --git a/magnolia-core/src/main/java/info/magnolia/jcr/nodebuilder/Ops.java b/magnolia-core/src/main/java/info/magnolia/jcr/nodebuilder/Ops.java index 66ab480..cefe0ff 100644 --- a/magnolia-core/src/main/java/info/magnolia/jcr/nodebuilder/Ops.java +++ b/magnolia-core/src/main/java/info/magnolia/jcr/nodebuilder/Ops.java @@ -33,14 +33,26 @@ */ package info.magnolia.jcr.nodebuilder; +import info.magnolia.jcr.iterator.FilteringNodeIterator; +import info.magnolia.jcr.predicate.AbstractPredicate; +import info.magnolia.jcr.predicate.NodeTypePredicate; import info.magnolia.jcr.util.NodeUtil; import info.magnolia.jcr.util.PropertyUtil; +import java.util.ArrayList; +import java.util.List; + import javax.jcr.ItemExistsException; import javax.jcr.ItemNotFoundException; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Value; +import javax.jcr.nodetype.NodeType; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.jackrabbit.commons.predicate.Predicate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Factory methods for most common NodeOperation implementations. @@ -172,4 +184,143 @@ public abstract class Ops { } }; } + + public static final NodeOperation getOrAddNode(final String name, final String nodeType) { + return new AbstractNodeOperation() { + + @Override + protected Node doExec(Node context, ErrorHandler errorHandler) throws RepositoryException { + if (context.hasNode(name)) { + return context.getNode(name); + } else { + return context.addNode(name, nodeType); + } + } + }; + } + + public static final NodeOperation conditional(final Predicate predicate, final NodeOperation ifTrue, final NodeOperation ifFalse) { + return new AbstractNodeOperation() { + // yes we do want to log into ANO logger + private final Logger log = LoggerFactory.getLogger(AbstractNodeOperation.class); + + private List childrenOps = new ArrayList(); + private boolean isTrue = false; + + @Override + protected Node doExec(Node context, ErrorHandler errorHandler) throws RepositoryException { + isTrue = predicate.evaluate(context); + return context; + } + + @Override + public void exec(Node context, ErrorHandler errorHandler) { + Node execResult = context; + try { + execResult = doExec(execResult, errorHandler); + } catch (RepositoryException e) { + try { + errorHandler.handle(e, execResult); + } catch (RepositoryException e1) { + log.warn("Could not handle original exception {} because of: ", e.getMessage(), e1); + } + } + if (isTrue) { + if (ifTrue != null) { + ifTrue.exec(context, errorHandler); + } + } else { + if (ifFalse != null) { + ifFalse.exec(context, errorHandler); + } + } + + for (NodeOperation childrenOp : childrenOps) { + childrenOp.exec(execResult, errorHandler); + } + } + + @Override + public NodeOperation then(NodeOperation... childrenOps) { + // add the operations to allow multiple calls on the method. + CollectionUtils.addAll(this.childrenOps, childrenOps); + return this; + } + + }; + } + + public static final NodeOperation onEachChild() { + return onEachChild(new NodeTypePredicate(NodeType.NT_BASE, true)); + } + + public static final NodeOperation onEachChild(final AbstractPredicate predicate) { + return new AbstractNodeOperation() { + // yes we do want to log into ANO logger + private final Logger log = LoggerFactory.getLogger(AbstractNodeOperation.class); + + private List childrenOps = new ArrayList(); + + @Override + protected Node doExec(Node context, ErrorHandler errorHandler) throws RepositoryException { + return context; + } + + @Override + public void exec(Node context, ErrorHandler errorHandler) { + try { + FilteringNodeIterator iter = new FilteringNodeIterator(context.getNodes(), predicate); + while (iter.hasNext()) { + for (NodeOperation childrenOp : childrenOps) { + childrenOp.exec(iter.nextNode(), errorHandler); + } + } + } catch (RepositoryException e) { + try { + errorHandler.handle(e, context); + } catch (RepositoryException e1) { + log.warn("Could not handle original exception {} because of: ", e.getMessage(), e1); + } + } + + } + + @Override + public NodeOperation then(NodeOperation... childrenOps) { + // add the operations to allow multiple calls on the method. + CollectionUtils.addAll(this.childrenOps, childrenOps); + return this; + } + + }; + } + + public static final NodeOperation ifTrue(final boolean bool) { + return new AbstractNodeOperation() { + + private List childrenOps = new ArrayList(); + + @Override + protected Node doExec(Node context, ErrorHandler errorHandler) throws RepositoryException { + return context; + } + + @Override + public void exec(Node context, ErrorHandler errorHandler) { + if (bool) { + for (NodeOperation childrenOp : childrenOps) { + childrenOp.exec(context, errorHandler); + } + } + } + + @Override + public NodeOperation then(NodeOperation... childrenOps) { + // add the operations to allow multiple calls on the method. + CollectionUtils.addAll(this.childrenOps, childrenOps); + return this; + } + + }; + } }