Search in sources :

Example 6 with MergeException

use of javax.jcr.MergeException in project jackrabbit by apache.

the class VersionManagerImplMerge method doMergeTest.

/**
     * Performs the merge test. If the result is 'update', then the corresponding
     * source node is returned. if the result is 'leave' or 'besteffort-fail'
     * then <code>null</code> is returned. If the result of the merge test is
     * 'fail' with bestEffort set to <code>false</code> a MergeException is
     * thrown.
     * <p>
     * jsr170 - 8.2.10 Merge:
     * [...]
     * <ul>
     * <li>If N is currently checked-in then:</li>
     * <ul>
     * <li>If V' is a successor (to any degree) of V, then the merge result
     *     for N is update.
     * </li>
     * <li>If V' is a predecessor (to any degree) of V or if V and
     *     V' are identical (i.e., are actually the same version),
     *     then the merge result for N is leave.
     * </li>
     * <li>If V is neither a successor of, predecessor of, nor
     *     identical with V', then the merge result for N is failed.
     *     This is the case where N and N' represent divergent
     *     branches of the version graph, thus determining the
     *     result of a merge is non-trivial.
     * </li>
     * </ul>
     * <li>If N is currently checked-out then:</li>
     * <ul>
     * <li>If V' is a predecessor (to any degree) of V or if V and
     *     V' are identical (i.e., are actually the same version),
     *     then the merge result for N is leave.
     * </li>
     * <li>If any other relationship holds between V and V',
     *     then the merge result for N is fail.
     * </li>
     * </ul>
     * </ul>
     *
     * @param state state to test
     * @param srcRoot root node state of the source workspace
     * @param failedIds the list to store the failed node ids.
     * @param bestEffort the best effort flag
     * @return the corresponding source node or <code>null</code>
     * @throws RepositoryException if an error occurs.
     * @throws AccessDeniedException if access is denied
     */
private NodeStateEx doMergeTest(NodeStateEx state, NodeStateEx srcRoot, List<ItemId> failedIds, boolean bestEffort) throws RepositoryException, AccessDeniedException {
    // If N does not have a corresponding node then the merge result for N is leave.
    NodeStateEx srcNode = getCorrespondingNode(state, srcRoot);
    if (srcNode == null) {
        return null;
    }
    // if not versionable, update
    if (!state.getEffectiveNodeType().includesNodeType(NameConstants.MIX_VERSIONABLE) || failedIds == null) {
        return srcNode;
    }
    // if source node is not versionable, leave
    if (!srcNode.getEffectiveNodeType().includesNodeType(NameConstants.MIX_VERSIONABLE)) {
        return null;
    }
    // test versions. the following code could be simplified but is
    // intentionally expanded for follow the spec.
    InternalVersion v = getBaseVersion(state);
    InternalVersion vp = getBaseVersion(srcNode);
    if (!isCheckedOut(state)) {
        // If N is currently checked-in then:
        if (vp.isMoreRecent(v)) {
            // - If V' is an eventual successor of V, then the merge result for N is update.
            return srcNode;
        } else if (v.equals(vp) || v.isMoreRecent(vp)) {
            // actually the same version), then the merge result for N is leave.
            return null;
        }
    // - If V is neither an eventual successor of, eventual predecessor of, nor
    // identical with V', then the merge result for N is failed. This is the case
    // where N and N' represent divergent branches of the version graph.
    // failed is covered below
    } else {
        // If N is currently checked-out then:
        if (v.equals(vp) || v.isMoreRecent(vp)) {
            //   N is leave.
            return null;
        }
    // - If any other relationship holds between V and V', then the merge result
    //   for N is fail.
    // failed is covered below
    }
    if (vp.isMoreRecent(v) && !isCheckedOut(state)) {
        // "newer" than N and therefore N should be updated to reflect N'.
        return srcNode;
    } else if (v.equals(vp) || v.isMoreRecent(vp)) {
        // N' is "older" or the "same age" as N and therefore N should be left alone.
        return null;
    } else {
        // thus determining the result of a merge is non-trivial.
        if (bestEffort) {
            // add 'offending' version to jcr:mergeFailed property
            Set<NodeId> set = getMergeFailed(state);
            set.add(vp.getId());
            setMergeFailed(state, set);
            failedIds.add(state.getNodeId());
            state.store();
            return null;
        } else {
            String msg = "Unable to merge nodes. Violating versions. " + safeGetJCRPath(state);
            log.debug(msg);
            throw new MergeException(msg);
        }
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) MergeException(javax.jcr.MergeException)

Example 7 with MergeException

use of javax.jcr.MergeException in project jackrabbit by apache.

the class MergeNodeTest method testMergeNodeBestEffortFalse.

/**
     * Node.merge(): bestEffort is false and any merge fails a MergeException is
     * thrown.<br>
     */
@SuppressWarnings("deprecation")
public void testMergeNodeBestEffortFalse() throws RepositoryException {
    /// create successor versions for a node
    // so merge fails for this node
    // default workspace
    Node originalNode = testRootNode.getNode(nodeName1);
    originalNode.checkout();
    originalNode.checkin();
    // merge, besteffort set to false
    try {
        nodeToMerge.merge(workspace.getName(), false);
        fail("bestEffort is false and any merge should throw a MergeException.");
    } catch (MergeException e) {
    // successful
    }
}
Also used : MergeException(javax.jcr.MergeException) Node(javax.jcr.Node)

Example 8 with MergeException

use of javax.jcr.MergeException in project jackrabbit by apache.

the class MergeCheckedoutSubNodeTest method testFailIfCorrespondingNodeIsSuccessorJcr2.

/**
     * VersionManager.merge(): If V' of a versionable subnode N' in the source workspace
     * is a successor of V (the base version of a subnode N in this workspace),
     * calling merge must fail.
     */
public void testFailIfCorrespondingNodeIsSuccessorJcr2() throws RepositoryException {
    // make V' of a subnode N' in source workspace be a successor version of
    // the base version of the corresponding subnode.
    Node n = testRootNode.getNode(nodeName1 + "/" + nodeName2);
    VersionManager versionManager = n.getSession().getWorkspace().getVersionManager();
    String path = n.getPath();
    versionManager.checkout(path);
    versionManager.checkin(path);
    versionManager.checkout(path);
    try {
        // merge, besteffort set to false to stop at the first failure
        nodeToMerge.getSession().getWorkspace().getVersionManager().merge(nodeToMerge.getPath(), workspace.getName(), false);
        fail("Merging a checkedout node if the version V' of the corresponding node is a successor of this node's base version must fail.");
    } catch (MergeException e) {
    // success
    }
}
Also used : MergeException(javax.jcr.MergeException) Node(javax.jcr.Node) VersionManager(javax.jcr.version.VersionManager)

Example 9 with MergeException

use of javax.jcr.MergeException in project jackrabbit by apache.

the class MergeNodeTest method testMergeNodeBestEffortFalseAmbiguousVersions.

/**
     * A MergeVersionException is thrown if bestEffort is false and a
     * versionable node is encountered whose corresponding node's base version
     * is on a divergent branch from this node's base version.
     */
@SuppressWarnings("deprecation")
public void testMergeNodeBestEffortFalseAmbiguousVersions() throws RepositoryException {
    /// create 2 independent base versions for a node and its corresponding node
    // so merge fails for this node
    // default workspace
    Node originalNode = testRootNode.getNode(nodeName1);
    originalNode.checkout();
    originalNode.checkin();
    // second workspace
    nodeToMerge.checkin();
    // "merge" the clonedNode with the newNode from the default workspace
    nodeToMerge.checkout();
    // merge, besteffort set to false
    try {
        nodeToMerge.merge(workspace.getName(), false);
        fail("BestEffort is false and corresponding node's version is ambiguous. Merge should throw a MergeException.");
    } catch (MergeException e) {
    // successful
    }
}
Also used : MergeException(javax.jcr.MergeException) Node(javax.jcr.Node)

Aggregations

MergeException (javax.jcr.MergeException)9 Node (javax.jcr.Node)8 VersionManager (javax.jcr.version.VersionManager)4 HashSet (java.util.HashSet)1 Set (java.util.Set)1