001/*
002 *  Copyright 2012 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.clientsideelement;
017
018import java.util.ArrayList;
019import java.util.List;
020import java.util.Map;
021
022import org.apache.avalon.framework.configuration.Configuration;
023import org.apache.avalon.framework.configuration.ConfigurationException;
024import org.apache.avalon.framework.configuration.DefaultConfiguration;
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027
028import org.ametys.cms.languages.Language;
029import org.ametys.cms.languages.LanguagesManager;
030import org.ametys.core.ui.SimpleMenu;
031import org.ametys.core.ui.StaticClientSideElement;
032import org.ametys.core.util.I18nUtils;
033import org.ametys.runtime.i18n.I18nizableText;
034
035/**
036 * Menu that lists the available languages for ODF contents
037 */
038public class LanguageMenu extends SimpleMenu
039{
040    /** The plugin in which are the language resources (messages and icons). */
041    protected static final String _RESOURCES_PLUGIN = "cms";
042    
043    /** The language manager */
044    protected LanguagesManager _languagesManager;
045    
046    /** The i18n utils */
047    protected I18nUtils _i18nUtils;
048    
049    private boolean _languagesInitialized;
050    
051    @Override
052    public void service(ServiceManager smanager) throws ServiceException
053    {
054        super.service(smanager);
055        _languagesManager = (LanguagesManager) smanager.lookup(LanguagesManager.ROLE);
056        _i18nUtils = (I18nUtils) smanager.lookup(I18nUtils.ROLE);
057    }
058    
059    @Override
060    protected void _getGalleryItems(Map<String, Object> parameters, Map<String, Object> contextualParameters)
061    {
062        try
063        {
064            _lazyInitializeLanguageGallery(contextualParameters);
065        }
066        catch (Exception e)
067        {
068            throw new IllegalStateException("Unable to lookup client side element local components", e);
069        }
070        
071        super._getGalleryItems(parameters, contextualParameters);
072    }
073    
074    private synchronized void _lazyInitializeLanguageGallery(Map<String, Object> contextualParameters) throws ConfigurationException
075    {
076        if (!_languagesInitialized)
077        {
078            Map<String, Language> languages = getAvailableLanguages (contextualParameters);
079            
080            if (languages.size() > 0)
081            {
082                GalleryItem galleryItem = new GalleryItem();
083                
084                GalleryGroup galleryGroup = new GalleryGroup(new I18nizableText("plugin." + _RESOURCES_PLUGIN, "PLUGINS_CMS_LANGUAGEMENU_GROUP_LABEL"));
085                galleryItem.addGroup(galleryGroup);
086                    
087                for (Language language : languages.values())
088                {
089                    String id = this.getId() + "." + language.getCode();
090                    
091                    Configuration conf = _getLanguageItemConfiguration (id, language);
092                    _getGalleryItemManager().addComponent(_pluginName, null, id, StaticClientSideElement.class, conf);
093                    galleryGroup.addItem(new UnresolvedItem(id, true));
094                }
095                
096                _galleryItems.add(galleryItem);
097            }
098            
099            if (_galleryItems.size() > 0)
100            {
101                try
102                {
103                    _getGalleryItemManager().initialize();
104                }
105                catch (Exception e)
106                {
107                    throw new ConfigurationException("Unable to lookup parameter local components", e);
108                }
109            }
110        }
111        
112        _languagesInitialized = true;
113    }
114    
115    /**
116     * Get the available languages 
117     * @param contextualParameters The contextual parameters
118     * @return the available languages 
119     */
120    protected Map<String, Language> getAvailableLanguages (Map<String, Object> contextualParameters)
121    {
122        return  _languagesManager.getAvailableLanguages();
123    }
124    
125    
126    @Override
127    public List<Script> getScripts(boolean ignoreRights, Map<String, Object> contextParameters)
128    {
129        Map<String, Language> availableLanguages = getAvailableLanguages(contextParameters);
130        if (availableLanguages == null || availableLanguages.isEmpty())
131        {
132            // Hide menu if there is no language
133            return new ArrayList<>();
134        }
135        
136        return super.getScripts(ignoreRights, contextParameters);
137    }
138    
139    /**
140     * Get the configuration for a language item
141     * @param itemId The item id
142     * @param language The language
143     * @return The configuration
144     */
145    protected Configuration _getLanguageItemConfiguration (String itemId, Language language)
146    {
147        DefaultConfiguration conf = new DefaultConfiguration("extension");
148        conf.setAttribute("id", itemId);
149        
150        DefaultConfiguration classConf = new DefaultConfiguration("class");
151        classConf.setAttribute("name", "Ametys.ribbon.element.ui.ButtonController");
152        
153        // Label
154        DefaultConfiguration labelConf = new DefaultConfiguration("label");
155        labelConf.setValue(_i18nUtils.translate(language.getLabel()));
156        classConf.addChild(labelConf);
157        
158        // Description
159        DefaultConfiguration descConf = new DefaultConfiguration("description");
160        descConf.setValue(_i18nUtils.translate(language.getLabel()));
161        classConf.addChild(descConf);
162        
163        // Code
164        DefaultConfiguration codeConf = new DefaultConfiguration("code");
165        codeConf.setValue(language.getCode());
166        classConf.addChild(codeConf);
167        
168        // Icons
169        DefaultConfiguration iconSmallConf = new DefaultConfiguration("icon-small");
170        iconSmallConf.setValue(language.getSmallIcon());
171        classConf.addChild(iconSmallConf);
172        DefaultConfiguration iconMediumConf = new DefaultConfiguration("icon-medium");
173        iconMediumConf.setValue(language.getMediumIcon());
174        classConf.addChild(iconMediumConf);
175        DefaultConfiguration iconLargeConf = new DefaultConfiguration("icon-large");
176        iconLargeConf.setValue(language.getLargeIcon());
177        classConf.addChild(iconLargeConf);
178        
179        // Common configuration
180        @SuppressWarnings("unchecked")
181        Map<String, Object> commonConfig = (Map<String, Object>) this._script.getParameters().get("items-config");
182        _addChildrenToConf(classConf, commonConfig);
183        
184        conf.addChild(classConf);
185        return conf;
186    }
187    
188    @SuppressWarnings("unchecked")
189    private void _addChildrenToConf (DefaultConfiguration conf, Map<String, Object> childrenAsMap)
190    {
191        for (String tagName : childrenAsMap.keySet())
192        {
193            DefaultConfiguration c = new DefaultConfiguration(tagName);
194            Object value = childrenAsMap.get(tagName);
195            if (value instanceof Map)
196            {
197                _addChildrenToConf(c, (Map<String, Object>) value);
198            }
199            else
200            {
201                c.setValue(String.valueOf(value));
202            }
203            conf.addChild(c);
204        }
205    }
206}