001/*
002 *  Copyright 2024 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.metamodel;
017
018import java.util.HashMap;
019import java.util.Map;
020
021import org.apache.avalon.framework.component.Component;
022
023import org.ametys.cms.contenttype.ContentType;
024import org.ametys.cms.model.ContentElementDefinition;
025import org.ametys.cms.model.properties.Property;
026import org.ametys.cms.search.model.CriterionDefinitionAwareElementDefinition;
027import org.ametys.runtime.i18n.I18nizableText;
028import org.ametys.runtime.model.ElementDefinition;
029import org.ametys.web.frontoffice.search.metamodel.impl.ContentReferencingSearchServiceCriterionDefinition;
030import org.ametys.web.frontoffice.search.metamodel.impl.ReferencingSearchServiceCriterionDefinition;
031import org.ametys.web.frontoffice.search.metamodel.impl.TagCriterionDefinition;
032
033/**
034 * Helper for {@link SearchServiceCriterionDefinition}
035 */
036public class SearchServiceCriterionDefinitionHelper implements Component
037{
038    /** The component role. */
039    public static final String ROLE = SearchServiceCriterionDefinitionHelper.class.getName();
040    
041    /**
042     * Retrieves a {@link SearchServiceCriterionDefinition} referencing the given definition
043     * @param criterionDefinitionName the name of the criterion definition to create
044     * @param reference the definition of the element to reference
045     * @param referencePath the path of the reference from the model containing the reference
046     * @param searchable the ({@link Searchable}) the criterion belongs to
047     * @param pluginName the name of the plugin declaring the criterion definition
048     * @return the {@link SearchServiceCriterionDefinition} 
049     */
050    public SearchServiceCriterionDefinition createReferencingSearchServiceCriterionDefinition(String criterionDefinitionName, ElementDefinition reference, String referencePath, Searchable searchable, String pluginName)
051    {
052        return createReferencingSearchServiceCriterionDefinition(criterionDefinitionName, reference, referencePath, searchable, null, pluginName);
053    }
054    
055    /**
056     * Retrieves a {@link SearchServiceCriterionDefinition} referencing the given definition
057     * @param criterionDefinitionName the name of the criterion definition to create
058     * @param reference the definition of the element to reference
059     * @param referencePath the path of the reference from the model containing the reference
060     * @param searchable the ({@link Searchable}) the criterion belongs to
061     * @param contentType the content type defining the reference
062     * @param pluginName the name of the plugin declaring the criterion definition
063     * @return the {@link SearchServiceCriterionDefinition} 
064     */
065    public SearchServiceCriterionDefinition createReferencingSearchServiceCriterionDefinition(String criterionDefinitionName, ElementDefinition reference, String referencePath, Searchable searchable, ContentType contentType, String pluginName)
066    {
067        if (reference instanceof Property && !(reference instanceof CriterionDefinitionAwareElementDefinition))
068        {
069            // This item can not be used as a criterion, ignore it
070            return null;
071        }
072        
073        SearchServiceCriterionDefinition criterionDefinition = "tags".equals(referencePath)
074                ? new TagCriterionDefinition(reference, referencePath, contentType)
075                : reference instanceof ContentElementDefinition
076                    ? new ContentReferencingSearchServiceCriterionDefinition(reference, referencePath, contentType)
077                    : new ReferencingSearchServiceCriterionDefinition<>(reference, referencePath, contentType);
078        
079        criterionDefinition.setName(criterionDefinitionName);
080        criterionDefinition.setPluginName(pluginName);
081        criterionDefinition.setSearchable(searchable);
082        
083        return criterionDefinition;
084    }
085    
086    /**
087     * Retrieves the default values to put in a Criterion definition JSON
088     * @param <T> Type of the criterion definition
089     * @param criterionDefinition the criterion definition
090     * @param isTooBigForStaticEnumerator <code>true</code> if the criterion definition can contain too much data
091     * @return the default values to put in a Criterion definition JSON
092     */
093    public <T> Map<String, Object> getDefaultSearchServiceCriterionDefinitionJSON(SearchServiceCriterionDefinition<T> criterionDefinition, boolean isTooBigForStaticEnumerator)
094    {
095        Map<String, Object> result = new HashMap<>();
096        
097        result.put("allowDisplayAllValues", !isTooBigForStaticEnumerator);
098        result.put("canBeRestricted", criterionDefinition.isEnumerated());
099        result.put("contextPrefixLabels", criterionDefinition.getContextPrefixLabels());
100        result.put("groupLabel", criterionDefinition.getSearchable()
101                                    .map(Searchable::getLabel)
102                                    .orElse(new I18nizableText("plugin.web", "PLUGINS_WEB_SERVICE_SEARCH_COMMON_CRITERIA_GROUP")));
103        
104        return result;
105    }
106}