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.synchronization;
017
018import java.util.Map;
019
020import javax.jcr.Node;
021import javax.jcr.RepositoryException;
022import javax.jcr.Session;
023
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026
027import org.ametys.core.observation.Event;
028import org.ametys.core.observation.Observer;
029import org.ametys.plugins.repository.jcr.JCRAmetysObject;
030import org.ametys.web.ObservationConstants;
031import org.ametys.web.repository.page.Page;
032import org.ametys.web.repository.page.PagesContainer;
033import org.ametys.web.repository.sitemap.Sitemap;
034import org.ametys.web.skin.Skin;
035import org.ametys.web.skin.SkinsManager;
036
037/**
038 * {@link Observer} for observing page move in order to synchronize live workspace.
039 */
040public class SynchronizePageMoveObserver extends AbstractSynchronizeObserver
041{
042    private SkinsManager _skinsManager;
043
044    @Override
045    public void service(ServiceManager manager) throws ServiceException
046    {
047        super.service(manager);
048        _skinsManager = (SkinsManager) manager.lookup(SkinsManager.ROLE);
049    }
050
051    @Override
052    public boolean supports(Event event)
053    {
054        return event.getId().equals(ObservationConstants.EVENT_PAGE_MOVED);
055    }
056    
057    @Override
058    protected void _internalObserve(Event event, Session liveSession) throws RepositoryException
059    {
060        Map<String, Object> arguments = event.getArguments();
061        Sitemap sitemap = (Sitemap) arguments.get(ObservationConstants.ARGS_SITEMAP);
062        
063        String newPathInSitemap = (String) arguments.get(ObservationConstants.ARGS_PAGE_PATH);
064        String oldPathInSitemap = (String) arguments.get("page.old.path");
065        
066        PagesContainer oldParent = (PagesContainer) arguments.get("page.old.parent");
067        
068        Page destPage = sitemap.getChild(newPathInSitemap);
069        
070        Skin skin = _skinsManager.getSkin(sitemap.getSite().getSkinId());
071        
072        if (!(destPage instanceof JCRAmetysObject))
073        {
074            return;
075        }
076
077        Node sitemapNode = sitemap.getNode();
078        String sitemapNodePath = sitemapNode.getPath();
079        
080        Node liveSitemapNode = (Node) liveSession.getItem(sitemapNodePath);
081        
082        if (oldPathInSitemap.equals(newPathInSitemap))
083        {
084            // same parent page
085            if (liveSitemapNode.hasNode(newPathInSitemap))
086            {
087                Node liveNode = liveSitemapNode.getNode(oldPathInSitemap);
088                
089                _synchronizeComponent.orderNode(((JCRAmetysObject) oldParent).getNode(), destPage.getName(), liveNode);
090            }
091        }
092        else
093        {
094            // This is a move with a optional orderBefore
095            // Consider it like a deletion followed by an addition
096            
097            // First remove the src node
098            String oldJcrPath = sitemapNodePath + '/' + oldPathInSitemap;
099
100            if (liveSession.itemExists(oldJcrPath))
101            {
102                liveSession.getItem(oldJcrPath).remove();
103                
104                if (oldParent instanceof Page)
105                {
106                    if (!_synchronizeComponent.isPageValid((Page) oldParent, skin))
107                    {
108                        _synchronizeComponent.invalidateHierarchy((Page) oldParent, skin, liveSession);
109                    }
110                }
111            }
112            
113            // then add the new node
114            _synchronizeComponent.synchronizePage(destPage, skin, liveSession);
115        }
116        
117        if (liveSession.hasPendingChanges())
118        {
119            liveSession.save();
120        }
121    }
122}