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