org.python.core.AnnotationReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython-standalone Show documentation
Show all versions of jython-standalone Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
/*
* Copyright (c) 2008 Jython Developers
* Licensed to PSF under a Contributor Agreement.
*/
package org.python.core;
import java.io.IOException;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.commons.EmptyVisitor;
/**
* This class reads a classfile from a byte array and pulls out the value of the class annotation
* for APIVersion, which can then be retrieved by a call to getVersion().
*
* Hopefully the use of ClassReader in this implementation is not too expensive. I suspect it is not
* since EmptyVisitor is just a bag of empty methods so shouldn't cost too much. If it turns out to
* cost too much, we will want to implement a special purpose ClassReader that only reads out the
* APIVersion annotation I think.
*/
public class AnnotationReader extends EmptyVisitor {
private boolean nextVisitIsVersion = false;
private boolean nextVisitIsMTime = false;
private int version = -1;
private long mtime = -1;
/**
* Reads the classfile bytecode in data and to extract the version.
* @throws IOException - if the classfile is malformed.
*/
public AnnotationReader(byte[] data) throws IOException {
ClassReader r;
try {
r = new ClassReader(data);
} catch (ArrayIndexOutOfBoundsException e) {
IOException ioe = new IOException("Malformed bytecode: not enough data");
ioe.initCause(e);// IOException didn't grow a constructor that could take a cause till
// 1.6, so do it the old fashioned way
throw ioe;
}
r.accept(this, 0);
}
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
nextVisitIsVersion = desc.equals("Lorg/python/compiler/APIVersion;");
nextVisitIsMTime = desc.equals("Lorg/python/compiler/MTime;");
return this;
}
public void visit(String name, Object value) {
if (nextVisitIsVersion) {
version = (Integer)value;
nextVisitIsVersion = false;
} else if (nextVisitIsMTime) {
mtime = (Long)value;
nextVisitIsVersion = false;
}
}
public int getVersion() {
return version;
}
public long getMTime() {
return mtime;
}
}