Package org.apache.jackrabbit.core.version

Source Code of org.apache.jackrabbit.core.version.JcrVersionManagerImpl$ChangeSetVersionSelector

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jackrabbit.core.version;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.version.Version;
import javax.jcr.version.VersionHistory;

import org.apache.jackrabbit.core.id.ItemId;
import org.apache.jackrabbit.core.LazyItemIterator;
import org.apache.jackrabbit.core.id.NodeId;
import org.apache.jackrabbit.core.NodeImpl;
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.spi.commons.name.NameConstants;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;

/**
* Implementation of the {@link javax.jcr.version.VersionManager}.
* <p/>
* Note: For a cleaner architecture, we should probably rename the existing classes
* that implement the internal version manager, and name this VersionManagerImpl.
*/
public class JcrVersionManagerImpl implements javax.jcr.version.VersionManager {

    /**
     * default logger
     */
    private static final Logger log = LoggerFactory.getLogger(JcrVersionManagerImpl.class);

    /**
     * workspace session
     */
    private final SessionImpl session;

    /**
     * the node id of the current activity
     */
    private NodeId currentActivity;


    /**
     * Creates a new version manager for the given session
     * @param session workspace sesion
     */
    public JcrVersionManagerImpl(SessionImpl session) {
        this.session = session;
    }

    /**
     * {@inheritDoc}
     */
    public Version checkin(String absPath) throws RepositoryException {
        return session.getNode(absPath).checkin();
    }

    /**
     * {@inheritDoc}
     */
    public void checkout(String absPath) throws RepositoryException {
        session.getNode(absPath).checkout();
    }

    /**
     * {@inheritDoc}
     */
    public Version checkpoint(String absPath) throws RepositoryException {
        // this is not quite correct, since the entire checkpoint operation
        // should be atomic
        Node node = session.getNode(absPath);
        Version v = node.checkin();
        node.checkout();
        return v;
    }

    /**
     * {@inheritDoc}
     */
    public boolean isCheckedOut(String absPath) throws RepositoryException {
        return session.getNode(absPath).isCheckedOut();
    }

    /**
     * {@inheritDoc}
     */
    public VersionHistory getVersionHistory(String absPath)
            throws RepositoryException {
        return session.getNode(absPath).getVersionHistory();
    }

    /**
     * {@inheritDoc}
     */
    public Version getBaseVersion(String absPath)
            throws RepositoryException {
        return session.getNode(absPath).getBaseVersion();
    }

    /**
     * {@inheritDoc}
     */
    public void restore(Version[] versions, boolean removeExisting)
            throws RepositoryException {
        session.getWorkspace().restore(versions, removeExisting);
    }

    /**
     * {@inheritDoc}
     */
    public void restore(String absPath, String versionName,
                        boolean removeExisting)
            throws RepositoryException {
        session.getNode(absPath).restore(versionName, removeExisting);
    }

    /**
     * {@inheritDoc}
     */
    public void restore(Version version, boolean removeExisting)
            throws RepositoryException {
        session.getWorkspace().restore(new Version[]{version}, removeExisting);
    }

    /**
     * {@inheritDoc}
     */
    public void restore(String absPath, Version version, boolean removeExisting)
            throws RepositoryException {
        session.getNode(absPath).restore(version, removeExisting);
    }

    /**
     * {@inheritDoc}
     */
    public void restoreByLabel(String absPath, String versionLabel,
                               boolean removeExisting)
            throws RepositoryException {
        session.getNode(absPath).restoreByLabel(versionLabel, removeExisting);
    }

    /**
     * {@inheritDoc}
     */
    public NodeIterator merge(String absPath, String srcWorkspace,
                              boolean bestEffort)
            throws RepositoryException {
        return ((NodeImpl) session.getNode(absPath))
                .merge(srcWorkspace, bestEffort, false);
    }

    /**
     * {@inheritDoc}
     */
    public NodeIterator merge(String absPath, String srcWorkspace,
                              boolean bestEffort, boolean isShallow)
            throws RepositoryException {
        return ((NodeImpl) session.getNode(absPath))
                .merge(srcWorkspace, bestEffort, isShallow);
    }

    /**
     * {@inheritDoc}
     */
    public void doneMerge(String absPath, Version version)
            throws RepositoryException {
        session.getNode(absPath).doneMerge(version);
    }

    /**
     * {@inheritDoc}
     */
    public void cancelMerge(String absPath, Version version)
            throws RepositoryException {
        session.getNode(absPath).cancelMerge(version);
    }

    /**
     * {@inheritDoc}
     */
    public Node createConfiguration(String absPath, Version baseline)
            throws RepositoryException {
        throw new UnsupportedRepositoryOperationException("comming soon...");
    }

    /**
     * {@inheritDoc}
     */
    public Node setActivity(Node activity) throws RepositoryException {
        Node oldActivity = getActivity();
        if (activity == null) {
            currentActivity = null;
        } else {
            NodeImpl actNode = (NodeImpl) activity;
            if (!actNode.isNodeType(NameConstants.NT_ACTIVITY)) {
                throw new UnsupportedRepositoryOperationException("Given node is not an activity.");
            }
            currentActivity = actNode.getNodeId();
        }
        return oldActivity;
    }

    /**
     * {@inheritDoc}
     */
    public Node getActivity() throws RepositoryException {
        if (currentActivity == null) {
            return null;
        } else {
            return session.getNodeById(currentActivity);
        }
    }

    /**
     * {@inheritDoc}
     */
    public Node createActivity(String title) throws RepositoryException {
        NodeId id = session.getVersionManager().createActivity(session, title);
        return session.getNodeById(id);
    }

    /**
     * {@inheritDoc}
     */
    public void removeActivity(Node node) throws RepositoryException {
        NodeImpl actNode = (NodeImpl) node;
        if (!actNode.isNodeType(NameConstants.NT_ACTIVITY)) {
            throw new UnsupportedRepositoryOperationException("Given node is not an activity.");
        }
        NodeId actId = actNode.getNodeId();
        session.getVersionManager().removeActivity(session, actId);
        if (actId.equals(currentActivity)) {
            currentActivity = null;
        }
    }

    /**
     * {@inheritDoc}
     */
    public NodeIterator merge(Node activityNode) throws RepositoryException {
        NodeImpl actNode = (NodeImpl) activityNode;
        if (!actNode.isNodeType(NameConstants.NT_ACTIVITY)) {
            throw new UnsupportedRepositoryOperationException("Given node is not an activity.");
        }
        InternalActivity activity = session.getVersionManager().getActivity(actNode.getNodeId());
        if (activity == null) {
            throw new UnsupportedRepositoryOperationException("Given activity not found.");
        }
        boolean success = false;
        try {
            NodeIterator ret = internalMerge(activity);
            session.save();
            success = true;
            return ret;
        } finally {
            if (!success) {
                // revert session
                try {
                    log.debug("reverting changes applied during merge...");
                    session.refresh(false);
                } catch (RepositoryException e) {
                    log.error("Error while reverting changes applied merge restore.", e);
                }
            }
        }
    }

    /**
     * Internally does the merge without saving the changes.
     * @param activity internal activity
     * @throws RepositoryException if an error occurs
     * @return a node iterator of all failed nodes
     */
    private NodeIterator internalMerge(InternalActivity activity)
            throws RepositoryException {
        List<ItemId> failedIds = new ArrayList<ItemId>();
        Map<NodeId, InternalVersion> changeSet = activity.getChangeSet();
        ChangeSetVersionSelector vsel = new ChangeSetVersionSelector(changeSet);
        Iterator<NodeId> iter = changeSet.keySet().iterator();
        while (iter.hasNext()) {
            InternalVersion v = changeSet.remove(iter.next());
            NodeId nodeId = new NodeId(v.getVersionHistory().getVersionableUUID());
            try {
                NodeImpl node = session.getNodeById(nodeId);
                InternalVersion base = ((VersionImpl) node.getBaseVersion()).getInternalVersion();
                VersionImpl version = (VersionImpl) session.getNodeById(v.getId());
                // if base version is newer than version, add to failed list
                // but merge it anyways
                if (base.isMoreRecent(version.getInternalVersion())) {
                    failedIds.add(node.getNodeId());
                    // should we add it to the jcr:mergeFailed property ?
                } else {
                    Version[] vs = node.internalRestore(version, vsel, true);
                    for (Version restored: vs) {
                        changeSet.remove(((VersionImpl) restored).getNodeId());
                    }
                }
            } catch (ItemNotFoundException e) {
                // ignore nodes not present in this workspace (not best practice)
            }

            // reset iterator
            iter = changeSet.keySet().iterator();
        }
        return new LazyItemIterator(session.getItemManager(), failedIds);
    }

    /**
     * Internal version selector that selects the version in the changeset.
     */
    private class ChangeSetVersionSelector implements VersionSelector {

        private final Map<NodeId, InternalVersion> changeSet;

        private ChangeSetVersionSelector(Map<NodeId, InternalVersion> changeSet) {
            this.changeSet = changeSet;
        }

        public Version select(VersionHistory vh) throws RepositoryException {
            InternalVersion v = changeSet.get(((VersionHistoryImpl) vh).getNodeId());
            if (v != null) {
                return (Version) session.getNodeById(v.getId());
            } else {
                return null;
            }
        }
    }
}
TOP

Related Classes of org.apache.jackrabbit.core.version.JcrVersionManagerImpl$ChangeSetVersionSelector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.