001/*
002 *  Copyright 2010 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.styles;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.LinkedHashMap;
021import java.util.List;
022import java.util.Map;
023
024import org.apache.avalon.framework.configuration.Configuration;
025import org.apache.avalon.framework.configuration.ConfigurationException;
026import org.apache.avalon.framework.service.ServiceException;
027import org.apache.avalon.framework.service.ServiceManager;
028
029import org.ametys.core.ui.SimpleMenu;
030import org.ametys.core.ui.widgets.richtext.RichTextConfigurationExtensionPoint;
031import org.ametys.core.util.I18nUtils;
032import org.ametys.plugins.core.ui.util.ConfigurationHelper;
033import org.ametys.runtime.i18n.I18nizableText;
034
035/**
036 * This StaticMenu also search for special tags to transform them into parameters
037 */
038public class EditorStyleMenu extends SimpleMenu
039{
040    /** I18n helper */
041    protected I18nUtils _i18nUtils;
042    
043    /** The default value */
044    protected Map<String, Object> _defaultValues = new HashMap<>();
045    /** The richtext config ep instance */
046    protected RichTextConfigurationExtensionPoint _richtextConfigurationEP;
047    /** The values configured to create the gallery items */
048    protected Map<String, String> _items;
049    /** The class name to use for gallery items */
050    protected String _itemsClassName;
051    /** The tag name to use for gallery items */
052    protected String _itemsTagName;
053    
054    
055    @Override
056    public void service(ServiceManager smanager) throws ServiceException
057    {
058        super.service(smanager);
059        _i18nUtils = (I18nUtils) smanager.lookup(I18nUtils.ROLE);
060        _richtextConfigurationEP = (RichTextConfigurationExtensionPoint) smanager.lookup(RichTextConfigurationExtensionPoint.ROLE);
061    }
062    
063    @Override
064    public void configure(Configuration configuration) throws ConfigurationException
065    {
066        super.configure(configuration);
067        
068        _configureItems(configuration);
069    }
070
071    private void _configureItems(Configuration configuration) throws ConfigurationException
072    {
073        Configuration itemsConfiguration = configuration.getChild("items");
074        
075        _itemsClassName = itemsConfiguration.getAttribute("classname");
076        _itemsTagName = itemsConfiguration.getAttribute("tagname");
077        
078        _items = new HashMap<>();
079        for (Configuration value : itemsConfiguration.getChildren())
080        {
081            _items.put(value.getName(), value.getValue(""));
082        }
083    }
084
085    @Override
086    public List<Script> getScripts(boolean ignoreRights, Map<String, Object> contextParameters)
087    {
088        List<Script> scripts = super.getScripts(ignoreRights, contextParameters);
089        
090        if (scripts.size() == 0)
091        {
092            return scripts;
093        }
094        
095        List<ScriptFile> cssFiles = new ArrayList<>();
096        List<ScriptFile> jsFiles = new ArrayList<>();
097        Map<String, Object> parameters = new HashMap<>();
098        for (Script script : scripts)
099        {
100            cssFiles.addAll(script.getCSSFiles());
101            jsFiles.addAll(script.getScriptFiles());
102            parameters.putAll(getParameters(ConfigurationHelper.clonePluginParameters(script.getParameters()), contextParameters));
103        }
104        
105        List<Script> scriptList = new ArrayList<>();
106        scriptList.add(new Script(this.getId(), _script.getScriptClassname(), jsFiles, cssFiles, parameters));
107        return scriptList;
108    }
109
110    @SuppressWarnings("unchecked")
111    private Map<String, Object> getParameters(Map<String, Object> parameters, Map<String, Object> contextualParameters)
112    {
113        
114        Map<String, Object> json = _richtextConfigurationEP.toJSON(contextualParameters);
115        
116        String category = "content";
117        // Looping on all existing categories would lead for many non content buttons
118        // for (String category : json.keySet())
119        Map<String, Object> contentJson = (Map<String, Object>) json.get(category);
120        Map<String, Object> styles = (Map<String, Object>) contentJson.get("styles");
121        Map<String, Object> itemsStyles = (Map<String, Object>) styles.get(_itemsTagName);
122        if (itemsStyles != null)
123        {
124            List<Map<String, Object>> groups = (List<Map<String, Object>>) itemsStyles.get("groups");
125            
126            for (Map<String, Object> group : groups)
127            {
128                List<Map<String, Object>> galleryGroupItems = _getOrCreateGalleryGroup(parameters, (Integer) group.get("priority"), (I18nizableText) group.get("label"));
129                
130                List<Map<String, Object>> groupValues = (List<Map<String, Object>>) group.get("values");
131                for (Map<String, Object> groupValue : groupValues)
132                {
133                    Map<String, Object> itemCfg = new HashMap<>();
134                    
135                    Map<String, Object> styleConfig = new HashMap<>();
136                    styleConfig.put("label", groupValue.get("label"));
137                    styleConfig.put("description", groupValue.get("description"));
138                    styleConfig.put("category", category);
139                    
140                    Object smallIcon = groupValue.get("buttonSmallIcon");
141                    if (smallIcon != null)
142                    {
143                        styleConfig.put("icon-small", smallIcon);
144                    }
145                    
146                    Object mediumIcon = groupValue.get("buttonMediumIcon");
147                    if (mediumIcon != null)
148                    {
149                        styleConfig.put("icon-medium", mediumIcon);
150                    }
151                    
152                    Object largeIcon = groupValue.get("buttonLArgeIcon");
153                    if (largeIcon != null)
154                    {
155                        styleConfig.put("icon-large", largeIcon);
156                    }
157                    
158                    Object buttonCSSClass = groupValue.get("buttonCSSClass");
159                    if (buttonCSSClass != null)
160                    {
161                        styleConfig.put("cls", buttonCSSClass);
162                    }
163                    
164                    styleConfig.put("css-class", groupValue.get("cssclass"));
165                    styleConfig.putAll(_items);
166                    
167                    itemCfg.put("className", _itemsClassName);
168                    itemCfg.put("config", styleConfig);
169                    
170                    galleryGroupItems.add(itemCfg);
171                }
172            }
173        }
174        
175        return parameters;
176    }
177    
178    @SuppressWarnings("unchecked")
179    private List<Map<String, Object>> _getOrCreateGalleryGroup(Map<String, Object> parameters, Integer priority, I18nizableText label)
180    {
181        Map<String, Object> galleryItems = (Map<String, Object>) parameters.computeIfAbsent("gallery-item", a -> new LinkedHashMap());
182        List<Map<String, Object>> galleryGroups = (List<Map<String, Object>>) galleryItems.computeIfAbsent("gallery-groups", a -> new ArrayList());
183        
184        for (Map<String, Object> groupParams : galleryGroups)
185        {
186            if (groupParams.get("label").equals(label))
187            {
188                return (List<Map<String, Object>>) groupParams.get("items");
189            }
190        }
191        
192        // Group not existing, let's create it
193        
194        int indexWhereToInsert = 0;
195        
196        for (Map<String, Object> groupParams : galleryGroups)
197        {
198            int groupPriority = 0;
199            
200            Object rawPriority = groupParams.get("priority");
201            if (rawPriority instanceof String rawPriorityAsString)
202            {
203                groupPriority = Integer.parseInt(rawPriorityAsString);
204            }
205            else if (rawPriority instanceof Integer rawPriorityAsInteger)
206            {
207                groupPriority = rawPriorityAsInteger;
208            }
209            
210            if (groupPriority > priority)
211            {
212                break;
213            }
214            
215            indexWhereToInsert++;
216        }
217        
218        List<Map<String, Object>> newItems = new ArrayList<>();
219        galleryGroups.add(indexWhereToInsert, Map.of("label", label, "priority", priority, "items", newItems));
220        return newItems;
221    }
222}