Package org.jahia.services.content

Source Code of org.jahia.services.content.JCRWorkspaceWrapper$VersionManagerWrapper

/**
* This file is part of Jahia, next-generation open source CMS:
* Jahia's next-generation, open source CMS stems from a widely acknowledged vision
* of enterprise application convergence - web, search, document, social and portal -
* unified by the simplicity of web content management.
*
* For more information, please visit http://www.jahia.com.
*
* Copyright (C) 2002-2011 Jahia Solutions Group SA. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* As a special exception to the terms and conditions of version 2.0 of
* the GPL (or any later version), you may redistribute this Program in connection
* with Free/Libre and Open Source Software ("FLOSS") applications as described
* in Jahia's FLOSS exception. You should have received a copy of the text
* describing the FLOSS exception, and it is also available here:
* http://www.jahia.com/license
*
* Commercial and Supported Versions of the program (dual licensing):
* alternatively, commercial and supported versions of the program may be used
* in accordance with the terms and conditions contained in a separate
* written agreement between you and Jahia Solutions Group SA.
*
* If you are unsure which license is appropriate for your use,
* please contact the sales department at sales@jahia.com.
*/

package org.jahia.services.content;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.jahia.api.Constants;
import org.jahia.services.content.decorator.JCRVersion;
import org.jahia.services.content.nodetypes.NodeTypeRegistry;
import org.jahia.services.query.QueryManagerImpl;
import org.xml.sax.ContentHandler;

import javax.jcr.*;
import javax.jcr.lock.LockException;
import javax.jcr.lock.LockManager;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.observation.ObservationManager;
import javax.jcr.query.*;
import javax.jcr.version.Version;
import javax.jcr.version.VersionException;
import javax.jcr.version.VersionHistory;
import javax.jcr.version.VersionManager;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.GregorianCalendar;
import java.util.List;

/**
* Jahia specific wrapper around <code>javax.jcr.Workspace</code> to be able to inject
* Jahia specific actions and to manage workspaces on multiple repository providers in
* the backend.
*
* Jahia services should use this wrapper rather than the original workspace interface to
* ensure that we manipulate wrapped nodes and not the ones from the underlying
* implementation.
*
* @author toto
*/
public class JCRWorkspaceWrapper implements Workspace {
    private static Logger logger = org.slf4j.LoggerFactory.getLogger(JCRWorkspaceWrapper.class);
    private JCRSessionFactory service;
    private String name;
    private JCRSessionWrapper session;
    private JCRObservationManager observationManager;

    public JCRWorkspaceWrapper(String name, JCRSessionWrapper session, JCRSessionFactory service) {
        this.name = name;
        this.service = service;
        this.session = session;
    }

    public JCRSessionWrapper getSession() {
        return session;
    }

    public String getName() {
        return name;
    }

    public void copy(String source, String dest) throws ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException {
        final JCRStoreProvider provider = service.getProvider(source);
        JCRStoreProvider destProvider = service.getProvider(dest);
        if (destProvider != provider) {
            throw new UnsupportedRepositoryOperationException();
        } else {
            if (provider.getMountPoint().length()>1) {
                dest = dest.substring(provider.getMountPoint().length());
                source = source.substring(provider.getMountPoint().length());
            }
            final String fSource = source;
            final String fDest = dest;
            JCRObservationManager.doWorkspaceWriteCall(getSession(), JCRObservationManager.WORKSPACE_COPY, new JCRCallback<Object>() {
                public Object doInJCR(JCRSessionWrapper session) throws RepositoryException {
                    session.getProviderSession(provider).getWorkspace().copy(fSource, fDest);
                    return null;
                }
            });
        }
    }

    public void copy(final String srcWs, String source, String dest) throws NoSuchWorkspaceException, ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException {
        final JCRStoreProvider provider = service.getProvider(source);
        JCRStoreProvider destProvider = service.getProvider(dest);
        if (destProvider != provider) {
            throw new UnsupportedRepositoryOperationException();
        } else {
            if (provider.getMountPoint().length()>1) {
                dest = dest.substring(provider.getMountPoint().length());
                source = source.substring(provider.getMountPoint().length());
            }
            final String fSource = source;
            final String fDest = dest;
            JCRObservationManager.doWorkspaceWriteCall(getSession(), JCRObservationManager.WORKSPACE_COPY, new JCRCallback<Object>() {
                public Object doInJCR(JCRSessionWrapper session) throws RepositoryException {
                    session.getProviderSession(provider).getWorkspace().copy(srcWs, fSource, fDest);
                    return null;
                }
            });
        }
        throw new UnsupportedRepositoryOperationException();
    }

    public void clone(final String srcWs, String source, String dest, final boolean removeExisting) throws NoSuchWorkspaceException, ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException {
        final JCRStoreProvider provider = service.getProvider(source);
        JCRStoreProvider destProvider = service.getProvider(dest);
        if (destProvider != provider) {
            throw new UnsupportedRepositoryOperationException();
        } else {
            if (provider.getMountPoint().length()>1) {
                dest = dest.substring(provider.getMountPoint().length());
                source = source.substring(provider.getMountPoint().length());
            }
            final String fSource = source;
            final String fDest = dest;
            JCRObservationManager.doWorkspaceWriteCall(getSession(), JCRObservationManager.WORKSPACE_CLONE, new JCRCallback<Object>() {
                public Object doInJCR(JCRSessionWrapper session) throws RepositoryException {
                    session.getProviderSession(provider).getWorkspace().clone(srcWs,fSource,fDest,removeExisting);
                    return null;
                }
            });
        }
    }

    public void move(String source, String dest) throws ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException {
        move(source, dest, false);
    }

    void move(String source, String dest, final boolean sessionMove) throws ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException {
        final JCRStoreProvider provider = service.getProvider(source);
        JCRStoreProvider destProvider = service.getProvider(dest);
        if (destProvider != provider) {
            try {
                session.getItem(dest);
                throw new ItemExistsException(dest);
            } catch (RepositoryException e) {
            }

            copy(source,dest);
            session.getItem(source).remove();
        } else {
            if (provider.getMountPoint().length()>1) {
                dest = dest.substring(provider.getMountPoint().length());
                source = source.substring(provider.getMountPoint().length());
            }
            final String sourcePath = source;
            Node sourceNode = session.getProviderSession(provider).getNode(source);
            if (sourceNode.isNodeType("jmix:shareable")) {
                final String destination = dest;
                final JCRCallback<Object> callback = new JCRCallback<Object>() {
                    public Object doInJCR(JCRSessionWrapper session) throws RepositoryException {
                        JCRNodeWrapper sourceNode = session.getNode(sourcePath);
                        JCRNodeWrapper parentNode = session.getNode(StringUtils.substringBeforeLast(destination,"/"));
                        String sourceParentPath = StringUtils.substringBeforeLast(sourcePath,"/");
                        if (parentNode.getPath().equals(sourceParentPath)) {
                            // rename case
                            JCRNodeWrapper userFolder = session.getNode(JCRStoreService.getInstance().getUserFolder(
                                    session.getUser()).getPath());
                            if (!userFolder.hasNode("tmp")) {
                                if (!userFolder.isCheckedOut()) {
                                    session.checkout(userFolder);
                                }
                                userFolder.addNode("tmp", "jnt:contentList");
                            }
                            JCRNodeWrapper newSourceNode = userFolder.getNode("tmp").clone(sourceNode, sourceNode.getIdentifier());
                            sourceNode.removeShare();
                            sourceNode = newSourceNode;
                        }
                        parentNode.clone(sourceNode, StringUtils.substringAfterLast(destination,"/"));
                        List<Value> values = new ArrayList<Value>();
                        String v = sourcePath + ":::" + destination;
                        if (sourceNode.hasProperty("j:movedFrom")) {
                            values.addAll(Arrays.asList(sourceNode.getProperty("j:movedFrom").getValues()));
                            for (Value value : values) {
                                String s = value.getString();
                                if (s.endsWith(":::"+sourcePath)) {
                                    v = StringUtils.substringBefore(s,":::") + ":::" + destination;
                                    values.remove(value);
                                    break;
                                }
                            }
                        }
                        values.add(getSession().getValueFactory().createValue(v));
                        sourceNode.setProperty("j:movedFrom", values.toArray(new Value[values.size()]));
                        sourceNode.removeShare();
                        if (parentNode.isNodeType("mix:lastModified")) {
                            parentNode.setProperty(Constants.JCR_LASTMODIFIED, new GregorianCalendar());
                            parentNode.setProperty(Constants.JCR_LASTMODIFIEDBY, session.getUser().getUsername());
                        }

                        if (!sessionMove) {
                            session.save();
                        }
                        return null;
                    }
                };
                if (sessionMove) {
                    callback.doInJCR(session);
                } else {
                    JCRTemplate.getInstance().doExecute(session.isSystem(), session.getUser().getUsername(), getName(), session.getLocale(), new JCRCallback<Object>() {
                        public Object doInJCR(JCRSessionWrapper session) throws RepositoryException {
                            return JCRObservationManager.doWorkspaceWriteCall(session, JCRObservationManager.WORKSPACE_MOVE, callback);
                        }
                    });
                }
            } else {
                if (sessionMove) {
                    session.getProviderSession(provider).move(source, dest);
                } else {
                    final String fSource = source;
                    final String fDest = dest;
                    JCRObservationManager.doWorkspaceWriteCall(getSession(), JCRObservationManager.WORKSPACE_MOVE, new JCRCallback<Object>() {
                        public Object doInJCR(JCRSessionWrapper session) throws RepositoryException {
                            session.getProviderSession(provider).getWorkspace().move(fSource, fDest);
                            return null;
                        }
                    });
                }
            }
        }
    }

    public void restore(Version[] versions, boolean b) throws ItemExistsException, UnsupportedRepositoryOperationException, VersionException, LockException, InvalidItemStateException, RepositoryException {
        throw new UnsupportedRepositoryOperationException();
    }

    public QueryManager getQueryManager() {
        return new QueryManagerImpl(session, service);
    }

    public NamespaceRegistry getNamespaceRegistry() throws RepositoryException {
        return service.getNamespaceRegistry();
    }

    public NodeTypeManager getNodeTypeManager() throws RepositoryException {
        return NodeTypeRegistry.getInstance();
    }

    public ObservationManager getObservationManager() throws UnsupportedRepositoryOperationException, RepositoryException {
        if (observationManager == null) {
            this.observationManager = new JCRObservationManager(this);
        }
        return observationManager;
    }

    public String[] getAccessibleWorkspaceNames() throws RepositoryException {
        return new String[0]//To change body of implemented methods use File | Settings | File Templates.
    }

    public ContentHandler getImportContentHandler(String s, int i) throws PathNotFoundException, ConstraintViolationException, VersionException, LockException, AccessDeniedException, RepositoryException {
        throw new UnsupportedRepositoryOperationException();
    }

    public void importXML(String s, InputStream inputStream, int i) throws IOException, PathNotFoundException, ItemExistsException, ConstraintViolationException, InvalidSerializedDataException, LockException, AccessDeniedException, RepositoryException {
        throw new UnsupportedRepositoryOperationException();
    }

    public LockManager getLockManager() throws UnsupportedRepositoryOperationException, RepositoryException {
        throw new UnsupportedRepositoryOperationException();
    }

    public VersionManager getVersionManager() throws UnsupportedRepositoryOperationException, RepositoryException {
        return new VersionManagerWrapper(getSession().getProviderSession(service.getProvider("/")).getWorkspace().getVersionManager());
    }

    public void createWorkspace(String name) throws AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
        throw new UnsupportedRepositoryOperationException();
    }

    public void createWorkspace(String name, String srcWorkspace) throws AccessDeniedException, UnsupportedRepositoryOperationException, NoSuchWorkspaceException, RepositoryException {
        throw new UnsupportedRepositoryOperationException();
    }

    public void deleteWorkspace(String name) throws AccessDeniedException, UnsupportedRepositoryOperationException, NoSuchWorkspaceException, RepositoryException {
        throw new UnsupportedRepositoryOperationException();
    }

    class VersionManagerWrapper implements VersionManager {
        private VersionManager versionManager;

        VersionManagerWrapper(VersionManager versionManager) {
            this.versionManager = versionManager;
        }

        public JCRVersion checkin(final String absPath) throws VersionException, UnsupportedRepositoryOperationException, InvalidItemStateException, LockException, RepositoryException {
            logger.debug("Checkin "+absPath  +" in "+getName()+", was "+getBaseVersion(absPath).getName());
            return JCRObservationManager.doWorkspaceWriteCall(getSession(), JCRObservationManager.NODE_CHECKIN, new JCRCallback<JCRVersion>() {
                public JCRVersion doInJCR(JCRSessionWrapper session) throws RepositoryException {
                    try {
                        JCRNodeWrapper node = session.getNode(absPath);
                        JCRVersion result = (JCRVersion) node.getProvider().getNodeWrapper(versionManager.checkin(node.getRealNode().getPath()), session);

                        if (session.getLocale() != null) {
                            try {
                                versionManager.checkin(node.getI18N(session.getLocale()).getPath());
                            } catch (ItemNotFoundException e) {
                            }
                        }

                        return result;
                    } finally {
                        logger.debug(" now "+getBaseVersion(absPath).getName());
                    }
                }
            });
        }

        public void checkout(final String absPath) throws UnsupportedRepositoryOperationException, LockException, RepositoryException {
            logger.debug("Checkout "+absPath +" in "+getName());
            JCRObservationManager.doWorkspaceWriteCall(getSession(), JCRObservationManager.NODE_CHECKOUT, new JCRCallback<Object>() {
                public Object doInJCR(JCRSessionWrapper session) throws RepositoryException {
                    JCRNodeWrapper node = session.getNode(absPath,false);
                    if (!node.getRealNode().isLocked() || session.isSystem()) {
                        versionManager.checkout(node.getRealNode().getPath());
                    }

                    if (session.getLocale() != null) {
                        try {
                            final Node i18n = node.getI18N(session.getLocale());
                            if (!i18n.isLocked() || session.isSystem()) {
                                versionManager.checkout(i18n.getPath());
                            }
                        } catch (ItemNotFoundException e) {
                        }
                    }

                    return null;
                }
            });
        }

        public Version checkpoint(final String absPath) throws VersionException, UnsupportedRepositoryOperationException, InvalidItemStateException, LockException, RepositoryException {
            return JCRObservationManager.doWorkspaceWriteCall(getSession(), JCRObservationManager.NODE_CHECKPOINT, new JCRCallback<Version>() {
                public Version doInJCR(JCRSessionWrapper session) throws RepositoryException {
                    return versionManager.checkpoint(absPath);
                }
            });
        }

        public boolean isCheckedOut(String absPath) throws RepositoryException {
            boolean result = true;
            JCRNodeWrapper node = getSession().getNode(absPath);
            if (getSession().getLocale() != null) {
                try {
                    result = versionManager.isCheckedOut(node.getI18N(getSession().getLocale()).getPath());
                } catch (ItemNotFoundException e) {
                }
            }
            result &= versionManager.isCheckedOut(absPath);
            return result;
        }

        public VersionHistory getVersionHistory(String absPath) throws UnsupportedRepositoryOperationException, RepositoryException {
            return (VersionHistory) session.getNode(absPath).getProvider().getNodeWrapper(versionManager.getVersionHistory(absPath), session);
        }

        public Version getBaseVersion(String absPath) throws UnsupportedRepositoryOperationException, RepositoryException {
            return versionManager.getBaseVersion(absPath);
        }

        public void restore(final Version[] versions, final boolean removeExisting) throws ItemExistsException,
                UnsupportedRepositoryOperationException, VersionException, LockException, InvalidItemStateException,
                RepositoryException {
            JCRObservationManager.doWorkspaceWriteCall(getSession(), JCRObservationManager.NODE_RESTORE,
                    new JCRCallback<Object>() {
                        public Object doInJCR(JCRSessionWrapper session) throws RepositoryException {
                            Version[] undecoratedVersions = new Version[(versions.length)];
                            int i = 0;
                            for (Version version : versions) {
                                undecoratedVersions[i++] = version instanceof JCRVersion ? ((JCRVersion) version)
                                        .getRealNode() : version;
                            }
                            versionManager.restore(undecoratedVersions, removeExisting);
                            return null;
                        }
                    });
            getSession().flushCaches();
        }

        public void restore(final String absPath, final String versionName, final boolean removeExisting) throws VersionException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
            JCRObservationManager.doWorkspaceWriteCall(getSession(), JCRObservationManager.NODE_RESTORE, new JCRCallback<Object>() {
                public Object doInJCR(JCRSessionWrapper session) throws RepositoryException {
                    versionManager.restore(absPath, versionName, removeExisting);
                    return null;
                }
            });
            getSession().flushCaches();
        }

        public void restore(final Version version, final boolean removeExisting) throws VersionException, ItemExistsException, InvalidItemStateException, UnsupportedRepositoryOperationException, LockException, RepositoryException {
            JCRObservationManager.doWorkspaceWriteCall(getSession(), JCRObservationManager.NODE_RESTORE, new JCRCallback<Object>() {
                public Object doInJCR(JCRSessionWrapper session) throws RepositoryException {
                    versionManager.restore(version instanceof JCRVersion ? ((JCRVersion) version).getRealNode() : version, removeExisting);
                    return null;
                }
            });
            getSession().flushCaches();
        }

        public void restore(final String absPath, final Version version, final boolean removeExisting) throws PathNotFoundException, ItemExistsException, VersionException, ConstraintViolationException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
            JCRObservationManager.doWorkspaceWriteCall(getSession(), JCRObservationManager.NODE_RESTORE, new JCRCallback<Object>() {
                public Object doInJCR(JCRSessionWrapper session) throws RepositoryException {
                    versionManager.restore(absPath, version instanceof JCRVersion ? ((JCRVersion) version).getRealNode() : version, removeExisting);
                    return null;
                }
            });
            getSession().flushCaches();
        }

        public void restoreByLabel(final String absPath, final String versionLabel, final boolean removeExisting) throws VersionException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
            JCRObservationManager.doWorkspaceWriteCall(getSession(), JCRObservationManager.NODE_RESTORE, new JCRCallback<Object>() {
                public Object doInJCR(JCRSessionWrapper session) throws RepositoryException {
                    versionManager.restoreByLabel(absPath, versionLabel, removeExisting);
                    return null;
                }
            });
            getSession().flushCaches();
        }

        public NodeIterator merge(final String absPath, final String srcWorkspace, final boolean bestEffort) throws NoSuchWorkspaceException, AccessDeniedException, MergeException, LockException, InvalidItemStateException, RepositoryException {
            return JCRObservationManager.doWorkspaceWriteCall(getSession(), JCRObservationManager.NODE_MERGE, new JCRCallback<NodeIterator>() {
                public NodeIterator doInJCR(JCRSessionWrapper session) throws RepositoryException {
                    return versionManager.merge(absPath, srcWorkspace, bestEffort);
                }
            });
        }

        public NodeIterator merge(final String absPath, final String srcWorkspace,final boolean bestEffort,final boolean isShallow) throws NoSuchWorkspaceException, AccessDeniedException, MergeException, LockException, InvalidItemStateException, RepositoryException {
            return JCRObservationManager.doWorkspaceWriteCall(getSession(), JCRObservationManager.NODE_MERGE, new JCRCallback<NodeIterator>() {
                public NodeIterator doInJCR(JCRSessionWrapper session) throws RepositoryException {
                    return versionManager.merge(absPath, srcWorkspace, bestEffort, isShallow);
                }
            });
        }

        public void doneMerge(String absPath, Version version) throws VersionException, InvalidItemStateException, UnsupportedRepositoryOperationException, RepositoryException {
            versionManager.doneMerge(absPath, version instanceof JCRVersion ? ((JCRVersion) version).getRealNode() : version);
        }

        public void cancelMerge(String absPath, Version version) throws VersionException, InvalidItemStateException, UnsupportedRepositoryOperationException, RepositoryException {
            versionManager.cancelMerge(absPath, version instanceof JCRVersion ? ((JCRVersion) version).getRealNode() : version);
        }

        public Node createConfiguration(String s) throws UnsupportedRepositoryOperationException, RepositoryException {
            return versionManager.createConfiguration(s);
        }

        public Node setActivity(Node activity) throws UnsupportedRepositoryOperationException, RepositoryException {
            return versionManager.setActivity(activity);
        }

        public Node getActivity() throws UnsupportedRepositoryOperationException, RepositoryException {
            return versionManager.getActivity();
        }

        public Node createActivity(final String title) throws UnsupportedRepositoryOperationException, RepositoryException {
            return JCRObservationManager.doWorkspaceWriteCall(getSession(), JCRObservationManager.WORKSPACE_CREATE_ACTIVITY, new JCRCallback<Node>() {
                public Node doInJCR(JCRSessionWrapper session) throws RepositoryException {
                    return versionManager.createActivity(title);
                }
            });
        }

        public void removeActivity(Node node) throws UnsupportedRepositoryOperationException, VersionException, RepositoryException {
            versionManager.removeActivity(node);
        }

        public NodeIterator merge(final Node activityNode) throws VersionException, AccessDeniedException, MergeException, LockException, InvalidItemStateException, RepositoryException {
            return JCRObservationManager.doWorkspaceWriteCall(getSession(), JCRObservationManager.NODE_MERGE, new JCRCallback<NodeIterator>() {
                public NodeIterator doInJCR(JCRSessionWrapper session) throws RepositoryException {
                    return versionManager.merge(activityNode);
                }
            });
        }
    }
}
TOP

Related Classes of org.jahia.services.content.JCRWorkspaceWrapper$VersionManagerWrapper

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.