001/* 002 * Copyright 2012 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.io.File; 019import java.util.ArrayList; 020import java.util.Collection; 021import java.util.Collections; 022import java.util.HashMap; 023import java.util.List; 024import java.util.Map; 025 026import org.apache.avalon.framework.parameters.Parameters; 027import org.apache.avalon.framework.thread.ThreadSafe; 028import org.apache.cocoon.acting.AbstractAction; 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.ActionResultGenerator; 035import org.ametys.runtime.config.ConfigManager; 036import org.ametys.runtime.i18n.I18nizableText; 037import org.ametys.runtime.model.ElementDefinition; 038import org.ametys.runtime.model.type.ElementType; 039import org.ametys.runtime.servlet.RuntimeServlet; 040import org.ametys.runtime.util.AmetysHomeHelper; 041 042 043/** 044 * This action is in charge to get and save the config values entered by the user.<br> 045 * The backup is delegated to <code>Config</code> 046 */ 047public class SaveConfigAction extends AbstractAction implements ThreadSafe 048{ 049 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 050 { 051 052 if (getLogger().isDebugEnabled()) 053 { 054 getLogger().debug("Starting SaveConfigAction"); 055 } 056 057 Request request = ObjectModelHelper.getRequest(objectModel); 058 Map<String, Object> result = new HashMap<> (); 059 060 try 061 { 062 Map<String, Object> values = new HashMap<>(); 063 064 ConfigManager configManager = ConfigManager.getInstance(); 065 Collection<ElementDefinition> definitions = configManager.getConfigurationParameters(); 066 Map<String, List<I18nizableText>> errorFields = new HashMap<>(); 067 068 for (ElementDefinition definition : definitions) 069 { 070 final String parameterId = definition.getName(); 071 try 072 { 073 Object value = _getTypedValueFromRequest(request, definition); 074 values.put(parameterId, value); 075 } 076 catch (Exception e) 077 { 078 if (getLogger().isWarnEnabled()) 079 { 080 getLogger().warn("The configuration parameter '" + parameterId + "' is not valid.", e); 081 } 082 I18nizableText errorLabel = new I18nizableText("plugin.core", "PLUGINS_CORE_SAVE_PARAMETER_VALUE_INVALID", Collections.singletonList(e.getMessage())); 083 errorFields.put(parameterId, Collections.singletonList(errorLabel)); 084 } 085 } 086 087 if (errorFields.isEmpty()) 088 { 089 // No type error, let's try to save configuration 090 String configFileName = new File(AmetysHomeHelper.getAmetysHomeConfig(), RuntimeServlet.CONFIG_FILE_NAME).getCanonicalPath(); 091 errorFields.putAll(configManager.save(values, configFileName)); 092 } 093 094 if (!errorFields.isEmpty()) 095 { 096 for (String paramId : errorFields.keySet()) 097 { 098 List<I18nizableText> errors = errorFields.get(paramId); 099 result.put(paramId, errors); 100 } 101 102 request.setAttribute(ActionResultGenerator.MAP_REQUEST_ATTR, result); 103 return EMPTY_MAP; 104 } 105 } 106 catch (Exception e) 107 { 108 getLogger().error("An error occured while saving config modifications", e); 109 110 result.put("error", e.getMessage()); 111 request.setAttribute(ActionResultGenerator.MAP_REQUEST_ATTR, result); 112 return EMPTY_MAP; 113 } 114 115 // Set the request attribute for Cocoon reloading 116 if (getLogger().isDebugEnabled()) 117 { 118 getLogger().debug("Positionning org.ametys.runtime.reload=true for Cocoon reloading"); 119 } 120 request.setAttribute("org.ametys.runtime.reload", true); 121 122 return EMPTY_MAP; 123 } 124 125 private Object _getTypedValueFromRequest(Request request, ElementDefinition definition) 126 { 127 final String parameterId = definition.getName(); 128 final ElementType type = definition.getType(); 129 130 Object value = null; 131 if (definition.isMultiple()) 132 { 133 String[] valuesAsString = request.getParameterValues(parameterId); 134 if (valuesAsString != null) 135 { 136 List<Object> valuesAsList = new ArrayList<>(); 137 for (String valueAsString : valuesAsString) 138 { 139 valuesAsList.add(type.castValue(valueAsString)); 140 } 141 value = valuesAsList.toArray(new Object[valuesAsList.size()]); 142 } 143 } 144 else 145 { 146 final String valueAsString = request.getParameter(parameterId); 147 value = definition.getType().castValue(valueAsString); 148 } 149 150 return value; 151 } 152}