Hi.

I've written a simple class which may help others writing Actions with lesser code. Feel free to use it (and expand it) if you like it.

An example:

public class TestAction extends AbstractAnnotationAction {

@ActionMethod
protected void doMyAction (@SitemapParam("my-param") @DefaultValue("true") boolean myParam, @QueryParam("login") String login, @QueryParam("counter") @DefaultValue("0") int counter;
                                             Session session) {
    System.out.println ("Login: "+login);
    }
}

You can use @QueryParam, @SitemapParam, @ConfParam, @HeaderParam, @CookieParam, @FileParam. In the signature of the method you can just add variables if you need them: Request, Session, Redirector, Response, ResultHashMap, Conext, SourceResolver. All of them will be set automatically.
All parameters are casted when needed.

The method to be invoked must have a @ActionMethod annotation or you can define the method using "_method" request or sitemap parameter.

Cheers,
Jörn
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.cocoon.acting.AbstractConfigurableAction;
import org.apache.cocoon.environment.Context;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Redirector;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Response;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.environment.SourceResolver;



 
public abstract class AbstractAnnotationAction extends AbstractConfigurableAction implements ThreadSafe {
    public final static String STATE = "state";
    public final static String SUCCESS = "success";
    public final static String FAILURE = "failure";
    public final static String MESSAGE = "message";
	
	public final static String METHOD_CALL_NAME = "_method";

	protected class ResultHashMap extends HashMap<String, String> {
	   private static final long serialVersionUID = -4191539718741319953L;
	   }
	
	
	@Target(ElementType.PARAMETER)
	@Retention (RetentionPolicy.RUNTIME)
    public @interface QueryParam {
       String value();
       }
	
	@Target(ElementType.PARAMETER)
	@Retention (RetentionPolicy.RUNTIME)
    public @interface SitemapParam {
	   String value();
       }
	
	@Target(ElementType.PARAMETER)
	@Retention (RetentionPolicy.RUNTIME)
    public @interface ConfParam {
	   String value();
       }
	
	@Target(ElementType.PARAMETER)
	@Retention (RetentionPolicy.RUNTIME)
    public @interface DefaultValue {
	   String value();
       }
	
	@Target(ElementType.PARAMETER)
	@Retention (RetentionPolicy.RUNTIME)
    public @interface Format {
       String value ();
       }

	// TODO
	@Target(ElementType.PARAMETER)
	@Retention (RetentionPolicy.RUNTIME)
    public @interface HeaderParam {
       String value ();
       }
	
	// TODO
	@Target(ElementType.PARAMETER)
	@Retention (RetentionPolicy.RUNTIME)
    public @interface CookieParam {
       String value ();
       }
	
	//TODO
	@Target(ElementType.PARAMETER)
	@Retention (RetentionPolicy.RUNTIME)
    public @interface FileParam {
       String value ();
       }	
	
	@Target(ElementType.METHOD)
	@Retention (RetentionPolicy.RUNTIME)
    public @interface ActionMethod {}
	
	
    @SuppressWarnings("unchecked")
    public Map act (Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters params) throws Exception {
       ResultHashMap hashMap = new ResultHashMap ();
	   Request request = ObjectModelHelper.getRequest (objectModel);
	   try {
  	       Method[] methods = this.getClass ().getDeclaredMethods ();
	       for (Method m : methods) {
		       if (m.isAnnotationPresent (ActionMethod.class) 
				   || m.getName ().equals (request.getParameter (METHOD_CALL_NAME)) 
				   || m.getName ().equals (params.getParameter (METHOD_CALL_NAME, ""))) {
			      callMethod (m, hashMap, redirector, resolver, objectModel, source, params);
		          }
	           }
	       } catch (Throwable t) { t.printStackTrace (); if (t instanceof Exception) throw (Exception) t; else throw new Exception (t); }
	  
       return hashMap;
       }
    
    protected void callMethod (Method m, ResultHashMap hashMap, Redirector redirector, SourceResolver resolver, Map<String,String> objectModel, String source, Parameters params) throws Exception {
	   Request request = ObjectModelHelper.getRequest (objectModel);
	   //de.agentsinaction.webalarm.Session session = (de.agentsinaction.webalarm.Session) request.getSession (true).getAttribute ("session");
	   Context context = ObjectModelHelper.getContext (objectModel);
	   Response response = ObjectModelHelper.getResponse (objectModel);
	   Class<?>[] methodParams = m.getParameterTypes ();
	   Object[] objects = new Object[methodParams.length];
	   Annotation[][] annotations = m.getParameterAnnotations ();
	   for (int i = 0; i < methodParams.length; i++) {
		   if (methodParams[i] == ResultHashMap.class)
			  objects[i] = hashMap;
			  else
		   if (methodParams[i] == Request.class)
		  	  objects[i] = request;
			  else
		   if (methodParams[i] == Context.class)
		 	  objects[i] = context;
			  else
		   if (methodParams[i] == Response.class)
			  objects[i] = response;
			  else
		   if (methodParams[i] == com.agentsinaction.foomondo.Session.class)
			  objects[i] = com.agentsinaction.foomondo.Session.getSession (request);
			   else
		   if (methodParams[i] == Session.class)
			  objects[i] = request.getSession (true);
			  else
		   if (methodParams[i] == Redirector.class)
			  objects[i] = redirector;
			  else
		   if (methodParams[i] == SourceResolver.class)
			  objects[i] = resolver;
			  else
		   if (methodParams[i] == Parameters.class)
		      objects[i] = params;
		      else {
		    	   String queryParam = null;
		    	   String sitemapParam = null;
		    	   String confParam = null;
		    	   String defaultValue = null;
		    	   String format = null;
		    	   for (Annotation a : annotations[i])
		    		   if (a.annotationType () == QueryParam.class)
		    			  queryParam = ((QueryParam) a).value ();
		    		      else
				       if (a.annotationType () == SitemapParam.class)
					      sitemapParam = ((SitemapParam) a).value ();
					      else
					   if (a.annotationType () == ConfParam.class)
						  confParam = ((ConfParam) a).value ();
					      else
				       if (a.annotationType () == DefaultValue.class)
					      defaultValue = ((DefaultValue) a).value ();
				          else
					   if (a.annotationType () == Format.class)
						  format = ((Format) a).value ();
		    	   try {
  		    	       if (queryParam != null && m.getParameterTypes ()[i].isArray ())
		    		      objects[i] = getValue (m.getParameterTypes ()[i].getComponentType (), request.getParameterValues (queryParam), defaultValue, format);   
		    	          else
                       if (queryParam != null)
                	      objects[i] = getValue (m.getParameterTypes ()[i], request.getParameter (queryParam), defaultValue, format);
                          else
                       if (sitemapParam != null)
                	      objects[i] = getValue (m.getParameterTypes ()[i], params.getParameter (sitemapParam, null), defaultValue, format);
                          else
                       if (confParam != null)
                    	  objects[i] = getValue (m.getParameterTypes ()[i], (String) settings.get (confParam), defaultValue, format);
                          else {
                    	       System.err.println ("Warning: Problem with argument #"+i);
                    	       objects[i] = null;
                               }
		    	        } catch (ParseException ex) {
		    	        	    ex.printStackTrace ();
		    	        	    objects[i] = null;
		    	                }
		           }
	          }
	   /*
	   System.out.print ("Calling "+m.getName ()+" with ");
	   for (Object o : objects)
		   System.out.print (o+",");
	   System.out.println ();
	   */
	   m.invoke (this, objects);
       }
    
   protected Object getValue (Class<?> paramClass, String values[], String defaultValue, String format) throws ParseException {
	  Object array = Array.newInstance (paramClass, values == null ? 0 : values.length);
	  for (int i = 0; i < (values == null ? 0 : values.length); i++)
		  Array.set (array, i, getValue (paramClass, values[i], defaultValue, format));
	  return array;
      }
    
   protected Object getValue (Class<?> paramClass, String value, String defaultValue, String format) throws ParseException {
	  if (paramClass == String.class)
		 return value != null ? value : defaultValue;
	  if (paramClass == Long.TYPE)
		 return value != null ? getFormattedNumber (paramClass, value, format).longValue () : defaultValue != null ? getFormattedNumber (paramClass, defaultValue, format).longValue () : 0;
      if (paramClass == Integer.TYPE)
    	 return value != null ? getFormattedNumber (paramClass, value, format).intValue () : defaultValue != null ? getFormattedNumber (paramClass, defaultValue, format).intValue () : 0;
      if (paramClass == Double.TYPE)
    	 return value != null ? getFormattedNumber (paramClass, value, format).doubleValue () : defaultValue != null ? getFormattedNumber (paramClass, defaultValue, format).doubleValue () : 0.0;
      if (paramClass == Boolean.TYPE)
    	 return value != null ? getBoolean (value) : defaultValue != null ? getBoolean (defaultValue) : false; 
      if (paramClass == Calendar.class) {
    	 Calendar c = Calendar.getInstance ();
    	 if (format != null) {
    		if (value != null)
     		   c.setTime (new SimpleDateFormat (format).parse (value));
     		   else
     	    if (defaultValue != null)
     	       c.setTime (new SimpleDateFormat (format).parse (defaultValue));
    	    }
    	 return c; 
         }
      return null;
      }
   
   protected boolean getBoolean (String text) {
	  return text.equalsIgnoreCase ("on") 
	         || text.equalsIgnoreCase ("true")
	         || text.equalsIgnoreCase ("yes")
	         || text.equalsIgnoreCase ("ja")
	         || text.equalsIgnoreCase ("1");
      }
   
   protected Number getFormattedNumber (Class<?> paramClass, String value, String format) throws ParseException {
	  if (format != null)
		 return new DecimalFormat (format).parse (value);
	  return paramClass == Long.TYPE ? new Long (value) : paramClass == Integer.TYPE ? new Integer (value) : new Double (value);
      }

}

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to