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}