Package objot.bytecode

Source Code of objot.bytecode.Annotations

//
// Copyright 2007-2010 Qianyan Cai
// Under the terms of the GNU Lesser General Public License version 2.1
//
package objot.bytecode;

import java.io.PrintStream;

import objot.util.Array2;
import objot.util.Class2;
import objot.util.InvalidValueException;


public final class Annotations
  extends Element
{
  public final Constants cons;
  public final boolean hided;
  int annoN;
  Annotation[] annos;

  public Annotations(Constants c, byte[] bs, int beginBi_, boolean hided_)
  {
    super(bs, beginBi_);
    cons = c;
    hided = hided_;
    annoN = readU2(bytes, beginBi + 6);
    int bi = beginBi + 8;
    for (int i = 0; i < annoN; i++)
      bi += Annotation.readByteN(bytes, bi);
    if (bi - beginBi - 6 != readU4(bytes, beginBi + 2))
      throw new ClassFormatError("inconsistent attribute length");
    end1Bi = bi;
  }

  public int getAnnoN()
  {
    return annoN;
  }

  void checkIndex(int ai)
  {
    if (ai < 0 || ai >= annoN)
      throw new InvalidValueException(ai);
  }

  void readAnnos()
  {
    if (annos != null)
      return;
    annos = new Annotation[allocN(annoN)];
    int bi = beginBi + 8;
    for (int i = 0; i < annoN; i++)
    {
      annos[i] = new Annotation(cons, bytes, bi);
      bi = annos[i].end1Bi;
    }
  }

  public Annotation getAnno(int ai)
  {
    checkIndex(ai);
    readAnnos();
    return annos[ai];
  }

  /** @return the index of annotation found, negative for not found. */
  public static int searchAnno(Annotations as,
    Class<? extends java.lang.annotation.Annotation> anno)
  {
    if (as != null)
      for (int i = as.annoN - 1; i >= 0; i--)
        if (as.cons.equalsUtf(as.getAnno(i).getDescCi(), utf(Class2.descript(anno))))
          return i;
    return -1;
  }

  /** @return the annotation found, null for not found. */
  public static Annotation searchAnno(Element a,
    Class<? extends java.lang.annotation.Annotation> anno)
  {
    int i = searchAnno(a.getAnnos(), anno);
    if (i >= 0)
      return a.getAnnos().getAnno(i);
    i = searchAnno(a.getAnnoHides(), anno);
    if (i >= 0)
      return a.getAnnoHides().getAnno(i);
    return null;
  }

  /** @return the index of annotated annotation found, negative for not found. */
  public static int searchAnnoAnno(ClassLoader cl, Annotations as,
    Class<? extends java.lang.annotation.Annotation> anno) throws ClassNotFoundException
  {
    if (as != null)
      for (int i = as.annoN - 1; i >= 0; i--)
      {
        int desc = as.getAnno(i).getDescCi();
        Class<?> ca = cl.loadClass(as.cons.classDesc2NameUcs(desc));
        if (ca.isAnnotationPresent(anno))
          return i;
      }
    return -1;
  }

  /** @return the annotated annotation found, null for not found. */
  public static Annotation searchAnnoAnno(ClassLoader cl, Element a,
    Class<? extends java.lang.annotation.Annotation> anno) throws ClassNotFoundException
  {
    int i = searchAnnoAnno(cl, a.getAnnos(), anno);
    if (i >= 0)
      return a.getAnnos().getAnno(i);
    i = searchAnnoAnno(cl, a.getAnnoHides(), anno);
    if (i >= 0)
      return a.getAnnoHides().getAnno(i);
    return null;
  }

  @Override
  void printContents(PrintStream out, int indent1st, int indent, int verbose)
  {
    if (verbose > 0)
    {
      printIndent(out, indent1st);
      out.print(" annoN ");
      out.print(annoN);
    }
    out.println();
    for (int i = 0; i < annoN; i++)
    {
      printIndent(out, indent);
      out.print(i);
      out.print('.');
      getAnno(i).printTo(out, 0, indent, verbose);
    }
  }

  public void ensureAnnoN(int n)
  {
    readAnnos();
    annos = Array2.ensureN(annos, n);
  }

  public int addAnno(Annotation a)
  {
    if (cons != a.cons)
      throw new IllegalArgumentException("inconsistent constants");
    readAnnos();
    ensureAnnoN(annoN + 1);
    annos[annoN] = a;
    return annoN++;
  }

  public void setAnno(int ai, Annotation a)
  {
    if (cons != a.cons)
      throw new IllegalArgumentException("inconsistent constants");
    checkIndex(ai);
    readAnnos();
    annos[ai] = a;
  }

  @Override
  public int normalizeByteN()
  {
    if (annos == null)
      return byteN0();
    int n = 8;
    for (int i = 0; i < annoN; i++)
      n += annos[i].normalizeByteN();
    return n;
  }

  @Override
  public int normalizeTo(byte[] bs, int begin)
  {
    if (annos == null)
    {
      System.arraycopy(bytes, beginBi, bs, begin, byteN0());
      return begin + byteN0();
    }
    writeU2(bs, begin, readU2(bytes, beginBi));
    writeU2(bs, begin + 6, annoN);
    int bi = begin + 8;
    for (int i = 0; i < annoN; i++)
      bi = annos[i].normalizeTo(bs, bi);
    writeS4(bs, begin + 2, bi - begin - 6);
    return bi;
  }
}
TOP

Related Classes of objot.bytecode.Annotations

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.