001/* 002 * Copyright 2023 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.cms.search.model; 017 018import java.util.List; 019import java.util.Locale; 020import java.util.Map; 021import java.util.Set; 022 023import org.apache.avalon.framework.component.Component; 024import org.apache.avalon.framework.configuration.Configuration; 025import org.apache.avalon.framework.configuration.ConfigurationException; 026import org.apache.avalon.framework.configuration.DefaultConfiguration; 027import org.apache.avalon.framework.service.ServiceException; 028import org.apache.avalon.framework.service.ServiceManager; 029import org.apache.avalon.framework.service.Serviceable; 030import org.apache.commons.lang3.StringUtils; 031import org.bouncycastle.util.Arrays; 032 033import org.ametys.cms.contenttype.ContentType; 034import org.ametys.cms.data.type.ModelItemTypeExtensionPoint; 035import org.ametys.cms.data.type.indexing.IndexableElementType; 036import org.ametys.cms.model.CMSDataContext; 037import org.ametys.runtime.i18n.I18nizableText; 038import org.ametys.runtime.model.exception.UnknownTypeException; 039import org.ametys.runtime.model.type.DataContext; 040import org.ametys.runtime.plugin.component.AbstractLogEnabled; 041 042/** 043 * Helper for {@link CriterionDefinition} 044 */ 045public class CriterionDefinitionHelper extends AbstractLogEnabled implements Component, Serviceable 046{ 047 /** The component role. */ 048 public static final String ROLE = CriterionDefinitionHelper.class.getName(); 049 050 /** The extension point containing all available criterion types */ 051 protected ModelItemTypeExtensionPoint _criterionTypeExtensionPoint; 052 053 public void service(ServiceManager manager) throws ServiceException 054 { 055 _criterionTypeExtensionPoint = (ModelItemTypeExtensionPoint) manager.lookup(ModelItemTypeExtensionPoint.ROLE_CRITERION_DEFINITION); 056 } 057 058 /** 059 * Retrieves the type implementation of the given criterion type identifier 060 * @param <T> the type of the criterion type 061 * @param criterionTypeId the criterion type identifier 062 * @return the criterion type implementation 063 */ 064 @SuppressWarnings("unchecked") 065 public <T> IndexableElementType<T> getCriterionDefinitionType(String criterionTypeId) 066 { 067 if (_criterionTypeExtensionPoint.hasExtension(criterionTypeId)) 068 { 069 return (IndexableElementType<T>) _criterionTypeExtensionPoint.getExtension(criterionTypeId); 070 } 071 else 072 { 073 throw new UnknownTypeException("Unable to retrieve type with identifier '" + criterionTypeId + "'. This type is not available for criteria"); 074 } 075 } 076 077 /** 078 * Retrieves the default widget for the given criterion definition 079 * @param criterionDefinition the criterion definition 080 * @return the default widget for the given criterion definition 081 */ 082 public String getCriterionDefinitionDefaultWidget(CriterionDefinition criterionDefinition) 083 { 084 String defaultWidget = criterionDefinition.getType().getDefaultCriterionWidget(CMSDataContext.newInstance() 085 .withModelItem(criterionDefinition)); 086 087 return "edition.textarea".equals(defaultWidget) ? null : defaultWidget; 088 } 089 090 /** 091 * Retrieves the default widget parameters for the given criterion definition 092 * @param criterionDefinition the criterion definition 093 * @return the default widget parameters for the given criterion definition 094 */ 095 public Map<String, I18nizableText> getCriterionDefinitionDefaultWidgetParameters(CriterionDefinition criterionDefinition) 096 { 097 return criterionDefinition.getType().getDefaultCriterionWidgetParameters(CMSDataContext.newInstance() 098 .withModelItem(criterionDefinition)); 099 } 100 101 /** 102 * Wrap the given configuration to add content types 103 * @param originalConf the configuration to wrap 104 * @param contentTypes the content types to add in wrapped configuration 105 * @return the wrapped configuration 106 * @throws ConfigurationException if an error occurs 107 */ 108 public Configuration wrapCriterionConfiguration(Configuration originalConf, Set<ContentType> contentTypes) throws ConfigurationException 109 { 110 DefaultConfiguration conf = new DefaultConfiguration(originalConf); 111 112 conf.removeChild(conf.getChild("contentTypes")); 113 114 DefaultConfiguration contentTypesConf = new DefaultConfiguration("contentTypes"); 115 for (ContentType contentType : contentTypes) 116 { 117 DefaultConfiguration contentTypeConf = new DefaultConfiguration("type"); 118 contentTypeConf.setAttribute("id", contentType.getId()); 119 contentTypesConf.addChild(contentTypeConf); 120 } 121 122 conf.addChild(contentTypesConf); 123 return conf; 124 } 125 126 /** 127 * Get the label of a facet value for the given criterion. 128 * @param <T> the type of the facet criterion 129 * @param criterion the criterion 130 * @param value the facet value. 131 * @param currentLocale the current locale 132 * @return the label, or null if the value does not exist. 133 */ 134 public <T> I18nizableText getFacetLabel(CriterionDefinition<T> criterion, String value, Locale currentLocale) 135 { 136 DataContext context = DataContext.newInstance() 137 .withModelItem(criterion) 138 .withLocale(currentLocale); 139 IndexableElementType<T> type = criterion.getType(); 140 return type.getFacetLabel(value, context); 141 } 142 143 /** 144 * Check if the given query value is empty 145 * @param value the query value to check 146 * @return <code>true</code> if the given query value is empty, <code>false</code> otherwise 147 */ 148 public boolean isQueryValueEmpty(Object value) 149 { 150 return value == null 151 || value instanceof String strValue && StringUtils.isEmpty(strValue) 152 || value instanceof List listValue && listValue.isEmpty() 153 || value.getClass().isArray() && Arrays.isNullOrEmpty((Object[]) value); 154 } 155}