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("canBeRestricted", criterionDefinition.isEnumerated());
086        
087        json.put("contextPrefixLabels", criterionDefinition.getContextPrefixLabels());
088        
089        json.put("groupLabel", criterionDefinition.getSearchable()
090                .map(Searchable::getLabel)
091                .orElse(new I18nizableText("plugin.web", "PLUGINS_WEB_SERVICE_SEARCH_COMMON_CRITERIA_GROUP")));
092        
093        return json;
094    }
095    
096    /**
097     * Gets the {@link FacetDefinition}s to display as JSON
098     * @param parameters The client parameters. It must contain 'returnableIds' and 'formValues' keys.
099     * @return the {@link FacetDefinition}s to display as JSON
100     */
101    @Callable
102    public List<Map<String, Object>> getFacetDefinitions(Map<String, Object> parameters)
103    {
104        @SuppressWarnings("unchecked")
105        List<String> returnableIds = (List<String>) parameters.get("returnableIds");
106        Objects.requireNonNull(returnableIds);
107        @SuppressWarnings("unchecked")
108        Map<String, Object> formValues = (Map<String, Object>) parameters.get("formValues");
109        Objects.requireNonNull(formValues);
110        return getFacetDefinitions(returnableIds, formValues);
111    }
112    
113    /**
114     * Gets the {@link FacetDefinition}s to display as JSON
115     * @param returnableIds The selected {@link Returnable}s
116     * @param formValues The values of the form
117     * @return the {@link FacetDefinition}s to display as JSON
118     */
119    public List<Map<String, Object>> getFacetDefinitions(List<String> returnableIds, Map<String, Object> formValues)
120    {
121        Collection<Returnable> returnables = _serviceCreationHelper.getReturnables(returnableIds);
122        Collection<AdditionalSearchServiceParameter> additionalParameters = _serviceCreationHelper.getAdditionalParameters();
123        AdditionalParameterValueMap additionalParameterValues = _serviceCreationHelper.getAdditionalParameterValues(additionalParameters, formValues);
124        Map<String, FacetDefinition> facetDefinitions = _serviceCreationHelper.getFacetDefinitions(returnables, additionalParameterValues);
125        return facetDefinitions.values()
126                .stream()
127                .map(this::_facetDefinitionToJson)
128                .collect(Collectors.toList());
129    }
130    
131    private Map<String, Object> _facetDefinitionToJson(FacetDefinition facetDefinition)
132    {
133        I18nizableText groupLabel = facetDefinition.getReturnable()
134                .map(Returnable::getLabel)
135                .orElse(new I18nizableText("plugin.web", "PLUGINS_WEB_SERVICE_SEARCH_COMMON_FACET_GROUP"));
136        return ImmutableMap.of(
137                "value", facetDefinition.getId(), 
138                "shortText", facetDefinition.getLabel(), 
139                "groupText", groupLabel);
140    }
141    
142    /**
143     * Gets the {@link SortDefinition}s to display as JSON
144     * @param parameters The client parameters. It must contain 'returnableIds' and 'formValues' keys.
145     * @return the {@link SortDefinition}s to display as JSON
146     */
147    @Callable
148    public List<Map<String, Object>> getSortDefinitions(Map<String, Object> parameters)
149    {
150        @SuppressWarnings("unchecked")
151        List<String> returnableIds = (List<String>) parameters.get("returnableIds");
152        Objects.requireNonNull(returnableIds);
153        @SuppressWarnings("unchecked")
154        Map<String, Object> formValues = (Map<String, Object>) parameters.get("formValues");
155        Objects.requireNonNull(formValues);
156        return getSortDefinitions(returnableIds, formValues);
157    }
158    
159    /**
160     * Gets the {@link SortDefinition}s to display as JSON
161     * @param returnableIds The selected {@link Returnable}s
162     * @param formValues The SortDefinition of the form
163     * @return the {@link FacetDefinition}s to display as JSON
164     */
165    public List<Map<String, Object>> getSortDefinitions(List<String> returnableIds, Map<String, Object> formValues)
166    {
167        Collection<Returnable> returnables = _serviceCreationHelper.getReturnables(returnableIds);
168        Collection<AdditionalSearchServiceParameter> additionalParameters = _serviceCreationHelper.getAdditionalParameters();
169        AdditionalParameterValueMap additionalParameterValues = _serviceCreationHelper.getAdditionalParameterValues(additionalParameters, formValues);
170        Map<String, SortDefinition> sortDefinitions = _serviceCreationHelper.getSortDefinitions(returnables, additionalParameterValues);
171        return sortDefinitions.values()
172                .stream()
173                .map(this::_sortDefinitionToJson)
174                .collect(Collectors.toList());
175    }
176    
177    private Map<String, Object> _sortDefinitionToJson(SortDefinition sortDefinition)
178    {
179        return ImmutableMap.of(
180                "value", sortDefinition.getId(), 
181                "shortText", sortDefinition.getLabel(), 
182                "availableOrders", Arrays.asList(sortDefinition.orders()));
183    }
184}