Package org.springmodules.xt.ajax

Source Code of org.springmodules.xt.ajax.AbstractAjaxHandler

/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springmodules.xt.ajax;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.apache.log4j.Logger;
import org.springmodules.xt.ajax.support.EventHandlingException;
import org.springmodules.xt.ajax.support.UnsupportedEventException;

/**
* Abstract {@link AjaxHandler} with the {@link #handle(AjaxEvent)} method implemented as a <i>dynamic template method</i>
* with automatic dispatching of different requests depending on the {@link AjaxEvent} id.<br>
* For handling different requests, hence different events, you have to simply implement a method named after the AjaxEvent id, with the following signature:
* <br><br>
* <code>public {@link AjaxResponse} eventId(<i>{@link AjaxEvent}</i> )</code>
* <br><br>
* The <i>AjaxEvent</i> in the signature above must be the effective subinterface of the {@link AjaxEvent} actually handled.<br>
* Given an ajax event with id <i>countrySelection</i>, the handling method will be:
* <br><br>
* <code>public {@link AjaxResponse} countrySelection({@link AjaxEvent} )</code>
* <br><br>
* The already implemented {@link #handle(AjaxEvent )} will do the appropriate dispatching.
* <br><br>
* NOTE: Implementors are required to be thread-safe.
*
* @author Sergio Bossa
*/
public abstract class AbstractAjaxHandler implements AjaxHandler {
   
    private static final Logger logger = Logger.getLogger(AbstractAjaxHandler.class);
   
    /**
     * Dynamic template method for handling ajax requests depending on the event id.
     * <br><br>
     * @see AjaxHandler#handle(AjaxEvent )
     */
    public AjaxResponse handle(AjaxEvent event) {
        if (event == null || event.getEventId() == null) {
            logger.error("Event and event id cannot be null.");
            throw new IllegalArgumentException("Event and event id cannot be null.");
        }
       
        String id = event.getEventId();
        AjaxResponse response = null;
        try {
            Method m = this.getMatchingMethod(event);
            if (m != null) {
                logger.info(new StringBuilder("Invoking method: ").append(m));
                response = (AjaxResponse) m.invoke(this, new Object[]{event});
            }
            else {
                logger.error("You need to call the supports() method first!");
                throw new UnsupportedEventException("You need to call the supports() method first!");
            }
        }
        catch(IllegalAccessException ex) {
            logger.error(ex.getMessage(), ex);
            logger.error("Cannot handle the given event with id: " + id);
            throw new UnsupportedEventException("Cannot handle the given event with id: " + id, ex);
        }
        catch(InvocationTargetException ex) {
            logger.error(ex.getMessage(), ex);
            logger.error("Exception while handling the given event with id: " + id);
            throw new EventHandlingException("Exception while handling the given event with id: " + id, ex);
        }
       
        return response;
    }
   
    /**
     * Supports the given event if the concrete class implements a method for handling it, that is, a method
     * with the following signature:
     * <br><br>
     * <i>public {@link AjaxResponse} eventId({@link AjaxEvent} )</i>
     * <br><br>
     * @see AjaxHandler#supports(AjaxEvent )
     */
    public boolean supports(AjaxEvent event) {
        String id = event.getEventId();
       
        if (id == null) {
            logger.error("Event id cannot be null.");
            throw new IllegalArgumentException("Event id cannot be null.");
        }
       
        Method m = this.getMatchingMethod(event);
        if (m != null) {
            logger.debug(new StringBuilder("Event supported by method: ").append(m));
            return true;
        }
        else {
            return false;
        }
    }
   
    /**
     * FIXME: Cache reflection results!
     */
    private Method getMatchingMethod(AjaxEvent event) {
        Class eventType = this.getEventType(event);
        Method[] methods = this.getClass().getMethods();
        Method ret = null;
        for (Method method : methods) {
            if (method.getName().equals(event.getEventId()) && method.getParameterTypes()[0].isAssignableFrom(eventType)) {
                ret = method;
                break;
            }
        }
        return ret;
    }
   
    /**
     * FIXME: Cache reflection results!
     */
    private Class getEventType(AjaxEvent event) {
        Class[] interfaces = event.getClass().getInterfaces();
        Class ret = event.getClass();
        for (Class intf : interfaces) {
            if (AjaxEvent.class.isAssignableFrom(intf)) {
                ret = intf;
                break;
            }
        }
        return ret;
    }
}
TOP

Related Classes of org.springmodules.xt.ajax.AbstractAjaxHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.