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.cms.search.systemprop;
017
018import java.util.LinkedHashMap;
019import java.util.Map;
020import java.util.Optional;
021
022import org.apache.avalon.framework.configuration.Configuration;
023import org.apache.avalon.framework.configuration.ConfigurationException;
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.cocoon.xml.AttributesImpl;
027import org.apache.cocoon.xml.XMLUtils;
028import org.xml.sax.ContentHandler;
029import org.xml.sax.SAXException;
030
031import org.ametys.cms.languages.Language;
032import org.ametys.cms.languages.LanguageEnumerator;
033import org.ametys.cms.languages.LanguagesManager;
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.ContentLanguageQuery;
038import org.ametys.cms.search.query.Query;
039import org.ametys.cms.search.query.Query.Operator;
040import org.ametys.cms.search.solr.field.LanguageSearchField;
041import org.ametys.core.model.type.ModelItemTypeHelper;
042import org.ametys.runtime.model.Enumerator;
043import org.ametys.runtime.model.ViewItem;
044import org.ametys.runtime.model.type.DataContext;
045import org.ametys.runtime.model.type.ModelItemTypeConstants;
046import org.ametys.runtime.plugin.component.ThreadSafeComponentManager;
047
048/**
049 * {@link SystemProperty} which represents the language of a Content.
050 */
051public class LanguageSystemProperty extends AbstractSystemProperty<String, Content>
052{
053    /** The language manager. */
054    protected LanguagesManager _languageManager;
055    
056    @Override
057    public void service(ServiceManager manager) throws ServiceException
058    {
059        super.service(manager);
060        _languageManager = (LanguagesManager) manager.lookup(LanguagesManager.ROLE);
061    }
062    
063    @Override
064    public boolean isMultiple()
065    {
066        return false;
067    }
068    
069    @Override
070    public boolean isSortable()
071    {
072        return true;
073    }
074    
075    @Override
076    public Query getQuery(Object value, Operator operator, String language, Map<String, Object> contextualParameters)
077    {
078        String langValue = null;
079        if ("CURRENT".equals(value))
080        {
081            langValue = language;
082        }
083        else
084        {
085            langValue = (String) value;
086        }
087        
088        return new ContentLanguageQuery(operator, langValue);
089    }
090    
091    @Override
092    public String getRenderer()
093    {
094        return "Ametys.plugins.cms.search.SearchGridHelper.renderLanguage";
095    }
096    
097    @Override
098    public String getConverter()
099    {
100        return "Ametys.plugins.cms.search.SearchGridHelper.convertLanguage";
101    }
102    
103    @Override
104    public Integer getColumnWidth()
105    {
106        return 70;
107    }
108    
109    @Override
110    public SearchField getSearchField()
111    {
112        return new LanguageSearchField();
113    }
114    
115    @Override
116    public Object getValue(Content content)
117    {
118        return content.getLanguage();
119    }
120    
121    public Object valueToJSON(Content content, Optional<ViewItem> viewItem, DataContext context)
122    {
123        String languageCode = (String) getValue(content);
124        Map<String, Object> infos = new LinkedHashMap<>();
125        
126        infos.put("code", languageCode);
127        
128        if (languageCode != null)
129        {
130            Language language = _languageManager.getLanguage(languageCode);
131            if (language != null)
132            {
133                infos.put("icon", language.getSmallIcon());
134                infos.put("label", language.getLabel());
135            }
136        }
137        
138        return infos;
139    }
140    
141    public void valueToSAX(ContentHandler contentHandler, Content content, Optional<ViewItem> viewItem, DataContext context) throws SAXException
142    {
143        Language language = Optional.of(content)
144                .map(this::getValue)
145                .map(String.class::cast)
146                .map(_languageManager::getLanguage)
147                .orElse(null);
148        
149        if (language != null)
150        {
151            AttributesImpl attr = ModelItemTypeHelper.getXMLAttributesFromDataContext(context);
152            attr.addCDATAAttribute("code", language.getCode());
153            XMLUtils.startElement(contentHandler, getName(),  attr);
154            language.getLabel().toSAX(contentHandler);
155            XMLUtils.endElement(contentHandler, getName());
156        }
157    }
158    
159    @Override
160    public Object getSortValue(Content content)
161    {
162        Language language = Optional.of(content)
163                .map(this::getValue)
164                .map(String.class::cast)
165                .map(_languageManager::getLanguage)
166                .orElse(null);
167        
168        if (language != null)
169        {
170            return _i18nUtils.translate(language.getLabel(), language.getCode());
171        }
172        
173        return null;
174    }
175    
176    public Enumerator<String> getCriterionEnumerator(Configuration configuration, ThreadSafeComponentManager<Enumerator> enumeratorManager) throws ConfigurationException
177    {
178        String role = "enumerator";
179        enumeratorManager.addComponent(getPluginName(), null, role, LanguageEnumerator.class, configuration);
180        
181        try
182        {
183            enumeratorManager.initialize();
184            return enumeratorManager.lookup(role);
185        }
186        catch (Exception e)
187        {
188            throw new ConfigurationException("Unable to initialize the language enumerator for system property '" + getName() + "'.", configuration, e);
189        }
190    }
191    
192    @Override
193    protected String _getTypeId()
194    {
195        return ModelItemTypeConstants.STRING_TYPE_ID;
196    }
197}