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