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.web.frontoffice.search.metamodel.AdditionalParameterValueMap;
034import org.ametys.web.frontoffice.search.metamodel.AdditionalSearchServiceParameter;
035import org.ametys.web.frontoffice.search.metamodel.FacetDefinition;
036import org.ametys.web.frontoffice.search.metamodel.Returnable;
037import org.ametys.web.frontoffice.search.metamodel.SearchCriterionDefinition;
038import org.ametys.web.frontoffice.search.metamodel.SearchServiceCreationHelper;
039import org.ametys.web.frontoffice.search.metamodel.Searchable;
040import org.ametys.web.frontoffice.search.metamodel.SortDefinition;
041
042import com.google.common.collect.ImmutableMap;
043
044/**
045 * The class for search service specific widgets.
046 */
047public class SearchServiceClientSideWidget extends StaticClientSideWidget
048{
049    private SearchServiceCreationHelper _serviceCreationHelper;
050    
051    @Override
052    public void service(ServiceManager smanager) throws ServiceException
053    {
054        super.service(smanager);
055        _serviceCreationHelper = (SearchServiceCreationHelper) smanager.lookup(SearchServiceCreationHelper.ROLE);
056    }
057    
058    /**
059     * Gets the {@link SearchCriterionDefinition}s to display as JSON
060     * @param returnableIds The selected {@link Returnable}s
061     * @param formValues The values of the form
062     * @return the {@link SearchCriterionDefinition}s to display as JSON
063     */
064    @Callable
065    public Map<String, Map<String, Object>> getSearchCriterionDefinitions(List<String> returnableIds, Map<String, Object> formValues)
066    {
067        Collection<Returnable> returnables = _serviceCreationHelper.getReturnables(returnableIds);
068        Collection<Searchable> searchables = _serviceCreationHelper.getSearchables(returnables);
069        Collection<AdditionalSearchServiceParameter> additionalParameters = _serviceCreationHelper.getAdditionalParameters();
070        AdditionalParameterValueMap additionalParameterValues = _serviceCreationHelper.getAdditionalParameterValues(additionalParameters, formValues);
071        Map<String, SearchCriterionDefinition> criterionDefinitions = _serviceCreationHelper.getCriterionDefinitions(searchables, additionalParameterValues);
072        
073        return criterionDefinitions.entrySet()
074                .stream()
075                .collect(LambdaUtils.Collectors.toLinkedHashMap(
076                        Map.Entry::getKey,
077                        LambdaUtils.wrap(e -> _criterionDefinitionToJson(e.getValue()))
078                ));
079    }
080    
081    private Map<String, Object> _criterionDefinitionToJson(SearchCriterionDefinition criterionDefinition) throws Exception
082    {
083        Map<String, Object> json = new HashMap<>(criterionDefinition.toJSON());
084        
085        json.put("allowDisplayAllValues", !criterionDefinition.isTooBigForStaticEnumerator());
086        
087        json.put("canBeRestricted", criterionDefinition.isEnumerated());
088        
089        json.put("contextPrefixLabels", criterionDefinition.getContextPrefixLabels());
090        
091        json.put("groupLabel", criterionDefinition.getSearchable()
092                .map(Searchable::getLabel)
093                .orElse(new I18nizableText("plugin.web", "PLUGINS_WEB_SERVICE_SEARCH_COMMON_CRITERIA_GROUP")));
094        
095        return json;
096    }
097    
098    /**
099     * Gets the {@link FacetDefinition}s to display as JSON
100     * @param parameters The client parameters. It must contain 'returnableIds' and 'formValues' keys.
101     * @return the {@link FacetDefinition}s to display as JSON
102     */
103    @Callable
104    public List<Map<String, Object>> getFacetDefinitions(Map<String, Object> parameters)
105    {
106        @SuppressWarnings("unchecked")
107        List<String> returnableIds = (List<String>) parameters.get("returnableIds");
108        Objects.requireNonNull(returnableIds);
109        @SuppressWarnings("unchecked")
110        Map<String, Object> formValues = (Map<String, Object>) parameters.get("formValues");
111        Objects.requireNonNull(formValues);
112        return getFacetDefinitions(returnableIds, formValues);
113    }
114    
115    /**
116     * Gets the {@link FacetDefinition}s to display as JSON
117     * @param returnableIds The selected {@link Returnable}s
118     * @param formValues The values of the form
119     * @return the {@link FacetDefinition}s to display as JSON
120     */
121    public List<Map<String, Object>> getFacetDefinitions(List<String> returnableIds, Map<String, Object> formValues)
122    {
123        Collection<Returnable> returnables = _serviceCreationHelper.getReturnables(returnableIds);
124        Collection<AdditionalSearchServiceParameter> additionalParameters = _serviceCreationHelper.getAdditionalParameters();
125        AdditionalParameterValueMap additionalParameterValues = _serviceCreationHelper.getAdditionalParameterValues(additionalParameters, formValues);
126        Map<String, FacetDefinition> facetDefinitions = _serviceCreationHelper.getFacetDefinitions(returnables, additionalParameterValues);
127        return facetDefinitions.values()
128                .stream()
129                .map(this::_facetDefinitionToJson)
130                .collect(Collectors.toList());
131    }
132    
133    private Map<String, Object> _facetDefinitionToJson(FacetDefinition facetDefinition)
134    {
135        I18nizableText groupLabel = facetDefinition.getReturnable()
136                .map(Returnable::getLabel)
137                .orElse(new I18nizableText("plugin.web", "PLUGINS_WEB_SERVICE_SEARCH_COMMON_FACET_GROUP"));
138        return ImmutableMap.of(
139                "value", facetDefinition.getId(), 
140                "shortText", facetDefinition.getLabel(), 
141                "groupText", groupLabel);
142    }
143    
144    /**
145     * Gets the {@link SortDefinition}s to display as JSON
146     * @param parameters The client parameters. It must contain 'returnableIds' and 'formValues' keys.
147     * @return the {@link SortDefinition}s to display as JSON
148     */
149    @Callable
150    public List<Map<String, Object>> getSortDefinitions(Map<String, Object> parameters)
151    {
152        @SuppressWarnings("unchecked")
153        List<String> returnableIds = (List<String>) parameters.get("returnableIds");
154        Objects.requireNonNull(returnableIds);
155        @SuppressWarnings("unchecked")
156        Map<String, Object> formValues = (Map<String, Object>) parameters.get("formValues");
157        Objects.requireNonNull(formValues);
158        return getSortDefinitions(returnableIds, formValues);
159    }
160    
161    /**
162     * Gets the {@link SortDefinition}s to display as JSON
163     * @param returnableIds The selected {@link Returnable}s
164     * @param formValues The SortDefinition of the form
165     * @return the {@link FacetDefinition}s to display as JSON
166     */
167    public List<Map<String, Object>> getSortDefinitions(List<String> returnableIds, Map<String, Object> formValues)
168    {
169        Collection<Returnable> returnables = _serviceCreationHelper.getReturnables(returnableIds);
170        Collection<AdditionalSearchServiceParameter> additionalParameters = _serviceCreationHelper.getAdditionalParameters();
171        AdditionalParameterValueMap additionalParameterValues = _serviceCreationHelper.getAdditionalParameterValues(additionalParameters, formValues);
172        Map<String, SortDefinition> sortDefinitions = _serviceCreationHelper.getSortDefinitions(returnables, additionalParameterValues);
173        return sortDefinitions.values()
174                .stream()
175                .map(this::_sortDefinitionToJson)
176                .collect(Collectors.toList());
177    }
178    
179    private Map<String, Object> _sortDefinitionToJson(SortDefinition sortDefinition)
180    {
181        return ImmutableMap.of(
182                "value", sortDefinition.getId(), 
183                "shortText", sortDefinition.getLabel(), 
184                "availableOrders", Arrays.asList(sortDefinition.orders()));
185    }
186}