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