001/*
002 *  Copyright 2016 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.runtime.plugins.admin.configuration;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022
023import org.apache.avalon.framework.parameters.Parameters;
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.cocoon.acting.ServiceableAction;
027import org.apache.cocoon.environment.ObjectModelHelper;
028import org.apache.cocoon.environment.Redirector;
029import org.apache.cocoon.environment.Request;
030import org.apache.cocoon.environment.SourceResolver;
031
032import org.ametys.core.cocoon.ActionResultGenerator;
033import org.ametys.core.util.JSONUtils;
034import org.ametys.runtime.config.ConfigManager;
035import org.ametys.runtime.config.ConfigParameterCheckerDescriptor;
036import org.ametys.runtime.model.checker.ItemChecker;
037
038/**
039 * Fetch the test values and dispatch the requests to the appropriate parameter checkers.
040 */
041public class CheckConfigAction extends ServiceableAction
042{
043    /** Helper component gathering utility methods for the management of JSON entities */
044    private JSONUtils _jsonUtils;
045    
046    @Override
047    public void service(ServiceManager serviceManager) throws ServiceException
048    {
049        _jsonUtils = (JSONUtils) serviceManager.lookup(JSONUtils.ROLE);
050    }
051    
052    @SuppressWarnings("unchecked")
053    @Override
054    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
055    {
056        Map<String, String> result = new HashMap<> ();
057        
058        // Handle the 'configuration not initialized' case
059        Map<String, Object> oldValues = ConfigManager.getInstance().getOldValues();
060        
061        // Fetch the request parameters
062        Request request = ObjectModelHelper.getRequest(objectModel);
063        
064        // Prepare the values for the test
065        String fieldCheckersInfoJSON = request.getParameter("fieldCheckersInfo");
066        Map<String, Object> fieldCheckersInfo = _jsonUtils.convertJsonToMap(fieldCheckersInfoJSON);
067        Map<String, Object> valuesByParameterChecker = _getValuesByParamCheckerId(fieldCheckersInfo, oldValues);
068
069        // Dispatch the requests
070        for (String fieldCheckerId : valuesByParameterChecker.keySet())
071        {
072            ItemChecker fieldChecker = (ItemChecker) ((Map<String, Object>) valuesByParameterChecker.get(fieldCheckerId)).get("checker");
073            List<String> values = (List<String>) ((Map<String, Object>) valuesByParameterChecker.get(fieldCheckerId)).get("values");
074            try 
075            {
076                fieldChecker.check(values); 
077            }
078            catch (Throwable t)
079            {
080                getLogger().error("The test '" + fieldCheckerId + "' failed : \n" + t.getMessage(), t);
081                String msg = t.getMessage() != null ? t.getMessage() : "Unknown error";
082                result.put(fieldCheckerId, msg);
083            }
084        }
085        
086        request.setAttribute(ActionResultGenerator.MAP_REQUEST_ATTR, result);
087        return result;
088    }
089
090    /**
091     * Compute the proper values and {@link ItemChecker} implementations to use for the test and order them by parameter checker id
092     * @param paramCheckersInfo the information concerning the parameter checkers
093     * @param oldValues the map of old values of the configuration
094     * @return the map of values lists ordered by parameter checker
095     */
096    @SuppressWarnings("unchecked")
097    private Map<String, Object> _getValuesByParamCheckerId(Map<String, Object> paramCheckersInfo, Map<String, Object> oldValues)
098    {
099        Map<String, Object> result = new HashMap<> ();
100        
101        ConfigManager configManager = ConfigManager.getInstance();
102        for (String paramCheckerId : paramCheckersInfo.keySet())
103        {
104            Map<String, Object> valuesByParamCheckerId = new HashMap<> (); 
105            
106            // Check the ids of the parameter checkers and build the parameter checkers' list
107            ConfigParameterCheckerDescriptor parameterCheckerDescriptor = configManager.getParameterChecker(paramCheckerId);
108            if (parameterCheckerDescriptor == null)
109            {
110                throw new IllegalArgumentException("The parameter checker '" + paramCheckerId + "' was not found.");
111            }
112            
113            ItemChecker parameterChecker  = parameterCheckerDescriptor.getParameterChecker();
114            
115            valuesByParamCheckerId.put("checker", parameterChecker);
116            
117            List<String> paramNames = (List<String>) ((Map<String, Object>) paramCheckersInfo.get(paramCheckerId)).get("testParamsNames");
118            List<Object> paramRawValues = (List<Object>) ((Map<String, Object>) paramCheckersInfo.get(paramCheckerId)).get("rawTestValues");
119            
120            List<String> values = new ArrayList<> ();
121            
122            // Compute the proper values for the test
123            for (int i = 0; i < paramNames.size(); i++)
124            {
125                String parameterName = paramNames.get(i);
126                Object value = paramRawValues.get(i);
127                
128                // Resolve the value
129                String resolvedValue = configManager.resolveValueForParameterChecker(parameterName, value, oldValues);
130                values.add(resolvedValue);
131            }
132            
133            valuesByParamCheckerId.put("values", values);
134            
135            result.put(paramCheckerId, valuesByParamCheckerId);
136        }
137        
138        return result;
139    }
140}