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