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.web.site;
017
018import java.util.ArrayList;
019import java.util.Collection;
020import java.util.HashMap;
021import java.util.LinkedHashMap;
022import java.util.List;
023import java.util.Map;
024
025import org.apache.avalon.framework.parameters.Parameters;
026import org.apache.avalon.framework.service.ServiceException;
027import org.apache.avalon.framework.service.ServiceManager;
028import org.apache.cocoon.acting.ServiceableAction;
029import org.apache.cocoon.environment.ObjectModelHelper;
030import org.apache.cocoon.environment.Redirector;
031import org.apache.cocoon.environment.Request;
032import org.apache.cocoon.environment.SourceResolver;
033
034import org.ametys.cms.languages.Language;
035import org.ametys.cms.languages.LanguagesManager;
036import org.ametys.core.cocoon.JSonReader;
037import org.ametys.plugins.repository.AmetysObjectIterable;
038import org.ametys.runtime.i18n.I18nizableText;
039import org.ametys.runtime.model.DefinitionContext;
040import org.ametys.runtime.model.ElementDefinition;
041import org.ametys.runtime.model.ModelItem;
042import org.ametys.runtime.model.View;
043import org.ametys.runtime.model.type.DataContext;
044import org.ametys.runtime.model.type.ModelItemTypeConstants;
045import org.ametys.web.repository.site.Site;
046import org.ametys.web.repository.site.SiteManager;
047import org.ametys.web.repository.sitemap.Sitemap;
048
049/**
050 * Get the site configuration parameters and their values
051 */
052public class SiteConfigurationAction extends ServiceableAction
053{
054    private static final String __SKIN_PARAMETER_NAME = "skin";
055    private static final String __LANG_PARAMETER_NAME = "lang";
056    
057    /** The site manager. */
058    protected SiteManager _siteManager;
059    
060    /** The site configuration. */
061    protected SiteConfigurationManager _siteConfigurationManager;
062    
063    /** The available languages manager */
064    protected LanguagesManager _languagesManager;
065    
066    @Override
067    public void service(ServiceManager serviceManager) throws ServiceException
068    {
069        super.service(serviceManager);
070        _siteManager = (SiteManager) serviceManager.lookup(SiteManager.ROLE);
071        _siteConfigurationManager = (SiteConfigurationManager) serviceManager.lookup(SiteConfigurationManager.ROLE);
072        _languagesManager = (LanguagesManager) serviceManager.lookup(LanguagesManager.ROLE);
073    }
074    
075    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
076    {
077        Request request = ObjectModelHelper.getRequest(objectModel);
078        
079        String siteName = parameters.getParameter("siteName", request.getParameter("siteName"));
080        
081        Map<String, Object> result = new HashMap<>();
082        
083        View view = _siteConfigurationManager.getSiteView(siteName);
084        // Insert an input to configure the language (no corresponding site parameter), just after the skin parameter
085        Map<String, Object> view2JSON = _insertLanguageParameterAfterSkinParameter(view.toJSON(DefinitionContext.newInstance().withEdition(true)));
086        result.put("parameters", view2JSON);
087        
088        result.put("values", _values2json(siteName));
089        
090        request.setAttribute(JSonReader.OBJECT_TO_READ, result);
091        return EMPTY_MAP;
092    }
093    
094    private Map<String, Object> _values2json (String siteName)
095    {
096        Map<String, Object> form = new HashMap<>();
097
098        Site site = _siteManager.getSite(siteName);
099        
100        Collection<ElementDefinition> siteParameters = _siteConfigurationManager.getSiteParameters(site);
101        View view = View.of(siteParameters.toArray(new ModelItem[siteParameters.size()]));
102        Map<String, Object> values = site.dataToJSONForEdition(view, DataContext.newInstance());
103        
104        List<String> languages = new ArrayList<>();
105        AmetysObjectIterable<Sitemap> sitemaps = site.getSitemaps();
106        for (Sitemap sitemap : sitemaps)
107        {
108            languages.add(sitemap.getName());
109        }
110        values.put("lang", languages);
111        
112        form.put("values", values);
113        return form;
114    }
115    
116    @SuppressWarnings("unchecked")
117    private Map<String, Object> _insertLanguageParameterAfterSkinParameter(Map<String, Object> view2JSON)
118    {
119        Map<String, Object> json = new LinkedHashMap<>();
120        json.putAll(view2JSON);
121        
122        Map<String, Map<String, Object>> categories = (Map<String, Map<String, Object>>) json.get("elements");
123        for (Map<String, Object> category : categories.values())
124        {
125            Map<String, Map<String, Object>> groups = (Map<String, Map<String, Object>>) category.get("elements");
126            for (Map<String, Object> group : groups.values())
127            {
128                Map<String, Object> groupElements = (Map<String, Object>) group.get("elements");
129                if (groupElements.containsKey(__SKIN_PARAMETER_NAME))
130                {
131                    // Create a new group elements that will contain the languages parameter
132                    Map<String, Object> newElements = new LinkedHashMap<>();
133                    for (Map.Entry<String, Object> element : groupElements.entrySet())
134                    {
135                        newElements.put(element.getKey(), element.getValue());
136                        
137                        if (__SKIN_PARAMETER_NAME.equals(element.getKey()))
138                        {
139                            // Insert languages parameter after the skin parameter
140                            newElements.put(__LANG_PARAMETER_NAME, _languages2JsonObject());
141                        }
142                    }
143                    
144                    // Replace the group elements by the new one (containing the language parameter)
145                    group.replace("elements", newElements);
146                }
147            }
148        }
149        
150        return json;
151    }
152    
153    private Map<String, Object> _languages2JsonObject ()
154    {
155        Map<String, Object> param = new HashMap<>();
156        Map<String, String> validation = new HashMap<>();  
157        
158        param.put("label", new I18nizableText("plugin.web", "PLUGINS_WEB_ADMINISTRATOR_SITES_SITE_LANG"));
159        param.put("description", new I18nizableText("plugin.web", "PLUGINS_WEB_ADMINISTRATOR_SITES_SITE_LANG_HELP"));
160        param.put("type", ModelItemTypeConstants.STRING_TYPE_ID);
161        param.put("widget", "edition.combobox");
162        
163        validation.put("mandatory", "mandatory"); 
164        param.put("validation", validation);
165        
166        param.put("multiple", true);
167        
168        List<Map<String, Object>> options = new ArrayList<>();
169        
170        Map<String, Language> availableLanguages = _languagesManager.getAvailableLanguages();
171        for (Language availableLanguage : availableLanguages.values())
172        {
173            Map<String, Object> option = new HashMap<>();
174            option.put("label", availableLanguage.getLabel());
175            option.put("value", availableLanguage.getCode());
176            options.add(option);
177            
178        }
179        
180        param.put("enumeration", options);
181        
182        return param;
183    }
184
185}