001/*
002 *  Copyright 2019 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.instance.model;
017
018import java.util.List;
019import java.util.Map;
020import java.util.stream.Collectors;
021
022import org.slf4j.Logger;
023import org.slf4j.LoggerFactory;
024
025import org.ametys.web.frontoffice.search.metamodel.SearchCriterionDefinition;
026
027/**
028 * The mode of a {@link FOSearchCriterion}
029 */
030public enum FOSearchCriterionMode
031{
032    /**
033     * The criterion is static, i.e. valued by the webmaster and is not a proposed criterion to the final user.
034     */
035    STATIC
036    {
037        @Override
038        public Object getValue(FOSearchCriterion searchCriterion, Map<String, Object> userCriteria, Map<String, Object> contextualParameters)
039        {
040            Object staticValue = searchCriterion.getStaticValue().get();
041            __LOGGER.debug("Value for static criterion '{}': {}", searchCriterion.getId(), staticValue);
042            return staticValue;
043        }
044    },
045    
046    /**
047     * The criterion is proposed to the final user.
048     */
049    USER_INPUT
050    {
051        @Override
052        public Object getValue(FOSearchCriterion searchCriterion, Map<String, Object> userCriteria, Map<String, Object> contextualParameters)
053        {
054            String criterionId = searchCriterion.getId();
055            Object val = userCriteria.get(criterionId);
056            if (val != null)
057            {
058                __LOGGER.debug("Value from user for criterion '{}': {}", criterionId, val);
059                return val;
060            }
061            
062            // val is null
063            // Is it enumerated ?
064            SearchCriterionDefinition criterionDefinition = searchCriterion.getCriterionDefinition();
065            if (criterionDefinition.isEnumerated())
066            {
067                // The criterion was not filled by the visitor
068                // As it is enumerated, consider it as the 'All' option to filter results matching with at least one value in the enumerated values
069                List<Object> vals = criterionDefinition.getEnumeratedValues(contextualParameters)
070                        .get()
071                        .getAllValues()
072                        .keySet()
073                        .stream()
074                        .collect(Collectors.toList());
075                __LOGGER.debug("Value for criterion '{}' (computed because not filled by user but is enumerated): {}", criterionId, vals);
076                return vals;
077            }
078            else
079            {
080                __LOGGER.debug("Value from user for criterion '{}': null", criterionId);
081                return null;
082            }
083        }
084    },
085    
086    /**
087     * The criterion is proposed to the final user, with a restricted enumeration of choices.
088     */
089    RESTRICTED_USER_INPUT
090    {
091        @Override
092        public Object getValue(FOSearchCriterion searchCriterion, Map<String, Object> userCriteria, Map<String, Object> contextualParameters)
093        {
094            String criterionId = searchCriterion.getId();
095            Object val = userCriteria.get(criterionId);
096            if (val != null)
097            {
098                __LOGGER.debug("Value from user for (restricted) criterion '{}': {}", criterionId, val);
099                return val;
100            }
101            else
102            {
103                // The criterion was not filled by the visitor
104                // Consider it as the 'All' option to filter results matching with at least one value in the restricted values
105                List<Object> vals = searchCriterion
106                        .getRestrictedValues()
107                        .get()
108                        .values()
109                        .keySet()
110                        .stream()
111                        .collect(Collectors.toList());
112                __LOGGER.debug("Value for criterion '{}' (computed because not filled by user but is restricted): {}", criterionId, vals);
113                return vals;
114            }
115        }
116    };
117    
118    static final Logger __LOGGER = LoggerFactory.getLogger(FOSearchCriterionMode.class);
119    
120    /**
121     * Gets the value from the {@link FOSearchCriterion criterion} and the final user criteria.
122     * @param searchCriterion The {@link FOSearchCriterion} which is in this mode
123     * @param finalUserCriteria The criteria from the final user
124     * @param contextualParameters The contextual parameters
125     * @return the value
126     */
127    public abstract Object getValue(FOSearchCriterion searchCriterion, Map<String, Object> finalUserCriteria, Map<String, Object> contextualParameters);
128}