// // Copyright (C) 2006 United States Government as represented by the // Administrator of the National Aeronautics and Space Administration // (NASA). All Rights Reserved. // // This software is distributed under the NASA Open Source Agreement // (NOSA), version 1.3. The NOSA has been approved by the Open Source // Initiative. See the file NOSA-1.3-JPF at the top of the distribution // directory tree for the complete NOSA document. // // THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY // KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT // LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO // SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR // A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT // THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT // DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. // package gov.nasa.jpf.test.vm.basic; import java.lang.annotation.Annotation; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; import org.junit.Test; import de.fosd.typechef.featureexpr.FeatureExpr; import gov.nasa.jpf.ListenerAdapter; import gov.nasa.jpf.jvm.bytecode.GETFIELD; import gov.nasa.jpf.jvm.bytecode.InvokeInstruction; import gov.nasa.jpf.util.test.TestJPF; import gov.nasa.jpf.vm.AnnotationInfo; import gov.nasa.jpf.vm.FieldInfo; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.MethodInfo; import gov.nasa.jpf.vm.ThreadInfo; import gov.nasa.jpf.vm.VM; @SuppressWarnings({ "unused" }) public class AnnotationTest extends TestJPF { @Test //---------------------------------------------------------------------- @A1("foo") public void testStringValueOk () { if (verifyNoPropertyViolation()) { try { java.lang.reflect.Method method = AnnotationTest.class.getMethod("testStringValueOk"); A1 annotation = method.getAnnotation(A1.class); assert ("foo".equals(annotation.value())); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } } @Retention(RetentionPolicy.RUNTIME) @interface A1 { String value(); } @Test //---------------------------------------------------------------------- @A2({"foo", "boo"}) public void testStringArrayValueOk () { if (verifyNoPropertyViolation()) { try { java.lang.reflect.Method method = AnnotationTest.class.getMethod("testStringArrayValueOk"); A2 annotation = method.getAnnotation(A2.class); Object v = annotation.value(); assert v instanceof String[]; String[] a = (String[])v; assert a.length == 2; assert "foo".equals(a[0]); assert "boo".equals(a[1]); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } } @Retention(RetentionPolicy.RUNTIME) @interface A2 { String[] value(); } @Test //---------------------------------------------------------------------- @A3(Long.MAX_VALUE) public void testLongValueOk () { if (verifyNoPropertyViolation()) { try { java.lang.reflect.Method method = AnnotationTest.class.getMethod("testLongValueOk"); A3 annotation = method.getAnnotation(A3.class); assert (annotation.value() == Long.MAX_VALUE); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } } @Retention(RetentionPolicy.RUNTIME) @interface A3 { long value(); } @Test //---------------------------------------------------------------------- @A4(a="one",b=42.0) public void testNamedParamsOk () { if (verifyNoPropertyViolation()) { try { java.lang.reflect.Method method = AnnotationTest.class.getMethod("testNamedParamsOk"); A4 annotation = method.getAnnotation(A4.class); assert ("one".equals(annotation.a())); assert ( 42.0 == annotation.b()); System.out.println(annotation); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } } @Retention(RetentionPolicy.RUNTIME) @interface A4 { String a(); double b(); } @Test //---------------------------------------------------------------------- @A5(b="foo") public void testPartialDefaultParamsOk () { if (verifyNoPropertyViolation()) { try { java.lang.reflect.Method method = AnnotationTest.class.getMethod("testPartialDefaultParamsOk"); A5 annotation = method.getAnnotation(A5.class); assert ("whatever".equals(annotation.a())); System.out.println(annotation); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } } @Retention(RetentionPolicy.RUNTIME) @interface A5 { String a() default "whatever"; String b(); } @Test //---------------------------------------------------------------------- @A6 public void testSingleDefaultParamOk () { if (verifyNoPropertyViolation()) { try { java.lang.reflect.Method method = AnnotationTest.class.getMethod("testSingleDefaultParamOk"); A6 annotation = method.getAnnotation(A6.class); assert ("whatever".equals(annotation.value())); System.out.println(annotation); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } } @Retention(RetentionPolicy.RUNTIME) @interface A6 { String value() default "whatever"; } @A6 @Test public void testAnnotationClass() throws ClassNotFoundException, NoSuchMethodException { if (verifyNoPropertyViolation()) { Class<?> clazz = Class.forName("gov.nasa.jpf.test.vm.basic.AnnotationTest"); Method method = clazz.getDeclaredMethod("testAnnotationClass"); Annotation annotations[] = method.getAnnotations(); for (int i=0; i<annotations.length; i++){ System.out.printf(" a[%d] = %s\n", i, annotations[i].toString()); } assertEquals(2, annotations.length); assertNotNull(annotations[0]); assertNotNull(annotations[1]); assertTrue(annotations[0] instanceof A6); assertTrue(annotations[1] instanceof Test); } } //-------------------------------------------------------------------- public enum MyEnum { ONE, TWO } @Retention(RetentionPolicy.RUNTIME) @interface A7 { MyEnum value(); } @Test @A7(MyEnum.ONE) public void testEnumValue() throws ClassNotFoundException, NoSuchMethodException { if (verifyNoPropertyViolation()){ Class<?> clazz = Class.forName("gov.nasa.jpf.test.vm.basic.AnnotationTest"); // Any class outside of this file will do. Method method = clazz.getDeclaredMethod("testEnumValue"); // Any method with an annotation will do. Annotation annotations[] = method.getAnnotations(); assertEquals(2, annotations.length); assertNotNull(annotations[1]); assertTrue(annotations[1] instanceof A7); A7 ann = (A7)annotations[1]; assertTrue( ann.value() == MyEnum.ONE); } } //-------------------------------------------------------------------- @Retention(RetentionPolicy.RUNTIME) @interface A8 { Class<?> value(); } @Test @A8(AnnotationTest.class) public void testClassValue() throws ClassNotFoundException, NoSuchMethodException { if (verifyNoPropertyViolation()){ Class<?> clazz = Class.forName("gov.nasa.jpf.test.vm.basic.AnnotationTest"); // Any class outside of this file will do. Method method = clazz.getDeclaredMethod("testClassValue"); // Any method with an annotation will do. Annotation annotations[] = method.getAnnotations(); assertEquals(2, annotations.length); assertNotNull(annotations[1]); assertTrue(annotations[1] instanceof A8); A8 ann = (A8)annotations[1]; assertTrue( ann.value() == AnnotationTest.class); } } @Retention(RetentionPolicy.RUNTIME) @interface A11 { Class<?>[] value(); } @Test @A11({ AnnotationTest.class, Class.class }) public void testClassArrayValueOk() throws ClassNotFoundException, SecurityException, NoSuchMethodException { if (verifyNoPropertyViolation()) { Class<?> clazz = Class.forName(AnnotationTest.class.getName()); Method method = clazz.getDeclaredMethod("testClassArrayValueOk"); Annotation[] annotations = method.getAnnotations(); assertEquals(2, annotations.length); assertNotNull(annotations[1]); assertTrue(annotations[1] instanceof A11); A11 ann = (A11) annotations[1]; assertTrue(ann.value()[0] == AnnotationTest.class); assertTrue(ann.value()[1] == Class.class); } } //------------------------------------------------------------------- static class MyClass { @A1("the answer") int data = 42; } public static class DataListener extends ListenerAdapter { @Override public void executeInstruction(FeatureExpr ctx, VM vm, ThreadInfo ti, Instruction insnToExecute){ if (insnToExecute instanceof GETFIELD){ FieldInfo fi = ((GETFIELD)insnToExecute).getFieldInfo(null); if (fi.getName().equals("data")){ AnnotationInfo ai = fi.getAnnotation("gov.nasa.jpf.test.vm.basic.AnnotationTest$A1"); System.out.println("annotation for " + fi.getFullName() + " = " + ai); if (ai != null){ String val = ai.getValueAsString("value"); System.out.println(" value = " + val); if (val == null || !val.equals("the answer")){ fail("wrong @A1 value = " + val); } } else { fail("no @A1 annotation for field " + fi.getFullName()); } } } } } @Test public void testFieldAnnotation(){ if (verifyNoPropertyViolation("+listener=.test.vm.basic.AnnotationTest$DataListener")){ MyClass obj = new MyClass(); int d = obj.data; } } //------------------------------------------------------------------- public static class ArgListener extends ListenerAdapter { @Override public void executeInstruction (FeatureExpr ctx, VM vm, ThreadInfo ti, Instruction insnToExecute){ if (insnToExecute instanceof InvokeInstruction){ MethodInfo mi = ((InvokeInstruction)insnToExecute).getInvokedMethod(); if (mi.getName().equals("foo")){ System.out.println("-- called method: " + mi.getUniqueName()); AnnotationInfo[][] pai = mi.getParameterAnnotations(); assert pai != null : "no parameter annotations found"; assert pai.length == 2 : "wrong number of parameter annotation arrays: " + pai.length; assert pai[0] != null : "no parameter annotation for first argument found"; assert pai[0].length == 1 : "wrong number of annotations for first argument: "+ pai[0].length; assert pai[1] != null : "no parameter annotation for second argument found"; assert pai[1].length == 0 : "wrong number of annotations for first argument: "+ pai[1].length; for (int i=0; i<pai.length; i++){ System.out.println("-- annotations for parameter: " + i); AnnotationInfo[] ai = pai[i]; if (ai != null && ai.length > 0) { for (int j = 0; j < ai.length; j++) { assert (ai[i] != null) : "null annotation for paramter: " + j; System.out.println(ai[i].asString()); } } else { System.out.println("none"); } } } } } } public void foo (@A1("arghh") MyClass x, String s){ // nothing } @Test public void testParameterAnnotation(){ if (verifyNoPropertyViolation("+listener=.test.vm.basic.AnnotationTest$ArgListener")){ MyClass obj = new MyClass(); foo( obj, "blah"); } } //--------------------------------------------------------------- @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface A9 { } @Retention(RetentionPolicy.RUNTIME) public @interface A10 { } @A9() public static class Parent { } @A10 public static class Child1 extends Parent { } public static class Child2 extends Child1 { } @Test public void getAnnotationsTest () { if (verifyNoPropertyViolation()) { assertTrue(Parent.class.getAnnotations().length == 1); assertTrue(Child1.class.getAnnotations().length == 2); assertTrue(Child2.class.getAnnotations().length == 1); } } //--------------------------------------------------------------- // test for RuntimeVisibleAnnotations attributes that in turn have // element_value entries @Retention(RetentionPolicy.RUNTIME) @interface A12 { // this one has the string value String value(); } @Retention(RetentionPolicy.RUNTIME) @A12("Whatever") @interface A13 { // this one has a RuntimeVisibleAnnotation attribute for A11 with a // String entry value } @A13 // causes loading of @C @Test public void testRecursiveRuntimeVisibleAnnotationValue(){ if (verifyNoPropertyViolation()){ // nothing to do other than just causing the loading of A12 } } //--------------------------------------------------------------- // test of char annotations @Retention(RetentionPolicy.RUNTIME) public @interface A14 { char value(); } @Test @A14('x') public void testCharAnnotation(){ if (verifyNoPropertyViolation()){ try { Class<?> clazz = Class.forName(AnnotationTest.class.getName()); Method method = clazz.getDeclaredMethod("testCharAnnotation"); Annotation[] annotations = method.getAnnotations(); assertEquals(2, annotations.length); assertNotNull(annotations[1]); assertTrue(annotations[1] instanceof A14); A14 ann = (A14) annotations[1]; assertTrue(ann.value() == 'x'); } catch (Throwable t){ t.printStackTrace(); fail("unexpected exception: " + t); } } } //--------------------------------------------------------------- // test of char annotations @Retention(RetentionPolicy.RUNTIME) public @interface A15 { float value(); } @Test @A15(12.34f) public void testFloatAnnotation(){ if (verifyNoPropertyViolation()){ try { Class<?> clazz = Class.forName(AnnotationTest.class.getName()); Method method = clazz.getDeclaredMethod("testFloatAnnotation"); Annotation[] annotations = method.getAnnotations(); assertEquals(2, annotations.length); assertNotNull(annotations[1]); assertTrue(annotations[1] instanceof A15); A15 ann = (A15) annotations[1]; assertTrue(Math.abs(ann.value() - 12.34f) < 0.00001); } catch (Throwable t){ t.printStackTrace(); fail("unexpected exception: " + t); } } } // test of char annotations @Retention(RetentionPolicy.RUNTIME) public @interface A16 { double value(); } @Test @A16(Double.MAX_VALUE) public void testDoubleAnnotation(){ if (verifyNoPropertyViolation()){ try { Class<?> clazz = Class.forName(AnnotationTest.class.getName()); Method method = clazz.getDeclaredMethod("testDoubleAnnotation"); Annotation[] annotations = method.getAnnotations(); assertEquals(2, annotations.length); assertNotNull(annotations[1]); assertTrue(annotations[1] instanceof A16); A16 ann = (A16) annotations[1]; assertTrue(ann.value() == Double.MAX_VALUE); } catch (Throwable t){ t.printStackTrace(); fail("unexpected exception: " + t); } } } // test of char annotations @Retention(RetentionPolicy.RUNTIME) public @interface A17 { long value(); } @Test @A17(Long.MAX_VALUE) public void testLongAnnotation(){ if (verifyNoPropertyViolation()){ try { Class<?> clazz = Class.forName(AnnotationTest.class.getName()); Method method = clazz.getDeclaredMethod("testLongAnnotation"); Annotation[] annotations = method.getAnnotations(); assertEquals(2, annotations.length); assertNotNull(annotations[1]); assertTrue(annotations[1] instanceof A17); A17 ann = (A17) annotations[1]; assertTrue(ann.value() == Long.MAX_VALUE); } catch (Throwable t){ t.printStackTrace(); fail("unexpected exception: " + t); } } } }