From: <ls...@us...> - 2008-06-27 19:27:51
|
Revision: 4280 http://jnode.svn.sourceforge.net/jnode/?rev=4280&view=rev Author: lsantha Date: 2008-06-27 12:27:49 -0700 (Fri, 27 Jun 2008) Log Message: ----------- Improved annotation support including annotation defaults. Modified Paths: -------------- trunk/builder/src/builder/org/jnode/build/ObjectEmitter.java trunk/core/descriptors/org.classpath.core.xml trunk/core/src/classpath/vm/java/lang/Class.java trunk/core/src/classpath/vm/java/lang/reflect/Method.java trunk/core/src/core/org/jnode/vm/VmSystem.java trunk/core/src/core/org/jnode/vm/classmgr/ClassDecoder.java trunk/core/src/core/org/jnode/vm/classmgr/VmAnnotation.java trunk/core/src/core/org/jnode/vm/classmgr/VmMethod.java trunk/core/src/openjdk/vm/java/lang/reflect/NativeProxy.java Added Paths: ----------- trunk/core/src/core/org/jnode/vm/classmgr/VmConstantPool.java Modified: trunk/builder/src/builder/org/jnode/build/ObjectEmitter.java =================================================================== --- trunk/builder/src/builder/org/jnode/build/ObjectEmitter.java 2008-06-26 20:11:32 UTC (rev 4279) +++ trunk/builder/src/builder/org/jnode/build/ObjectEmitter.java 2008-06-27 19:27:49 UTC (rev 4280) @@ -243,6 +243,8 @@ bis.writeObjectRef(null); // enumConstantsDirectory bis.writeObjectRef(null); + // annotationType + bis.writeObjectRef(null); } } catch (ClassNotFoundException ex) { throw new BuildException("emitting object: [" + c + "]", ex); Modified: trunk/core/descriptors/org.classpath.core.xml =================================================================== --- trunk/core/descriptors/org.classpath.core.xml 2008-06-26 20:11:32 UTC (rev 4279) +++ trunk/core/descriptors/org.classpath.core.xml 2008-06-27 19:27:49 UTC (rev 4280) @@ -11,6 +11,8 @@ <runtime> <library name="jnode-core.jar"> + <export name="com.sun.beans.*"/> + <export name="com.sun.beans.finder.*"/> <export name="com.sun.java.util.jar.pack.*"/> <export name="com.sun.naming.internal.*"/> <export name="com.sun.security.auth.UserPrincipal"/> @@ -20,6 +22,15 @@ <export name="sun.misc.*"/> <export name="sun.reflect.*"/> <export name="sun.reflect.annotation.*"/> + <export name="sun.reflect.generics.*"/> + <export name="sun.reflect.generics.factory.*"/> + <export name="sun.reflect.generics.parser.*"/> + <export name="sun.reflect.generics.reflectiveObjects.*"/> + <export name="sun.reflect.generics.repository.*"/> + <export name="sun.reflect.generics.scope.*"/> + <export name="sun.reflect.generics.tree.*"/> + <export name="sun.reflect.generics.visitor.*"/> + <export name="sun.reflect.misc.*"/> <export name="sun.net.InetAddressCachePolicy"/> <export name="sun.net.util.IPAddressUtil"/> <export name="sun.net.www.ParseUtil"/> Modified: trunk/core/src/classpath/vm/java/lang/Class.java =================================================================== --- trunk/core/src/classpath/vm/java/lang/Class.java 2008-06-26 20:11:32 UTC (rev 4279) +++ trunk/core/src/classpath/vm/java/lang/Class.java 2008-06-27 19:27:49 UTC (rev 4280) @@ -73,6 +73,7 @@ import org.jnode.vm.classmgr.VmMethod; import org.jnode.vm.classmgr.VmType; import org.jnode.vm.classmgr.VmClassLoader; +import sun.reflect.annotation.AnnotationType; /** * A Class represents a Java type. There will never be multiple Class @@ -161,8 +162,8 @@ } public static Class forName(String className, boolean initialize, - ClassLoader loader) throws ClassNotFoundException { - return VmSystem.forName(className); + ClassLoader loader) throws ClassNotFoundException { + return (loader == null) ? VmSystem.forName(className) : loader.loadClass(className, initialize); } /** @@ -1295,30 +1296,29 @@ */ public boolean isAnnotation() { - //todo implement it - throw new UnsupportedOperationException(); + return vmClass.isAnnotation(); } public String getCanonicalName() { - //todo implement it - throw new UnsupportedOperationException(); - /* - if (vmClass.isArray()) - { - String componentName = vmClass.getComponentType().getCanonicalName(); - if (componentName != null) - return componentName + "[]"; + if (isArray()) { + String canonicalName = getComponentType().getCanonicalName(); + if (canonicalName != null) + return canonicalName + "[]"; + else + return null; } - if (vmClass.isMemberClass(klass)) - { - String memberName = getDeclaringClass(klass).getCanonicalName(); - if (memberName != null) - return memberName + "." + getSimpleName(klass); + if (isLocalOrAnonymousClass()) + return null; + Class<?> enclosingClass = getEnclosingClass(); + if (enclosingClass == null) { // top level class + return getName(); + } else { + String enclosingName = enclosingClass.getCanonicalName(); + if (enclosingName == null) + return null; + return enclosingName + "." + getSimpleName(); } - if (isLocalClass(klass) || vmClass.isAnonymousClass(klass)) - return null; - return getName(klass); - */ + } /** @@ -1420,7 +1420,8 @@ * identical to getEnumConstantsShared except that * the result is uncloned, cached, and shared by all callers. */ - T[] getEnumConstantsShared() { + //todo make it package private + public T[] getEnumConstantsShared() { if (enumConstants == null) { if (!isEnum()) return null; try { @@ -1602,4 +1603,17 @@ public boolean isSynthetic() { return vmClass.isSynthetic(); } + + // Annotation types cache their internal (AnnotationType) form + private AnnotationType annotationType; + + //todo change this to package private + public void setAnnotationType(AnnotationType type) { + annotationType = type; + } + + //todo change this to package private + public AnnotationType getAnnotationType() { + return annotationType; + } } Modified: trunk/core/src/classpath/vm/java/lang/reflect/Method.java =================================================================== --- trunk/core/src/classpath/vm/java/lang/reflect/Method.java 2008-06-26 20:11:32 UTC (rev 4279) +++ trunk/core/src/classpath/vm/java/lang/reflect/Method.java 2008-06-27 19:27:49 UTC (rev 4280) @@ -40,6 +40,7 @@ import gnu.java.lang.ClassHelper; import java.lang.annotation.Annotation; +import java.lang.annotation.AnnotationFormatError; import java.util.ArrayList; import org.jnode.vm.VmReflection; @@ -48,7 +49,12 @@ import gnu.java.lang.reflect.MethodSignatureParser; import java.util.Arrays; +import java.util.Map; +import java.nio.ByteBuffer; import sun.reflect.MethodAccessor; +import sun.reflect.annotation.AnnotationParser; +import sun.reflect.annotation.AnnotationType; +import sun.misc.SharedSecrets; /** * The Method class represents a member method of a class. It also allows @@ -95,14 +101,17 @@ | Modifier.STATIC | Modifier.STRICT | Modifier.SYNCHRONIZED; /** - * This class is uninstantiable. + * */ public Method(VmMethod vmMethod) { this.vmMethod = vmMethod; + this.annotationDefault = vmMethod.getRawAnnotationDefault(); + this.annotations = vmMethod.getRawAnnotations(); + this.parameterAnnotations = vmMethod.getRawParameterAnnotations(); } public Method(Class declaringClass, String name, Class[] parameterTypes, Class returnType, Class[] checkedExceptions, int modifiers, int slot, String signature, byte[] annotations, byte[] parameterAnnotations, byte[] annotationDefault) { - //todo implement it + throw new UnsupportedOperationException(); } @@ -471,32 +480,90 @@ * @see java.lang.reflect.AnnotatedElement#getAnnotation(java.lang.Class) */ public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { - return vmMethod.getAnnotation(annotationClass); + if(annotationClass.getName().equals(org.jnode.vm.annotation.AllowedPackages.class.getName())) { + return vmMethod.getAnnotation(annotationClass); + } else { + return _getAnnotation(annotationClass); + } } + //jnode openjdk + public MethodAccessor getMethodAccessor() { + //todo implement it + throw new UnsupportedOperationException(); + } + public void setMethodAccessor(MethodAccessor accessor) { + //todo implement it + throw new UnsupportedOperationException(); + } + + public Method copy() { + //todo implement it + throw new UnsupportedOperationException(); + } + + private transient Map<Class, Annotation> declaredAnnotations; + private byte[] annotations; + private byte[] parameterAnnotations; + private byte[] annotationDefault; + + private synchronized Map<Class, Annotation> declaredAnnotations() { + + if (declaredAnnotations == null) { + declaredAnnotations = AnnotationParser.parseAnnotations(annotations, + SharedSecrets.getJavaLangAccess().getConstantPool(getDeclaringClass()), getDeclaringClass()); + } + + return declaredAnnotations; + } + /** - * @see java.lang.reflect.AnnotatedElement#getAnnotations() + * If this method is an annotation method, returns the default + * value for the method. If there is no default value, or if the + * method is not a member of an annotation type, returns null. + * Primitive types are wrapped. + * + * @throws TypeNotPresentException if the method returns a Class, + * and the class cannot be found + * + * @since 1.5 */ - public Annotation[] getAnnotations() { - return vmMethod.getAnnotations(); + public Object getDefaultValue() { + if (annotationDefault == null) + return null; + + Class memberType = AnnotationType.invocationHandlerReturnType(getReturnType()); + + Object result = AnnotationParser.parseMemberValue(memberType, ByteBuffer.wrap(annotationDefault), + SharedSecrets.getJavaLangAccess().getConstantPool(getDeclaringClass()), getDeclaringClass()); + + if (result instanceof sun.reflect.annotation.ExceptionProxy) + throw new AnnotationFormatError("Invalid default: " + this); + + return result; } /** - * @see java.lang.reflect.AnnotatedElement#getDeclaredAnnotations() + * @throws NullPointerException {@inheritDoc} + * @since 1.5 */ - public Annotation[] getDeclaredAnnotations() { - return vmMethod.getDeclaredAnnotations(); + public <T extends Annotation> T _getAnnotation(Class<T> annotationClass) { + if (annotationClass == null) + throw new NullPointerException(); + + return (T) declaredAnnotations().get(annotationClass); } /** - * @see java.lang.reflect.AnnotatedElement#isAnnotationPresent(java.lang.Class) + * @since 1.5 */ - public boolean isAnnotationPresent(Class< ? extends Annotation> annotationClass) { - return vmMethod.isAnnotationPresent(annotationClass); + public Annotation[] getDeclaredAnnotations() { + return declaredAnnotations().values().toArray(EMPTY_ANNOTATION_ARRAY); } - //jnode openjdk + private static final Annotation[] EMPTY_ANNOTATION_ARRAY=new Annotation[0]; + /** * Returns an array of arrays that represent the annotations on the formal * parameters, in declaration order, of the method represented by @@ -514,37 +581,19 @@ * @since 1.5 */ public Annotation[][] getParameterAnnotations() { - return new Annotation[vmMethod.getNoArguments()][]; - } - /** - * If this method is an annotation method, returns the default - * value for the method. If there is no default value, or if the - * method is not a member of an annotation type, returns null. - * Primitive types are wrapped. - * - * @throws TypeNotPresentException if the method returns a Class, - * and the class cannot be found - * - * @since 1.5 - */ - public Object getDefaultValue(){ - //todo implement it - return null; - } + int numParameters = vmMethod.getNoArguments(); - public MethodAccessor getMethodAccessor() { - //todo implement it - throw new UnsupportedOperationException(); - } + if (parameterAnnotations == null) + return new Annotation[numParameters][0]; - public void setMethodAccessor(MethodAccessor accessor) { - //todo implement it - throw new UnsupportedOperationException(); + Annotation[][] result = AnnotationParser.parseParameterAnnotations(parameterAnnotations, + SharedSecrets.getJavaLangAccess().getConstantPool(getDeclaringClass()), getDeclaringClass()); + + if (result.length != numParameters) + throw new AnnotationFormatError("Parameter annotations don't match number of parameters"); + + return result; } - public Method copy() { - //todo implement it - throw new UnsupportedOperationException(); - } } Modified: trunk/core/src/core/org/jnode/vm/VmSystem.java =================================================================== --- trunk/core/src/core/org/jnode/vm/VmSystem.java 2008-06-26 20:11:32 UTC (rev 4279) +++ trunk/core/src/core/org/jnode/vm/VmSystem.java 2008-06-27 19:27:49 UTC (rev 4280) @@ -57,6 +57,7 @@ import org.jnode.vm.classmgr.VmMethod; import org.jnode.vm.classmgr.VmStaticField; import org.jnode.vm.classmgr.VmType; +import org.jnode.vm.classmgr.VmConstantPool; import org.jnode.vm.isolate.VmIsolate; import org.jnode.vm.memmgr.VmWriteBarrier; import org.jnode.vm.scheduler.VmProcessor; @@ -123,8 +124,7 @@ VmSystem.out = getSystemOut(); /* Initialize the system classloader */ - VmSystemClassLoader loader = (VmSystemClassLoader) (getVmClass(VmProcessor - .current()).getLoader()); + VmSystemClassLoader loader = (VmSystemClassLoader) (getVmClass(VmProcessor.current()).getLoader()); systemLoader = loader; loader.initialize(); @@ -166,8 +166,7 @@ // Initialize log4j final Logger root = Logger.getRootLogger(); - final ConsoleAppender infoApp = new ConsoleAppender( - new PatternLayout(LAYOUT)); + final ConsoleAppender infoApp = new ConsoleAppender(new PatternLayout(LAYOUT)); root.addAppender(infoApp); initOpenJDKSpeciffics(); @@ -178,24 +177,19 @@ //todo this will be moved to java.lang.System during openjdk integration sun.misc.SharedSecrets.setJavaLangAccess(new sun.misc.JavaLangAccess() { public sun.reflect.ConstantPool getConstantPool(Class klass) { - //return klass.getConstantPool(); - throw new UnsupportedOperationException(); + return new VmConstantPool(klass.getVmClass()); } public void setAnnotationType(Class klass, AnnotationType type) { - //klass.setAnnotationType(type); - throw new UnsupportedOperationException(); + klass.setAnnotationType(type); } public AnnotationType getAnnotationType(Class klass) { - //return klass.getAnnotationType(); - throw new UnsupportedOperationException(); + return klass.getAnnotationType(); } - public <E extends Enum<E>> - E[] getEnumConstantsShared(Class<E> klass) { - //return klass.getEnumConstantsShared(); - return klass.getEnumConstants(); + public <E extends Enum<E>> E[] getEnumConstantsShared(Class<E> klass) { + return klass.getEnumConstantsShared(); } public void blockedOn(Thread t, Interruptible b) { @@ -233,7 +227,7 @@ /** * Load the initial jarfile. * - * @param rm + * @param rm the resource manager * @return The initial jarfile resource, or null if no initial jarfile is * available. */ @@ -265,7 +259,7 @@ /** * This method adds some default system properties * - * @param res + * @param res the system properties object */ public static void insertSystemProperties(Properties res) { Modified: trunk/core/src/core/org/jnode/vm/classmgr/ClassDecoder.java =================================================================== --- trunk/core/src/core/org/jnode/vm/classmgr/ClassDecoder.java 2008-06-26 20:11:32 UTC (rev 4279) +++ trunk/core/src/core/org/jnode/vm/classmgr/ClassDecoder.java 2008-06-27 19:27:49 UTC (rev 4280) @@ -26,6 +26,7 @@ import java.nio.ByteBuffer; import java.security.ProtectionDomain; import org.jnode.system.BootLog; +import org.jnode.vm.JvmType; import org.jnode.vm.VmUtils; import org.jnode.vm.annotation.AllowedPackages; import org.jnode.vm.annotation.CheckPermission; @@ -43,6 +44,8 @@ import org.jnode.vm.annotation.Uninterruptible; import org.vmmagic.pragma.PragmaException; import org.vmmagic.pragma.UninterruptiblePragma; +import sun.reflect.annotation.AnnotationParser; +import sun.reflect.annotation.ExceptionProxy; /** * Decoder of .class files into VmType instances. @@ -77,6 +80,8 @@ private static char[] RuntimeInvisibleParameterAnnotationsAttrName; + private static char[] AnnotationDefaultAttrName; + @SuppressWarnings("deprecation") private static final MethodPragmaException[] METHOD_PRAGMA_EXCEPTIONS = new MethodPragmaException[]{ new MethodPragmaException(UninterruptiblePragma.class, @@ -208,6 +213,7 @@ .toCharArray(); RuntimeInvisibleParameterAnnotationsAttrName = "RuntimeInvisibleParameterAnnotations" .toCharArray(); + AnnotationDefaultAttrName = "AnnotationDefault".toCharArray(); } } @@ -404,7 +410,7 @@ cls.addPragmaFlags(readInterfaces(data, cls, cp)); // Field table - final FieldData[] fieldData = readFields(data, cp, slotSize); + final FieldData[] fieldData = readFields(data, cp, slotSize, clc); // Method Table readMethods(data, rejectNatives, cls, cp, sharedStatics, clc); @@ -419,10 +425,10 @@ final String attrName = cp.getUTF8(data.getChar()); final int length = data.getInt(); if (VmArray.equals(RuntimeVisibleAnnotationsAttrName, attrName)) { - rVisAnn = readRuntimeAnnotations(data, cp, true); + rVisAnn = readRuntimeAnnotations(data, cp, true, clc); } else if (VmArray.equals(RuntimeInvisibleAnnotationsAttrName, attrName)) { - rInvisAnn = readRuntimeAnnotations(data, cp, false); + rInvisAnn = readRuntimeAnnotations(data, cp, false, clc); } else if (VmArray.equals(SourceFileAttrName, attrName)) { sourceFile = cp.getUTF8(data.getChar()); } else if (VmArray.equals(SignatureAttrName, attrName)) { @@ -621,7 +627,7 @@ * @param pragmaFlags */ private static FieldData[] readFields(ByteBuffer data, VmCP cp, - int slotSize) { + int slotSize, VmClassLoader loader) { final int fcount = data.getChar(); if (fcount > 0) { final FieldData[] ftable = new FieldData[fcount]; @@ -644,10 +650,10 @@ constantValue = cp.getAny(data.getChar()); } else if (VmArray.equals( RuntimeVisibleAnnotationsAttrName, attrName)) { - rVisAnn = readRuntimeAnnotations(data, cp, true); + rVisAnn = readRuntimeAnnotations(data, cp, true, loader); } else if (VmArray.equals( RuntimeInvisibleAnnotationsAttrName, attrName)) { - readRuntimeAnnotations(data, cp, false); + readRuntimeAnnotations(data, cp, false, loader); } else { skip(data, length); } @@ -947,18 +953,78 @@ mts.setExceptions(readExceptions(data, cls, cp)); } else if (VmArray.equals( RuntimeVisibleAnnotationsAttrName, attrName)) { - rVisAnn = readRuntimeAnnotations(data, cp, true); + + byte[] buf = new byte[length]; + data.slice().get(buf); + mts.setRawAnnotations(buf); + + //todo will get obsolate with openjdk based annotation support + //rVisAnn = readRuntimeAnnotations(data, cp, true, cl); + rVisAnn = readRuntimeAnnotations2(data, cp, true, cl, cls); + } else if (VmArray.equals( RuntimeInvisibleAnnotationsAttrName, attrName)) { - rInvisAnn = readRuntimeAnnotations(data, cp, false); + rInvisAnn = readRuntimeAnnotations(data, cp, false, cl); } else if (VmArray.equals( RuntimeVisibleParameterAnnotationsAttrName, attrName)) { - readRuntimeParameterAnnotations(data, cp, true); + + byte[] buf = new byte[length]; + data.slice().get(buf); + mts.setRawParameterAnnotations(buf); + //todo will get obsolate with openjdk based annotation support + readRuntimeParameterAnnotations(data, cp, true, cl); } else if (VmArray.equals( RuntimeInvisibleParameterAnnotationsAttrName, attrName)) { - readRuntimeParameterAnnotations(data, cp, false); + readRuntimeParameterAnnotations(data, cp, false, cl); + } else if (VmArray.equals(AnnotationDefaultAttrName, attrName)) { + //todo will get obsolate with openjdk based annotation support + byte[] buf = new byte[length]; + data.slice().get(buf); + mts.setRawAnnotationDefault(buf); + + Class r_class; + VmType vtm = mts.getReturnType(); + if (vtm.isPrimitive()) { + switch (vtm.getJvmType()) { + case JvmType.BOOLEAN: + vtm = Boolean.class.getVmClass(); + break; + case JvmType.BYTE: + vtm = Byte.class.getVmClass(); + break; + case JvmType.SHORT: + vtm = Short.class.getVmClass(); + break; + case JvmType.CHAR: + vtm = Character.class.getVmClass(); + break; + case JvmType.INT: + vtm = Integer.class.getVmClass(); + break; + case JvmType.FLOAT: + vtm = Float.class.getVmClass(); + break; + case JvmType.LONG: + vtm = Long.class.getVmClass(); + break; + case JvmType.DOUBLE: + vtm = Double.class.getVmClass(); + break; + + } + r_class = new Class(vtm); + } else { + try { + r_class = Class.forName(vtm.getName(), false, vtm.getLoader().asClassLoader()); + } catch (ClassNotFoundException cnf) { + throw new RuntimeException(cnf); + } + } + Object defo = AnnotationParser.parseMemberValue(r_class, data, new VmConstantPool(cls), + new Class(cls)); + mts.setAnnotationDefault(defo); } else { skip(data, length); } @@ -996,11 +1062,11 @@ * @param cp */ private static VmAnnotation[][] readRuntimeParameterAnnotations( - ByteBuffer data, VmCP cp, boolean visible) { + ByteBuffer data, VmCP cp, boolean visible, VmClassLoader loader) { final int numParams = data.get(); final VmAnnotation[][] arr = new VmAnnotation[numParams][]; for (int i = 0; i < numParams; i++) { - arr[i] = readRuntimeAnnotations(data, cp, visible); + arr[i] = readRuntimeAnnotations(data, cp, visible, loader); } return arr; } @@ -1012,7 +1078,7 @@ * @param cp */ private static VmAnnotation[] readRuntimeAnnotations(ByteBuffer data, - VmCP cp, boolean visible) { + VmCP cp, boolean visible, VmClassLoader loader) { final int numAnn = data.getChar(); final VmAnnotation[] arr = new VmAnnotation[numAnn]; for (int i = 0; i < numAnn; i++) { @@ -1022,6 +1088,23 @@ } /** + * Read a runtime annotations attributes. + * + * @param data + * @param cp + */ + private static VmAnnotation[] readRuntimeAnnotations2(ByteBuffer data, + VmCP cp, boolean visible, VmClassLoader loader, + VmType vmtype) { + final int numAnn = data.getChar(); + final VmAnnotation[] arr = new VmAnnotation[numAnn]; + for (int i = 0; i < numAnn; i++) { + arr[i] = readAnnotation2(data, cp, visible, loader, vmtype); + } + return arr; + } + + /** * Combine the pragma flags for a given list of annotations. * * @param annotations @@ -1092,8 +1175,7 @@ * @param data * @param cp */ - private static VmAnnotation readAnnotation(ByteBuffer data, VmCP cp, - boolean visible) { + private static VmAnnotation readAnnotation(ByteBuffer data, VmCP cp, boolean visible) { final String typeDescr = cp.getUTF8(data.getChar()); final int numElemValuePairs = data.getChar(); final VmAnnotation.ElementValue[] values; @@ -1116,7 +1198,110 @@ return new VmAnnotation(typeDescr, values); } + //todo will get obsolate with openjdk based annotation support /** + * Read a single annotation structure. + * + * @param data + * @param cp + */ + private static VmAnnotation readAnnotation2(ByteBuffer data, VmCP cp, + boolean visible, VmClassLoader loader, VmType vmType) { + final String typeDescr = cp.getUTF8(data.getChar()); + final int numElemValuePairs = data.getChar(); + final VmAnnotation.ElementValue[] values; + if (numElemValuePairs == 0) { + values = VmAnnotation.ElementValue.EMPTY_ARR; + } else if (visible) { + values = new VmAnnotation.ElementValue[numElemValuePairs]; + for (int i = 0; i < numElemValuePairs; i++) { + final String elemName = cp.getUTF8(data.getChar()); + + Object defo = null; //readElementValue(data, cp); + + try { + VmType annType = new Signature(typeDescr, loader).getType(); + + VmMethod mts = null; + int dmc = annType.getNoDeclaredMethods(); + for (int v = 0; v < dmc; v++) { + VmMethod m = annType.getDeclaredMethod(v); + if (elemName.equals(m.getName())) { + mts = m; + break; + } + } + + Class r_class; + VmType vtm = mts.getReturnType(); + if (vtm.isPrimitive()) { + switch (vtm.getJvmType()) { + case JvmType.BOOLEAN: + vtm = Boolean.class.getVmClass(); + break; + case JvmType.BYTE: + vtm = Byte.class.getVmClass(); + break; + case JvmType.SHORT: + vtm = Short.class.getVmClass(); + break; + case JvmType.CHAR: + vtm = Character.class.getVmClass(); + break; + case JvmType.INT: + vtm = Integer.class.getVmClass(); + break; + case JvmType.FLOAT: + vtm = Float.class.getVmClass(); + break; + case JvmType.LONG: + vtm = Long.class.getVmClass(); + break; + case JvmType.DOUBLE: + vtm = Double.class.getVmClass(); + break; + + } + r_class = new Class(vtm); + } else { + try { + r_class = vtm.getLoader().asClassLoader().loadClass(vtm.getName()); + } catch (ClassNotFoundException cnf) { + throw new RuntimeException(cnf); + } + } + Class container; + try { + + container = annType.getLoader().asClassLoader().loadClass(annType.getName()); + } catch (ClassNotFoundException cnf) { + throw new RuntimeException(cnf); + } + defo = AnnotationParser.parseMemberValue(r_class, data, new VmConstantPool(vmType), container); + + if (defo instanceof ExceptionProxy) + throw new RuntimeException("Error parsing annotation parameter value (annotation= " + + annType.getName() + ", parameter=" + mts.getName() + ")"); + + } catch (Exception e) { + throw new RuntimeException(e); + } + + + final Object value = defo; //readElementValue(data, cp); + values[i] = new VmAnnotation.ElementValue(elemName, value); + } + } else { + values = VmAnnotation.ElementValue.EMPTY_ARR; + for (int i = 0; i < numElemValuePairs; i++) { + data.getChar(); // Skip name ref + skipElementValue(data, cp); + } + } + return new VmAnnotation(typeDescr, values); + } + + /** * Read a single element_value structure. * * @param data Modified: trunk/core/src/core/org/jnode/vm/classmgr/VmAnnotation.java =================================================================== --- trunk/core/src/core/org/jnode/vm/classmgr/VmAnnotation.java 2008-06-26 20:11:32 UTC (rev 4279) +++ trunk/core/src/core/org/jnode/vm/classmgr/VmAnnotation.java 2008-06-27 19:27:49 UTC (rev 4280) @@ -25,7 +25,11 @@ import java.lang.annotation.Inherited; import java.lang.reflect.Array; import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; import org.jnode.vm.VmSystemObject; +import sun.reflect.annotation.AnnotationParser; /** * VM representation of a single annotation. @@ -47,7 +51,7 @@ /** * The element values */ - private final ElementValue[] values; + private ElementValue[] values; /** * The type of this annotation @@ -57,13 +61,13 @@ /** * The type implementing this annotation */ - private transient ImplBase value; + private transient Annotation value; /** - * @param runtimeVisible + * @param typeDescr the annotation type descriptor + * @param values annotation parameter name-value pairs */ - public VmAnnotation(String typeDescr, - ElementValue[] values) { + public VmAnnotation(String typeDescr, ElementValue[] values) { this.typeDescr = typeDescr; this.values = values; } @@ -95,17 +99,65 @@ throws ClassNotFoundException { if (value == null) { final VmType<? extends Annotation> annType = annotationType(loader); - final VmType<? extends ImplBase> implType = getImplClass(annType); - final ImplBase value; - try { - value = (ImplBase) implType.asClass().newInstance(); - } catch (InstantiationException ex) { - throw new RuntimeException(ex); - } catch (IllegalAccessException ex) { - throw new RuntimeException(ex); + //todo will be obsolate when annotation paring is migrated to openjdk + if (!annType.getName().equals(org.jnode.vm.annotation.AllowedPackages.class.getName())) { + int dmc = annType.getNoDeclaredMethods(); + Map vmap = new HashMap(); + for (int i = 0; i < dmc; i++) { + VmMethod met = annType.getDeclaredMethod(i); + Object o = met.getAnnotationDefault(); + if (o != null) { + String name = met.getName(); + vmap.put(name, o); + } + } + + + for (int i = 0; i < values.length; i++) { + vmap.put(values[i].name, values[i].value); + } + + Set<Map.Entry> set = vmap.entrySet(); + values = new ElementValue[set.size()]; + int i = 0; + for (Map.Entry e : set) { + values[i++] = new ElementValue((String) e.getKey(), e.getValue()); + } + + for (Map.Entry e : set) { + Object o = e.getValue(); + if (o != null && o.getClass().isArray()) { + Object[] arr = (Object[]) o; + if (arr.length > 0) { + Object el = arr[0]; + Class elc = el.getClass(); + Object[] ar2 = (Object[]) Array.newInstance(elc, arr.length); + for (int v = 0; v < arr.length; v++) { + ar2[v] = elc.cast(arr[v]); + } + e.setValue(ar2); + } + } + } + + //try { + /*value =*/ + return AnnotationParser.annotationForMap(loader.asClassLoader().loadClass(annType.getName()), vmap); + + } else { + + final VmType<? extends ImplBase> implType = getImplClass(annType); + final ImplBase value; + try { + value = implType.asClass().newInstance(); + } catch (InstantiationException ex) { + throw new RuntimeException(ex); + } catch (IllegalAccessException ex) { + throw new RuntimeException(ex); + } + value.initialize(annType, values, loader); + this.value = value; } - value.initialize(annType, values, loader); - this.value = value; } return value; } Added: trunk/core/src/core/org/jnode/vm/classmgr/VmConstantPool.java =================================================================== --- trunk/core/src/core/org/jnode/vm/classmgr/VmConstantPool.java (rev 0) +++ trunk/core/src/core/org/jnode/vm/classmgr/VmConstantPool.java 2008-06-27 19:27:49 UTC (rev 4280) @@ -0,0 +1,116 @@ +/* + * $ + */ +package org.jnode.vm.classmgr; + +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import sun.reflect.ConstantPool; + +/** + * @author Levente S\u00e1ntha + */ +public class VmConstantPool extends ConstantPool { + private VmType vmt; + private VmCP cp; + private VmClassLoader loader; + + public VmConstantPool(VmType vmt) { + this.vmt = vmt; + this.cp = vmt.getCP(); + this.loader = vmt.getLoader(); + } + + @Override + public Class getClassAt(int index) { + VmConstClass cc = cp.getConstClass(index); + cc.doResolve(loader); + VmType vmt = cc.getResolvedVmClass(); + return (vmt == null) ? null : vmt.asClass(); + } + + @Override + public Class getClassAtIfLoaded(int index) { + VmConstClass cc = cp.getConstClass(index); + VmType vmt = cc.getResolvedVmClass(); + return (vmt == null) ? null : vmt.asClass(); + } + + @Override + public double getDoubleAt(int index) { + return cp.getDouble(index); + } + + @Override + public Field getFieldAt(int index) { + VmConstFieldRef f = cp.getConstFieldRef(index); + f.doResolve(loader); + VmField vmf = f.getResolvedVmField(); + return new Field(vmf); + } + + @Override + public Field getFieldAtIfLoaded(int index) { + VmConstFieldRef f = cp.getConstFieldRef(index); + try { + VmField vmf = f.getResolvedVmField(); + return new Field(vmf); + } catch (NotResolvedYetException x) { + return null; + } + } + + @Override + public float getFloatAt(int index) { + return cp.getFloat(index); + } + + @Override + public int getIntAt(int index) { + return cp.getInt(index); + } + + @Override + public long getLongAt(int index) { + return cp.getLong(index); + } + + // Fetches the class name, member (field, method or interface + // method) name, and type descriptor as an array of three Strings + @Override + public String[] getMemberRefInfoAt(int index) { + //todo implement it + throw new UnsupportedOperationException(); + } + + // Returns either a Method or Constructor. + // Static initializers are returned as Method objects. + @Override + public Member getMethodAt(int index) { + //todo implement it + throw new UnsupportedOperationException(); + } + + @Override + public Member getMethodAtIfLoaded(int index) { + //todo implement it + throw new UnsupportedOperationException(); + } + + // Number of entries in this constant pool (= maximum valid constant pool index) + @Override + public int getSize() { + return cp.getLength(); + } + + @Override + public String getStringAt(int index) { + return (vmt.isSharedStatics() ? loader.getSharedStatics() : loader.getIsolatedStatics()). + getStringEntry(cp.getString(index).getSharedStaticsIndex()); + } + + @Override + public String getUTF8At(int index) { + return cp.getUTF8(index); + } +} Modified: trunk/core/src/core/org/jnode/vm/classmgr/VmMethod.java =================================================================== --- trunk/core/src/core/org/jnode/vm/classmgr/VmMethod.java 2008-06-26 20:11:32 UTC (rev 4279) +++ trunk/core/src/core/org/jnode/vm/classmgr/VmMethod.java 2008-06-27 19:27:49 UTC (rev 4280) @@ -99,6 +99,11 @@ */ private char pragmaFlags; + private Object annotationDefault; + private byte[] rawAnnotationDefault; + private byte[] rawAnnotations; + private byte[] rawParameterAnnotations; + /** * Constructor for VmMethod. * @@ -637,4 +642,36 @@ } } } + + public Object getAnnotationDefault() { + return annotationDefault; + } + + public void setAnnotationDefault(Object annotationDefault) { + this.annotationDefault = annotationDefault; + } + + public byte[] getRawAnnotationDefault() { + return rawAnnotationDefault; + } + + public void setRawAnnotationDefault(byte[] rawAnnotationDefault) { + this.rawAnnotationDefault = rawAnnotationDefault; + } + + public byte[] getRawAnnotations() { + return rawAnnotations; + } + + public void setRawAnnotations(byte[] rawAnnotations) { + this.rawAnnotations = rawAnnotations; + } + + public byte[] getRawParameterAnnotations() { + return rawParameterAnnotations; + } + + public void setRawParameterAnnotations(byte[] rawParameterAnnotations) { + this.rawParameterAnnotations = rawParameterAnnotations; + } } Modified: trunk/core/src/openjdk/vm/java/lang/reflect/NativeProxy.java =================================================================== --- trunk/core/src/openjdk/vm/java/lang/reflect/NativeProxy.java 2008-06-26 20:11:32 UTC (rev 4279) +++ trunk/core/src/openjdk/vm/java/lang/reflect/NativeProxy.java 2008-06-27 19:27:49 UTC (rev 4280) @@ -12,6 +12,8 @@ */ private static Class defineClass0(ClassLoader loader, String name, byte[] b, int off, int len){ + if(loader == null) + loader = Thread.currentThread().getContextClassLoader(); return loader.getVmClassLoader().defineClass(name, b, off, len, Object.class.getProtectionDomain()).asClass(); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |