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.workflow;
017
018import java.util.HashMap;
019import java.util.List;
020import java.util.Map;
021import java.util.concurrent.Future;
022
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025
026import org.ametys.cms.repository.Content;
027import org.ametys.cms.repository.ModifiableContent;
028import org.ametys.cms.repository.ModifiableWorkflowAwareContent;
029import org.ametys.core.observation.Event;
030import org.ametys.core.user.CurrentUserProvider;
031import org.ametys.plugins.repository.RepositoryConstants;
032import org.ametys.plugins.repository.UnknownAmetysObjectException;
033import org.ametys.plugins.repository.collection.AmetysObjectCollection;
034import org.ametys.runtime.i18n.I18nizableText;
035import org.ametys.web.ObservationConstants;
036import org.ametys.web.repository.ModifiableSiteAwareAmetysObject;
037import org.ametys.web.repository.page.LockablePage;
038import org.ametys.web.repository.page.ModifiablePage;
039import org.ametys.web.repository.page.ModifiableZone;
040import org.ametys.web.repository.page.ModifiableZoneItem;
041import org.ametys.web.repository.page.Page.PageType;
042import org.ametys.web.repository.page.SitemapElement;
043import org.ametys.web.repository.page.ZoneItem;
044import org.ametys.web.repository.page.ZoneItem.ZoneType;
045import org.ametys.web.repository.site.Site;
046import org.ametys.web.repository.site.SiteManager;
047
048import com.opensymphony.workflow.WorkflowException;
049
050/**
051 * OSWorkflow function for creating a content.
052 */
053public class CreateContentFunction extends org.ametys.cms.workflow.CreateContentFunction
054{
055    /** Constant for storing the site to use into the transient variables map. */
056    public static final String SITE_KEY = Site.class.getName();
057    /** Constant for knowing on which page the content will be affected. */
058    public static final String PAGE_KEY = CreateContentFunction.class.getName() + "$pageId";
059    /** Constant for knowing on which zone of the page to affect the content. */
060    public static final String PAGE_ZONE_KEY = CreateContentFunction.class.getName() + "$zoneName";
061    
062    /** The sites manager */
063    protected SiteManager _siteManager;
064    /** Current user provider */
065    protected CurrentUserProvider _currentUserProvider;
066    
067    @Override
068    public void service(ServiceManager manager) throws ServiceException
069    {
070        super.service(manager);
071        _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE);
072        _currentUserProvider = (CurrentUserProvider) manager.lookup(CurrentUserProvider.ROLE);
073    }
074    
075    @Override
076    protected List<Future> _notifyContentAdded(Content content, Map transientVars) throws WorkflowException
077    {
078        List<Future> futures = super._notifyContentAdded(content, transientVars);
079        
080        String pageId = (String) transientVars.get(PAGE_KEY);
081        if (pageId != null)
082        {
083            SitemapElement sitemapElement = _resolver.resolveById(pageId);
084    
085            Map<String, Object> eventParams = new HashMap<>();
086            eventParams.put(ObservationConstants.ARGS_SITEMAP_ELEMENT, sitemapElement);
087            eventParams.put(ObservationConstants.ARGS_ZONE_ITEM_ID, getResultsMap(transientVars).get("zoneitem-id"));
088            eventParams.put(ObservationConstants.ARGS_ZONE_TYPE, ZoneType.CONTENT);
089            eventParams.put(ObservationConstants.ARGS_ZONE_ITEM_CONTENT, content);
090            _observationManager.notify(new Event(ObservationConstants.EVENT_ZONEITEM_ADDED, _currentUserProvider.getUser(), eventParams));
091        }
092        
093        return futures;
094    }
095
096    
097    @Override
098    protected String _getObjectType(Map transientVars, Map args)
099    {
100        return RepositoryConstants.NAMESPACE_PREFIX + ":defaultWebContent";
101    }
102        
103    @Override
104    protected AmetysObjectCollection< ? , ModifiableWorkflowAwareContent> _getContentRoot(Map transientVars) throws WorkflowException
105    {
106        String siteName = _getNonNullVar(transientVars, SITE_KEY, "Missing sitename");
107
108        Site site = null;
109        try
110        {
111            site = _siteManager.getSite(siteName);
112        }
113        catch (UnknownAmetysObjectException e)
114        {
115            throw new WorkflowException("Site does not exist", e);
116        }
117        
118        // FIXME use constant or site getter
119        return site.getChild(RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":contents");
120    }
121    
122    @Override
123    protected void _populateContent(Map transientVars, ModifiableContent content) throws WorkflowException
124    {
125        super._populateContent(transientVars, content);
126        
127        String siteName = _getNonNullVar(transientVars, SITE_KEY, "Missing sitename");
128        
129        // FIXME API what if not modifiable
130        ((ModifiableSiteAwareAmetysObject) content).setSiteName(siteName);
131    }
132    
133    @Override
134    protected void _populateAdditionalData(Map transientVars, ModifiableContent content) throws WorkflowException
135    {
136        super._populateAdditionalData(transientVars, content);
137        
138        // FIXME API test if not modifiable
139        ModifiablePage page = null;
140        ModifiableZone zone = null;
141        try
142        {
143            String zoneName = (String) transientVars.get(PAGE_ZONE_KEY);
144            if (zoneName != null)
145            {
146                String pageId = (String) transientVars.get(PAGE_KEY);
147                if (pageId != null)
148                {
149                    page = _resolver.resolveById(pageId);
150                    
151                    if (page.getType() != PageType.CONTAINER)
152                    {
153                        throw new WorkflowException("Page is not of type Container");
154                    }
155                    if (page instanceof LockablePage lockablePage && lockablePage.isLocked())
156                    {
157                        throw new WorkflowException("Page is locked");
158                    }
159                    
160                    if (page.hasZone(zoneName))
161                    {
162                        zone = page.getZone(zoneName);
163                    }
164                    else
165                    {
166                        zone = page.createZone(zoneName);
167                    }
168                    
169                    ModifiableZoneItem zoneItem = zone.addZoneItem();
170                    zoneItem.setType(ZoneItem.ZoneType.CONTENT);
171                    zoneItem.setContent(content);
172                    zoneItem.setViewName("main");
173                    page.saveChanges();
174
175                    getResultsMap(transientVars).put("zoneitem-id", zoneItem.getId());
176                }
177            }
178        }
179        catch (UnknownAmetysObjectException e)
180        {
181            throw new WorkflowException("Page does not exist", e);
182        }
183    }
184    
185    @Override
186    public I18nizableText getLabel()
187    {
188        return new I18nizableText("plugin.web", "PLUGINS_WEB_CREATE_CONTENT_FUNCTION_LABEL");
189    }
190}