001/* 002 * Copyright 2012 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.frontoffice; 017 018import java.util.List; 019import java.util.Optional; 020 021import org.apache.avalon.framework.configuration.Configuration; 022import org.apache.avalon.framework.configuration.ConfigurationException; 023import org.apache.avalon.framework.service.ServiceException; 024import org.apache.avalon.framework.service.ServiceManager; 025import org.apache.commons.lang3.StringUtils; 026 027import org.ametys.plugins.repository.data.holder.ModelAwareDataHolder; 028import org.ametys.runtime.model.ModelItem; 029import org.ametys.runtime.model.ModelItemGroup; 030import org.ametys.runtime.model.ModelViewItem; 031import org.ametys.runtime.model.ViewHelper; 032import org.ametys.runtime.model.ViewItem; 033import org.ametys.runtime.model.ViewItemGroup; 034import org.ametys.runtime.model.exception.UndefinedItemPathException; 035import org.ametys.web.repository.page.Page; 036import org.ametys.web.repository.page.ZoneItem; 037import org.ametys.web.service.StaticService; 038 039/** 040 * Service which can be cacheable or not, depending on a parameter. 041 */ 042public class SearchPagesService extends StaticService 043{ 044 /** The additional parameter for FO search extension point */ 045 protected AdditionalParameterFOSearchExtensionPoint _additionalParameterFOSearch; 046 047 @Override 048 public void service(ServiceManager smanager) throws ServiceException 049 { 050 super.service(smanager); 051 _additionalParameterFOSearch = (AdditionalParameterFOSearchExtensionPoint) smanager.lookup(AdditionalParameterFOSearchExtensionPoint.ROLE); 052 } 053 054 @Override 055 public boolean isCacheable(Page currentPage, ZoneItem zoneItem) 056 { 057 ModelAwareDataHolder serviceParameters = zoneItem.getServiceParameters(); 058 059 if (serviceParameters.getValueOrDefault("search-mode", StringUtils.EMPTY).equals("criteria-only")) 060 { 061 String resultsPageId = serviceParameters.getValueOrDefault("page-with-search", StringUtils.EMPTY); 062 063 return !resultsPageId.equals(currentPage.getId()); 064 } 065 066 return false; 067 } 068 069 @Override 070 protected void configureParameters(Configuration parametersConfiguration) throws ConfigurationException 071 { 072 super.configureParameters(parametersConfiguration); 073 074 for (String additionalParamExtentionId : _additionalParameterFOSearch.getExtensionsIds()) 075 { 076 Configuration paramsConfiguration = _additionalParameterFOSearch.getExtension(additionalParamExtentionId); 077 String pluginName = _additionalParameterFOSearch.getPluginName(additionalParamExtentionId); 078 079 for (Configuration paramConfiguration : paramsConfiguration.getChildren()) 080 { 081 // Parse the item to insert 082 String paramName = paramConfiguration.getName(); 083 ModelViewItem itemToInsert = paramName.equals("repeater") ? _viewAndParametersParser.parseRepeater(paramConfiguration, null, pluginName, "plugin." + pluginName, _view, _modelItems, this, _serviceParameterDefinitionParser, _repeaterDefinitionParser) : _viewAndParametersParser.parseParameter(paramConfiguration, null, pluginName, "plugin." + pluginName, _view, _modelItems, this, _serviceParameterDefinitionParser, _repeaterDefinitionParser); 084 085 if (itemToInsert != null) 086 { 087 String insertAfter = paramConfiguration.getAttribute("insertAfter", null); 088 089 // Insert the item after the item with the given name 090 _insertItemAfter(itemToInsert, Optional.ofNullable(insertAfter)); 091 } 092 } 093 } 094 } 095 096 private void _insertItemAfter(ModelViewItem viewItemToInsert, Optional<String> insertAfter) throws ConfigurationException 097 { 098 if (insertAfter.isPresent()) 099 { 100 try 101 { 102 ModelViewItem insertAfterViewItem = _view.getModelViewItem(insertAfter.get()); 103 if (insertAfterViewItem != null) 104 { 105 ViewHelper.insertViewItemAfter(insertAfterViewItem.getParent(), viewItemToInsert, insertAfter.get()); 106 107 // Insert the corresponding model item in the right model item container 108 ModelItem modelItemToInsert = viewItemToInsert.getDefinition(); 109 ModelItemGroup parent = insertAfterViewItem.getDefinition().getParent(); 110 if (parent != null) 111 { 112 parent.addChild(modelItemToInsert); 113 } 114 else 115 { 116 _modelItems.put(modelItemToInsert.getName(), modelItemToInsert); 117 } 118 } 119 else 120 { 121 getLogger().warn("For service {}, could not find the item with name '{}' to insert after. The attribute {} will be added at the end of the view.", this.getId(), insertAfter.get(), viewItemToInsert.getName()); 122 _insertItemAtTheEnd(viewItemToInsert); 123 } 124 } 125 catch (UndefinedItemPathException | IllegalArgumentException ex) 126 { 127 throw new ConfigurationException("Could not add the attribute " + viewItemToInsert.getName() + " after " + insertAfter.get(), ex); 128 } 129 } 130 else 131 { 132 _insertItemAtTheEnd(viewItemToInsert); 133 } 134 } 135 136 private void _insertItemAtTheEnd(ModelViewItem viewItemToInsert) 137 { 138 // Insert the item at the end of the last group 139 List<ViewItem> firstLevelGroups = _view.getViewItems(); 140 141 ViewItem lastElement = firstLevelGroups.get(firstLevelGroups.size() - 1); 142 if (lastElement instanceof ViewItemGroup lastGroup) 143 { 144 // There are only groups in the view, so we can cast without checking 145 lastGroup.addViewItem(viewItemToInsert); 146 } 147 else 148 { 149 // There are no groups in the view, just add the item at the end of the view 150 _view.addViewItem(viewItemToInsert); 151 } 152 153 // Insert the corresponding model item in the service 154 ModelItem itemToInsertDefinition = viewItemToInsert.getDefinition(); 155 _modelItems.put(itemToInsertDefinition.getName(), itemToInsertDefinition); 156 } 157}