001/*
002 *  Copyright 2018 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.search.widgets;
017
018import java.util.Arrays;
019import java.util.Collection;
020import java.util.HashMap;
021import java.util.List;
022import java.util.Map;
023import java.util.Objects;
024import java.util.stream.Collectors;
025
026import org.apache.avalon.framework.service.ServiceException;
027import org.apache.avalon.framework.service.ServiceManager;
028
029import org.ametys.core.ui.Callable;
030import org.ametys.core.ui.widgets.StaticClientSideWidget;
031import org.ametys.core.util.LambdaUtils;
032import org.ametys.runtime.i18n.I18nizableText;
033import org.ametys.runtime.model.DefinitionContext;
034import org.ametys.web.frontoffice.search.metamodel.AdditionalParameterValueMap;
035import org.ametys.web.frontoffice.search.metamodel.AdditionalSearchServiceParameter;
036import org.ametys.web.frontoffice.search.metamodel.Returnable;
037import org.ametys.web.frontoffice.search.metamodel.SearchServiceCreationHelper;
038import org.ametys.web.frontoffice.search.metamodel.SearchServiceCriterionDefinition;
039import org.ametys.web.frontoffice.search.metamodel.SearchServiceFacetDefinition;
040import org.ametys.web.frontoffice.search.metamodel.SearchServiceSortDefinition;
041import org.ametys.web.frontoffice.search.metamodel.Searchable;
042
043/**
044 * The class for search service specific widgets.
045 */
046public class SearchServiceClientSideWidget extends StaticClientSideWidget
047{
048    private SearchServiceCreationHelper _serviceCreationHelper;
049    
050    @Override
051    public void service(ServiceManager smanager) throws ServiceException
052    {
053        super.service(smanager);
054        _serviceCreationHelper = (SearchServiceCreationHelper) smanager.lookup(SearchServiceCreationHelper.ROLE);
055    }
056    
057    /**
058     * Gets the {@link SearchServiceCriterionDefinition}s to display as JSON
059     * @param returnableIds The selected {@link Returnable}s
060     * @param formValues The values of the form
061     * @return the {@link SearchServiceCriterionDefinition}s to display as JSON
062     */
063    @Callable (rights = Callable.NO_CHECK_REQUIRED) // Definition of search criteria is public
064    public Map<String, Map<String, Object>> getCriterionDefinitions(List<String> returnableIds, Map<String, Object> formValues)
065    {
066        Collection<Returnable> returnables = _serviceCreationHelper.getReturnables(returnableIds);
067        Collection<Searchable> searchables = _serviceCreationHelper.getSearchables(returnables);
068        Collection<AdditionalSearchServiceParameter> additionalParameters = _serviceCreationHelper.getAdditionalParameters();
069        AdditionalParameterValueMap additionalParameterValues = _serviceCreationHelper.getAdditionalParameterValues(additionalParameters, formValues);
070        Map<String, SearchServiceCriterionDefinition> criterionDefinitions = _serviceCreationHelper.getCriterionDefinitions(searchables, additionalParameterValues);
071        
072        return criterionDefinitions.entrySet()
073                .stream()
074                .collect(LambdaUtils.Collectors.toLinkedHashMap(
075                        Map.Entry::getKey,
076                        LambdaUtils.wrap(e -> e.getValue().toJSON(DefinitionContext.newInstance()))
077                ));
078    }
079    
080    /**
081     * Gets the {@link SearchServiceFacetDefinition}s to display as JSON
082     * @param parameters The client parameters. It must contain 'returnableIds' and 'formValues' keys.
083     * @return the {@link SearchServiceFacetDefinition}s to display as JSON
084     */
085    @Callable (rights = Callable.NO_CHECK_REQUIRED) // Definition of search facets is public
086    public List<Map<String, Object>> getFacetDefinitions(Map<String, Object> parameters)
087    {
088        @SuppressWarnings("unchecked")
089        List<String> returnableIds = (List<String>) parameters.get("returnableIds");
090        Objects.requireNonNull(returnableIds);
091        @SuppressWarnings("unchecked")
092        Map<String, Object> formValues = (Map<String, Object>) parameters.get("formValues");
093        Objects.requireNonNull(formValues);
094        return getFacetDefinitions(returnableIds, formValues);
095    }
096    
097    /**
098     * Gets the {@link SearchServiceFacetDefinition}s to display as JSON
099     * @param returnableIds The selected {@link Returnable}s
100     * @param formValues The values of the form
101     * @return the {@link SearchServiceFacetDefinition}s to display as JSON
102     */
103    public List<Map<String, Object>> getFacetDefinitions(List<String> returnableIds, Map<String, Object> formValues)
104    {
105        Collection<Returnable> returnables = _serviceCreationHelper.getReturnables(returnableIds);
106        Collection<AdditionalSearchServiceParameter> additionalParameters = _serviceCreationHelper.getAdditionalParameters();
107        AdditionalParameterValueMap additionalParameterValues = _serviceCreationHelper.getAdditionalParameterValues(additionalParameters, formValues);
108        Map<String, SearchServiceFacetDefinition> facetDefinitions = _serviceCreationHelper.getFacetDefinitions(returnables, additionalParameterValues);
109        return facetDefinitions.values()
110                .stream()
111                .map(this::_facetDefinitionToJson)
112                .collect(Collectors.toList());
113    }
114    
115    private Map<String, Object> _facetDefinitionToJson(SearchServiceFacetDefinition facetDefinition)
116    {
117        Map<String, Object> result = new HashMap<>();
118        
119        result.put("value", facetDefinition.getName());
120        result.put("shortText", facetDefinition.getLabel());
121        result.put("contextPrefixLabel", facetDefinition.getContextPrefixLabel());
122        result.put("groupText", facetDefinition.getReturnable()
123                                                .map(Returnable::getLabel)
124                                                .orElse(new I18nizableText("plugin.web", "PLUGINS_WEB_SERVICE_SEARCH_COMMON_FACET_GROUP")));
125        
126        return result;
127    }
128    
129    /**
130     * Gets the {@link SearchServiceSortDefinition}s to display as JSON
131     * @param parameters The client parameters. It must contain 'returnableIds' and 'formValues' keys.
132     * @return the {@link SearchServiceSortDefinition}s to display as JSON
133     */
134    @Callable (rights = Callable.NO_CHECK_REQUIRED) // Definition of search sorts is public
135    public List<Map<String, Object>> getSortDefinitions(Map<String, Object> parameters)
136    {
137        @SuppressWarnings("unchecked")
138        List<String> returnableIds = (List<String>) parameters.get("returnableIds");
139        Objects.requireNonNull(returnableIds);
140        @SuppressWarnings("unchecked")
141        Map<String, Object> formValues = (Map<String, Object>) parameters.get("formValues");
142        Objects.requireNonNull(formValues);
143        return getSortDefinitions(returnableIds, formValues);
144    }
145    
146    /**
147     * Gets the {@link SearchServiceSortDefinition}s to display as JSON
148     * @param returnableIds The selected {@link Returnable}s
149     * @param formValues The SortDefinition of the form
150     * @return the {@link SearchServiceFacetDefinition}s to display as JSON
151     */
152    public List<Map<String, Object>> getSortDefinitions(List<String> returnableIds, Map<String, Object> formValues)
153    {
154        Collection<Returnable> returnables = _serviceCreationHelper.getReturnables(returnableIds);
155        Collection<AdditionalSearchServiceParameter> additionalParameters = _serviceCreationHelper.getAdditionalParameters();
156        AdditionalParameterValueMap additionalParameterValues = _serviceCreationHelper.getAdditionalParameterValues(additionalParameters, formValues);
157        Map<String, SearchServiceSortDefinition> sortDefinitions = _serviceCreationHelper.getSortDefinitions(returnables, additionalParameterValues);
158        return sortDefinitions.values()
159                .stream()
160                .map(this::_sortDefinitionToJson)
161                .collect(Collectors.toList());
162    }
163    
164    private Map<String, Object> _sortDefinitionToJson(SearchServiceSortDefinition sortDefinition)
165    {
166        Map<String, Object> result = new HashMap<>();
167        
168        result.put("value", sortDefinition.getName());
169        result.put("shortText", sortDefinition.getLabel());
170        result.put("contextPrefixLabel", sortDefinition.getContextPrefixLabel());
171        result.put("groupText", sortDefinition.getReturnable()
172                                                .map(Returnable::getLabel)
173                                                .orElse(new I18nizableText("plugin.web", "PLUGINS_WEB_SERVICE_SEARCH_COMMON_SORT_GROUP")));
174        result.put("availableOrders", Arrays.asList(sortDefinition.orders()));
175        
176        return result;
177    }
178}