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