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