001/* 002 * Copyright 2020 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.parameters.view; 017 018import java.io.IOException; 019import java.util.ArrayList; 020import java.util.Collection; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024import java.util.Optional; 025import java.util.stream.Collectors; 026 027import org.apache.avalon.framework.component.Component; 028import org.apache.avalon.framework.context.Context; 029import org.apache.avalon.framework.context.ContextException; 030import org.apache.avalon.framework.context.Contextualizable; 031import org.apache.avalon.framework.service.ServiceException; 032import org.apache.avalon.framework.service.ServiceManager; 033import org.apache.avalon.framework.service.Serviceable; 034import org.apache.cocoon.ProcessingException; 035import org.apache.cocoon.components.ContextHelper; 036import org.apache.cocoon.environment.Request; 037import org.apache.commons.collections4.MapUtils; 038import org.apache.commons.lang3.StringUtils; 039 040import org.ametys.cms.repository.Content; 041import org.ametys.core.observation.Event; 042import org.ametys.core.observation.ObservationManager; 043import org.ametys.core.ui.Callable; 044import org.ametys.core.user.CurrentUserProvider; 045import org.ametys.plugins.repository.AmetysObjectResolver; 046import org.ametys.plugins.repository.UnknownAmetysObjectException; 047import org.ametys.plugins.repository.data.holder.ModifiableModelAwareDataHolder; 048import org.ametys.runtime.i18n.I18nizableText; 049import org.ametys.runtime.i18n.I18nizableTextParameter; 050import org.ametys.runtime.model.DefinitionContext; 051import org.ametys.runtime.model.ElementDefinition; 052import org.ametys.runtime.model.Model; 053import org.ametys.runtime.model.ModelItem; 054import org.ametys.runtime.model.SimpleViewItemGroup; 055import org.ametys.runtime.model.View; 056import org.ametys.runtime.model.ViewElement; 057import org.ametys.runtime.model.ViewItemContainer; 058import org.ametys.runtime.model.ViewItemGroup; 059import org.ametys.runtime.model.disableconditions.DisableCondition.OPERATOR; 060import org.ametys.runtime.plugin.component.AbstractLogEnabled; 061import org.ametys.web.ObservationConstants; 062import org.ametys.web.WebConstants; 063import org.ametys.web.parameters.ParametersManager; 064import org.ametys.web.repository.page.LockablePage; 065import org.ametys.web.repository.page.ModifiableSitemapElement; 066import org.ametys.web.repository.page.ModifiableZone; 067import org.ametys.web.repository.page.ModifiableZoneItem; 068import org.ametys.web.repository.page.SitemapElement; 069import org.ametys.web.repository.page.Zone; 070import org.ametys.web.repository.page.ZoneItem; 071import org.ametys.web.repository.page.ZoneItem.ZoneType; 072import org.ametys.web.repository.site.Site; 073import org.ametys.web.rights.PageRightAssignmentContext; 074import org.ametys.web.service.Service; 075import org.ametys.web.service.ServiceExtensionPoint; 076import org.ametys.web.skin.Skin; 077import org.ametys.web.skin.SkinTemplate; 078import org.ametys.web.skin.SkinTemplateZone; 079import org.ametys.web.skin.SkinsManager; 080 081/** 082 * Manager for view parameters 083 */ 084public class ViewParametersDAO extends AbstractLogEnabled implements Component, Serviceable, Contextualizable 085{ 086 /** Avalon Role */ 087 public static final String ROLE = ViewParametersDAO.class.getName(); 088 089 /** The separator for model item name */ 090 public static final String MODEL_ITEM_NAME_SEPARATOR = "$"; 091 092 /** The prefix for template view parameters */ 093 public static final String PREFIX_TEMPLATE = "template"; 094 095 /** The prefix for zone view parameters */ 096 public static final String PREFIX_ZONE = "zone"; 097 098 /** The prefix for zoneItem view parameters */ 099 public static final String PREFIX_ZONE_ITEM = "zoneitem"; 100 101 /** The prefix for content view parameters */ 102 public static final String PREFIX_CONTENT = "content"; 103 104 /** The prefix for service view parameters */ 105 public static final String PREFIX_SERVICE = "service" + MODEL_ITEM_NAME_SEPARATOR + ViewParametersManager.SERVICE_VIEW_DEFAULT_MODEL_ITEM_NAME; 106 107 /** The Ametys object resolver */ 108 protected AmetysObjectResolver _resolver; 109 110 /** The skins manager */ 111 protected SkinsManager _skinsManager; 112 113 /** The service view parameters manager */ 114 protected ServiceViewParametersManager _serviceViewParametersManager; 115 116 /** The content view parameters manager */ 117 protected ContentViewParametersManager _contentViewParametersManager; 118 119 /** The service extension point */ 120 protected ServiceExtensionPoint _serviceEP; 121 122 /** The parameters manager */ 123 protected ParametersManager _parametersManager; 124 125 /** The observation manager */ 126 protected ObservationManager _observationManager; 127 128 /** The current user provider */ 129 protected CurrentUserProvider _currentUserProvider; 130 131 /** The view parameter manager */ 132 protected ViewParametersManager _viewParametersManager; 133 134 /** The Avalon context */ 135 protected Context _context; 136 137 public void service(ServiceManager manager) throws ServiceException 138 { 139 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 140 _skinsManager = (SkinsManager) manager.lookup(SkinsManager.ROLE); 141 _serviceViewParametersManager = (ServiceViewParametersManager) manager.lookup(ServiceViewParametersManager.ROLE); 142 _contentViewParametersManager = (ContentViewParametersManager) manager.lookup(ContentViewParametersManager.ROLE); 143 _serviceEP = (ServiceExtensionPoint) manager.lookup(ServiceExtensionPoint.ROLE); 144 _parametersManager = (ParametersManager) manager.lookup(ParametersManager.ROLE); 145 _observationManager = (ObservationManager) manager.lookup(ObservationManager.ROLE); 146 _currentUserProvider = (CurrentUserProvider) manager.lookup(CurrentUserProvider.ROLE); 147 _viewParametersManager = (ViewParametersManager) manager.lookup(ViewParametersManager.ROLE); 148 } 149 150 public void contextualize(Context context) throws ContextException 151 { 152 _context = context; 153 } 154 155 /** 156 * Get the definition of the created view of all view parameters 157 * @param pageId the page id 158 * @param zoneName the zone name (can be null) 159 * @param zoneItemId the zone item id (can be null) 160 * @return the JSON of view parameters 161 * @throws ProcessingException if a processing error occurred 162 */ 163 @Callable(rights = Callable.NO_CHECK_REQUIRED) 164 public Map<String, Object> getViewParametersDefinitions(String pageId, String zoneName, String zoneItemId) throws ProcessingException 165 { 166 Map<String, Object> response = new HashMap<>(); 167 View view = _createViewParametersDialogView(pageId, zoneName, zoneItemId); 168 response.put("parameters", view.toJSON(DefinitionContext.newInstance().withEdition(true))); 169 170 return response; 171 } 172 173 /** 174 * Create the view of all view parameters 175 * @param pageId the page id 176 * @param zoneName the zone name (can be null) 177 * @param zoneItemId the zone item id (can be null) 178 * @return the view of all view parameters 179 */ 180 protected View _createViewParametersDialogView(String pageId, String zoneName, String zoneItemId) 181 { 182 View view = new View(); 183 184 ModifiableSitemapElement page = _getModifiablePage(pageId); 185 Site site = page.getSite(); 186 Skin skin = _skinsManager.getSkin(site.getSkinId()); 187 188 SkinTemplate template = skin.getTemplate(page.getTemplate()); 189 if (template != null) 190 { 191 _addTemplateViewItem(page, skin, template, view); 192 193 Optional<ModifiableZoneItem> zoneItem = _getModifiableZoneItem(zoneItemId); 194 Optional<SkinTemplateZone> templateZone = _getSkinTemplateZone(template, zoneName, zoneItem); 195 if (templateZone.isPresent()) 196 { 197 SkinTemplateZone skinTemplateZone = templateZone.get(); 198 _addZoneViewItem(page, skin, template, skinTemplateZone, view); 199 200 if (zoneItem.isPresent()) 201 { 202 _addZoneItemViewItem(skin, template, skinTemplateZone, zoneItem.get(), view); 203 } 204 } 205 } 206 207 return view; 208 } 209 210 /** 211 * Add template view item 212 * @param page the page (to determine inheritance) 213 * @param skin the skin 214 * @param template the template 215 * @param viewItemContainer the container in which add the template view 216 */ 217 protected void _addTemplateViewItem(ModifiableSitemapElement page, Skin skin, SkinTemplate template, ViewItemContainer viewItemContainer) 218 { 219 String templateId = template.getId(); 220 Optional<ViewParametersModel> templateViewParametersOptional = _viewParametersManager.getTemplateViewParametersModel(skin.getId(), templateId); 221 if (templateViewParametersOptional.isEmpty()) 222 { 223 return; 224 } 225 226 ViewParametersModel templateViewParameters = templateViewParametersOptional.get(); 227 if (templateViewParameters.isNotEmpty()) 228 { 229 SimpleViewItemGroup group = new SimpleViewItemGroup(); 230 group.setName(templateId); 231 232 Map<String, I18nizableTextParameter> parameters = new HashMap<>(); 233 parameters.put("title", template.getLabel()); 234 group.setLabel(new I18nizableText("plugin.web", "PLUGINS_WEB_VIEW_PARAMETERS_DIALOG_BOX_TEMPLATE_LABEL", parameters)); 235 group.setRole(ViewItemGroup.FIELDSET_ROLE); 236 237 Collection< ? extends ModelItem> inheritModelItems = templateViewParameters.getInheritedModelItems(page); 238 239 List< ? extends ModelItem> noInheritModelItems = templateViewParameters.getModelItems() 240 .stream() 241 .filter(m -> !inheritModelItems.contains(m)) 242 .filter(m -> !(m.getName().equals(ViewParametersManager.TEMPLATE_INHERIT_MODEL_ITEM_NAME) && inheritModelItems.isEmpty())) 243 .collect(Collectors.toList()); 244 245 List<ModelItem> includedModelItems = new ArrayList<>(); 246 247 String prefix = PREFIX_TEMPLATE + MODEL_ITEM_NAME_SEPARATOR + template.getId() + MODEL_ITEM_NAME_SEPARATOR; 248 includedModelItems.addAll(_viewParametersManager.includeModelItems(noInheritModelItems, prefix, group)); 249 250 if (!inheritModelItems.isEmpty()) 251 { 252 List<ModelItem> includedInheritModelItems = _viewParametersManager.includeModelItems(inheritModelItems, prefix, group); 253 includedModelItems.addAll(includedInheritModelItems); 254 _viewParametersManager.setDisableConditions(prefix + ViewParametersManager.TEMPLATE_INHERIT_MODEL_ITEM_NAME, OPERATOR.EQ, "false", includedInheritModelItems); 255 } 256 257 // Create a model from the included (copied) model items. So the model of the model items is not the one with the original not prefixed items 258 Model.of(PREFIX_TEMPLATE, ROLE, includedModelItems.toArray(new ModelItem[includedModelItems.size()])); 259 260 viewItemContainer.addViewItem(group); 261 } 262 } 263 264 /** 265 * Add zone view item 266 * @param page the page (to determine inheritance) 267 * @param skin the skin 268 * @param template the template 269 * @param zone the zone 270 * @param viewItemContainer the container in which add the zone view 271 */ 272 protected void _addZoneViewItem(SitemapElement page, Skin skin, SkinTemplate template, SkinTemplateZone zone, ViewItemContainer viewItemContainer) 273 { 274 String zoneId = zone.getId(); 275 Optional<ViewParametersModel> zoneViewParametersOptional = _viewParametersManager.getZoneViewParametersModel(skin.getId(), template.getId(), zoneId); 276 if (zoneViewParametersOptional.isEmpty()) 277 { 278 return; 279 } 280 281 ViewParametersModel zoneViewParameters = zoneViewParametersOptional.get(); 282 if (zoneViewParameters.isNotEmpty()) 283 { 284 SimpleViewItemGroup group = new SimpleViewItemGroup(); 285 group.setName(zoneId); 286 287 Map<String, I18nizableTextParameter> parameters = new HashMap<>(); 288 parameters.put("title", zone.getLabel()); 289 group.setLabel(new I18nizableText("plugin.web", "PLUGINS_WEB_VIEW_PARAMETERS_DIALOG_BOX_ZONE_LABEL", parameters)); 290 group.setRole(ViewItemGroup.FIELDSET_ROLE); 291 292 Collection< ? extends ModelItem> inheritModelItems = zoneViewParameters.getInheritedModelItems(page); 293 294 List< ? extends ModelItem> noInheritModelItems = zoneViewParameters.getModelItems() 295 .stream() 296 .filter(m -> !inheritModelItems.contains(m)) 297 .filter(m -> !(m.getName().equals(ViewParametersManager.ZONE_INHERIT_MODEL_ITEM_NAME) && inheritModelItems.isEmpty())) 298 .collect(Collectors.toList()); 299 300 List<ModelItem> includedModelItems = new ArrayList<>(); 301 302 String prefix = PREFIX_ZONE + MODEL_ITEM_NAME_SEPARATOR + zoneId + MODEL_ITEM_NAME_SEPARATOR; 303 includedModelItems.addAll(_viewParametersManager.includeModelItems(noInheritModelItems, prefix, group)); 304 305 if (!inheritModelItems.isEmpty()) 306 { 307 List<ModelItem> includedInheritModelItems = _viewParametersManager.includeModelItems(inheritModelItems, prefix, group); 308 includedModelItems.addAll(includedInheritModelItems); 309 _viewParametersManager.setDisableConditions(prefix + ViewParametersManager.ZONE_INHERIT_MODEL_ITEM_NAME, OPERATOR.EQ, "false", includedInheritModelItems); 310 } 311 312 // Create a model from the included (copied) model items. So the model of the model items is not the one with the original not prefixed items 313 Model.of(PREFIX_ZONE, ROLE, includedModelItems.toArray(new ModelItem[includedModelItems.size()])); 314 315 viewItemContainer.addViewItem(group); 316 } 317 } 318 319 /** 320 * Add zone item view item and the service or content view items 321 * @param skin the skin 322 * @param template the template 323 * @param zone the zone 324 * @param zoneItem the zone item 325 * @param viewItemContainer the container in which add the zone item view 326 */ 327 protected void _addZoneItemViewItem(Skin skin, SkinTemplate template, SkinTemplateZone zone, ZoneItem zoneItem, ViewItemContainer viewItemContainer) 328 { 329 ModelItemViewsWrapper modelItemViews = new ModelItemViewsWrapper(); 330 331 String skinId = skin.getId(); 332 Optional<ViewParametersModel> zoneItemViewParameters = _viewParametersManager.getZoneItemViewParametersModel(skinId, template.getId(), zone.getId()); 333 modelItemViews.setZoneItemViewParameters(zoneItemViewParameters); 334 335 ZoneType type = zoneItem.getType(); 336 if (type == ZoneType.SERVICE) 337 { 338 _addServiceViewParameters(modelItemViews, zoneItem, skinId); 339 } 340 else if (type == ZoneType.CONTENT) 341 { 342 _addContentViewParameters(modelItemViews, zoneItem, skinId); 343 } 344 345 _addZoneItemViewParameters(modelItemViews, zone, zoneItem, viewItemContainer); 346 } 347 348 /** 349 * Add all view parameters of the zone item 350 * @param modelItemViews the model item views 351 * @param zone the zone 352 * @param zoneItem the zone item 353 * @param viewItemContainer the container in which add the zone item view 354 */ 355 protected void _addZoneItemViewParameters(ModelItemViewsWrapper modelItemViews, SkinTemplateZone zone, ZoneItem zoneItem, ViewItemContainer viewItemContainer) 356 { 357 if (modelItemViews.hasViewParameters()) 358 { 359 SimpleViewItemGroup group = new SimpleViewItemGroup(); 360 group.setName(zoneItem.getName()); 361 group.setLabel(modelItemViews.getLabel()); 362 group.setRole(ViewItemGroup.FIELDSET_ROLE); 363 364 if (modelItemViews.hasZoneItemViewParameters()) 365 { 366 ViewParametersModel zoneItemViewParameters = modelItemViews.getZoneItemViewParameters().get(); 367 368 SimpleViewItemGroup zoneItemGroup = new SimpleViewItemGroup(); 369 zoneItemGroup.setName(zoneItem.getName() + "_zoneItem"); 370 371 String prefix = PREFIX_ZONE_ITEM + MODEL_ITEM_NAME_SEPARATOR + zone.getId() + MODEL_ITEM_NAME_SEPARATOR; 372 List<ModelItem> includedModelItems = _viewParametersManager.includeModelItems(zoneItemViewParameters.getModelItems(), prefix, zoneItemGroup); 373 374 // Create a model from the included (copied) model items. So the model of the model items is not the one with the original not prefixed items 375 Model.of(PREFIX_ZONE_ITEM, ROLE, includedModelItems.toArray(new ModelItem[includedModelItems.size()])); 376 377 group.addViewItem(zoneItemGroup); 378 } 379 380 if (modelItemViews.hasServiceOrContentViewParameters()) 381 { 382 SimpleViewItemGroup serviceOrContentGroup = new SimpleViewItemGroup(); 383 serviceOrContentGroup.setName(zoneItem.getName() + "_contentOrService"); 384 385 ViewElement viewElement = new ViewElement(); 386 ElementDefinition<String> enumeratorViewDefinition = modelItemViews.getEnumeratorViewDefinition(); 387 viewElement.setDefinition(enumeratorViewDefinition); 388 serviceOrContentGroup.addViewItem(viewElement); 389 390 Map<String, ViewParametersModel> serviceOrContentViewParameters = modelItemViews.getServiceOrContentViewParameters(); 391 for (String viewName : serviceOrContentViewParameters.keySet()) 392 { 393 ViewParametersModel viewParameters = serviceOrContentViewParameters.get(viewName); 394 Collection< ? extends ModelItem> modelItems = viewParameters.getModelItems(); 395 396 String prefix = modelItemViews.getPrefix() + MODEL_ITEM_NAME_SEPARATOR + _viewParametersManager.normalizeViewName(viewName) + MODEL_ITEM_NAME_SEPARATOR; 397 List<ModelItem> includedModelItems = _viewParametersManager.includeModelItems(modelItems, prefix, serviceOrContentGroup); 398 _viewParametersManager.setDisableConditions(enumeratorViewDefinition.getName(), OPERATOR.NEQ, viewName, includedModelItems); 399 400 // Create a model from the included (copied) model items. So the model of the model items is not the one with the original not prefixed items 401 Model.of(PREFIX_TEMPLATE, ROLE, includedModelItems.toArray(new ModelItem[includedModelItems.size()])); 402 } 403 404 group.addViewItem(serviceOrContentGroup); 405 } 406 407 viewItemContainer.addViewItem(group); 408 } 409 } 410 411 412 private void _setRequestAttribute(String serviceId, String pageId, String zoneItemId, String zoneName) 413 { 414 Request request = ContextHelper.getRequest(_context); 415 416 request.setAttribute(WebConstants.REQUEST_ATTR_SERVICE_ID, serviceId); 417 request.setAttribute(WebConstants.REQUEST_ATTR_PAGE_ID, pageId); 418 request.setAttribute(WebConstants.REQUEST_ATTR_ZONEITEM_ID, zoneItemId); 419 request.setAttribute(WebConstants.REQUEST_ATTR_ZONE_NAME, zoneName); 420 } 421 422 /** 423 * Add service view parameters to the model item views wrapper 424 * @param modelItemViews the model item views wrapper 425 * @param zoneItem the zone item 426 * @param skinId the skin id 427 */ 428 protected void _addServiceViewParameters(ModelItemViewsWrapper modelItemViews, ZoneItem zoneItem, String skinId) 429 { 430 // The zone item contains a service 431 String serviceId = zoneItem.getServiceId(); 432 Service service = _serviceEP.getExtension(serviceId); 433 434 Zone zone = zoneItem.getZone(); 435 _setRequestAttribute(serviceId, zone.getSitemapElement().getId(), zoneItem.getId(), zone.getName()); 436 437 Map<String, I18nizableTextParameter> parameters = new HashMap<>(); 438 parameters.put("title", service.getLabel()); 439 modelItemViews.setLabel(new I18nizableText("plugin.web", "PLUGINS_WEB_VIEW_PARAMETERS_DIALOG_BOX_SERVICE_LABEL", parameters)); 440 modelItemViews.setPrefix(PREFIX_SERVICE); 441 442 ElementDefinition<String> serviceViewEnumerator = _viewParametersManager.getServiceViewEnumerator(serviceId); 443 if (serviceViewEnumerator != null) 444 { 445 modelItemViews.setEnumeratorViewDefinition(serviceViewEnumerator); 446 447 Map<String, ViewParametersModel> serviceViewParametersModels = _viewParametersManager.getServiceViewParametersModels(skinId, serviceId); 448 for (String viewName : serviceViewParametersModels.keySet()) 449 { 450 ViewParametersModel serviceViewParameters = serviceViewParametersModels.get(viewName); 451 modelItemViews.addServiceOrContentViewParameters(viewName, serviceViewParameters); 452 } 453 } 454 } 455 456 /** 457 * Add content view parameters to the model item views wrapper 458 * @param modelItemViews the model item views wrapper 459 * @param zoneItem the zone item 460 * @param skinId the skin id 461 */ 462 protected void _addContentViewParameters(ModelItemViewsWrapper modelItemViews, ZoneItem zoneItem, String skinId) 463 { 464 // The zone item contains a content 465 Content content = zoneItem.getContent(); 466 List<String> parameters = new ArrayList<>(); 467 parameters.add(content.getTitle()); 468 modelItemViews.setLabel(new I18nizableText("plugin.web", "PLUGINS_WEB_VIEW_PARAMETERS_DIALOG_BOX_CONTENT_LABEL", parameters)); 469 modelItemViews.setPrefix(PREFIX_CONTENT); 470 471 ElementDefinition<String> elementDef = _viewParametersManager.getContentViewEnumerator(skinId, content); 472 modelItemViews.setEnumeratorViewDefinition(elementDef); 473 474 Map<String, ViewParametersModel> contentViewParametersModels = _viewParametersManager.getContentViewParametersModels(skinId, content); 475 for (String viewName : contentViewParametersModels.keySet()) 476 { 477 ViewParametersModel contentViewParameters = contentViewParametersModels.get(viewName); 478 modelItemViews.addServiceOrContentViewParameters(viewName, contentViewParameters); 479 } 480 } 481 482 /** 483 * Get the view parameters values 484 * @param pageId the page id 485 * @param zoneName the zone name (Can be null) 486 * @param zoneItemId the zone item id (Can be null) 487 * @return the values 488 */ 489 @Callable(rights = "Web_Rights_Page_Configure_View_Parameters", rightContext = PageRightAssignmentContext.ID, paramIndex = 0) 490 public Map<String, Object> getViewParametersValues(String pageId, String zoneName, String zoneItemId) 491 { 492 Map<String, Object> response = new HashMap<>(); 493 Map<String, Object> values = new HashMap<>(); 494 495 ModifiableSitemapElement page = _getModifiablePage(pageId); 496 Site site = page.getSite(); 497 Skin skin = _skinsManager.getSkin(site.getSkinId()); 498 499 SkinTemplate template = skin.getTemplate(page.getTemplate()); 500 if (template != null) 501 { 502 values.putAll(_getTemplateViewParametersValues(page, template)); 503 504 Optional<ModifiableZoneItem> zoneItem = _getModifiableZoneItem(zoneItemId); 505 Optional<SkinTemplateZone> templateZone = _getSkinTemplateZone(template, zoneName, zoneItem); 506 if (templateZone.isPresent()) 507 { 508 SkinTemplateZone skinTemplateZone = templateZone.get(); 509 values.putAll(_getZoneViewParametersValues(page, skinTemplateZone)); 510 511 if (zoneItem.isPresent()) 512 { 513 values.putAll(_getZoneItemViewParametersValues(page, skin, skinTemplateZone, zoneItem.get())); 514 } 515 } 516 } 517 518 response.put("values", values); 519 return response; 520 } 521 522 /** 523 * Get the template view parameters values 524 * @param page the page 525 * @param template the template 526 * @return the values 527 */ 528 protected Map<String, Object> _getTemplateViewParametersValues(ModifiableSitemapElement page, SkinTemplate template) 529 { 530 Optional<ViewParametersModel> templateViewParameters = _viewParametersManager.getTemplateViewParametersModel(template); 531 if (templateViewParameters.isEmpty()) 532 { 533 return MapUtils.EMPTY_SORTED_MAP; 534 } 535 536 ModifiableModelAwareDataHolder pageViewParametersHolder = page.getTemplateParametersHolder(); 537 Map<String, Object> templateValues = _parametersManager.getParametersValues(templateViewParameters.get().getModelItems(), pageViewParametersHolder, ""); 538 539 String prefix = PREFIX_TEMPLATE + MODEL_ITEM_NAME_SEPARATOR + template.getId() + MODEL_ITEM_NAME_SEPARATOR; 540 return _parametersManager.addPrefixToParameters(templateValues, prefix); 541 } 542 543 /** 544 * Get the zone view parameters values 545 * @param page the page 546 * @param skinZone the zone 547 * @return the values 548 */ 549 protected Map<String, Object> _getZoneViewParametersValues(ModifiableSitemapElement page, SkinTemplateZone skinZone) 550 { 551 Optional<ViewParametersModel> zoneViewParameters = _viewParametersManager.getZoneViewParametersModel(skinZone); 552 if (zoneViewParameters.isEmpty()) 553 { 554 return MapUtils.EMPTY_SORTED_MAP; 555 } 556 557 String zoneName = skinZone.getId(); 558 if (page.hasZone(zoneName)) 559 { 560 ModifiableZone zone = page.getZone(zoneName); 561 562 ModifiableModelAwareDataHolder zoneViewParametersHolder = zone.getZoneParametersHolder(); 563 Map<String, Object> zoneValues = _parametersManager.getParametersValues(zoneViewParameters.get().getModelItems(), zoneViewParametersHolder, ""); 564 565 String prefix = PREFIX_ZONE + MODEL_ITEM_NAME_SEPARATOR + zoneName + MODEL_ITEM_NAME_SEPARATOR; 566 return _parametersManager.addPrefixToParameters(zoneValues, prefix); 567 } 568 569 return MapUtils.EMPTY_SORTED_MAP; 570 } 571 572 /** 573 * Get the zone item view parameters values 574 * @param page the page 575 * @param skin the skin 576 * @param skinZone the zone 577 * @param zoneItem the zone item 578 * @return the values 579 */ 580 protected Map<String, Object> _getZoneItemViewParametersValues(ModifiableSitemapElement page, Skin skin, SkinTemplateZone skinZone, ModifiableZoneItem zoneItem) 581 { 582 Map<String, Object> values = new HashMap<>(); 583 584 ModifiableModelAwareDataHolder zoneItemViewParametersHolder = zoneItem.getZoneItemParametersHolder(); 585 Optional<ViewParametersModel> zoneItemViewParameters = skinZone.getZoneItemViewParameters(); 586 if (zoneItemViewParameters.isEmpty()) 587 { 588 return MapUtils.EMPTY_SORTED_MAP; 589 } 590 591 Map<String, Object> zoneItemValues = _parametersManager.getParametersValues(zoneItemViewParameters.get().getModelItems(), zoneItemViewParametersHolder, ""); 592 String prefix = PREFIX_ZONE_ITEM + MODEL_ITEM_NAME_SEPARATOR + skinZone.getId() + MODEL_ITEM_NAME_SEPARATOR; 593 values.putAll(_parametersManager.addPrefixToParameters(zoneItemValues, prefix)); 594 595 if (zoneItem.getType() == ZoneType.SERVICE) 596 { 597 values.putAll(_getServiceViewParametersValues(skin, zoneItem)); 598 } 599 else if (zoneItem.getType() == ZoneType.CONTENT) 600 { 601 values.putAll(_getContentViewParametersValues(skin, zoneItem)); 602 } 603 604 return values; 605 } 606 607 /** 608 * Get the service view parameters values 609 * @param skin the skin 610 * @param zoneItem the zone item 611 * @return the values 612 */ 613 protected Map<String, Object> _getServiceViewParametersValues(Skin skin, ModifiableZoneItem zoneItem) 614 { 615 Map<String, Object> values = new HashMap<>(); 616 617 Zone zone = zoneItem.getZone(); 618 _setRequestAttribute(zoneItem.getServiceId(), zone.getSitemapElement().getId(), zoneItem.getId(), zone.getName()); 619 620 ModifiableModelAwareDataHolder serviceParameters = zoneItem.getServiceParameters(); 621 if (serviceParameters.hasDefinition(ViewParametersManager.SERVICE_VIEW_DEFAULT_MODEL_ITEM_NAME)) 622 { 623 values.put(ViewParametersManager.SERVICE_VIEW_DEFAULT_MODEL_ITEM_NAME, serviceParameters.getValue(ViewParametersManager.SERVICE_VIEW_DEFAULT_MODEL_ITEM_NAME)); 624 } 625 626 Map<String, ViewParametersModel> serviceViewParametersModels = _viewParametersManager.getServiceViewParametersModels(skin.getId(), zoneItem.getServiceId()); 627 for (String viewName : serviceViewParametersModels.keySet()) 628 { 629 ViewParametersModel serviceViewParameters = serviceViewParametersModels.get(viewName); 630 ModifiableModelAwareDataHolder serviceViewParametersHolder = zoneItem.getServiceViewParametersHolder(viewName); 631 632 Map<String, Object> serviceValues = _parametersManager.getParametersValues(serviceViewParameters.getModelItems(), serviceViewParametersHolder, ""); 633 String prefix = PREFIX_SERVICE + MODEL_ITEM_NAME_SEPARATOR + _viewParametersManager.normalizeViewName(viewName) + MODEL_ITEM_NAME_SEPARATOR; 634 values.putAll(_parametersManager.addPrefixToParameters(serviceValues, prefix)); 635 } 636 637 return values; 638 } 639 640 /** 641 * Get the content view parameters values 642 * @param skin the skin 643 * @param zoneItem the zone item 644 * @return the values 645 */ 646 protected Map<String, Object> _getContentViewParametersValues(Skin skin, ModifiableZoneItem zoneItem) 647 { 648 Map<String, Object> values = new HashMap<>(); 649 650 values.put(ViewParametersManager.CONTENT_VIEW_MODEL_ITEM_NAME, zoneItem.getViewName()); 651 652 Map<String, ViewParametersModel> contentViewParametersModels = _viewParametersManager.getContentViewParametersModels(skin.getId(), zoneItem.getContent()); 653 for (String viewName : contentViewParametersModels.keySet()) 654 { 655 ViewParametersModel contentViewParameters = contentViewParametersModels.get(viewName); 656 ModifiableModelAwareDataHolder contentViewParametersHolder = zoneItem.getContentViewParametersHolder(viewName); 657 658 Map<String, Object> serviceValues = _parametersManager.getParametersValues(contentViewParameters.getModelItems(), contentViewParametersHolder, ""); 659 String prefix = PREFIX_CONTENT + MODEL_ITEM_NAME_SEPARATOR + _viewParametersManager.normalizeViewName(viewName) + MODEL_ITEM_NAME_SEPARATOR; 660 values.putAll(_parametersManager.addPrefixToParameters(serviceValues, prefix)); 661 } 662 663 return values; 664 } 665 666 /** 667 * Set view parameters values 668 * @param pageId the page id 669 * @param zoneName the zone name (Can be null) 670 * @param zoneItemId the zone item id (Can be null) 671 * @param parameterValues the parameter values 672 * @return results map 673 * @throws IOException If an error occurred 674 */ 675 @Callable(rights = "Web_Rights_Page_Configure_View_Parameters", rightContext = PageRightAssignmentContext.ID, paramIndex = 0) 676 public Map<String, Object> setViewParametersValues(String pageId, String zoneName, String zoneItemId, Map<String, Object> parameterValues) throws IOException 677 { 678 Map<String, Object> results = new HashMap<>(); 679 Map<String, List<I18nizableText>> allErrors = new HashMap<>(); 680 681 ModifiableSitemapElement sitemapElement = _getModifiablePage(pageId); 682 683 if (sitemapElement instanceof LockablePage lockablePage && lockablePage.isLocked()) 684 { 685 throw new IllegalArgumentException("Can not change view of a locked page '/" + sitemapElement.getSitemapName() + "/" + sitemapElement.getPathInSitemap() + "'"); 686 } 687 688 Site site = sitemapElement.getSite(); 689 Skin skin = _skinsManager.getSkin(site.getSkinId()); 690 SkinTemplate template = skin.getTemplate(sitemapElement.getTemplate()); 691 692 if (template != null) 693 { 694 allErrors.putAll(_setTemplateViewParameters(sitemapElement, template, parameterValues)); 695 696 Optional<ModifiableZoneItem> zoneItem = _getModifiableZoneItem(zoneItemId); 697 Optional<SkinTemplateZone> templateZone = _getSkinTemplateZone(template, zoneName, zoneItem); 698 if (templateZone.isPresent()) 699 { 700 SkinTemplateZone skinTemplateZone = templateZone.get(); 701 allErrors.putAll(_setZoneViewParameters(sitemapElement, skinTemplateZone, parameterValues)); 702 703 if (zoneItem.isPresent()) 704 { 705 allErrors.putAll(_setZoneItemViewParameters(sitemapElement, skin, skinTemplateZone, zoneItem.get(), parameterValues)); 706 } 707 } 708 } 709 710 if (!allErrors.isEmpty()) 711 { 712 results.put("errors", allErrors); 713 return results; 714 } 715 716 sitemapElement.saveChanges(); 717 718 Map<String, Object> eventParams = new HashMap<>(); 719 eventParams.put(ObservationConstants.ARGS_SITEMAP_ELEMENT, sitemapElement); 720 _observationManager.notify(new Event(ObservationConstants.EVENT_VIEW_PARAMETERS_MODIFIED, _currentUserProvider.getUser(), eventParams)); 721 722 return results; 723 } 724 725 /** 726 * Set template view parameters values 727 * @param page the page 728 * @param template the template 729 * @param parameterValues the parameter values 730 * @return the errors 731 */ 732 protected Map<String, List<I18nizableText>> _setTemplateViewParameters(ModifiableSitemapElement page, SkinTemplate template, Map<String, Object> parameterValues) 733 { 734 Optional<ViewParametersModel> templateViewParameters = _viewParametersManager.getTemplateViewParametersModel(template); 735 if (templateViewParameters.isEmpty()) 736 { 737 return MapUtils.EMPTY_SORTED_MAP; 738 } 739 740 String templatePrefix = PREFIX_TEMPLATE + MODEL_ITEM_NAME_SEPARATOR + template.getId() + MODEL_ITEM_NAME_SEPARATOR; 741 Map<String, Object> templateParameters = _parametersManager.getParametersStartWithPrefix(parameterValues, templatePrefix); 742 743 // Do this because can't set null value to boolean model item. FIXME CMS-10275 744 if (!templateParameters.containsKey(ViewParametersManager.TEMPLATE_INHERIT_MODEL_ITEM_NAME)) 745 { 746 templateParameters.put(ViewParametersManager.TEMPLATE_INHERIT_MODEL_ITEM_NAME, true); 747 } 748 749 ModifiableModelAwareDataHolder pageViewParametersHolder = page.getTemplateParametersHolder(); 750 return _parametersManager.setParameterValues(pageViewParametersHolder, templateViewParameters.get().getModelItems(), templateParameters); 751 } 752 753 /** 754 * Set zone view parameters values 755 * @param page the page 756 * @param skinZone the zone 757 * @param parameterValues the parameter values 758 * @return the errors 759 */ 760 protected Map<String, List<I18nizableText>> _setZoneViewParameters(ModifiableSitemapElement page, SkinTemplateZone skinZone, Map<String, Object> parameterValues) 761 { 762 Optional<ViewParametersModel> zoneViewParameters = _viewParametersManager.getZoneViewParametersModel(skinZone); 763 if (zoneViewParameters.isEmpty()) 764 { 765 return MapUtils.EMPTY_SORTED_MAP; 766 } 767 768 String zoneName = skinZone.getId(); 769 ModifiableZone zone = page.hasZone(zoneName) ? page.getZone(zoneName) : page.createZone(zoneName); 770 771 String zonePrefix = PREFIX_ZONE + MODEL_ITEM_NAME_SEPARATOR + zoneName + MODEL_ITEM_NAME_SEPARATOR; 772 Map<String, Object> zoneParameters = _parametersManager.getParametersStartWithPrefix(parameterValues, zonePrefix); 773 774 // Do this because can't set null value to boolean model item. FIXME CMS-10275 775 if (!zoneParameters.containsKey(ViewParametersManager.ZONE_INHERIT_MODEL_ITEM_NAME)) 776 { 777 zoneParameters.put(ViewParametersManager.ZONE_INHERIT_MODEL_ITEM_NAME, true); 778 } 779 780 ModifiableModelAwareDataHolder zoneViewParametersHolder = zone.getZoneParametersHolder(); 781 return _parametersManager.setParameterValues(zoneViewParametersHolder, zoneViewParameters.get().getModelItems(), zoneParameters); 782 } 783 784 /** 785 * Set zone item view parameters values 786 * @param page the page 787 * @param skin the skin 788 * @param skinZone the zone 789 * @param zoneItem the zone item 790 * @param parameterValues the parameter values 791 * @return the errors 792 */ 793 protected Map<String, List<I18nizableText>> _setZoneItemViewParameters(ModifiableSitemapElement page, Skin skin, SkinTemplateZone skinZone, ModifiableZoneItem zoneItem, Map<String, Object> parameterValues) 794 { 795 Map<String, List<I18nizableText>> allErrors = new HashMap<>(); 796 797 Optional<ViewParametersModel> zoneItemViewParameters = skinZone.getZoneItemViewParameters(); 798 if (zoneItemViewParameters.isEmpty()) 799 { 800 return allErrors; 801 } 802 803 ModifiableModelAwareDataHolder zoneItemViewParametersHolder = zoneItem.getZoneItemParametersHolder(); 804 805 String zoneItemPrefix = PREFIX_ZONE_ITEM + MODEL_ITEM_NAME_SEPARATOR + skinZone.getId() + MODEL_ITEM_NAME_SEPARATOR; 806 Map<String, Object> zoneItemParameters = _parametersManager.getParametersStartWithPrefix(parameterValues, zoneItemPrefix); 807 808 allErrors.putAll(_parametersManager.setParameterValues(zoneItemViewParametersHolder, zoneItemViewParameters.get().getModelItems(), zoneItemParameters)); 809 810 if (zoneItem.getType() == ZoneType.SERVICE) 811 { 812 allErrors.putAll(_setServiceViewParameters(skin, zoneItem, parameterValues)); 813 } 814 else if (zoneItem.getType() == ZoneType.CONTENT) 815 { 816 allErrors.putAll(_setContentViewParameters(skin, zoneItem, parameterValues)); 817 } 818 819 return allErrors; 820 } 821 822 /** 823 * Set service view parameters values 824 * @param skin the skin 825 * @param zoneItem the zone item 826 * @param parameterValues the parameter values 827 * @return the errors 828 */ 829 protected Map<String, List<I18nizableText>> _setServiceViewParameters(Skin skin, ModifiableZoneItem zoneItem, Map<String, Object> parameterValues) 830 { 831 String viewName = (String) parameterValues.get(ViewParametersManager.SERVICE_VIEW_DEFAULT_MODEL_ITEM_NAME); 832 if (StringUtils.isEmpty(viewName)) 833 { 834 // We have a service with no view parameters 835 return MapUtils.EMPTY_SORTED_MAP; 836 } 837 838 String serviceId = zoneItem.getServiceId(); 839 ModifiableModelAwareDataHolder serviceParameters = zoneItem.getServiceParameters(); 840 serviceParameters.setValue(ViewParametersManager.SERVICE_VIEW_DEFAULT_MODEL_ITEM_NAME, viewName); 841 842 Optional<ViewParametersModel> serviceViewParameters = _viewParametersManager.getServiceViewParametersModel(skin.getId(), serviceId, viewName); 843 if (serviceViewParameters.isEmpty()) 844 { 845 return MapUtils.EMPTY_SORTED_MAP; 846 } 847 848 ModifiableModelAwareDataHolder serviceViewParametersHolder = zoneItem.getServiceViewParametersHolder(viewName); 849 850 String servicePrefix = PREFIX_SERVICE + MODEL_ITEM_NAME_SEPARATOR + _viewParametersManager.normalizeViewName(viewName) + MODEL_ITEM_NAME_SEPARATOR; 851 Map<String, Object> parameters = _parametersManager.getParametersStartWithPrefix(parameterValues, servicePrefix); 852 853 return _parametersManager.setParameterValues(serviceViewParametersHolder, serviceViewParameters.get().getModelItems(), parameters); 854 } 855 856 /** 857 * Set content view parameters values 858 * @param skin the skin 859 * @param zoneItem the zone item 860 * @param parameterValues the parameter values 861 * @return the errors 862 */ 863 protected Map<String, List<I18nizableText>> _setContentViewParameters(Skin skin, ModifiableZoneItem zoneItem, Map<String, Object> parameterValues) 864 { 865 String viewName = (String) parameterValues.get(ViewParametersManager.CONTENT_VIEW_MODEL_ITEM_NAME); 866 if (StringUtils.isEmpty(viewName)) 867 { 868 // We have a content with no view parameters 869 return MapUtils.EMPTY_SORTED_MAP; 870 } 871 872 Content content = zoneItem.getContent(); 873 zoneItem.setViewName(viewName); 874 Optional<ViewParametersModel> contentViewParameters = _viewParametersManager.getContentViewParametersModel(skin.getId(), content, viewName); 875 if (contentViewParameters.isEmpty()) 876 { 877 return MapUtils.EMPTY_SORTED_MAP; 878 } 879 880 ModifiableModelAwareDataHolder contentViewParametersHolder = zoneItem.getContentViewParametersHolder(viewName); 881 882 String contentPrefix = PREFIX_CONTENT + MODEL_ITEM_NAME_SEPARATOR + _viewParametersManager.normalizeViewName(viewName) + MODEL_ITEM_NAME_SEPARATOR; 883 Map<String, Object> contentParameters = _parametersManager.getParametersStartWithPrefix(parameterValues, contentPrefix); 884 885 return _parametersManager.setParameterValues(contentViewParametersHolder, contentViewParameters.get().getModelItems(), contentParameters); 886 } 887 888 /** 889 * Get the modifiable page from id 890 * @param pageId the page id 891 * @return the modifiable page 892 */ 893 protected ModifiableSitemapElement _getModifiablePage(String pageId) 894 { 895 try 896 { 897 SitemapElement page = _resolver.resolveById(pageId); 898 if (!(page instanceof ModifiableSitemapElement)) 899 { 900 throw new IllegalArgumentException("The non-modifiable page (" + pageId + ") can't have view parameters"); 901 } 902 903 return (ModifiableSitemapElement) page; 904 905 } 906 catch (UnknownAmetysObjectException e) 907 { 908 throw new IllegalArgumentException("An error occured getting the modifiable page from id " + pageId, e); 909 } 910 } 911 912 /** 913 * Get the modifiable zone item from id 914 * @param zoneItemId the zone item id 915 * @return the modifiable zone item 916 */ 917 protected Optional<ModifiableZoneItem> _getModifiableZoneItem(String zoneItemId) 918 { 919 if (StringUtils.isNotBlank(zoneItemId)) 920 { 921 try 922 { 923 ZoneItem zoneItem = _resolver.resolveById(zoneItemId); 924 if (!(zoneItem instanceof ModifiableZoneItem)) 925 { 926 throw new IllegalArgumentException("The non-modifiable zone item (" + zoneItemId + ") can't have view parameters"); 927 } 928 929 return Optional.of((ModifiableZoneItem) zoneItem); 930 931 } 932 catch (UnknownAmetysObjectException e) 933 { 934 throw new IllegalArgumentException("An error occured getting the modifiable zone item from id " + zoneItemId, e); 935 } 936 } 937 938 return Optional.empty(); 939 } 940 941 /** 942 * Get the skin template zone 943 * @param template the template 944 * @param zoneName the zone name 945 * @param zoneItem the zone item 946 * @return the skin template zone 947 */ 948 protected Optional<SkinTemplateZone> _getSkinTemplateZone(SkinTemplate template, String zoneName, Optional<ModifiableZoneItem> zoneItem) 949 { 950 if (StringUtils.isNotBlank(zoneName)) 951 { 952 return Optional.ofNullable(template.getZone(zoneName)); 953 } 954 else if (zoneItem.isPresent()) 955 { 956 String name = zoneItem.get().getZone().getName(); 957 return Optional.ofNullable(template.getZone(name)); 958 } 959 960 return Optional.empty(); 961 } 962 963 /** 964 * Class representing a model item and its view parameters 965 */ 966 static class ModelItemViewsWrapper 967 { 968 I18nizableText _label; 969 Optional<ViewParametersModel> _zoneItemViewParameters; 970 Map<String, ViewParametersModel> _contentOrServiceViewParameters; 971 ElementDefinition<String> _enumeratorViewDefinition; 972 String _prefix; 973 974 ModelItemViewsWrapper() 975 { 976 this._label = null; 977 this._zoneItemViewParameters = null; 978 this._contentOrServiceViewParameters = new HashMap<>(); 979 this._enumeratorViewDefinition = null; 980 this._prefix = StringUtils.EMPTY; 981 } 982 983 I18nizableText getLabel() 984 { 985 return this._label; 986 } 987 988 void setLabel(I18nizableText label) 989 { 990 this._label = label; 991 } 992 993 Optional<ViewParametersModel> getZoneItemViewParameters() 994 { 995 return this._zoneItemViewParameters; 996 } 997 998 void setZoneItemViewParameters(Optional<ViewParametersModel> viewParameters) 999 { 1000 this._zoneItemViewParameters = viewParameters; 1001 } 1002 1003 Map<String, ViewParametersModel> getServiceOrContentViewParameters() 1004 { 1005 return this._contentOrServiceViewParameters; 1006 } 1007 1008 void addServiceOrContentViewParameters(String viewName, ViewParametersModel serviceViewParameters) 1009 { 1010 this._contentOrServiceViewParameters.put(viewName, serviceViewParameters); 1011 } 1012 1013 ElementDefinition<String> getEnumeratorViewDefinition() 1014 { 1015 return this._enumeratorViewDefinition; 1016 } 1017 1018 void setEnumeratorViewDefinition(ElementDefinition<String> elementDefinition) 1019 { 1020 this._enumeratorViewDefinition = elementDefinition; 1021 } 1022 1023 String getPrefix() 1024 { 1025 return this._prefix; 1026 } 1027 1028 void setPrefix(String prefix) 1029 { 1030 this._prefix = prefix; 1031 } 1032 1033 boolean hasZoneItemViewParameters() 1034 { 1035 return _zoneItemViewParameters.isPresent() && _zoneItemViewParameters.get().isNotEmpty(); 1036 } 1037 1038 boolean hasServiceOrContentViewParameters() 1039 { 1040 boolean hasViewParameters = false; 1041 for (ViewParametersModel viewParameters : _contentOrServiceViewParameters.values()) 1042 { 1043 hasViewParameters = viewParameters.isNotEmpty() || hasViewParameters; 1044 } 1045 1046 return hasViewParameters; 1047 } 1048 1049 boolean hasViewParameters() 1050 { 1051 return hasZoneItemViewParameters() || hasServiceOrContentViewParameters(); 1052 } 1053 } 1054}