001/*
002 *  Copyright 2011 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.workflow;
017
018import java.util.ArrayList;
019import java.util.Collection;
020import java.util.HashMap;
021import java.util.List;
022import java.util.Map;
023
024import javax.jcr.Node;
025import javax.jcr.RepositoryException;
026import javax.jcr.Session;
027
028import org.apache.commons.lang3.StringUtils;
029
030import org.ametys.cms.repository.Content;
031import org.ametys.cms.repository.WorkflowAwareContent;
032import org.ametys.cms.workflow.ArchiveContentAction;
033import org.ametys.core.observation.Event;
034import org.ametys.core.user.UserIdentity;
035import org.ametys.plugins.repository.AmetysObjectIterable;
036import org.ametys.web.ObservationConstants;
037import org.ametys.web.repository.content.WebContent;
038import org.ametys.web.repository.page.ModifiablePage;
039import org.ametys.web.repository.page.ModifiableZoneItem;
040import org.ametys.web.repository.page.Page;
041import org.ametys.web.repository.page.Zone;
042import org.ametys.web.repository.page.ZoneItem;
043import org.ametys.web.repository.page.ZoneItem.ZoneType;
044
045/**
046 * Action for archiving a content and removing referencing zone items if necessary
047 */
048public class ArchiveWebContentAction extends ArchiveContentAction
049{
050    @Override
051    protected Event _prepareDeletingEvent(UserIdentity user, Content content)
052    {
053        Event event = super._prepareDeletingEvent(user, content);
054        
055        if (content instanceof WebContent)
056        {
057            event.getArguments().put(ObservationConstants.ARGS_SITE_NAME, ((WebContent) content).getSiteName());
058        }
059        
060        return event;
061        
062    }
063    
064    @Override
065    protected Event _prepareDeletedEvent(UserIdentity user, Content content)
066    {
067        Event event = super._prepareDeletedEvent(user, content);
068        
069        if (content instanceof WebContent)
070        {
071            event.getArguments().put(ObservationConstants.ARGS_SITE_NAME, ((WebContent) content).getSiteName());
072        }
073        
074        return event;
075    }
076    
077    @Override
078    protected void archiveContent(WorkflowAwareContent content, Map objectModel, Map<String, Object> result) throws RepositoryException
079    {
080        Session session = null;
081        Session archiveSession = null;
082        
083        try
084        {
085            archiveSession = getArchiveSession();
086            
087            Node contentNode = content.getNode();
088            
089            session = contentNode.getSession();
090            
091            _cloneComponent.cloneContentNodeWithWorkflow(archiveSession, contentNode);
092            
093            archiveSession.save();
094            
095            removeZoneItems(content, objectModel, result);
096            
097            content.remove();
098            session.save();
099        }
100        finally
101        {
102            if (archiveSession != null)
103            {
104                archiveSession.logout();
105            }
106        }
107    }
108    
109    /**
110     * Remove zone items referencing the content
111     * @param content the content
112     * @param objectModel the current object model.
113     * @param result the result map
114     */
115    protected void removeZoneItems (Content content, Map objectModel, Map<String, Object> result)
116    {
117        List<Map<String, Object>> modifiedZones = new ArrayList<>();
118        
119        List<String> modifiedPages = new ArrayList<>();
120        
121        if (content instanceof WebContent)
122        {
123            WebContent wContent = (WebContent) content;
124            
125            Collection<Page> pages = wContent.getReferencingPages();
126            for (Page page : pages)
127            {
128                if (page instanceof ModifiablePage)
129                {
130                    AmetysObjectIterable< ? extends Zone> zones = page.getZones();
131                    for (Zone zone : zones)
132                    {
133                        boolean hasChanges = false;
134                        AmetysObjectIterable< ? extends ZoneItem> zoneItems = zone.getZoneItems();
135                        for (ZoneItem zoneItem : zoneItems)
136                        {
137                            if (zoneItem.getType() == ZoneType.CONTENT)
138                            {
139                                if (zoneItem.getContent().equals(content) && zoneItem instanceof ModifiableZoneItem)
140                                {
141                                    String zoneItemId = zoneItem.getId();
142                                    
143                                    ((ModifiableZoneItem) zoneItem).remove();
144                                    ((ModifiablePage) page).saveChanges();
145                                    
146                                    modifiedPages.add(page.getId());
147                                    hasChanges = true;
148                                    
149                                    Map<String, Object> eventParams = new HashMap<>();
150                                    eventParams.put(ObservationConstants.ARGS_ZONE_ITEM_ID, zoneItemId);
151                                    eventParams.put(ObservationConstants.ARGS_PAGE, page);
152                                    _observationManager.notify(new Event(ObservationConstants.EVENT_ZONEITEM_DELETED, _getUser(objectModel), eventParams));
153                                }
154                            }
155                        }
156                        
157                        if (hasChanges)
158                        {
159                            Map<String, Object> zoneInfos = new HashMap<>();
160                            zoneInfos.put("zoneName", zone.getName());
161                            zoneInfos.put("pageId", page.getId());
162                            modifiedZones.add(zoneInfos);
163                        }
164                    }
165                }
166            }
167        }
168        
169        result.put("modifiedZones", modifiedZones);
170        result.put("modifiedPages", StringUtils.join(modifiedPages, ","));
171    }
172}