001/* 002 * Copyright 2026 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.plugins.odfweb.service.search; 017 018import org.apache.avalon.framework.service.ServiceException; 019import org.apache.avalon.framework.service.ServiceManager; 020import org.apache.avalon.framework.service.Serviceable; 021 022import org.ametys.cms.search.query.JoinQuery; 023import org.ametys.cms.search.query.Query; 024import org.ametys.cms.search.solr.SearcherFactory.Searcher; 025import org.ametys.plugins.odfweb.restrictions.OdfProgramRestriction; 026import org.ametys.plugins.odfweb.restrictions.OdfProgramRestrictionManager; 027import org.ametys.web.frontoffice.search.instance.SearchServiceInstance; 028import org.ametys.web.frontoffice.search.metamodel.Returnable; 029import org.ametys.web.frontoffice.search.requesttime.AbstractSearchComponent; 030import org.ametys.web.frontoffice.search.requesttime.SearchComponent; 031import org.ametys.web.frontoffice.search.requesttime.SearchComponentArguments; 032 033/** 034 * This {@link SearchComponent} add a query to take into account the ODF restrictions on the current site 035 */ 036public class ProgramRestrictionSearchComponent extends AbstractSearchComponent implements Serviceable 037{ 038 private OdfProgramRestrictionManager _odfRestrictionManager; 039 040 public void service(ServiceManager manager) throws ServiceException 041 { 042 _odfRestrictionManager = (OdfProgramRestrictionManager) manager.lookup(OdfProgramRestrictionManager.ROLE); 043 } 044 045 public boolean supports(SearchComponentArguments args) 046 { 047 SearchServiceInstance serviceInstance = args.serviceInstance(); 048 return _isProgramSearch(serviceInstance) || _isCourseSearch(serviceInstance); 049 } 050 051 private boolean _isProgramSearch(SearchServiceInstance serviceInstance) 052 { 053 return serviceInstance.getReturnables() 054 .stream() 055 .map(Returnable::getId) 056 .anyMatch(r -> ProgramReturnable.ROLE.equals(r)); 057 } 058 059 private boolean _isCourseSearch(SearchServiceInstance serviceInstance) 060 { 061 return serviceInstance.getReturnables() 062 .stream() 063 .map(Returnable::getId) 064 .anyMatch(r -> CourseReturnable.ROLE.equals(r)); 065 } 066 067 public int getPriority() 068 { 069 return SEARCH_PRIORITY - 10000; 070 } 071 072 public void execute(SearchComponentArguments args) throws Exception 073 { 074 String siteName = args.currentPage().getSiteName(); 075 076 OdfProgramRestriction restriction = _odfRestrictionManager.getRestriction(siteName); 077 078 if (restriction != null) 079 { 080 Query query = restriction.getQuery(); 081 if (query != null) 082 { 083 Searcher searcher = args.searcher(); 084 085 if (_isProgramSearch(args.serviceInstance())) 086 { 087 searcher.addFilterQuery(query); 088 } 089 else 090 { 091 // Course search: add a join query on parent programs 092 searcher.addFilterQuery(new JoinQuery(query, "parentPrograms")); 093 } 094 } 095 } 096 } 097}