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 Set<String> models = _modelsManager.getModels(); 065 if (models != null) 066 { 067 // Test to find if at lease one model has a design (if not, no scripts are added) 068 boolean hasDesigns = models.stream() 069 .map(_designsManager::getDesigns) 070 .anyMatch(d -> !d.isEmpty()); 071 072 if (hasDesigns) 073 { 074 return super.getScripts(ignoreRights, contextParameters); 075 } 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<>()); 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 synchronized void _lazyInitializeDesignsGallery() throws ConfigurationException, ProcessingException 137 { 138 if (!_designsInitialized) 139 { 140 Set<String> models = _modelsManager.getModels(); 141 142 GalleryItem galleryItem = new GalleryItem(); 143 144 GalleryGroup galleryGroup = new GalleryGroup(new I18nizableText("plugin." + _pluginName, "PLUGINS_SKINFACTORY_DESIGNMENU_GROUP_LABEL")); 145 galleryItem.addGroup(galleryGroup); 146 147 for (String modelName : models) 148 { 149 Set<Design> designs = _designsManager.getDesigns(modelName); 150 151 if (designs.size() > 0) 152 { 153 for (Design design : designs) 154 { 155 String itemId = this.getId() + "-" + modelName + "-" + design.getId(); 156 157 Configuration conf = _getDesignConfiguration(itemId, design, modelName); 158 _getGalleryItemManager().addComponent(_pluginName, null, itemId, StaticClientSideElement.class, conf); 159 galleryGroup.addItem(new UnresolvedItem(itemId, true)); 160 } 161 } 162 } 163 164 _galleryItems.add(galleryItem); 165 166 try 167 { 168 _getGalleryItemManager().initialize(); 169 } 170 catch (Exception e) 171 { 172 throw new ConfigurationException("Unable to lookup parameter local components", e); 173 } 174 175 _designsInitialized = true; 176 } 177 } 178 179 /** 180 * Get the configuration of the model item 181 * @param id The id of item 182 * @param design The design 183 * @param modelName The model name 184 * @return The configuration 185 */ 186 protected Configuration _getDesignConfiguration(String id, Design design, String modelName) 187 { 188 DefaultConfiguration conf = new DefaultConfiguration("extension"); 189 conf.setAttribute("id", id); 190 191 DefaultConfiguration classConf = new DefaultConfiguration("class"); 192 classConf.setAttribute("name", "Ametys.ribbon.element.ui.ButtonController"); 193 194 // Label 195 DefaultConfiguration labelConf = new DefaultConfiguration("label"); 196 labelConf.setValue(_i18nUtils.translate(design.getLabel())); 197 classConf.addChild(labelConf); 198 199 // Description 200 DefaultConfiguration descriptionConf = new DefaultConfiguration("description"); 201 descriptionConf.setValue(_i18nUtils.translate(design.getDescription())); 202 classConf.addChild(descriptionConf); 203 204 // Icons 205 DefaultConfiguration iconSmallConf = new DefaultConfiguration("icon-small"); 206 iconSmallConf.setValue(design.getIcon()); 207 classConf.addChild(iconSmallConf); 208 DefaultConfiguration iconMediumConf = new DefaultConfiguration("icon-medium"); 209 iconMediumConf.setValue(design.getIcon()); 210 classConf.addChild(iconMediumConf); 211 DefaultConfiguration iconLargeConf = new DefaultConfiguration("icon-large"); 212 iconLargeConf.setValue(design.getIcon()); 213 classConf.addChild(iconLargeConf); 214 215 // Model name 216 DefaultConfiguration modelNameConf = new DefaultConfiguration("modelName"); 217 modelNameConf.setValue(modelName); 218 classConf.addChild(modelNameConf); 219 220 // Design id 221 DefaultConfiguration designConf = new DefaultConfiguration("designId"); 222 designConf.setValue(design.getId()); 223 classConf.addChild(designConf); 224 225 // Common configuration 226 @SuppressWarnings("unchecked") 227 Map<String, Object> commonConfig = (Map<String, Object>) this._script.getParameters().get("items-config"); 228 for (String tagName : commonConfig.keySet()) 229 { 230 DefaultConfiguration c = new DefaultConfiguration(tagName); 231 c.setValue(String.valueOf(commonConfig.get(tagName))); 232 classConf.addChild(c); 233 } 234 235 conf.addChild(classConf); 236 return conf; 237 } 238}