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.plugins.repository.jcr.JCRAmetysObject;
036import org.ametys.runtime.plugin.component.AbstractLogEnabled;
037import org.ametys.web.synchronization.SynchronizeComponent;
038
039/**
040 * {@link LivePopulator} for synchronizing '/ametys:root/ametys:contents'.
041 */
042public class ContentsLivePopulator extends AbstractLogEnabled implements LivePopulator, Serviceable
043{
044    /** The synchronize helper */
045    protected SynchronizeComponent _synchronizeHelper;
046    /** The Ametys resolver */
047    protected AmetysObjectResolver _resolver;
048
049    @Override
050    public void service(ServiceManager smanager) throws ServiceException
051    {
052        _synchronizeHelper = (SynchronizeComponent) smanager.lookup(SynchronizeComponent.ROLE);
053        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
054    }
055    
056    @Override
057    public List<String> populate(Session session, Session liveSession) throws Exception
058    {
059        Node contentsNode = session.getRootNode().getNode("ametys:root/ametys:contents");
060        
061        Node liveRootNode = liveSession.getRootNode().getNode(AmetysObjectResolver.ROOT_REPO);
062        
063        if (liveRootNode.hasNode("ametys:contents"))
064        {
065            liveRootNode.getNode("ametys:contents").remove();
066        }
067        
068        Node clonedParentNode = _synchronizeHelper.cloneAncestorsAndPreserveUUID(contentsNode, liveSession);
069        _synchronizeHelper.addNodeWithUUID(contentsNode, clonedParentNode, contentsNode.getName());
070        
071        _cloneContents(contentsNode, liveSession);
072        
073        return Collections.EMPTY_LIST;
074    }
075    
076    /**
077     * Clone contents in live workspace
078     * @param contentsNode The root contents node
079     * @param liveSession The live session
080     * @throws RepositoryException if failed to clone contents in live
081     */
082    protected void _cloneContents(Node contentsNode, Session liveSession) throws RepositoryException
083    {
084        _synchronizeHelper.synchronizeACL(contentsNode, liveSession);
085        
086        // Clone the contents.
087        AmetysObjectIterable<Content> contents = _getContents(contentsNode);
088        
089        getLogger().info("Synchronizing {} shared contents at path {}", contents.getSize(), contentsNode.getPath());
090        
091        for (Content content : contents)
092        {
093            if (content instanceof JCRAmetysObject)
094            {
095                _synchronizeHelper.synchronizeContent(content, liveSession);
096                
097                liveSession.save();
098            }
099        }
100    }
101    
102    /**
103     * Get the contents of root contents node
104     * @param contentsNode The root contents node
105     * @return The child contents
106     * @throws RepositoryException if failed to get the child contents
107     */
108    protected AmetysObjectIterable<Content> _getContents(Node contentsNode) throws RepositoryException
109    {
110        String contentsPath = StringUtils.substringAfter(contentsNode.getPath(), "/" + RepositoryConstants.NAMESPACE_PREFIX + ":root");
111        
112        AmetysObjectCollection rootContents = _resolver.resolveByPath(contentsPath);
113        return rootContents.getChildren();
114    }
115
116}