001 package org.apache.turbine.util.velocity; 002 003 004 /* 005 * Licensed to the Apache Software Foundation (ASF) under one 006 * or more contributor license agreements. See the NOTICE file 007 * distributed with this work for additional information 008 * regarding copyright ownership. The ASF licenses this file 009 * to you under the Apache License, Version 2.0 (the 010 * "License"); you may not use this file except in compliance 011 * with the License. You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, 016 * software distributed under the License is distributed on an 017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 018 * KIND, either express or implied. See the License for the 019 * specific language governing permissions and limitations 020 * under the License. 021 */ 022 023 024 import java.lang.reflect.InvocationTargetException; 025 import java.lang.reflect.Method; 026 import java.util.Iterator; 027 028 import org.apache.fulcrum.parser.ParameterParser; 029 import org.apache.turbine.modules.ActionEvent; 030 import org.apache.turbine.pipeline.PipelineData; 031 import org.apache.turbine.services.velocity.TurbineVelocity; 032 import org.apache.turbine.util.RunData; 033 import org.apache.velocity.context.Context; 034 035 /** 036 * If you are using VelocitySite stuff, then your Action's should 037 * extend this class instead of extending the ActionEvent class. The 038 * difference between this class and the ActionEvent class is that 039 * this class will first attempt to execute one of your doMethod's 040 * with a constructor like this: 041 * 042 * <p><code>doEvent(RunData data, Context context)</code></p> 043 * 044 * <p>It gets the context from the TemplateInfo.getTemplateContext() 045 * method. If it can't find a method like that, then it will try to 046 * execute the method without the Context in it.</p> 047 * 048 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> 049 * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a> 050 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> 051 * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a> 052 * @version $Id: VelocityActionEvent.java 1073174 2011-02-21 22:18:45Z tv $ 053 */ 054 public abstract class VelocityActionEvent extends ActionEvent 055 { 056 /** Constant needed for Reflection */ 057 private static final Class [] methodParams 058 = new Class [] { RunData.class, Context.class }; 059 060 /** Indicates whether or not this module has been initialized. */ 061 protected boolean initialized = false; 062 063 /** 064 * You need to implement this in your classes that extend this 065 * class. 066 * 067 * @deprecated Use PipelineData version instead. 068 * @param data A Turbine RunData object. 069 * @exception Exception a generic exception. 070 */ 071 @Deprecated 072 @Override 073 public abstract void doPerform(RunData data) 074 throws Exception; 075 076 /** 077 * You need to implement this in your classes that extend this class. 078 * Should revert to abstract once RunData is gone. 079 * @param data Turbine information. 080 * @exception Exception a generic exception. 081 */ 082 @Override 083 public void doPerform(PipelineData pipelineData) 084 throws Exception 085 { 086 RunData data = getRunData(pipelineData); 087 doPerform(data); 088 } 089 /** 090 * Provides a means of initializing the module. 091 * 092 * @throws Exception a generic exception. 093 */ 094 protected abstract void initialize() 095 throws Exception; 096 097 /** 098 * This overrides the default Action.perform() to execute the 099 * doEvent() method. If that fails, then it will execute the 100 * doPerform() method instead. 101 * 102 * @deprecated Use PipelineData version instead. 103 * @param data A Turbine RunData object. 104 * @exception Exception a generic exception. 105 */ 106 @Deprecated 107 @Override 108 protected void perform(RunData data) 109 throws Exception 110 { 111 try 112 { 113 if (!initialized) 114 { 115 initialize(); 116 } 117 executeEvents(data, TurbineVelocity.getContext(data)); 118 } 119 catch (NoSuchMethodException e) 120 { 121 doPerform(data); 122 } 123 } 124 125 /** 126 * This overrides the default Action.perform() to execute the 127 * doEvent() method. If that fails, then it will execute the 128 * doPerform() method instead. 129 * 130 * @param data A Turbine RunData object. 131 * @exception Exception a generic exception. 132 */ 133 @Override 134 protected void perform(PipelineData pipelineData) 135 throws Exception 136 { 137 try 138 { 139 if (!initialized) 140 { 141 initialize(); 142 } 143 144 executeEvents(pipelineData, TurbineVelocity.getContext(pipelineData)); 145 } 146 catch (NoSuchMethodException e) 147 { 148 doPerform(pipelineData); 149 } 150 } 151 /** 152 * This method should be called to execute the event based system. 153 * @deprecated Use PipelineData version instead. 154 * @param data A Turbine RunData object. 155 * @param context Velocity context information. 156 * @exception Exception a generic exception. 157 */ 158 @Deprecated 159 public void executeEvents(RunData data, Context context) 160 throws Exception 161 { 162 // Name of the button. 163 String theButton = null; 164 165 // ParameterParser. 166 ParameterParser pp = data.getParameters(); 167 168 String button = pp.convert(BUTTON); 169 String key = null; 170 171 // Loop through and find the button. 172 for (Iterator it = pp.keySet().iterator(); it.hasNext();) 173 { 174 key = (String) it.next(); 175 if (key.startsWith(button)) 176 { 177 if (considerKey(key, pp)) 178 { 179 theButton = formatString(key, pp); 180 break; 181 } 182 } 183 } 184 185 if (theButton == null) 186 { 187 throw new NoSuchMethodException( 188 "ActionEvent: The button was null"); 189 } 190 191 Method method = null; 192 try 193 { 194 method = getClass().getMethod(theButton, methodParams); 195 Object[] methodArgs = new Object[] { data, context }; 196 197 if (log.isDebugEnabled()) 198 { 199 log.debug("Invoking " + method); 200 } 201 202 method.invoke(this, methodArgs); 203 } 204 catch (NoSuchMethodException nsme) 205 { 206 // Attempt to execute things the old way.. 207 if (log.isDebugEnabled()) 208 { 209 log.debug("Couldn't locate the Event ( " + theButton 210 + "), running executeEvents() in " 211 + super.getClass().getName()); 212 } 213 214 super.executeEvents(data); 215 } 216 catch (InvocationTargetException ite) 217 { 218 Throwable t = ite.getTargetException(); 219 log.error("Invokation of " + method , t); 220 throw ite; 221 } 222 finally 223 { 224 pp.remove(key); 225 } 226 } 227 228 /** 229 * This method should be called to execute the event based system. 230 * 231 * @param data A Turbine RunData object. 232 * @param context Velocity context information. 233 * @exception Exception a generic exception. 234 */ 235 public void executeEvents(PipelineData pipelineData, Context context) 236 throws Exception 237 { 238 RunData data = getRunData(pipelineData); 239 // Name of the button. 240 String theButton = null; 241 242 // ParameterParser. 243 ParameterParser pp = data.getParameters(); 244 245 String button = pp.convert(BUTTON); 246 String key = null; 247 248 // Loop through and find the button. 249 for (Iterator it = pp.keySet().iterator(); it.hasNext();) 250 { 251 key = (String) it.next(); 252 if (key.startsWith(button)) 253 { 254 if (considerKey(key, pp)) 255 { 256 theButton = formatString(key, pp); 257 break; 258 } 259 } 260 } 261 262 if (theButton == null) 263 { 264 throw new NoSuchMethodException( 265 "ActionEvent: The button was null"); 266 } 267 268 Method method = null; 269 try 270 { 271 method = getClass().getMethod(theButton, methodParams); 272 Object[] methodArgs = new Object[] { pipelineData, context }; 273 274 if (log.isDebugEnabled()) 275 { 276 log.debug("Invoking " + method); 277 } 278 279 method.invoke(this, methodArgs); 280 } 281 catch (NoSuchMethodException nsme) 282 { 283 // Attempt to execute things the old way.. 284 if (log.isDebugEnabled()) 285 { 286 log.debug("Couldn't locate the Event ( " + theButton 287 + "), running executeEvents() in " 288 + super.getClass().getName()); 289 } 290 291 super.executeEvents(pipelineData); 292 } 293 catch (InvocationTargetException ite) 294 { 295 Throwable t = ite.getTargetException(); 296 log.error("Invokation of " + method , t); 297 throw ite; 298 } 299 finally 300 { 301 pp.remove(key); 302 } 303 } 304 305 }