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.ArrayList; 019import java.util.Collection; 020import java.util.Collections; 021import java.util.List; 022import java.util.Optional; 023import java.util.function.Function; 024import java.util.stream.Collectors; 025 026import org.apache.avalon.framework.configuration.Configurable; 027import org.apache.avalon.framework.configuration.Configuration; 028import org.apache.avalon.framework.configuration.ConfigurationException; 029import org.apache.avalon.framework.service.ServiceException; 030import org.apache.avalon.framework.service.ServiceManager; 031import org.apache.avalon.framework.service.Serviceable; 032import org.apache.commons.collections4.CollectionUtils; 033 034import org.ametys.cms.content.ContentHelper; 035import org.ametys.cms.contenttype.ContentTypesHelper; 036import org.ametys.cms.contenttype.MetadataManager; 037import org.ametys.cms.search.query.AndQuery; 038import org.ametys.cms.search.query.ContentTypeQuery; 039import org.ametys.cms.search.query.DocumentTypeQuery; 040import org.ametys.cms.search.query.Query; 041import org.ametys.runtime.i18n.I18nizableText; 042import org.ametys.web.frontoffice.search.instance.model.SearchContext.LangQueryProducer; 043import org.ametys.web.frontoffice.search.metamodel.AdditionalParameterValueMap; 044import org.ametys.web.frontoffice.search.metamodel.FacetDefinition; 045import org.ametys.web.frontoffice.search.metamodel.Returnable; 046import org.ametys.web.frontoffice.search.metamodel.ReturnableExtensionPoint; 047import org.ametys.web.frontoffice.search.metamodel.ReturnableSaxer; 048import org.ametys.web.frontoffice.search.metamodel.SortDefinition; 049import org.ametys.web.frontoffice.search.metamodel.context.ContextQueriesWrapper; 050import org.ametys.web.indexing.solr.SolrWebFieldNames; 051import org.ametys.web.repository.page.Page; 052import org.ametys.web.repository.site.SiteManager; 053import org.ametys.web.search.query.PageContentQuery; 054import org.ametys.web.search.query.SitemapQuery; 055 056/** 057 * {@link Returnable} for {@link Page}s 058 */ 059public class PageReturnable implements Returnable, Serviceable, Configurable 060{ 061 /** Avalon Role */ 062 public static final String ROLE = PageReturnable.class.getName(); 063 064 /** The prefix for the ids of facets and sorts */ 065 protected static final String __PREFIX_ID = "PageReturnable$"; 066 067 /** The sites manager */ 068 protected SiteManager _siteManager; 069 /** The content returnable */ 070 protected Returnable _contentReturnable; 071 072 /** The helper to handler content types */ 073 protected ContentTypesHelper _contentTypesHelper; 074 /** The helper to handler contents */ 075 protected ContentHelper _contentHelper; 076 /** Metadata manager. */ 077 protected MetadataManager _metadataManager; 078 /** The service manager. */ 079 protected ServiceManager _manager; 080 081 /** The label */ 082 protected I18nizableText _label; 083 /** The saxer */ 084 protected ReturnableSaxer _saxer; 085 086 087 @Override 088 public void service(ServiceManager manager) throws ServiceException 089 { 090 _manager = manager; 091 _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE); 092 ReturnableExtensionPoint resultTypeEP = (ReturnableExtensionPoint) manager.lookup(ReturnableExtensionPoint.ROLE); 093 _contentReturnable = resultTypeEP.getExtension(ContentReturnable.ROLE); 094 095 _contentTypesHelper = (ContentTypesHelper) manager.lookup(ContentTypesHelper.ROLE); 096 _contentHelper = (ContentHelper) manager.lookup(ContentHelper.ROLE); 097 _metadataManager = (MetadataManager) manager.lookup(MetadataManager.ROLE); 098 } 099 100 @Override 101 public void configure(Configuration configuration) throws ConfigurationException 102 { 103 _label = I18nizableText.parseI18nizableText(configuration.getChild("label"), "plugin.web"); 104 } 105 106 @Override 107 public String getId() 108 { 109 return ROLE; 110 } 111 112 @Override 113 public I18nizableText getLabel() 114 { 115 return _label; 116 } 117 118 @Override 119 public boolean selectedByDefault() 120 { 121 return true; 122 } 123 124 @Override 125 public Query filterReturnedDocumentQuery(Collection<ContextQueriesWrapper> contextQueriesWrappers, AdditionalParameterValueMap additionalParameterValues) 126 { 127 Collection<String> contentTypes = additionalParameterValues.getValue(ContentSearchable.PARAMETER_CONTENT_TYPES); 128 129 // site property is indexed on page documents 130 Function<Query, Query> siteQueryJoiner = Function.identity(); 131 // A SitemapQuery is on pages 132 Function<Query, Query> sitemapQueryJoiner = Function.identity(); 133 // lang query 134 LangQueryProducer langQueryProducer = new LangQueryProducer(SitemapQuery.class, false); 135 // tag query is on contents => ignore it by passing an empty optional 136 Query pageContextQuery = ContextQueriesWrapper.getQuery(contextQueriesWrappers, Optional.of(siteQueryJoiner), Optional.of(sitemapQueryJoiner), Optional.of(langQueryProducer), Optional.empty()); 137 138 List<Query> queries = new ArrayList<>(); 139 queries.add(new DocumentTypeQuery(SolrWebFieldNames.TYPE_PAGE)); 140 if (CollectionUtils.isNotEmpty(contentTypes)) 141 { 142 queries.add(new PageContentQuery(new ContentTypeQuery(contentTypes))); 143 } 144 queries.add(pageContextQuery); 145 return new AndQuery(queries); 146 } 147 148 @Override 149 public ReturnableSaxer getSaxer(Collection<Returnable> allReturnables, AdditionalParameterValueMap additionalParameterValues) 150 { 151 if (_saxer == null) 152 { 153 _saxer = new PageSaxer(this); 154 } 155 return _saxer; 156 } 157 158 @Override 159 public Collection<FacetDefinition> getFacets(AdditionalParameterValueMap additionalParameterValues) 160 { 161 Collection<FacetDefinition> contentFacets = _contentReturnable.getFacets(additionalParameterValues); 162 Collection<FacetDefinition> facetDefs = contentFacets.stream() 163 .filter(ContentFacetDefinition.class::isInstance) 164 .map(ContentFacetDefinition.class::cast) 165 .map(contentFacetDefinition -> new PageContentFacetDefinition(contentFacetDefinition, this)) 166 .collect(Collectors.toList()); 167 168 return facetDefs; 169 } 170 171 @Override 172 public Collection<SortDefinition> getSorts(AdditionalParameterValueMap additionalParameterValues) 173 { 174 return Collections.emptySet(); 175 } 176}