001/* 002 * Copyright 2019 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.odf.course.search; 017 018import java.util.ArrayList; 019import java.util.List; 020import java.util.Map; 021import java.util.Set; 022 023import org.apache.avalon.framework.service.ServiceException; 024import org.apache.avalon.framework.service.ServiceManager; 025import org.apache.commons.lang3.StringUtils; 026 027import org.ametys.cms.contenttype.MetadataType; 028import org.ametys.cms.search.query.AndQuery; 029import org.ametys.cms.search.query.NotQuery; 030import org.ametys.cms.search.query.OrQuery; 031import org.ametys.cms.search.query.Query; 032import org.ametys.cms.search.query.Query.Operator; 033import org.ametys.cms.search.query.StringQuery; 034import org.ametys.cms.search.ui.model.impl.AbstractCustomSearchUICriterion; 035import org.ametys.odf.ODFHelper; 036import org.ametys.odf.ProgramItem; 037import org.ametys.odf.course.ShareableCourseConstants; 038import org.ametys.odf.course.ShareableCourseHelper; 039import org.ametys.odf.course.ShareableCourseStatusHelper.ShareableStatus; 040import org.ametys.odf.program.Container; 041import org.ametys.odf.program.Program; 042import org.ametys.plugins.repository.AmetysObjectResolver; 043import org.ametys.runtime.model.ModelItem; 044 045/** 046 * UI criteria for shareable course 047 */ 048public class ShareableCourseSearchUICriteria extends AbstractCustomSearchUICriterion 049{ 050 /** The ametys object resolver. */ 051 protected AmetysObjectResolver _resolver; 052 053 /** The ODF helper */ 054 protected ODFHelper _odfHelper; 055 056 /** The shareable course helper */ 057 protected ShareableCourseHelper _shareableCourseHelper; 058 059 @Override 060 public void service(ServiceManager manager) throws ServiceException 061 { 062 super.service(manager); 063 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 064 _odfHelper = (ODFHelper) manager.lookup(ODFHelper.ROLE); 065 _shareableCourseHelper = (ShareableCourseHelper) manager.lookup(ShareableCourseHelper.ROLE); 066 } 067 068 public String getFieldId() 069 { 070 return "shareable.course.field"; 071 } 072 073 public Operator getOperator() 074 { 075 // Not suppose to be used 076 return Operator.EQ; 077 } 078 079 @Override 080 public MetadataType getType() 081 { 082 // Not suppose to be used 083 return MetadataType.STRING; 084 } 085 086 public Query getQuery(Object value, Operator customOperator, Map<String, Object> allValues, String language, Map<String, Object> contextualParameters) 087 { 088 if (!_shareableCourseHelper.handleShareableCourse()) 089 { 090 return null; 091 } 092 093 return _getShareableQuery(value, customOperator, allValues, language, contextualParameters); 094 } 095 096 /** 097 * Get the {@link Query} associated to shareable fields 098 * @param value The user-submitted value (or the default value if not set) for this criterion. 099 * @param customOperator In advanced search mode, the operator chosen by the user. <code>null</code> to use the criterion-defined operator (simple search mode). 100 * @param allValues All the user-submitted values. 101 * @param language The current search language. 102 * @param contextualParameters the search contextual parameters. 103 * @return {@link Query} associated to shareable fields 104 */ 105 protected Query _getShareableQuery(Object value, Operator customOperator, Map<String, Object> allValues, String language, Map<String, Object> contextualParameters) 106 { 107 List<Query> queries = new ArrayList<>(); 108 109 // Shareable course must be validated 110 queries.add(_getValidatedShareableCourseQuery()); 111 112 if (contextualParameters.containsKey("courseListId")) 113 { 114 String courseListId = (String) contextualParameters.get("courseListId"); 115 if (StringUtils.isNotBlank(courseListId)) 116 { 117 ProgramItem courseList = _resolver.resolveById(courseListId); 118 queries.addAll(_getShareableFieldQueries(courseList)); 119 } 120 } 121 122 return queries.stream() 123 .filter(q -> q != null) 124 .collect(AndQuery.collector()); 125 } 126 127 /** 128 * Get the query to get only validated shareable course 129 * @return the query 130 */ 131 protected Query _getValidatedShareableCourseQuery() 132 { 133 return new StringQuery(ShareableCourseConstants.SHAREABLE_COURSE_COMPOSITE_METADATA + ModelItem.ITEM_PATH_SEPARATOR + ShareableCourseConstants.SHAREABLE_COURSE_STATUS_METADATA, ShareableStatus.VALIDATED.name()); 134 } 135 136 /** 137 * Get query form each shareable field 138 * @param programItem the program item 139 * @return the list of query 140 */ 141 protected List<Query> _getShareableFieldQueries(ProgramItem programItem) 142 { 143 List<Query> queries = new ArrayList<>(); 144 145 Set<Program> programs = _odfHelper.getParentPrograms(programItem); 146 Set<Container> containers = _odfHelper.getParentContainers(programItem); 147 148 // Query for programs field 149 Set<String> programValues = _shareableCourseHelper.getProgramIds(programs); 150 queries.add(_getFieldQuery(programValues, ShareableCourseConstants.PROGRAMS_FIELD_ATTRIBUTE_NAME)); 151 152 // Query for periods field 153 Set<String> periodValues = _shareableCourseHelper.getPeriods(containers); 154 queries.add(_getFieldQuery(periodValues, ShareableCourseConstants.PERIODS_FIELD_ATTRIBUTE_NAME)); 155 156 // Query for degree field 157 Set<String> degreeValues = _shareableCourseHelper.getDegrees(programs); 158 queries.add(_getFieldQuery(degreeValues, ShareableCourseConstants.DEGREES_FIELD_ATTRIBUTE_NAME)); 159 160 // Query for orgunits field 161 Set<String> orgunitValues = _shareableCourseHelper.getOrgUnits(programs); 162 queries.add(_getFieldQuery(orgunitValues, ShareableCourseConstants.ORGUNITS_FIELD_ATTRIBUTE_NAME)); 163 164 return queries; 165 } 166 167 /** 168 * Get query for the shareable course field. Query is "not(field) or field = values" 169 * @param values the values 170 * @param metadataName the metadata name of the field 171 * @return the fitler query 172 */ 173 protected Query _getFieldQuery(Set<String> values, String metadataName) 174 { 175 if (values.isEmpty()) 176 { 177 return null; 178 } 179 180 Query programValuesQuery = values.stream() 181 .map(v -> new StringQuery(metadataName, v)) 182 .collect(OrQuery.collector()); 183 184 Query noProgramValueQuery = new NotQuery(new StringQuery(metadataName)); 185 186 return new OrQuery(noProgramValueQuery, programValuesQuery); 187 } 188}