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.List;
021import java.util.Map;
022import java.util.Objects;
023import java.util.stream.Collectors;
024
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027
028import org.ametys.core.ui.Callable;
029import org.ametys.core.ui.widgets.StaticClientSideWidget;
030import org.ametys.core.util.LambdaUtils;
031import org.ametys.runtime.i18n.I18nizableText;
032import org.ametys.runtime.model.DefinitionContext;
033import org.ametys.web.frontoffice.search.metamodel.AdditionalParameterValueMap;
034import org.ametys.web.frontoffice.search.metamodel.AdditionalSearchServiceParameter;
035import org.ametys.web.frontoffice.search.metamodel.SearchServiceFacetDefinition;
036import org.ametys.web.frontoffice.search.metamodel.Returnable;
037import org.ametys.web.frontoffice.search.metamodel.SearchServiceCriterionDefinition;
038import org.ametys.web.frontoffice.search.metamodel.SearchServiceCreationHelper;
039import org.ametys.web.frontoffice.search.metamodel.Searchable;
040import org.ametys.web.frontoffice.search.metamodel.SearchServiceSortDefinition;
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 SearchServiceCriterionDefinition}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 SearchServiceCriterionDefinition}s to display as JSON
063     */
064    @Callable
065    public Map<String, Map<String, Object>> getCriterionDefinitions(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, SearchServiceCriterionDefinition> 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 -> e.getValue().toJSON(DefinitionContext.newInstance()))
078                ));
079    }
080    
081    /**
082     * Gets the {@link SearchServiceFacetDefinition}s to display as JSON
083     * @param parameters The client parameters. It must contain 'returnableIds' and 'formValues' keys.
084     * @return the {@link SearchServiceFacetDefinition}s to display as JSON
085     */
086    @Callable
087    public List<Map<String, Object>> getFacetDefinitions(Map<String, Object> parameters)
088    {
089        @SuppressWarnings("unchecked")
090        List<String> returnableIds = (List<String>) parameters.get("returnableIds");
091        Objects.requireNonNull(returnableIds);
092        @SuppressWarnings("unchecked")
093        Map<String, Object> formValues = (Map<String, Object>) parameters.get("formValues");
094        Objects.requireNonNull(formValues);
095        return getFacetDefinitions(returnableIds, formValues);
096    }
097    
098    /**
099     * Gets the {@link SearchServiceFacetDefinition}s to display as JSON
100     * @param returnableIds The selected {@link Returnable}s
101     * @param formValues The values of the form
102     * @return the {@link SearchServiceFacetDefinition}s to display as JSON
103     */
104    public List<Map<String, Object>> getFacetDefinitions(List<String> returnableIds, Map<String, Object> formValues)
105    {
106        Collection<Returnable> returnables = _serviceCreationHelper.getReturnables(returnableIds);
107        Collection<AdditionalSearchServiceParameter> additionalParameters = _serviceCreationHelper.getAdditionalParameters();
108        AdditionalParameterValueMap additionalParameterValues = _serviceCreationHelper.getAdditionalParameterValues(additionalParameters, formValues);
109        Map<String, SearchServiceFacetDefinition> facetDefinitions = _serviceCreationHelper.getFacetDefinitions(returnables, additionalParameterValues);
110        return facetDefinitions.values()
111                .stream()
112                .map(this::_facetDefinitionToJson)
113                .collect(Collectors.toList());
114    }
115    
116    private Map<String, Object> _facetDefinitionToJson(SearchServiceFacetDefinition facetDefinition)
117    {
118        I18nizableText groupLabel = facetDefinition.getReturnable()
119                .map(Returnable::getLabel)
120                .orElse(new I18nizableText("plugin.web", "PLUGINS_WEB_SERVICE_SEARCH_COMMON_FACET_GROUP"));
121        return ImmutableMap.of(
122                "value", facetDefinition.getName(), 
123                "shortText", facetDefinition.getLabel(), 
124                "groupText", groupLabel);
125    }
126    
127    /**
128     * Gets the {@link SearchServiceSortDefinition}s to display as JSON
129     * @param parameters The client parameters. It must contain 'returnableIds' and 'formValues' keys.
130     * @return the {@link SearchServiceSortDefinition}s to display as JSON
131     */
132    @Callable
133    public List<Map<String, Object>> getSortDefinitions(Map<String, Object> parameters)
134    {
135        @SuppressWarnings("unchecked")
136        List<String> returnableIds = (List<String>) parameters.get("returnableIds");
137        Objects.requireNonNull(returnableIds);
138        @SuppressWarnings("unchecked")
139        Map<String, Object> formValues = (Map<String, Object>) parameters.get("formValues");
140        Objects.requireNonNull(formValues);
141        return getSortDefinitions(returnableIds, formValues);
142    }
143    
144    /**
145     * Gets the {@link SearchServiceSortDefinition}s to display as JSON
146     * @param returnableIds The selected {@link Returnable}s
147     * @param formValues The SortDefinition of the form
148     * @return the {@link SearchServiceFacetDefinition}s to display as JSON
149     */
150    public List<Map<String, Object>> getSortDefinitions(List<String> returnableIds, Map<String, Object> formValues)
151    {
152        Collection<Returnable> returnables = _serviceCreationHelper.getReturnables(returnableIds);
153        Collection<AdditionalSearchServiceParameter> additionalParameters = _serviceCreationHelper.getAdditionalParameters();
154        AdditionalParameterValueMap additionalParameterValues = _serviceCreationHelper.getAdditionalParameterValues(additionalParameters, formValues);
155        Map<String, SearchServiceSortDefinition> sortDefinitions = _serviceCreationHelper.getSortDefinitions(returnables, additionalParameterValues);
156        return sortDefinitions.values()
157                .stream()
158                .map(this::_sortDefinitionToJson)
159                .collect(Collectors.toList());
160    }
161    
162    private Map<String, Object> _sortDefinitionToJson(SearchServiceSortDefinition sortDefinition)
163    {
164        return ImmutableMap.of(
165                "value", sortDefinition.getName(), 
166                "shortText", sortDefinition.getLabel(), 
167                "availableOrders", Arrays.asList(sortDefinition.orders()));
168    }
169}