001/*
002 *  Copyright 2017 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.restrictions.rules;
017
018import java.util.Set;
019
020import org.apache.commons.lang.StringUtils;
021
022import org.ametys.cms.search.query.OrQuery;
023import org.ametys.cms.search.query.Query;
024import org.ametys.cms.search.query.StringQuery;
025import org.ametys.odf.ProgramItem;
026import org.ametys.odf.orgunit.RootOrgUnitProvider;
027import org.ametys.odf.program.Program;
028import org.ametys.plugins.repository.query.expression.Expression;
029import org.ametys.plugins.repository.query.expression.Expression.Operator;
030import org.ametys.plugins.repository.query.expression.OrExpression;
031import org.ametys.plugins.repository.query.expression.StringExpression;
032
033/**
034 * This implementation of {@link OdfRestrictionRule} restricts ODF to a orgunit and their child orgunits
035 */
036public class OdfOrgunitRestrictionRule implements OdfRestrictionRule
037{
038    private final RootOrgUnitProvider _ouProvider;
039    private final String _rootOrgUnitId;
040    
041    /**
042     * Constructor for ODF rule restriction on a orgunit
043     * @param ouProvider The orgunits provider
044     * @param orgUnitId The id of orgunit
045     */
046    public OdfOrgunitRestrictionRule(RootOrgUnitProvider ouProvider, String orgUnitId)
047    {
048        _ouProvider = ouProvider;
049        _rootOrgUnitId = orgUnitId;
050        
051        if (StringUtils.isEmpty(_rootOrgUnitId))
052        {
053            throw new IllegalArgumentException("At least one non-null rule is required.");
054        }
055    }
056    
057    @Override
058    public Expression getExpression()
059    {
060        Set<String> validOrgUnits = _getValidOrgUnits();
061        
062        Expression[] orgUnitExprs = validOrgUnits.stream()
063            .map(ou -> new StringExpression(ProgramItem.ORG_UNITS_REFERENCES, Operator.EQ, ou))
064            .toArray(Expression[]::new);
065            
066        return new OrExpression(orgUnitExprs);
067    }
068    
069    @Override
070    public Query getQuery()
071    {
072        Set<String> validOrgUnits = _getValidOrgUnits();
073        
074        Query[] orgUnitQueries = validOrgUnits.stream()
075            .map(ou -> new StringQuery(ProgramItem.ORG_UNITS_REFERENCES, ou))
076            .toArray(Query[]::new);
077        
078        return new OrQuery(orgUnitQueries);
079    }
080    
081    @Override
082    public boolean contains(Program program)
083    {
084        Set<String> validOrgUnits = _getValidOrgUnits();
085        
086        return program.getOrgUnits().stream()
087            .filter(StringUtils::isNotEmpty)
088            .anyMatch(orgUnitId -> validOrgUnits.contains(orgUnitId));
089    }
090    
091    @Override
092    public boolean hasOrgunitRestrictions()
093    {
094        return true;
095    }
096    
097    private Set<String> _getValidOrgUnits()
098    {
099        Set<String> validOrgUnits = _ouProvider.getChildOrgUnitIds(_rootOrgUnitId, true);
100        validOrgUnits.add(_rootOrgUnitId);
101        return validOrgUnits;
102    }
103}