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.metamodel.impl; 017 018import java.util.Collections; 019import java.util.List; 020import java.util.Locale; 021import java.util.Map; 022import java.util.Optional; 023 024import org.apache.avalon.framework.component.Component; 025import org.apache.avalon.framework.service.ServiceException; 026import org.apache.avalon.framework.service.ServiceManager; 027 028import org.ametys.cms.contenttype.ContentType; 029import org.ametys.cms.search.model.SearchCriterionHelper; 030import org.ametys.cms.search.query.NotQuery; 031import org.ametys.cms.search.query.Query; 032import org.ametys.cms.search.query.Query.Operator; 033import org.ametys.cms.search.ui.model.SearchUICriterion; 034import org.ametys.runtime.i18n.I18nizableText; 035import org.ametys.runtime.parameter.Validator; 036import org.ametys.web.frontoffice.search.metamodel.SearchCriterionDefinition; 037import org.ametys.web.frontoffice.search.metamodel.Searchable; 038 039/** 040 * {@link SearchCriterionDefinition} for {@link ContentSearchable} proposing a search criterion (based on a {@link SearchUICriterion}). 041 */ 042public class ContentSearchCriterionDefinition extends AbstractDefaultSearchCriterionDefinition 043{ 044 /** The service manager */ 045 protected static ServiceManager __serviceManager; 046 /** The SearchUICriterion */ 047 protected SearchUICriterion _searchUICriterion; 048 /** The content type on which this criterion definition applies. Can be empty if it applies to all types of contents. */ 049 protected Optional<ContentType> _contentType; 050 051 /** 052 * Default constructor 053 * @param id The id 054 * @param pluginName The plugin name 055 * @param searchable the {@link Searchable} 056 * @param criterion The linked {@link SearchUICriterion} 057 * @param contentType The content type on which this criterion definition applies. Can be empty if it applies to all types of contents. 058 * @param validator The validator 059 */ 060 public ContentSearchCriterionDefinition( 061 String id, 062 String pluginName, 063 Optional<Searchable> searchable, 064 SearchUICriterion criterion, 065 Optional<ContentType> contentType, 066 Optional<Validator> validator) 067 { 068 super( 069 id, 070 pluginName, 071 criterion.getLabel(), 072 criterion.getType(), 073 Optional.ofNullable(criterion.getWidget()), 074 Optional.ofNullable(criterion.getWidgetParameters()), 075 Optional.ofNullable(criterion.getEnumerator()), 076 validator.isPresent() ? validator : Optional.ofNullable(criterion.getValidator()), 077 Optional.ofNullable(criterion.getDefaultValue()), 078 searchable 079 ); 080 _searchUICriterion = criterion; 081 _contentType = contentType; 082 } 083 084 /** 085 * Get the label of a facet value. 086 * @param value the facet value. 087 * @param contextualParameters the contextual parameters 088 * @return the label, or null if the value does not exist. 089 */ 090 public Optional<I18nizableText> getFacetLabel(String value, Map<String, Object> contextualParameters) 091 { 092 Locale currentLocale = new Locale((String) contextualParameters.get("lang")); 093 094 try 095 { 096 SearchCriterionHelper searchCriterionHelper = (SearchCriterionHelper) __serviceManager.lookup(SearchCriterionHelper.ROLE); 097 098 return Optional.of(getSearchUICriterion()) 099 .map(criterion -> searchCriterionHelper.getFacetLabel(criterion, value, currentLocale)) 100 .or(() -> Optional.of(new I18nizableText(value))); 101 } 102 catch (ServiceException e) 103 { 104 return Optional.of(new I18nizableText(value)); 105 } 106 } 107 108 /** 109 * Gets the {@link SearchUICriterion} associated to this definition 110 * @return the {@link SearchUICriterion} associated to this definition 111 */ 112 public SearchUICriterion getSearchUICriterion() 113 { 114 return _searchUICriterion; 115 } 116 117 @Override 118 public List<I18nizableText> getContextPrefixLabels() 119 { 120 return Collections.singletonList( 121 _contentType 122 .map(ContentType::getLabel) 123 .orElse(new I18nizableText("plugin.web", "PLUGINS_WEB_SERVICE_SEARCH_SEARCHABLE_CONTENT_ALL_PREFIX_LABEL"))); 124 } 125 126 @Override 127 public Map<String, Object> toJSON() throws Exception 128 { 129 Map<String, Object> json = super.toJSON(); 130 json.put("multiple", _searchUICriterion.isMultiple()); 131 return json; 132 } 133 134 @Override 135 public Query getQuery(Object value, Operator operator, String language, Map<String, Object> contextualParameters) 136 { 137 return _searchUICriterion.getQuery(value, operator, Collections.EMPTY_MAP, language, contextualParameters); 138 } 139 140 @Override 141 public Query getEmptyValueQuery(String language, Map<String, Object> contextualParameters) 142 { 143 Query existQuery = _searchUICriterion.getQuery(null, Operator.EXISTS, Collections.EMPTY_MAP, language, contextualParameters); 144 return new NotQuery(existQuery); 145 } 146 147 /** 148 * Set the service manager 149 * The {@link ServiceManager} is used in the criterion definition to get the search criterion helper 150 * {@link SearchCriterionDefinition} is not a {@link Component} and can't have a {@link ServiceManager} itself. Another {@link Component} has to set it 151 * @param manager the service manager to set 152 */ 153 public static void setServiceManager(ServiceManager manager) 154 { 155 __serviceManager = manager; 156 } 157}