001/* 002 * Copyright 2017 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.plugins.workspaces.about; 017 018import java.util.HashMap; 019import java.util.Map; 020import java.util.Set; 021 022import org.apache.avalon.framework.service.ServiceException; 023import org.apache.avalon.framework.service.ServiceManager; 024import org.apache.commons.lang.StringUtils; 025 026import org.ametys.cms.repository.Content; 027import org.ametys.cms.repository.ModifiableWorkflowAwareContent; 028import org.ametys.plugins.repository.jcr.NameHelper; 029import org.ametys.plugins.workflow.AbstractWorkflowComponent; 030import org.ametys.plugins.workflow.support.WorkflowProvider; 031import org.ametys.plugins.workflow.support.WorkflowProvider.AmetysObjectWorkflow; 032import org.ametys.plugins.workspaces.AbstractWorkspaceModule; 033import org.ametys.plugins.workspaces.WorkspacesConstants; 034import org.ametys.plugins.workspaces.project.ProjectConstants; 035import org.ametys.runtime.i18n.I18nizableText; 036import org.ametys.web.repository.page.ModifiablePage; 037import org.ametys.web.repository.page.ModifiableZone; 038import org.ametys.web.repository.page.ModifiableZoneItem; 039import org.ametys.web.repository.page.Page; 040import org.ametys.web.repository.page.Page.PageType; 041import org.ametys.web.repository.page.ZoneItem.ZoneType; 042import org.ametys.web.repository.site.Site; 043import org.ametys.web.skin.Skin; 044import org.ametys.web.skin.SkinTemplate; 045import org.ametys.web.skin.SkinTemplateZone; 046import org.ametys.web.workflow.CreateContentFunction; 047 048import com.opensymphony.workflow.WorkflowException; 049 050/** 051 * Manager for the About module 052 */ 053public class AboutWorkspaceModule extends AbstractWorkspaceModule 054{ 055 /** Avalon ROLE */ 056 public static final String ABOUT_MODULE_ID = AboutWorkspaceModule.class.getName(); 057 058 /** Workspaces tasks list node name */ 059 private static final String __WORKSPACES_ABOUT_NODE_NAME = "about"; 060 061 /** The initial workflow action id */ 062 private static final int __INIT_WORKFLOW_ACTION_ID = 16; 063 064 /** The workflow provider */ 065 protected WorkflowProvider _workflowProvider; 066 067 @Override 068 public void service(ServiceManager manager) throws ServiceException 069 { 070 super.service(manager); 071 _workflowProvider = (WorkflowProvider) manager.lookup(WorkflowProvider.ROLE); 072 } 073 074 @Override 075 public String getId() 076 { 077 return ABOUT_MODULE_ID; 078 } 079 080 @Override 081 public String getModuleName() 082 { 083 return __WORKSPACES_ABOUT_NODE_NAME; 084 } 085 086 public int getOrder() 087 { 088 return ORDER_ABOUT; 089 } 090 091 @Override 092 protected String getModulePageName() 093 { 094 return "about"; 095 } 096 097 public I18nizableText getModuleTitle() 098 { 099 return new I18nizableText("plugin." + _pluginName, "PLUGINS_WORKSPACES_PROJECT_SERVICE_MODULE_ABOUT_LABEL"); 100 } 101 public I18nizableText getModuleDescription() 102 { 103 return new I18nizableText("plugin." + _pluginName, "PLUGINS_WORKSPACES_PROJECT_SERVICE_MODULE_ABOUT_DESCRIPTION"); 104 } 105 @Override 106 protected I18nizableText getModulePageTitle() 107 { 108 return new I18nizableText("plugin." + _pluginName, "PLUGINS_WORKSPACES_PROJECT_WORKSPACE_PAGE_ABOUT_TITLE"); 109 } 110 111 @Override 112 protected String getModulePageTemplate() 113 { 114 return ProjectConstants.ABOUT_TEMPLATE; 115 } 116 117 @Override 118 protected void initializeModulePage(ModifiablePage page) 119 { 120 String contentTitle = StringUtils.defaultIfEmpty(_i18nUtils.translate(getModulePageTitle(), page.getSitemapName()), "Missing title"); 121 _initializeAboutDefaultZone(page, page.getSite(), page.getSitemapName(), contentTitle); 122 } 123 124 /** 125 * Initialize the default zone for the about page 126 * @param aboutPage The about page 127 * @param site The site 128 * @param sitemapName The sitemap name 129 * @param title The content title 130 */ 131 protected void _initializeAboutDefaultZone(ModifiablePage aboutPage, Site site, String sitemapName, String title) 132 { 133 ModifiableZone defaultZone = aboutPage.createZone("default"); 134 135 ModifiableZoneItem defaultZoneItem = defaultZone.addZoneItem(); 136 defaultZoneItem.setType(ZoneType.CONTENT); 137 138 try 139 { 140 ModifiableWorkflowAwareContent content = createAboutContent(site, sitemapName, title); 141 defaultZoneItem.setContent(content); 142 content.saveChanges(); 143 } 144 catch (WorkflowException e) 145 { 146 getLogger().error("Unable to initialize the About page content for the new workspace, the about page will not be editable until the content is manually created in the BackOffice", e); 147 } 148 } 149 150 /** 151 * Retrieves the rights for the current user in the project 152 * @return The project 153 */ 154 /** 155 * Create the about content 156 * @param site The site 157 * @param sitemapName the name of the sitemap 158 * @param title The content title 159 * @return The content 160 * @throws WorkflowException if an error occurred 161 */ 162 public ModifiableWorkflowAwareContent createAboutContent(Site site, String sitemapName, String title) throws WorkflowException 163 { 164 Map<String, Object> inputs = new HashMap<>(); 165 inputs.put(org.ametys.cms.workflow.CreateContentFunction.CONTENT_TITLE_KEY, title); 166 inputs.put(org.ametys.cms.workflow.CreateContentFunction.CONTENT_NAME_KEY, NameHelper.filterName(title)); 167 inputs.put(org.ametys.cms.workflow.CreateContentFunction.CONTENT_TYPES_KEY, new String[] {WorkspacesConstants.ABOUT_CONTENT_TYPE}); 168 inputs.put(org.ametys.cms.workflow.CreateContentFunction.CONTENT_LANGUAGE_KEY, sitemapName); 169 inputs.put(CreateContentFunction.SITE_KEY, site.getName()); 170 171 AmetysObjectWorkflow workflow = _workflowProvider.getAmetysObjectWorkflow(); 172 workflow.initialize(WorkspacesConstants.CONTENT_WORKFLOW_NAME, __INIT_WORKFLOW_ACTION_ID, inputs); 173 174 @SuppressWarnings("unchecked") 175 Map<String, Object> results = (Map<String, Object>) inputs.get(AbstractWorkflowComponent.RESULT_MAP_KEY); 176 ModifiableWorkflowAwareContent content = (ModifiableWorkflowAwareContent) results.get(Content.class.getName()); 177 178 return content; 179 } 180 181 182 183 184 /** 185 * Initialize the new about page 186 * @param aboutPage The page 187 * @param site The site 188 * @param sitemapName The sitemap name 189 * @param title The page title 190 * @param parentPage The parent page 191 */ 192 protected void _initializeAboutPage(ModifiablePage aboutPage, Site site, String sitemapName, String title, Page parentPage) 193 { 194 Skin skin = _skinsManager.getSkin(site.getSkinId()); 195 SkinTemplate template = skin.getTemplate(ProjectConstants.ABOUT_TEMPLATE); 196 197 if (template != null) 198 { 199 // Set the type and template. 200 aboutPage.setType(PageType.CONTAINER); 201 aboutPage.setTemplate(ProjectConstants.ABOUT_TEMPLATE); 202 203 // Initialize the zones. 204 Map<String, SkinTemplateZone> templateZones = template.getZones(); 205 if (templateZones.containsKey("default")) 206 { 207 _initializeAboutDefaultZone(aboutPage, site, sitemapName, title); 208 } 209 else 210 { 211 getLogger().error("A 'default' zone is mandatory in the about template!"); 212 return; 213 } 214 215 // Tag page as a sitemap section. 216 aboutPage.tag("SECTION"); 217 } 218 else 219 { 220 String errorMsg = String.format( 221 "The project workspace '%s' was created with the skin '%s' which doesn't possess the mandatory template '%s'.\nThe '%s' page of the project workspace could not be initialized.", 222 site.getName(), site.getSkinId(), ProjectConstants.ABOUT_TEMPLATE, aboutPage.getName()); 223 224 getLogger().error(errorMsg); 225 } 226 } 227 228 @Override 229 public Set<String> getAllowedEventTypes() 230 { 231 return Set.of(); 232 } 233 234 @Override 235 protected boolean _showActivatedStatus() 236 { 237 return false; 238 } 239}