Package net.sourceforge.javautil.bytecode.api.type

Source Code of net.sourceforge.javautil.bytecode.api.type.BytecodeAnnotationDeclaration

package net.sourceforge.javautil.bytecode.api.type;

import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import net.sourceforge.javautil.bytecode.api.IBytecodeAnnotated;
import net.sourceforge.javautil.bytecode.api.IBytecodeAnnotation;
import net.sourceforge.javautil.bytecode.api.IBytecodeResolvable;
import net.sourceforge.javautil.bytecode.api.IBytecodeSource;
import net.sourceforge.javautil.bytecode.api.LiteralValue;
import net.sourceforge.javautil.bytecode.api.TypeDescriptor;
import net.sourceforge.javautil.bytecode.api.type.method.IBytecodeMethod;
import net.sourceforge.javautil.common.CollectionUtil;

/**
* An implementation for declaring on {@link IBytecodeSource}'s that are marked {@link IBytecodeAnnotated}.
*
* @author elponderador
* @author $Author$
* @version $Id$
*/
public class BytecodeAnnotationDeclaration implements IBytecodeAnnotation {
 
  protected final IBytecodeResolvable type;
  protected final Set<BytecodeAnnotationDeclaration> annotations = new LinkedHashSet<BytecodeAnnotationDeclaration>();
  protected final Map<String, AnnotationValue> values = new LinkedHashMap<String, AnnotationValue>();
  protected final Map<String, IBytecodeMethod> methods = new LinkedHashMap<String, IBytecodeMethod>();
 
  public BytecodeAnnotationDeclaration(IBytecodeResolvable type) {
    this.type = type;
   
    for (IBytecodeMethod dm : type.getDeclaredMethods()) {
      methods.put(dm.getName(), dm);
    }
  }
 
  public IBytecodeResolvable getType() {
    return type;
  }

  public Map<String, AnnotationValue> getValues() {
    return Collections.unmodifiableMap(values);
  }

  public Set<BytecodeAnnotationDeclaration> getDeclaredAnnotations() {
    return Collections.unmodifiableSet(annotations);
  }
 
  public Set<String> getDeclaredMethodNames() { return methods.keySet(); }
 
  /**
   * @param annotationType The type to use for annotating this annotation
   * @return The new declaration
   */
  public BytecodeAnnotationDeclaration annotate (IBytecodeResolvable annotationType) {
    BytecodeAnnotationDeclaration bad = new BytecodeAnnotationDeclaration(annotationType);
    this.annotations.add(bad);
    return bad;
  }
 
  public BytecodeAnnotationDeclaration setValue (String name, int... value) { this.setValue(name, value); return this; }
 
  public BytecodeAnnotationDeclaration setValue (String name, long... value) { this.setValue(name, value); return this; }
 
  public BytecodeAnnotationDeclaration setValue (String name, double... value) { this.setValue(name, value); return this; }
 
  public BytecodeAnnotationDeclaration setValue (String name, short... value) { this.setValue(name, value); return this; }
 
  public BytecodeAnnotationDeclaration setValue (String name, byte... value) { this.setValue(name, value); return this; }
 
  public BytecodeAnnotationDeclaration setValue (String name, char... value) { this.setValue(name, value); return this; }
 
  public BytecodeAnnotationDeclaration setValue (String name, boolean... value) { this.setValue(name, value); return this; }
 
  public BytecodeAnnotationDeclaration setValue (String name, String... value) { this.setValue(name, value); return this; }
 
  public BytecodeAnnotationDeclaration setValue (String name, Enum... value) { this.setValue(name, value); return this; }
 
  public BytecodeAnnotationDeclaration setValue (String name, Class... value) { this.setValue(name, value); return this; }
 
  /**
   * This will perform type safety checks.
   *
   * @param name The name of the annotation value
   * @param value The value for the annotation
   */
  protected void setValue (String name, Object value) {
    if (value == null) throw new IllegalArgumentException("Annotation values cannot be null");
    if (!this.methods.containsKey(name)) throw new IllegalArgumentException("No such annotation value named: " + name + " for " + type);
   
    TypeDescriptor type = this.methods.get(name).getDescriptor().getReturnType();
    TypeDescriptor pt = TypeDescriptor.getFor(value.getClass());
   
    if (type.compareTo(pt) != 0) {
      if (pt.isArray() && type.compareTo(pt.getComponentType()) == 0) {
        value = Array.get(value, 0);
      } else if (type.isArray() && pt.compareTo(type.getComponentType()) == 0) {
        Object array = Array.newInstance(value.getClass(), 1);
        Array.set(array, 0, value);
        value = array;
      } else {
        throw new IllegalArgumentException(value + " is not of the expected annotation value type: " + type);
      }
    }
   
    this.values.put(name, new AnnotationValue(name, value));
  }
 
}
TOP

Related Classes of net.sourceforge.javautil.bytecode.api.type.BytecodeAnnotationDeclaration

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.