001/*
002 *  Copyright 2010 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.web.live;
017
018import java.util.Collections;
019import java.util.List;
020
021import javax.jcr.Node;
022import javax.jcr.RepositoryException;
023import javax.jcr.Session;
024
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.avalon.framework.service.Serviceable;
028import org.apache.commons.lang3.StringUtils;
029
030import org.ametys.cms.repository.Content;
031import org.ametys.plugins.repository.AmetysObjectIterable;
032import org.ametys.plugins.repository.AmetysObjectResolver;
033import org.ametys.plugins.repository.RepositoryConstants;
034import org.ametys.plugins.repository.collection.AmetysObjectCollection;
035import org.ametys.runtime.plugin.component.AbstractLogEnabled;
036import org.ametys.web.synchronization.SynchronizeComponent;
037
038/**
039 * {@link LivePopulator} for synchronizing '/ametys:root/ametys:contents'.
040 */
041public class ContentsLivePopulator extends AbstractLogEnabled implements LivePopulator, Serviceable
042{
043    /** The synchronize helper */
044    protected SynchronizeComponent _synchronizeHelper;
045    /** The Ametys resolver */
046    protected AmetysObjectResolver _resolver;
047
048    @Override
049    public void service(ServiceManager smanager) throws ServiceException
050    {
051        _synchronizeHelper = (SynchronizeComponent) smanager.lookup(SynchronizeComponent.ROLE);
052        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
053    }
054    
055    @Override
056    public List<String> populate(Session session, Session liveSession) throws Exception
057    {
058        Node contentsNode = session.getRootNode().getNode("ametys:root/ametys:contents");
059        
060        Node liveRootNode = liveSession.getRootNode().getNode(AmetysObjectResolver.ROOT_REPO);
061        
062        if (liveRootNode.hasNode("ametys:contents"))
063        {
064            liveRootNode.getNode("ametys:contents").remove();
065        }
066        
067        Node clonedParentNode = _synchronizeHelper.cloneAncestorsAndPreserveUUID(contentsNode, liveSession);
068        _synchronizeHelper.addNodeWithUUID(contentsNode, clonedParentNode, contentsNode.getName());
069        
070        _cloneContents(contentsNode, liveSession);
071        
072        return Collections.EMPTY_LIST;
073    }
074    
075    /**
076     * Clone contents in live workspace
077     * @param contentsNode The root contents node
078     * @param liveSession The live session
079     * @throws RepositoryException if failed to clone contents in live
080     */
081    protected void _cloneContents(Node contentsNode, Session liveSession) throws RepositoryException
082    {
083        _synchronizeHelper.synchronizeACL(contentsNode, liveSession);
084        
085        // Clone the contents.
086        try (AmetysObjectIterable<Content> contents = _getContents(contentsNode))
087        {
088            getLogger().info("Synchronizing {} shared contents at path {}", contents.getSize(), contentsNode.getPath());
089            
090            _synchronizeHelper.synchronizeContents(contents, liveSession);
091        }
092    }
093
094    /**
095     * Get the contents of root contents node
096     * @param contentsNode The root contents node
097     * @return The child contents
098     * @throws RepositoryException if failed to get the child contents
099     */
100    protected AmetysObjectIterable<Content> _getContents(Node contentsNode) throws RepositoryException
101    {
102        String contentsPath = StringUtils.substringAfter(contentsNode.getPath(), "/" + RepositoryConstants.NAMESPACE_PREFIX + ":root");
103        
104        AmetysObjectCollection rootContents = _resolver.resolveByPath(contentsPath);
105        return rootContents.getChildren();
106    }
107
108}