001/*
002 *  Copyright 2013 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.skinfactory.clientsidelement;
017
018import java.util.ArrayList;
019import java.util.Collections;
020import java.util.LinkedHashMap;
021import java.util.List;
022import java.util.Map;
023import java.util.Set;
024
025import org.apache.avalon.framework.configuration.Configuration;
026import org.apache.avalon.framework.configuration.ConfigurationException;
027import org.apache.avalon.framework.configuration.DefaultConfiguration;
028import org.apache.avalon.framework.service.ServiceException;
029import org.apache.avalon.framework.service.ServiceManager;
030import org.apache.cocoon.ProcessingException;
031
032import org.ametys.core.ui.ClientSideElement;
033import org.ametys.core.ui.SimpleMenu;
034import org.ametys.core.ui.StaticClientSideElement;
035import org.ametys.core.util.I18nUtils;
036import org.ametys.runtime.i18n.I18nizableText;
037import org.ametys.skinfactory.model.ModelDesignsManager;
038import org.ametys.skinfactory.model.ModelDesignsManager.Design;
039import org.ametys.web.skin.SkinModelsManager;
040
041/**
042 * {@link StaticClientSideElement} for design of model
043 *
044 */
045public class DesignsMenu extends SimpleMenu
046{
047    private ModelDesignsManager _designsManager;
048    private boolean _designsInitialized;
049    private SkinModelsManager _modelsManager;
050    private I18nUtils _i18nUtils;
051    
052    @Override
053    public void service(ServiceManager smanager) throws ServiceException
054    {
055        super.service(smanager);
056        _designsManager = (ModelDesignsManager) smanager.lookup(ModelDesignsManager.ROLE);
057        _modelsManager = (SkinModelsManager) smanager.lookup(SkinModelsManager.ROLE);
058        _i18nUtils = (I18nUtils) smanager.lookup(I18nUtils.ROLE);
059    }
060
061    @Override
062    public List<Script> getScripts(boolean ignoreRights, Map<String, Object> contextParameters)
063    {
064        try
065        {
066            Set<String> models = _modelsManager.getModels();
067            
068            if (models.size() > 0)
069            {
070                return super.getScripts(ignoreRights, contextParameters);
071            }
072        }
073        catch (ProcessingException e)
074        {
075            throw new RuntimeException(e);
076        }
077        
078        return Collections.EMPTY_LIST;
079    }
080    
081    @Override
082    protected void _getGalleryItems(Map<String, Object> parameters, Map<String, Object> contextualParameters)
083    {
084        try
085        {
086            _lazyInitializeDesignsGallery();
087        }
088        catch (Exception e)
089        {
090            throw new IllegalStateException("Unable to lookup client side element local components", e);
091        }
092        
093        if (_galleryItems.size() > 0)
094        {
095            parameters.put("gallery-item", new LinkedHashMap<String, Object>());
096            
097            for (GalleryItem galleryItem : _galleryItems)
098            {
099                @SuppressWarnings("unchecked")
100                Map<String, Object> galleryItems = (Map<String, Object>) parameters.get("gallery-item");
101                galleryItems.put("gallery-groups", new ArrayList<>());
102                
103                for (GalleryGroup galleryGp : galleryItem.getGroups())
104                {
105                    @SuppressWarnings("unchecked")
106                    List<Object> galleryGroups = (List<Object>) galleryItems.get("gallery-groups");
107                    
108                    Map<String, Object> groupParams = new LinkedHashMap<>();
109                    
110                    I18nizableText label = galleryGp.getLabel();
111                    groupParams.put("label", label);
112                    
113                    // Group items
114                    List<String> gpItems = new ArrayList<>();
115                    for (ClientSideElement element : galleryGp.getItems())
116                    {
117                        gpItems.add(element.getId());
118                    }
119                    
120                    if (gpItems.size() > 0)
121                    {
122                        groupParams.put("items", gpItems);
123                        galleryGroups.add(groupParams);
124                    }
125                }
126            }
127        }
128    }
129    
130
131    /**
132     * Lazy initialization of the design gallery
133     * @throws ConfigurationException if the design configuration is wrong
134     * @throws ProcessingException if an error occurs when retrieving the models
135     */
136    private void _lazyInitializeDesignsGallery() throws ConfigurationException, ProcessingException
137    {
138        if (!_designsInitialized)
139        {
140            Set<String> models = _modelsManager.getModels();
141            
142            if (models.size() > 0)
143            {
144                GalleryItem galleryItem = new GalleryItem();
145                
146                GalleryGroup galleryGroup = new GalleryGroup(new I18nizableText("plugin." + _pluginName, "PLUGINS_SKINFACTORY_DESIGNMENU_GROUP_LABEL"));
147                galleryItem.addGroup(galleryGroup);
148
149                for (String modelName : models)
150                {
151                    Map<String, Design> designs = _designsManager.getDesigns(modelName);
152                
153                    if (designs.size() > 0)
154                    {
155                        for (Design design : designs.values())
156                        {
157                            String itemId = this.getId() + "-" + modelName + "-" + design.getId();
158                            
159                            Configuration conf = _getDesignConfiguration(itemId, design, modelName);
160                            _galleryItemManager.addComponent(_pluginName, null, itemId, StaticClientSideElement.class, conf);
161                            galleryGroup.addItem(new UnresolvedItem(itemId, true));
162                        }
163                    }
164                }
165                
166                _galleryItems.add(galleryItem);
167            }
168            
169            if (_galleryItems.size() > 0)
170            {
171                try
172                {
173                    _galleryItemManager.initialize();
174                }
175                catch (Exception e)
176                {
177                    throw new ConfigurationException("Unable to lookup parameter local components", e);
178                }
179            }
180            _designsInitialized = true;
181        }
182    }
183
184    /**
185     * Get the configuration of the model item
186     * @param id The id of item
187     * @param design The design
188     * @param modelName The model name
189     * @return The configuration
190     */
191    protected Configuration _getDesignConfiguration(String id, Design design, String modelName)
192    {
193        DefaultConfiguration conf = new DefaultConfiguration("extension");
194        conf.setAttribute("id", id);
195        
196        DefaultConfiguration classConf = new DefaultConfiguration("class");
197        classConf.setAttribute("name", "Ametys.ribbon.element.ui.ButtonController");
198        
199        // Label
200        DefaultConfiguration labelConf = new DefaultConfiguration("label");
201        labelConf.setValue(_i18nUtils.translate(design.getLabel()));
202        classConf.addChild(labelConf);
203        
204        // Description
205        DefaultConfiguration descriptionConf = new DefaultConfiguration("description");
206        descriptionConf.setValue(_i18nUtils.translate(design.getDescription()));
207        classConf.addChild(descriptionConf);
208        
209        // Icons
210        DefaultConfiguration iconSmallConf = new DefaultConfiguration("icon-small");
211        iconSmallConf.setValue(design.getIcon());
212        classConf.addChild(iconSmallConf);
213        DefaultConfiguration iconMediumConf = new DefaultConfiguration("icon-medium");
214        iconMediumConf.setValue(design.getIcon());
215        classConf.addChild(iconMediumConf);
216        DefaultConfiguration iconLargeConf = new DefaultConfiguration("icon-large");
217        iconLargeConf.setValue(design.getIcon());
218        classConf.addChild(iconLargeConf);
219
220        // Model name
221        DefaultConfiguration modelNameConf = new DefaultConfiguration("modelName");
222        modelNameConf.setValue(modelName);
223        classConf.addChild(modelNameConf);
224        
225        // Design id
226        DefaultConfiguration designConf = new DefaultConfiguration("designId");
227        designConf.setValue(design.getId());
228        classConf.addChild(designConf);
229        
230        // Common configuration
231        @SuppressWarnings("unchecked")
232        Map<String, Object> commonConfig = (Map<String, Object>) this._script.getParameters().get("items-config");
233        for (String tagName : commonConfig.keySet())
234        {
235            DefaultConfiguration c = new DefaultConfiguration(tagName);
236            c.setValue(String.valueOf(commonConfig.get(tagName)));
237            classConf.addChild(c);
238        }
239        
240        conf.addChild(classConf);
241        return conf;
242    }
243}