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.search.model.SearchModelCriterionDefinition; 034import org.ametys.cms.search.model.impl.AbstractStaticSearchModelCriterionDefinition; 035import org.ametys.cms.search.model.impl.ReferencingSearchModelCriterionDefinition; 036import org.ametys.cms.search.query.Query; 037import org.ametys.cms.search.query.Query.Operator; 038import org.ametys.core.util.JSONUtils; 039import org.ametys.runtime.model.type.ModelItemTypeConstants; 040import org.ametys.web.filter.SharedContentsHelper; 041import org.ametys.web.repository.site.Site; 042import org.ametys.web.repository.site.SiteManager; 043 044/** 045 * Custom boolean {@link SearchModelCriterionDefinition} representing whether to take content 046 * access restrictions ("content privacy") into account.<br> 047 * It's generally used as a hidden criterion to force the "true" or "false" value. 048 */ 049public class ContentPrivacyCriterionDefinition extends AbstractStaticSearchModelCriterionDefinition<Boolean> implements Contextualizable 050{ 051 /** The site manager. */ 052 protected SiteManager _siteManager; 053 054 /** The JSON utils. */ 055 protected JSONUtils _jsonUtils; 056 057 /** The avalon context */ 058 protected Context _context; 059 060 /** The site criterion ID. */ 061 protected String _siteCriterionName; 062 063 @Override 064 public void service(ServiceManager manager) throws ServiceException 065 { 066 super.service(manager); 067 068 _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE); 069 _jsonUtils = (JSONUtils) manager.lookup(JSONUtils.ROLE); 070 } 071 072 public void contextualize(Context context) throws ContextException 073 { 074 _context = context; 075 } 076 077 @Override 078 public void configure(Configuration configuration) throws ConfigurationException 079 { 080 super.configure(configuration); 081 setSiteCriterionName(configuration.getChild("site-criterion").getValue("site")); 082 } 083 084 @Override 085 protected String getTypeId() 086 { 087 return ModelItemTypeConstants.BOOLEAN_TYPE_ID; 088 } 089 090 @Override 091 public boolean isMultiple() 092 { 093 return false; 094 } 095 096 @Override 097 public Operator getOperator() 098 { 099 return Operator.EQ; 100 } 101 102 /** 103 * Set the site criterion name 104 * @param siteCriterionName the site criterion name to set 105 */ 106 public void setSiteCriterionName(String siteCriterionName) 107 { 108 _siteCriterionName = siteCriterionName; 109 } 110 111 @Override 112 public Query getQuery(Object value, Operator customOperator, Map<String, Object> allValues, String language, Map<String, Object> contextualParameters) 113 { 114 if (_getCriterionDefinitionHelper().isQueryValueEmpty(value)) 115 { 116 return null; 117 } 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(ReferencingSearchModelCriterionDefinition.CRITERION_DEFINITION_PREFIX + _siteCriterionName + "-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}