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.PropertyIterator;
022import javax.jcr.RepositoryException;
023import javax.jcr.Session;
024
025import org.apache.avalon.framework.context.ContextException;
026import org.apache.avalon.framework.context.Contextualizable;
027import org.apache.avalon.framework.service.ServiceException;
028import org.apache.avalon.framework.service.ServiceManager;
029import org.apache.cocoon.components.ContextHelper;
030import org.apache.cocoon.environment.Request;
031
032import org.ametys.cms.repository.Content;
033import org.ametys.cms.repository.RequestAttributeWorkspaceSelector;
034import org.ametys.core.observation.Event;
035import org.ametys.core.observation.Observer;
036import org.ametys.plugins.repository.AmetysObjectResolver;
037import org.ametys.plugins.repository.UnknownAmetysObjectException;
038import org.ametys.plugins.repository.jcr.JCRAmetysObject;
039import org.ametys.web.WebConstants;
040import org.ametys.web.repository.page.Page;
041import org.ametys.web.repository.page.jcr.DefaultZone;
042import org.ametys.web.skin.Skin;
043import org.ametys.web.skin.SkinsManager;
044
045/**
046 * {@link Observer} for observing content deletion in order to synchronize live workspace.
047 */
048public class SynchronizeContentUnpublishObserver extends AbstractSynchronizeObserver implements Contextualizable
049{
050    /** Ametys object resolver. */
051    protected AmetysObjectResolver _resolver;
052    /** The context. */
053    protected org.apache.avalon.framework.context.Context _context;
054    private SkinsManager _skinsManager;
055    
056    @Override
057    public void service(ServiceManager manager) throws ServiceException
058    {
059        super.service(manager);
060        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
061        _skinsManager = (SkinsManager) manager.lookup(SkinsManager.ROLE);
062    }
063    
064    @Override
065    public void contextualize(org.apache.avalon.framework.context.Context context) throws ContextException
066    {
067        _context = context;
068    }
069    
070    @Override
071    public boolean supports(Event event)
072    {
073        return event.getId().equals(org.ametys.web.ObservationConstants.EVENT_CONTENT_UNPUBLISHED);
074    }
075    
076    @Override
077    protected void _internalObserve(Event event, Session liveSession) throws RepositoryException
078    {
079        Map<String, Object> arguments = event.getArguments();
080        Content content = (Content) arguments.get(org.ametys.cms.ObservationConstants.ARGS_CONTENT);
081        
082        if (!(content instanceof JCRAmetysObject))
083        {
084            return;
085        }
086        
087        // Retrieve current workspace
088        Request request = ContextHelper.getRequest(_context);
089        String currentWsp = RequestAttributeWorkspaceSelector.getForcedWorkspace(request);
090        
091        try
092        {
093            // Use live workspace
094            RequestAttributeWorkspaceSelector.setForcedWorkspace(request, WebConstants.LIVE_WORKSPACE);
095            Content liveContent = null;
096            
097            try
098            {
099                // Retrieve content in the live workspace
100                liveContent = _resolver.resolveById(content.getId());
101            }
102            catch (UnknownAmetysObjectException e)
103            {
104                // Content is not synchronized
105            }
106            
107            if (liveContent != null && liveContent instanceof JCRAmetysObject)
108            {
109                Node node = ((JCRAmetysObject) content).getNode();
110                
111                PropertyIterator itReferences = node.getReferences();
112                while (itReferences.hasNext())
113                {
114                    Node refererNode = itReferences.nextProperty().getParent();
115                    if (refererNode.getPrimaryNodeType().getName().equals(DefaultZone.ZONEITEM_NODE_NAME))
116                    {
117                        Node pageNode = refererNode.getParent().getParent().getParent().getParent();
118                        Page page = _resolver.resolve(pageNode, false);
119                        Skin skin = _skinsManager.getSkin(page.getSite().getSkinId());
120                        
121                        _synchronizeComponent.synchronizePage(page, skin, liveSession);
122                        
123                        liveSession.save();
124                    }
125                }
126                
127                Node liveNode = ((JCRAmetysObject) liveContent).getNode();
128                if (!liveNode.getReferences().hasNext())
129                {
130                    ((JCRAmetysObject) liveContent).getNode().remove();
131                }
132                
133                if (liveSession.hasPendingChanges())
134                {
135                    liveSession.save();
136                }
137            }
138        }
139        finally
140        {
141            // Restore context
142            RequestAttributeWorkspaceSelector.setForcedWorkspace(request, currentWsp);
143        }
144    }
145}