Package org.strecks.navigate.internal

Source Code of org.strecks.navigate.internal.BeanNavigationReader

/*
* 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.navigate.internal;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import org.strecks.controller.NavigableControllerAction;
import org.strecks.controller.internal.ActionBeanAnnotationReader;
import org.strecks.exceptions.ApplicationConfigurationException;
import org.strecks.navigate.NavigationHandler;
import org.strecks.navigate.NavigationHandlerFactory;
import org.strecks.navigate.NavigationHolder;
import org.strecks.navigate.annotation.NavigationInfo;
import org.strecks.util.Assert;
import org.strecks.util.ReflectHelper;

/**
* <code>ActionBeanAnnotationReader</code> which reads navigation information using annotations,
* themselves identified using the marker annotation <code>NavigationInfo</code>
* @author Phil Zoio
*/
public class BeanNavigationReader implements ActionBeanAnnotationReader<NavigableControllerAction>
{

  private NavigationHolder navigationHolder;

  public boolean readAnnotations(Class actionBeanClass)
  {

    NavigationHandlerInfo navigationInfo = readNavigationHandlerFactory(actionBeanClass);

    if (navigationInfo != null)
    {
      NavigationHandler navigationHandler = getNavigationHandler(actionBeanClass, navigationInfo);

      checkTypes(navigationHandler.getClass(), navigationInfo.getMethod());

      navigationHolder = new NavigationHolder(navigationHandler, navigationInfo.getFactory(), navigationInfo
          .getMethod());

      return true;
    }
    else
    {
      throw new ApplicationConfigurationException("No annotation using the @"
          + NavigationInfo.class.getSimpleName()
          + " annotation found. This is needed to determine the navigation for the action bean "
          + actionBeanClass);
    }

  }

  public void populateController(NavigableControllerAction controller)
  {
    controller.setNavigationHolder(navigationHolder);
  }

  public NavigationHolder getNavigationHolder()
  {
    return navigationHolder;
  }

  void checkTypes(Class navigationHandlerClass, Method extractionMethod)
  {
    Class<Object> genericType = getGenericType(navigationHandlerClass);

    if (genericType != null)
    {
      Class returnType = extractionMethod.getReturnType();

      if (!genericType.isAssignableFrom(returnType))
      {
        throw new ApplicationConfigurationException("The return type of " + extractionMethod.getName()
            + "() in " + extractionMethod.getDeclaringClass().getName()
            + " is not compatible with the parameterized generic type " + genericType
            + " of the navigation handler " + navigationHandlerClass.getName());

      }
    }
  }

  @SuppressWarnings("unchecked")
  private Class<Object> getGenericType(Class navigationHandlerClass)
  {
    Class<Object> genericType = ReflectHelper.getGenericType(navigationHandlerClass, NavigationHandler.class);
    return genericType;
  }

  NavigationHandlerInfo readNavigationHandlerFactory(Class actionClass)
  {

    Method[] methods = actionClass.getMethods();

    NavigationReader reader = null;
    Method containingMethod = null;
    Annotation annotationFound = null;

    boolean found = false;

    for (Method method : methods)
    {

      NavigationReader tempReader = null;
      Annotation tempAnnotation = null;

      Annotation[] annotations = method.getAnnotations();

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

        if (navigationInfo != null)
        {
          tempReader = ReflectHelper.createInstance(navigationInfo.value(), NavigationReader.class);
          tempAnnotation = annotation;
        }
      }

      if (tempReader != null)
      {
        if (found)
        {
          throw new ApplicationConfigurationException(actionClass.getName()
              + " violates rule that only one method containing an annotation which uses the @"
              + NavigationInfo.class.getSimpleName() + " annotation is permitted");
        }

        ReflectHelper.checkParameterTypeLength(method, 0);

        if (!ReflectHelper.hasReturnValue(method))
        {
          throw new ApplicationConfigurationException(actionClass.getName()
              + " contains an annotation which uses the @" + NavigationInfo.class.getSimpleName()
              + " annotation but returns void");
        }

        reader = tempReader;
        containingMethod = method;
        annotationFound = tempAnnotation;
        found = true;
      }
    }

    if (reader != null)
    {
      return reader.getNavigationHandlerFactory(annotationFound, actionClass, containingMethod);
    }
    else
      return null;

  }

  NavigationHandler getNavigationHandler(Class actionClass, NavigationHandlerInfo info)
  {
    NavigationHandlerFactory factory = info.getFactory();
    Class type = info.getMethod().getReturnType();

    NavigationHandler navigationHandler = factory.getNavigationHandler(actionClass.getName(), type);

    // make sure that navigationHandler is not null
    Assert.notNull(navigationHandler);
    return navigationHandler;
  }

}
TOP

Related Classes of org.strecks.navigate.internal.BeanNavigationReader

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.