Package org.strecks.controller

Source Code of org.strecks.controller.ActionCreatorImpl

/*
* Copyright 2005-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.strecks.controller;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.Action;
import org.strecks.action.BasicAction;
import org.strecks.action.BasicDispatchAction;
import org.strecks.action.BasicFormAction;
import org.strecks.action.BasicSubmitAction;
import org.strecks.action.NavigableAction;
import org.strecks.action.NavigableDispatchAction;
import org.strecks.action.NavigableFormAction;
import org.strecks.action.NavigableSubmitAction;
import org.strecks.action.basic.BasicController;
import org.strecks.action.basic.BasicDispatchController;
import org.strecks.action.basic.BasicFormController;
import org.strecks.action.basic.BasicSubmitController;
import org.strecks.action.navigable.NavigableController;
import org.strecks.action.navigable.NavigableDispatchController;
import org.strecks.action.navigable.NavigableFormController;
import org.strecks.action.navigable.NavigableSubmitController;
import org.strecks.controller.annotation.ActionInterface;
import org.strecks.controller.annotation.BeanAnnotationReader;
import org.strecks.controller.annotation.Controller;
import org.strecks.controller.internal.ActionBeanAnnotationReader;
import org.strecks.exceptions.ApplicationConfigurationException;
import org.strecks.injection.internal.InjectionAnnotationReader;
import org.strecks.interceptor.internal.ActionBeanInterceptorReader;
import org.strecks.lifecycle.LifecycleMethodAware;
import org.strecks.lifecycle.impl.LifecycleMethodReader;
import org.strecks.source.BeanSourceAnnotationReader;
import org.strecks.source.DefaultActionBeanSource;
import org.strecks.util.ReflectHelper;

/**
* The default implementation of the <code>ActionController</code>
* @author Phil Zoio
*/
public class ActionCreatorImpl implements ActionCreator
{

  private static Log log = LogFactory.getLog(ActionCreatorImpl.class);

  private HashMap<Class, Class> implicitControllers;

  public ActionCreatorImpl()
  {
    // we don't need to worry about this method returning null
    this.implicitControllers = new HashMap<Class, Class>();
    this.implicitControllers.putAll(initImplicitControllers());
  }

  public Action createAction(Class actionClass) throws Exception
  {

    Action strutsAction = null;

    // Create and return a new Action instance
    if (log.isTraceEnabled())
    {
      log.trace("Creating new Action instance");
    }

    if (Action.class.isAssignableFrom(actionClass))
    {
      strutsAction = (Action) actionClass.newInstance();
    }
    else
    {
      strutsAction = createControllerAction(actionClass);
    }

    return strutsAction;

  }

  Class getActionInterfaceType(Class controllerClass, Class actionBeanClass)
  {

    @SuppressWarnings("unchecked")
    ActionInterface actionInterface = (ActionInterface) controllerClass.getAnnotation(ActionInterface.class);

    if (actionInterface == null)
    {
      throw new ApplicationConfigurationException("The controller class " + controllerClass + " declared from "
          + actionBeanClass + " does not have an " + ActionInterface.class + " annnotation");
    }

    Class actionInterfaceType = actionInterface.name();

    // check that actionInterfaceType is an interface
    if (!actionInterfaceType.isInterface())
    {
      throw new ApplicationConfigurationException("The controller class " + controllerClass + " declared from "
          + actionBeanClass + " declares an action interface type " + actionInterfaceType
          + " which is not an interface");
    }
    return actionInterfaceType;
  }

  Object instantiateControllerAction(Class controllerClass, Class actionBeanClass)
  {
    // now instantiate the controllerClass
    Object controllerActionInstance = null;
    try
    {
      controllerActionInstance = controllerClass.newInstance();
    }
    catch (InstantiationException e)
    {
      throw new ApplicationConfigurationException("Could not instantiate " + controllerClass
          + " declared from action bean class " + actionBeanClass);
    }
    catch (IllegalAccessException e)
    {
      throw new ApplicationConfigurationException("Illegal access to " + controllerClass
          + " declared from action bean class " + actionBeanClass);
    }
    return controllerActionInstance;
  }

  void checkIsAssignable(Class actionClass, Class actionInterfaceType, Class controllerClass)
  {
    // check that actionBean implements this interface
    @SuppressWarnings("unchecked")
    boolean assignableFrom = actionInterfaceType.isAssignableFrom(actionClass);
    if (!assignableFrom)
    {
      throw new ApplicationConfigurationException("The action bean class " + actionClass
          + " does not implement the action interface type " + actionInterfaceType
          + " mandated by the controller action class " + controllerClass + " with which it is associated ");
    }
  }

  Class getControllerClass(Class actionClass)
  {
    @SuppressWarnings("unchecked")
    Controller controller = (Controller) actionClass.getAnnotation(Controller.class);

    Class controllerClass = null;

    if (controller == null)
    {
      // check for implicity controllers
      controllerClass = checkImplicitController(actionClass);

      if (controllerClass == null)
      {
        throw new ApplicationConfigurationException(actionClass.getName()
            + " is not a Struts Action subclass and does not have a " + Controller.class.getName()
            + " annotation");
      }
    }
    else
    {
      controllerClass = controller.name();
    }

    if (!ControllerAction.class.isAssignableFrom(controllerClass))
    {
      throw new ApplicationConfigurationException(actionClass.getName() + " has a controller class "
          + controllerClass.getName() + " which does not implement the " + ControllerAction.class.getName()
          + " interface");
    }
    if (!Action.class.isAssignableFrom(controllerClass))
    {
      throw new ApplicationConfigurationException(actionClass.getName() + " is has a "
          + Controller.class.getName() + " annotation which points to the class " + controllerClass.getName()
          + " which is not a Struts Action subclass");
    }
    return controllerClass;
  }

  /**
   * Looks for implicit controller for given action bean class. Returns the first one encountered
   */
  Class checkImplicitController(Class actionClass)
  {
    Class controllerClass = null;

    Set<Class> actionInterfaces = implicitControllers.keySet();
    for (Class<Object> interfaceClass : actionInterfaces)
    {
      if (interfaceClass.isAssignableFrom(actionClass))
      {
        controllerClass = implicitControllers.get(interfaceClass);
        break;
      }
    }
    return controllerClass;
  }

  /**
   * Creates action which will need to be an instance of <code>ControllerAction</code>
   */
  Action createControllerAction(Class actionBeanClass)
  {

    // get the class of the controller struts action
    Class controllerClass = getControllerClass(actionBeanClass);

    // check that the conroller has the correct annotations
    Class actionInterfaceType = getActionInterfaceType(controllerClass, actionBeanClass);

    // check that the action class is assignable to the declared action interface type
    checkIsAssignable(actionBeanClass, actionInterfaceType, controllerClass);

    Object controllerActionInstance = instantiateControllerAction(controllerClass, actionBeanClass);

    // cast to Struts action
    Action strutsAction = (Action) controllerActionInstance;

    // cast the same reference to ControllerAction, so that its factory can be set
    ControllerAction controllerAction = (ControllerAction) controllerActionInstance;

    if (controllerAction instanceof BeanSourceAware)
    {

      BeanSourceAware bsa = (BeanSourceAware) controllerAction;

      // set the name of the actionBean to be instantiated
      bsa.setBeanSource(new DefaultActionBeanSource(actionBeanClass));

      // set action class injection handlers
      BeanSourceAnnotationReader sourceAnnotationReader = new BeanSourceAnnotationReader();
      sourceAnnotationReader.readAnnotations(actionBeanClass);

      // tell controller action about action class injection handlers
      sourceAnnotationReader.populateController(bsa);

    }

    if (controllerAction instanceof Injectable)
    {

      // set action class injection handlers
      InjectionAnnotationReader injectionAnnotationReader = new InjectionAnnotationReader();
      injectionAnnotationReader.readAnnotations(actionBeanClass);

      // tell controller action about action class injection handlers
      injectionAnnotationReader.populateController((Injectable) controllerAction);

    }
   
    if (controllerAction instanceof InterceptorAware)
    {
      ActionBeanInterceptorReader interceptorAware = new ActionBeanInterceptorReader();
      interceptorAware.readAnnotations(actionBeanClass);

      interceptorAware.populateController((InterceptorAware) controllerAction);
    }
   
    if (controllerAction instanceof LifecycleMethodAware)
    {
      LifecycleMethodReader initMethodReader = new LifecycleMethodReader();
      initMethodReader.readAnnotations(actionBeanClass);

      initMethodReader.populateController((LifecycleMethodAware) controllerAction);
    }

    readControllerClassAnnotations(actionBeanClass, controllerAction);

    return strutsAction;

  }

  @SuppressWarnings("unchecked")
  void readControllerClassAnnotations(Class actionBeanClass, ControllerAction controllerAction)
  {

    Annotation[] annotations = controllerAction.getClass().getAnnotations();

    for (Annotation annotation : annotations)
    {
      Class<? extends Annotation> annotationType = annotation.annotationType();
      BeanAnnotationReader readerAnnotation = annotationType.getAnnotation(BeanAnnotationReader.class);

      if (readerAnnotation != null)
      {
        Class value = readerAnnotation.value();

        ActionBeanAnnotationReader reader = ReflectHelper.createInstance(value,
            ActionBeanAnnotationReader.class);
        if (reader.readAnnotations(actionBeanClass))
        {
          reader.populateController(controllerAction);
        }
      }
    }

  }

  protected Map<Class, Class> initImplicitControllers()
  {
    Map<Class, Class> map = new LinkedHashMap<Class, Class>();
    map.put(BasicAction.class, BasicController.class);
    map.put(BasicFormAction.class, BasicFormController.class);
    map.put(BasicSubmitAction.class, BasicSubmitController.class);
    map.put(BasicDispatchAction.class, BasicDispatchController.class);
    map.put(NavigableAction.class, NavigableController.class);
    map.put(NavigableFormAction.class, NavigableFormController.class);
    map.put(NavigableSubmitAction.class, NavigableSubmitController.class);
    map.put(NavigableDispatchAction.class, NavigableDispatchController.class);

    return map;
  }

}
TOP

Related Classes of org.strecks.controller.ActionCreatorImpl

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.