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.web.service;
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.parameters.Parameters;
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.cocoon.ProcessingException;
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.core.cocoon.JSonReader;
035import org.ametys.runtime.i18n.I18nizableText;
036import org.ametys.runtime.parameter.Enumerator;
037import org.ametys.runtime.parameter.ParameterHelper;
038import org.ametys.runtime.parameter.Validator;
039
040/**
041 * Get service parameters as JSON object
042 *
043 */
044public class GetServiceParametersAction extends ServiceableAction
045{
046    /** The {@link ServiceExtensionPoint} */
047    protected ServiceExtensionPoint _serviceExtPt;
048    
049    @Override
050    public void service(ServiceManager sManager) throws ServiceException
051    {
052        super.service(sManager);
053        _serviceExtPt = (ServiceExtensionPoint) sManager.lookup(ServiceExtensionPoint.ROLE);
054    }
055    
056    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
057    {
058        Request request = ObjectModelHelper.getRequest(objectModel);
059        String serviceId = request.getParameter("serviceId");
060        
061        Map<String, Object> jsonObject = new HashMap<>();
062        
063        Service service = _serviceExtPt.getExtension(serviceId);
064        
065        jsonObject.put("id", serviceId);
066        jsonObject.put("url", service.getURL());
067        jsonObject.put("label", service.getLabel());
068        
069        jsonObject.put("parameters", parameters2JsonObject(service));
070        
071        request.setAttribute(JSonReader.OBJECT_TO_READ, jsonObject);
072        return EMPTY_MAP;
073    }
074    
075    /**
076     * Convert service parameters to JSON object
077     * @param service true the service
078     * @return The JSON object representing the user preferences
079     * @throws ProcessingException if an error occurred
080     */
081    @SuppressWarnings("unchecked")
082    protected Map<String, Object> parameters2JsonObject (Service service) throws ProcessingException
083    {
084        Map<String, Object> jsonObject = new LinkedHashMap<>();
085        jsonObject.put("groups", new ArrayList<Map<String, Object>>());
086        
087        for (ServiceParameterGroup group : service.getParameterGroups())
088        {
089            Map<String, Object> parameters = new LinkedHashMap<>();
090            
091            for (ServiceParameterOrRepeater serviceParameter : group.getParameters())
092            {
093                if (serviceParameter instanceof ServiceParameter)
094                {
095                    parameters.put(serviceParameter.getId(), parameter2JsonObject((ServiceParameter) serviceParameter, null));
096                }
097                else
098                {
099                    parameters.put(serviceParameter.getId(), repeater2JsonObject((ServiceParameterRepeater) serviceParameter));
100                }
101                
102            }
103            
104            List<Map<String, Object>> groups = (List<Map<String, Object>>) jsonObject.get("groups");
105            groups.add(parameters);
106        }
107        
108        return jsonObject;
109    }
110    
111    /**
112     * Convert a service parameter to JSON object
113     * @param parameter the service parameter.
114     * @param value The value
115     * @return The JSON object representing the user preferences
116     * @throws ProcessingException if an error occurred
117     */
118    protected Map<String, Object> parameter2JsonObject (ServiceParameter parameter, Object value) throws ProcessingException
119    {
120        Map<String, Object> jsonObject = new LinkedHashMap<>();
121        
122        jsonObject.put("label", parameter.getLabel());
123        jsonObject.put("description", parameter.getDescription());
124        jsonObject.put("type", parameter.getType().name());
125        
126        Validator validator = parameter.getValidator();
127        if (validator != null)
128        {
129            jsonObject.put("validation", validator.toJson());
130        }
131        
132        String widget = parameter.getWidget();
133        if (widget != null)
134        {
135            jsonObject.put("widget", widget);
136        }
137        
138        Map<String, I18nizableText> widgetParameters = parameter.getWidgetParameters();
139        if (widgetParameters != null && widgetParameters.size() > 0)
140        {
141            jsonObject.put("widget-params", parameter.getWidgetParameters());
142        }
143        
144        jsonObject.put("multiple", parameter.isMultiple());
145        
146        Object defaultValue = parameter.getDefaultValue();
147        if (defaultValue != null)
148        {
149            jsonObject.put("default-value", parameter.getDefaultValue());
150        }
151
152        if (value != null)
153        {
154            jsonObject.put("value", value);
155        }
156        else
157        {
158            jsonObject.put("value", defaultValue);
159        }
160        
161        Enumerator enumerator = parameter.getEnumerator();
162        if (enumerator != null)
163        {
164            try
165            {
166                List<Map<String, Object>> options = new ArrayList<>();
167                
168                for (Map.Entry<Object, I18nizableText> entry : enumerator.getEntries().entrySet())
169                {
170                    String valueAsString = ParameterHelper.valueToString(entry.getKey());
171                    I18nizableText entryLabel = entry.getValue();
172                    
173                    Map<String, Object> option = new HashMap<>();
174                    option.put("label", entryLabel != null ? entryLabel : valueAsString);
175                    option.put("value", valueAsString);
176                    options.add(option);
177                }
178                
179                jsonObject.put("enumeration", options);
180            }
181            catch (Exception e)
182            {
183                throw new ProcessingException("Unable to enumerate entries with enumerator: " + enumerator, e);
184            }
185        }
186        return jsonObject;
187    }
188    
189    /**
190     * Convert the repeater object to JSON
191     * @param repeater the repeater of service parameters
192     * @return the repeater in JSON
193     * @throws ProcessingException if something goes wrong while gathering the properties of the repeater
194     */
195    protected Map<String, Object> repeater2JsonObject (ServiceParameterRepeater repeater) throws ProcessingException
196    {
197        Map<String, Object> jsonObject = new LinkedHashMap<>();
198        
199        Map<String, Object> repeater2json = new HashMap<>();
200        
201        jsonObject.put("label", repeater.getLabel());
202        jsonObject.put("description", repeater.getDescription());
203        jsonObject.put("type", "COMPOSITE");
204        
205        repeater2json.put("initial-size", repeater.getInitialSize());
206        repeater2json.put("min-size", repeater.getMinSize());
207        
208        int maxSize = repeater.getMaxSize();
209        if (maxSize >= 0)
210        {
211            repeater2json.put("max-size", maxSize);
212        }
213
214        
215        repeater2json.put("add-label", repeater.getAddLabel());
216        repeater2json.put("del-label", repeater.getDeleteLabel());
217        
218        Map<String, Object> composition = new LinkedHashMap<>();
219        
220        Map<String, ServiceParameter> parameters = repeater.getChildrenParameters();
221        for (ServiceParameter parameter : parameters.values())
222        {
223            composition.put(parameter.getId(), parameter2JsonObject(parameter, null));
224        }
225        
226        repeater2json.put("composition", composition);
227        jsonObject.put("repeater", repeater2json);
228        
229        return jsonObject;
230    }
231}