package onlinefrontlines.web; import java.util.HashMap; import java.lang.reflect.*; import onlinefrontlines.utils.Tools; import org.apache.log4j.Logger; /** * Settings object for a WebAction * * @see WebAction * * @author jorrit * * Copyright (C) 2009-2013 Jorrit Rouwe * * This file is part of Online Frontlines. * * Online Frontlines is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Online Frontlines is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Online Frontlines. If not, see <http://www.gnu.org/licenses/>. */ public class WebActionConfig { private static final Logger log = Logger.getLogger(WebActionConfig.class); /** * Possible methods */ public static enum ActionMethod { INPUT, EXECUTE }; /** * Interceptor to use */ public WebInterceptor interceptor; /** * Action to create */ public Class<?> action; /** * View to use on input */ public WebView inputView; /** * View to use on success */ public WebView successView; /** * View to use on error */ public WebView errorView; /** * View to use on redirect (used from interceptor) */ public WebView redirectView; /** * Method to call */ public ActionMethod method; /** * Cached information on a parameter for this action */ private static class Param { public Class<?> type; public Method method; public Field field; public Param(Class<?> type, Method method, Field field) { this.type = type; this.method = method; this.field = field; } } /** * Cached setters */ private HashMap<String, Param> setters = new HashMap<String, Param>(); /** * Cached getters */ private HashMap<String, Param> getters = new HashMap<String, Param>(); /** * Constructor */ public WebActionConfig() { action = WebAction.class; method = ActionMethod.EXECUTE; } /** * Copy constructor */ public WebActionConfig(WebActionConfig other) { interceptor = other.interceptor; action = other.action; inputView = other.inputView; successView = other.successView; errorView = other.errorView; redirectView = other.redirectView; method = ActionMethod.EXECUTE; } private Param createSetter(String name) { // Get method name String methodName = "set" + Character.toUpperCase(name.charAt(0)) + name.substring(1, name.length()); // Find method for (Method m : action.getMethods()) if (m.getName().equals(methodName) && m.getParameterTypes().length == 1) { Class<?> t = m.getParameterTypes()[0]; if (t.equals(String.class) || t.equals(int.class) || t.equals(long.class) || t.equals(boolean.class)) { return new Param(t, m, null); } } // Try as field try { Field f = action.getField(name); Class<?> t = f.getType(); if (t.equals(String.class) || t.equals(int.class) || t.equals(long.class) || t.equals(boolean.class)) { return new Param(t, null, f); } } catch (NoSuchFieldException e) { } return new Param(null, null, null); } private Param createGetter(String name) { // Try as method try { String methodName = "get" + Character.toUpperCase(name.charAt(0)) + name.substring(1, name.length()); Method method = action.getMethod(methodName); return new Param(method.getReturnType(), method, null); } catch (NoSuchMethodException e) { } // Try as field try { Field field = action.getField(name); return new Param(field.getType(), null, field); } catch (NoSuchFieldException e) { } return new Param(null, null, null); } /** * Set field on action * * @param action Action to set field on * @param name Name of field * @param value Value of field */ public void setField(WebAction action, String name, String value) { // Get setter Param setter = setters.get(name); if (setter == null) { setter = createSetter(name); setters.put(name, setter); } try { // Call method if (setter.method != null) { if (setter.type.equals(String.class)) { setter.method.invoke(action, value); } else if (setter.type.equals(int.class)) { try { int intValue = Integer.parseInt(value); setter.method.invoke(action, intValue); } catch (NumberFormatException e) { log.warn(action.getClass().getName() + ": Parameter '" + name + "' could not be set to int value '" + value + "'"); } } else if (setter.type.equals(long.class)) { try { long longValue = Long.parseLong(value); setter.method.invoke(action, longValue); } catch (NumberFormatException e) { log.warn(action.getClass().getName() + ": Parameter '" + name + "' could not be set to long value '" + value + "'"); } } else if (setter.type.equals(boolean.class)) { boolean booleanValue = Boolean.parseBoolean(value); setter.method.invoke(action, booleanValue); } } else if (setter.field != null) { if (setter.type.equals(String.class)) { setter.field.set(action, value); } else if (setter.type.equals(int.class)) { try { int intValue = Integer.parseInt(value); setter.field.set(action, intValue); } catch (NumberFormatException e) { log.warn(action.getClass().getName() + ": Parameter '" + name + "' could not be set to int value '" + value + "'"); } } else if (setter.type.equals(long.class)) { try { long longValue = Long.parseLong(value); setter.field.set(action, longValue); } catch (NumberFormatException e) { log.warn(action.getClass().getName() + ": Parameter '" + name + "' could not be set to long value '" + value + "'"); } } else if (setter.type.equals(boolean.class)) { boolean booleanValue = Boolean.parseBoolean(value); setter.field.set(action, booleanValue); } } else if (!action.setRequestParameter(name, value)) { log.warn(action.getClass().getName() + ": Parameter '" + name + "' could not be set to value '" + value + "'"); } } catch (IllegalAccessException e) { Tools.logException(action.getClass().getName() + ": Unable to set field '" + name + "' due to exception: ", e); } catch (InvocationTargetException e) { Tools.logException(action.getClass().getName() + ": Unable to set field '" + name + "' due to exception: ", e); } } /** * Get value of field on action * * @param action Action to get field of * @param name Field name * @return Field value */ Object getField(WebAction action, String name) { // Get getter Param getter = getters.get(name); if (getter == null) { getter = createGetter(name); getters.put(name, getter); } try { if (getter.method != null) { return getter.method.invoke(action); } else if (getter.field != null) { return getter.field.get(action); } else { log.warn(action.getClass().getName() + ": Unable to get field '" + name + "'"); } } catch (IllegalAccessException e) { Tools.logException(action.getClass().getName() + ": Unable to get field '" + name + "' due to exception: ", e); } catch (InvocationTargetException e) { Tools.logException(action.getClass().getName() + ": Unable to get field '" + name + "' due to exception: ", e); } return null; } }