Package org.codehaus.annogen.view.internal.jam

Source Code of org.codehaus.annogen.view.internal.jam.JamIAE

/*   Copyright 2004 The Apache Software Foundation
*
*   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.codehaus.annogen.view.internal.jam;

import com.sun.javadoc.ExecutableMemberDoc;
import com.sun.javadoc.ProgramElementDoc;
import org.codehaus.annogen.override.AnnoBean;
import org.codehaus.annogen.override.AnnoBeanSet;
import org.codehaus.annogen.view.internal.IndigenousAnnoExtractor;
import org.codehaus.annogen.view.internal.NullIAE;
import org.codehaus.annogen.view.internal.javadoc.JavadocAnnogenTigerDelegate;
import org.codehaus.annogen.view.internal.javadoc.ParameterJavadocIAE;
import org.codehaus.annogen.view.internal.javadoc.ProgramElementJavadocIAE;
import org.codehaus.annogen.view.internal.reflect.ReflectAnnogenTigerDelegate;
import org.codehaus.annogen.view.internal.reflect.ReflectIAE;
import org.codehaus.jam.JAnnotatedElement;
import org.codehaus.jam.JAnnotation;
import org.codehaus.jam.JAnnotationValue;
import org.codehaus.jam.JInvokable;
import org.codehaus.jam.JParameter;
import org.codehaus.jam.JProperty;
import org.codehaus.jam.provider.JamLogger;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
* @author Patrick Calahan <email: codehaus-at-bea-dot-com>
*/
public final class JamIAE implements IndigenousAnnoExtractor {

  // ========================================================================
  // Factory methods

  /**
   * This factory method tries to dig into the JAM element's artifact
   * (i.e. the real object that it represents, e.g. a java.lang.Class)
   * and delegate to an appropriate IAE for that artifact.  If there
   * is no artifact, or the artifact is unknown, then an instance of
   * JamIAE will be returned, which operates on JAM's untyped API
   * for accessing annotations.  This is less efficient but is the only
   * option in the absence of something we know about (javadoc or reflection).
   */
  public static IndigenousAnnoExtractor create(JAnnotatedElement element,
                                               JamLogger logger,
                                               ReflectAnnogenTigerDelegate rtiger,
                                               JavadocAnnogenTigerDelegate jtiger) {
    {
      if (element == null) throw new IllegalArgumentException("null element");
      Object artifact = element.getArtifact();
      if (artifact == null) return createForUnknownArtifact(element,logger);
      if (element instanceof JProperty) {
        throw new IllegalStateException("NYI");
      } else if (element instanceof JParameter) {
        JInvokable parent = (JInvokable)element.getParent();
        Object parentArt = parent.getArtifact();
        int num = getParameterNumber((JParameter)element);
        if (parentArt instanceof ExecutableMemberDoc) {
          return ParameterJavadocIAE.create((ExecutableMemberDoc)parentArt,
                                            num,jtiger);
        } else if (parentArt instanceof Method) {
          return ReflectIAE.create((Method)parentArt,num,rtiger);
        } else if (parentArt instanceof Constructor) {
          return ReflectIAE.create((Constructor)parentArt,num,rtiger);
        } else {
          return createForUnknownArtifact(element,logger);
        }
      } else if (artifact instanceof ProgramElementDoc) {
        return ProgramElementJavadocIAE.create((ProgramElementDoc)artifact,jtiger);
      } else if (artifact instanceof Class) {
        return ReflectIAE.create((Class)artifact,rtiger);
      } else if (artifact instanceof Package) {
        return ReflectIAE.create((Package)artifact,rtiger);
      } else if (artifact instanceof Method) {
        return ReflectIAE.create((Method)artifact,rtiger);
      } else if (artifact instanceof Constructor) {
        return ReflectIAE.create((Constructor)artifact,rtiger);
      } else if (artifact instanceof Field) {
        return ReflectIAE.create((Field)artifact,rtiger);
      } else {
        return createForUnknownArtifact(element,logger);
      }
    }
  }

  private static IndigenousAnnoExtractor
    createForUnknownArtifact(JAnnotatedElement element, JamLogger logger) {
    JAnnotation[] anns = element.getAnnotations();
    if (anns == null || anns.length == 0) {
      // if there are no annotations on it anyway, let's not bother with it
      return NullIAE.getInstance();
    }
    return new JamIAE(element,logger);
  }

  // ========================================================================
  // Variables

  private JAnnotatedElement mElement;
  private JamLogger mLogger;

  // ========================================================================
  // Constructors

  private JamIAE(JAnnotatedElement element, JamLogger logger) {
    mElement = element;
    mLogger = logger;
  }

  // ========================================================================
  // IAE implementation

  public boolean extractIndigenousAnnotations(AnnoBeanSet out) {
    JAnnotation[] anns = mElement.getAnnotations();
    if (anns == null || anns.length == 0) return false;
    for(int i=0; i<anns.length; i++) {
      Class annoClass = getAnnotationTypeClass(anns[i]);
      if (annoClass == null) continue;
      AnnoBean bean = out.findOrCreateBeanFor(annoClass);
      populate(anns[i],bean);
    }
    return true;
  }

  // ========================================================================
  // Private methods

  private void populate(JAnnotation src, AnnoBean dest) {
    JAnnotationValue[] values = src.getValues();
    if (values == null || values.length == 0) return;
    for(int i=0; i<values.length; i++) {
      //FIXME this is way busted for nested complex types
      dest.setValue(values[i].getName(),values[i].getValue());
    }
  }

  //REVIEW this is pretty fragile, but do we have a choice?
  private Class getAnnotationTypeClass(JAnnotation ann) {
    try {
    return Class.forName(ann.getQualifiedName());
    } catch(ClassNotFoundException cnfe) {
      mLogger.error(cnfe);
    }
    return null;
  }

  /**
   * REVIEW is it worth doing a more efficient implementation here?  We
   * could add getNumber() to JParameter but it just feels wrong.
   */
  public static int getParameterNumber(JParameter param) {
    JParameter[] params = ((JInvokable)param.getParent()).getParameters();
    for(int i=0; i<params.length; i++) if (param == params[i]) return i;
    throw new IllegalStateException();
  }
}
TOP

Related Classes of org.codehaus.annogen.view.internal.jam.JamIAE

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.