View Javadoc
1 /* 2 * Scope: a generic MVC framework. 3 * Copyright (c) 2000-2002, The Scope team 4 * All rights reserved. 5 * 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * Neither the name "Scope" nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 * 35 * 36 * $Id: BeansActionManager.java,v 1.8 2002/09/12 10:51:03 ludovicc Exp $ 37 */ 38 package org.scopemvc.model.beans; 39 40 41 import java.beans.MethodDescriptor; 42 import java.lang.reflect.InvocationTargetException; 43 import java.lang.reflect.Method; 44 import org.apache.commons.logging.Log; 45 import org.apache.commons.logging.LogFactory; 46 import org.scopemvc.core.ActionManager; 47 import org.scopemvc.core.ModelAction; 48 import org.scopemvc.util.Debug; 49 50 /*** 51 * <P> 52 * 53 * BeansActionManager is a {@link org.scopemvc.core.ActionManager} that handles 54 * the actions (invokable methods) of JavaBean model objects. </P> 55 * 56 * @author <A HREF="mailto:smeyfroi@users.sourceforge.net">Steve Meyfroidt</A> 57 * @created 05 September 2002 58 * @version $Revision: 1.8 $ $Date: 2002/09/12 10:51:03 $ 59 */ 60 public class BeansActionManager extends ActionManager { 61 62 private static final Log LOG = LogFactory.getLog(BeansActionManager.class); 63 64 65 /*** 66 * Utility method to determine if a given parameter class array matches the 67 * supplied prototype class array 68 * 69 * @param inPrototypeClasses the prototype that is used in the comparison 70 * @param inParameterClasses these are the parameter classes that must be 71 * validated against the prototype 72 * @return whether the parameter classes match the prototype 73 */ 74 protected static boolean matchesPrototype(Class[] inPrototypeClasses, Class[] inParameterClasses) { 75 if (LOG.isDebugEnabled()) { 76 LOG.debug("matchesPrototype: prototype classes: " + inPrototypeClasses + ", parameter classes: " + inParameterClasses); 77 if (inPrototypeClasses != null) { 78 LOG.debug("matchesPrototype: prototype classes: " + java.util.Arrays.asList(inPrototypeClasses)); 79 } 80 if (inParameterClasses != null) { 81 LOG.debug("matchesPrototype: parameter classes: " + java.util.Arrays.asList(inParameterClasses)); 82 } 83 } 84 85 if (inPrototypeClasses == null || inParameterClasses == null || inPrototypeClasses.length == 0 || inParameterClasses.length == 0) { 86 // Equivalent if both are zero length or null 87 if (LOG.isDebugEnabled()) { 88 LOG.debug("matchesPrototype: nulls or 0 lengths"); 89 } 90 return (inPrototypeClasses == null || inPrototypeClasses.length == 0) && (inParameterClasses == null || inParameterClasses.length == 0); 91 } else if (inPrototypeClasses.length == inParameterClasses.length) { 92 if (LOG.isDebugEnabled()) { 93 LOG.debug("matchesPrototype: lengths: " + inPrototypeClasses.length + ", " + inParameterClasses.length); 94 } 95 96 for (int i = 0; i < inPrototypeClasses.length; ++i) { 97 if (!matchesItem(inPrototypeClasses[i], inParameterClasses[i])) { 98 return false; 99 } 100 } 101 return true; 102 } else { 103 // different lengths 104 return false; 105 } 106 } 107 108 109 /*** 110 * Utility method to determine if a given class matches another class, 111 * taking into account primitive<->class mapping and inheritance. 112 * 113 * @param inPrototypeClass TODO: Describe the Parameter 114 * @param inParameterClass TODO: Describe the Parameter 115 * @return TODO: Describe the Return Value 116 */ 117 protected static boolean matchesItem(Class inPrototypeClass, Class inParameterClass) { 118 if (LOG.isDebugEnabled()) { 119 LOG.debug("matchesItem: prototype class: " + inPrototypeClass + ", parameter class: " + inPrototypeClass); 120 } 121 122 if (inPrototypeClass.isAssignableFrom(inParameterClass)) { 123 return true; 124 } 125 126 if (inPrototypeClass.isPrimitive()) { 127 if ((inPrototypeClass.equals(int.class) && inParameterClass.equals(Integer.class)) || 128 (inPrototypeClass.equals(long.class) && inParameterClass.equals(Long.class)) || 129 (inPrototypeClass.equals(short.class) && inParameterClass.equals(Short.class)) || 130 (inPrototypeClass.equals(float.class) && inParameterClass.equals(Float.class)) || 131 (inPrototypeClass.equals(double.class) && inParameterClass.equals(Double.class)) || 132 (inPrototypeClass.equals(char.class) && inParameterClass.equals(Character.class)) || 133 (inPrototypeClass.equals(byte.class) && inParameterClass.equals(Byte.class)) 134 ) { 135 return true; 136 } 137 } 138 return false; 139 } 140 141 142 /*** 143 * Execute the ModelAction with the given parameters 144 * 145 * @param inModel The model used for executing the ModelAction 146 * @param inAction The action (method) to execute 147 * @param inParameters The parameters of the method 148 * @return The result of the ModelAction method 149 * @throws Exception if the execution of the ModelAction failed for any 150 * reason 151 */ 152 public Object doAction(Object inModel, ModelAction inAction, Object[] inParameters) throws Exception { 153 if (inModel == null) { 154 throw new IllegalArgumentException("Can't doAction on a null model."); 155 } 156 if (inAction == null) { 157 throw new IllegalArgumentException("Can't doAction with a null action."); 158 } 159 160 Method method = getMethod(inModel, inAction); 161 if (method == null) { 162 throw new IllegalArgumentException("Cannot do action: " + inAction + " on model: " + inModel); 163 } 164 165 try { 166 return method.invoke(inModel, inParameters); 167 } catch (InvocationTargetException e) { 168 if (LOG.isDebugEnabled()) { 169 LOG.debug("doAction:" + e); 170 } 171 if (e.getTargetException() instanceof Exception) { 172 throw (Exception) e.getTargetException(); 173 } 174 throw e; 175 // throw new ModelException(inModel, "doAction on: " + inModel + ": " + e); 176 } catch (Exception e1) { 177 if (LOG.isDebugEnabled()) { 178 LOG.debug("doAction:" + e1); 179 } 180 throw e1; 181 } 182 } 183 184 185 /*** 186 * Returns true if the ModelAction can be executed on the model object. <br> 187 * If the model implements {@link DynamicInvokable}, then check that the 188 * ModelAction can be invoked by calling the {@link 189 * DynamicInvokable#isActionInvokable isActionInvokable()} method on the 190 * model. 191 * 192 * @param inModel The model used for executing the ModelAction 193 * @param inAction The action (method) to execute 194 * @return true if the ModelAction can be executed on the model 195 */ 196 public boolean canDoAction(Object inModel, ModelAction inAction) { 197 if (inModel instanceof DynamicInvokable) { 198 return ((DynamicInvokable) inModel).isActionInvokable(inAction); 199 } 200 return (getMethod(inModel, inAction) != null); 201 } 202 203 204 /*** 205 * Find a Method matching the prototype in the passed ModelAction for the 206 * passed model object, using the BeanInfo to introspect the model as a 207 * JavaBean. 208 * 209 * @param inAction find a Method that matches the prototype described in 210 * this ModelAction. 211 * @param inModel The model used for executing the ModelAction 212 * @return a Method matching the ModelAction for the passed model or null if 213 * no match. 214 */ 215 protected Method getMethod(Object inModel, ModelAction inAction) { 216 if (LOG.isDebugEnabled()) { 217 LOG.debug("getMethod: " + inAction); 218 } 219 if (inModel == null) { 220 throw new IllegalArgumentException("Can't getMethod on a null model."); 221 } 222 if (inAction == null) { 223 throw new IllegalArgumentException("Can't getMethod with a null action."); 224 } 225 226 MethodDescriptor[] descriptors = BeanInfos.getBeanInfo(inModel.getClass()).getMethodDescriptors(); 227 if (Debug.ON) { 228 Debug.assertTrue(descriptors != null); 229 } 230 231 for (int i = 0; i < descriptors.length; ++i) { 232 MethodDescriptor desc = descriptors[i]; 233 if (Debug.ON) { 234 Debug.assertTrue(desc != null); 235 } 236 237 if (desc.getName().equals(inAction.getMethodName())) { 238 if (matchesPrototype(desc.getMethod().getParameterTypes(), inAction.getParameterClasses())) { 239 return desc.getMethod(); 240 } 241 } 242 } 243 return null; 244 } 245 }

This page was automatically generated by Maven