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