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.systemprop; 017 018import java.util.Collection; 019import java.util.LinkedHashMap; 020import java.util.List; 021import java.util.Map; 022 023import org.apache.avalon.framework.configuration.Configuration; 024import org.apache.avalon.framework.configuration.DefaultConfiguration; 025import org.apache.avalon.framework.context.Context; 026import org.apache.avalon.framework.context.ContextException; 027import org.apache.avalon.framework.context.Contextualizable; 028import org.apache.avalon.framework.service.ServiceException; 029import org.apache.avalon.framework.service.ServiceManager; 030import org.apache.cocoon.components.ContextHelper; 031import org.apache.cocoon.environment.Request; 032import org.apache.commons.lang3.StringUtils; 033 034import org.ametys.cms.contenttype.MetadataType; 035import org.ametys.cms.repository.Content; 036import org.ametys.cms.search.SearchField; 037import org.ametys.cms.search.model.SystemProperty; 038import org.ametys.cms.search.query.AndQuery; 039import org.ametys.cms.search.query.Query; 040import org.ametys.cms.search.query.Query.Operator; 041import org.ametys.cms.search.systemprop.AbstractSystemProperty; 042import org.ametys.core.util.JSONUtils; 043import org.ametys.web.repository.content.WebContent; 044import org.ametys.web.repository.site.Site; 045import org.ametys.web.search.query.SiteQuery; 046import org.ametys.web.search.solr.field.SiteSearchField; 047import org.ametys.web.site.SiteEnumerator; 048 049/** 050 * {@link SystemProperty} which represents the site of a Content. 051 */ 052public class SiteSystemProperty extends AbstractSystemProperty implements Contextualizable 053{ 054 055 private JSONUtils _jsonUtils; 056 private Context _context; 057 058 @Override 059 public void contextualize(Context context) throws ContextException 060 { 061 _context = context; 062 } 063 064 @Override 065 public void service(ServiceManager manager) throws ServiceException 066 { 067 super.service(manager); 068 _jsonUtils = (JSONUtils) manager.lookup(JSONUtils.ROLE); 069 } 070 071 @Override 072 public MetadataType getType() 073 { 074 return MetadataType.STRING; 075 } 076 077 @Override 078 public boolean isMultiple() 079 { 080 return false; 081 } 082 083 @Override 084 public boolean isSortable() 085 { 086 return true; 087 } 088 089 @SuppressWarnings("unchecked") 090 @Override 091 public Query getQuery(Object value, Operator operator, String language, Map<String, Object> contextualParameters) 092 { 093 // Handles a list of given site names (SITES_LIST) as well as "CURRENT_SITE", "OTHER_SITES" and "SITES" (all sites). 094 Map<String, Object> valueMap = _parseSite(value); 095 096 String context = (String) valueMap.get("context"); 097 098 Request request = ContextHelper.getRequest(_context); 099 String currentSite = (String) request.getAttribute("siteName"); 100 if (StringUtils.isBlank(currentSite)) 101 { 102 currentSite = (String) contextualParameters.get("siteName"); 103 } 104 105 if ("CURRENT_SITE".equals(context)) 106 { 107 return new SiteQuery(Operator.EQ, currentSite); 108 } 109 else if ("OTHER_SITES".equals(context)) 110 { 111 return new AndQuery(new SiteQuery(), new SiteQuery(Operator.NE, currentSite)); 112 } 113 else if ("SITES".equals(context)) 114 { 115 return new SiteQuery(); 116 } 117 118 // "SITES_LIST" context: get the site list from the value map. 119 List<String> names = (List<String>) valueMap.get("sites"); 120 121 // Standard context: site list. 122 return new SiteQuery(operator, names); 123 } 124 125 @SuppressWarnings("unchecked") 126 private Map<String, Object> _parseSite (Object value) 127 { 128 if (value instanceof Map) 129 { 130 return (Map<String, Object>) value; 131 } 132 else if (value instanceof String) 133 { 134 return _jsonUtils.convertJsonToMap((String) value); 135 } 136 else 137 { 138 throw new IllegalArgumentException("The value " + value + " for criterion " + getId() + " is not a valid Site value."); 139 } 140 } 141 142 @Override 143 public String getWidget() 144 { 145 return "edition.select-site"; 146 } 147 148 @Override 149 public String getRenderer() 150 { 151 return "Ametys.plugins.web.search.SearchTool.renderSite"; 152 } 153 154 @Override 155 public String getConverter() 156 { 157 return "Ametys.plugins.web.search.SearchTool.convertSite"; 158 } 159 160 @Override 161 public SearchField getSearchField() 162 { 163 return new SiteSearchField(); 164 } 165 166 @Override 167 public Object getValue(Content content) 168 { 169 if (content instanceof WebContent) 170 { 171 return ((WebContent) content).getSiteName(); 172 } 173 174 return null; 175 } 176 177 @Override 178 public Object getFullValue(Content content) 179 { 180 Map<String, Object> value = new LinkedHashMap<>(); 181 182 if (content instanceof WebContent) 183 { 184 value.put("name", ((WebContent) content).getSiteName()); 185 186 Site site = ((WebContent) content).getSite(); 187 if (site != null) 188 { 189 value.put("title", site.getTitle()); 190 } 191 } 192 193 return value; 194 } 195 196 @Override 197 public Object getSortValue(Content content) 198 { 199 if (content instanceof WebContent) 200 { 201 return ((WebContent) content).getSite().getTitle(); 202 } 203 204 return null; 205 } 206 207 @Override 208 public EnumeratorDefinition getEnumeratorDefinition(Collection<String> contentTypes, Configuration configuration) 209 { 210 Configuration conf = new DefaultConfiguration("enumeration"); 211 return new EnumeratorDefinition(SiteEnumerator.class, conf); 212 } 213 214}