001/*
002 *  Copyright 2015 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.search.model.impl;
017
018import java.util.List;
019import java.util.Map;
020import java.util.stream.Collectors;
021
022import org.apache.avalon.framework.configuration.Configuration;
023import org.apache.avalon.framework.configuration.ConfigurationException;
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.cocoon.components.ContextHelper;
027import org.apache.cocoon.environment.Request;
028import org.apache.commons.lang3.StringUtils;
029
030import org.ametys.cms.contenttype.MetadataType;
031import org.ametys.cms.search.query.Query;
032import org.ametys.cms.search.query.Query.Operator;
033import org.ametys.cms.search.ui.model.SearchUICriterion;
034import org.ametys.cms.search.ui.model.impl.AbstractCustomSearchUICriterion;
035import org.ametys.core.util.JSONUtils;
036import org.ametys.web.filter.SharedContentsHelper;
037import org.ametys.web.repository.site.Site;
038import org.ametys.web.repository.site.SiteManager;
039
040/**
041 * Custom boolean {@link SearchUICriterion} representing whether to take content
042 * access restrictions ("content privacy") into account.<br>
043 * It's generally used as a hidden search criterion to force the "true" or "false" value.
044 */
045public class ContentPrivacySearchUICriterion extends AbstractCustomSearchUICriterion
046{
047    
048    /** The site manager. */
049    protected SiteManager _siteManager;
050    
051    /** The JSON utils. */
052    protected JSONUtils _jsonUtils;
053    
054    /** The site criterion ID. */
055    protected String _siteCriterionId;
056    
057    @Override
058    public void service(ServiceManager manager) throws ServiceException
059    {
060        super.service(manager);
061        _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE);
062        _jsonUtils = (JSONUtils) manager.lookup(JSONUtils.ROLE);
063    }
064    
065    @Override
066    public void configure(Configuration configuration) throws ConfigurationException
067    {
068        super.configure(configuration);
069        
070        _siteCriterionId = configuration.getChild("site-criterion").getValue("site");
071    }
072    
073    @Override
074    public MetadataType getType()
075    {
076        return MetadataType.BOOLEAN;
077    }
078    
079    @Override
080    public boolean isMultiple()
081    {
082        return false;
083    }
084    
085    @Override
086    public boolean isSortable()
087    {
088        // Not destined to be displayed.
089        return false;
090    }
091    
092    @Override
093    public Operator getOperator()
094    {
095        return Operator.EQ;
096    }
097    
098    @Override
099    public String getFieldId()
100    {
101        return getId();
102    }
103    
104    @Override
105    public Query getQuery(Object value, Operator customOperator, Map<String, Object> allValues, String language, Map<String, Object> contextualParameters)
106    {
107        boolean restrict = (value instanceof Boolean) ? (Boolean) value : Boolean.parseBoolean(value.toString());
108        
109        if (restrict)
110        {
111            Request request = ContextHelper.getRequest(_context);
112            
113            String currentSiteName = (String) request.getAttribute("siteName");
114            if (StringUtils.isBlank(currentSiteName))
115            {
116                currentSiteName = (String) contextualParameters.get("siteName");
117            }
118            
119            // TODO Find a way to reference a value without ID.
120            Object siteParam = allValues.get("property-" + _siteCriterionId + "-eq");
121            if (siteParam != null)
122            {
123                Map<String, Object> siteValueMap = _jsonUtils.convertJsonToMap((String) siteParam);
124                String context = (String) siteValueMap.get("context");
125                if (context == null)
126                {
127                    context = "SITES_LIST";
128                }
129                
130                // CURRENT_SITE: no restriction.
131                // OTHER_SITES / SITES / SITES_LIST
132                
133                // "SITES_LIST" context: get the site list from the value map.
134                Iterable<Site> sites = null;
135                switch (context)
136                {
137                    case "SITES":
138                        // All sites
139                        sites = _siteManager.getSites();
140                        break;
141                    case "OTHER_SITES":
142                        // All sites except the current one.
143                        sites = _siteManager.getSites();
144                        break;
145                    case "SITES_LIST":
146                        // The given site list.
147                        @SuppressWarnings("unchecked")
148                        List<String> siteNames = (List<String>) siteValueMap.get("sites");
149                        sites = siteNames.stream().map(name -> _siteManager.getSite(name)).collect(Collectors.toList());
150                        break;
151                    case "CURRENT_SITE":
152                        // The current site means no restriction: return null.
153                    default:
154                        return null;
155                }
156                
157                Site currentSite = _siteManager.getSite(currentSiteName);
158                return SharedContentsHelper.getContentAccessQuery(currentSite, sites);
159            }
160        }
161        
162        return null;
163    }
164    
165}