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.runtime.model.ModelItem;
043
044/**
045 * UI criteria for shareable course
046 */
047public class ShareableCourseSearchUICriteria extends AbstractCustomSearchUICriterion
048{
049    /** The ODF helper */
050    protected ODFHelper _odfHelper;
051    
052    /** The shareable course helper */
053    protected ShareableCourseHelper _shareableCourseHelper;
054    
055    @Override
056    public void service(ServiceManager manager) throws ServiceException
057    {
058        super.service(manager);
059        _odfHelper = (ODFHelper) manager.lookup(ODFHelper.ROLE);
060        _shareableCourseHelper = (ShareableCourseHelper) manager.lookup(ShareableCourseHelper.ROLE);
061    }
062    
063    public String getFieldId()
064    {
065        return "shareable.course.field";
066    }
067
068    public Operator getOperator()
069    {
070        // Not suppose to be used
071        return Operator.EQ;
072    }
073    
074    @Override
075    public MetadataType getType()
076    {
077        // Not suppose to be used
078        return MetadataType.STRING;
079    }
080
081    public Query getQuery(Object value, Operator customOperator, Map<String, Object> allValues, String language, Map<String, Object> contextualParameters)
082    {
083        if (!_shareableCourseHelper.handleShareableCourse())
084        {
085            return null;
086        }
087        
088        List<Query> queries = new ArrayList<>();
089        
090        // Shareable course must be validated
091        Query isValidated = new StringQuery(ShareableCourseConstants.SHAREABLE_COURSE_COMPOSITE_METADATA + ModelItem.ITEM_PATH_SEPARATOR + ShareableCourseConstants.SHAREABLE_COURSE_STATUS_METADATA, ShareableStatus.VALIDATED.name());
092        queries.add(isValidated);
093        
094        if (contextualParameters.containsKey("courseListId"))
095        {
096            String courseListId = (String) contextualParameters.get("courseListId");
097            if (StringUtils.isNotBlank(courseListId))
098            {
099                ProgramItem courseList = _resolver.resolveById(courseListId);
100                Set<Program> programs = _odfHelper.getParentPrograms(courseList);
101                Set<Container> containers = _odfHelper.getParentContainers(courseList);
102                
103                // Query for programs field
104                Set<String> programValues = _shareableCourseHelper.getProgramIds(programs);
105                queries.add(_getFieldQuery(programValues, ShareableCourseConstants.PROGRAMS_FIELD_ATTRIBUTE_NAME));
106                
107                // Query for periods field
108                Set<String> periodValues = _shareableCourseHelper.getPeriods(containers);
109                queries.add(_getFieldQuery(periodValues, ShareableCourseConstants.PERIODS_FIELD_ATTRIBUTE_NAME));
110                
111                // Query for degree field
112                Set<String> degreeValues = _shareableCourseHelper.getDegrees(programs);
113                queries.add(_getFieldQuery(degreeValues, ShareableCourseConstants.DEGREES_FIELD_ATTRIBUTE_NAME));
114                
115                // Query for orgunits field
116                Set<String> orgunitValues = _shareableCourseHelper.getOrgUnits(programs);
117                queries.add(_getFieldQuery(orgunitValues, ShareableCourseConstants.ORGUNITS_FIELD_ATTRIBUTE_NAME));
118            }
119        }
120        
121        return queries.stream()
122                    .filter(q -> q != null)
123                    .collect(AndQuery.collector());
124    }
125
126    /**
127     * Get query for the shareable course field. Query is "not(field) or field = values"
128     * @param values the values
129     * @param metadataName the metadata name of the field
130     * @return the fitler query
131     */
132    protected Query _getFieldQuery(Set<String> values, String metadataName)
133    {
134        if (values.isEmpty())
135        {
136            return null;
137        }
138        
139        Query programValuesQuery = values.stream()
140                .map(v -> new StringQuery(metadataName, v))
141                .collect(OrQuery.collector());
142        
143        Query noProgramValueQuery = new NotQuery(new StringQuery(metadataName));
144        
145        return new OrQuery(noProgramValueQuery, programValuesQuery);
146    }
147}