1 /******************************************************************************* 2 * Copyright 2011 See AUTHORS file. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17 package com.badlogic.gdx.tests; 18 19 import java.lang.annotation.Inherited; 20 import java.lang.annotation.Retention; 21 import java.lang.annotation.RetentionPolicy; 22 import java.util.Arrays; 23 24 import com.badlogic.gdx.Gdx; 25 import com.badlogic.gdx.graphics.GL20; 26 import com.badlogic.gdx.graphics.g2d.BitmapFont; 27 import com.badlogic.gdx.graphics.g2d.SpriteBatch; 28 import com.badlogic.gdx.tests.utils.GdxTest; 29 import com.badlogic.gdx.utils.reflect.Annotation; 30 import com.badlogic.gdx.utils.reflect.ClassReflection; 31 import com.badlogic.gdx.utils.reflect.Field; 32 import com.badlogic.gdx.utils.reflect.Method; 33 34 /** Performs some tests with {@link Annotation} and prints the results on the screen. 35 * @author dludwig */ 36 public class AnnotationTest extends GdxTest { 37 String message = ""; 38 BitmapFont font; 39 SpriteBatch batch; 40 41 public enum TestEnum { 42 EnumA, EnumB 43 } 44 45 /** Sample annotation. It is required to annotate annotations themselves with {@link RetentionPolicy}.RUNTIME to become 46 * available to the {@link ClassReflection} package. */ 47 @Retention(RetentionPolicy.RUNTIME) 48 static public @interface TestAnnotation { 49 // String parameter, no default name()50 String name(); 51 52 // Array of integers, with default values values()53 int[] values() default {1, 2, 3}; 54 55 // Enumeration, with default value someEnum()56 TestEnum someEnum() default TestEnum.EnumA; 57 } 58 59 /** Sample usage of class and field annotations. */ 60 @TestAnnotation(name = "MyAnnotatedClass", someEnum = TestEnum.EnumB) 61 static public class AnnotatedClass { 62 public int unanottatedField; unannotatedMethod()63 public int unannotatedMethod() { return 0; } 64 @TestAnnotation(name = "MyAnnotatedField", values = {4, 5}) public int annotatedValue; annotatedMethod()65 @TestAnnotation(name = "MyAnnotatedMethod", values = {6, 7}) public int annotatedMethod () { return 0; }; 66 } 67 68 @Retention(RetentionPolicy.RUNTIME) 69 @Inherited 70 static public @interface TestInheritAnnotation { 71 } 72 73 @TestInheritAnnotation 74 static public class InheritClassA { 75 } 76 77 @TestAnnotation(name = "MyInheritClassB") 78 static public class InheritClassB extends InheritClassA { 79 } 80 81 @Override create()82 public void create () { 83 font = new BitmapFont(); 84 batch = new SpriteBatch(); 85 86 try { 87 Annotation annotation = ClassReflection.getDeclaredAnnotation(AnnotatedClass.class, TestAnnotation.class); 88 if (annotation != null) { 89 TestAnnotation annotationInstance = annotation.getAnnotation(TestAnnotation.class); 90 println("Class annotation:\n name=" + annotationInstance.name() + ",\n values=" 91 + Arrays.toString(annotationInstance.values()) + ",\n enum=" + annotationInstance.someEnum().toString()); 92 } else { 93 println("ERROR: Class annotation not found."); 94 } 95 96 Field field = ClassReflection.getDeclaredField(AnnotatedClass.class, "annotatedValue"); 97 if (field != null) { 98 Annotation[] annotations = field.getDeclaredAnnotations(); 99 for (Annotation a : annotations) { 100 if (a.getAnnotationType().equals(TestAnnotation.class)) { 101 TestAnnotation annotationInstance = a.getAnnotation(TestAnnotation.class); 102 println("Field annotation:\n name=" + annotationInstance.name() + ",\n values=" 103 + Arrays.toString(annotationInstance.values()) + ",\n enum=" + annotationInstance.someEnum().toString()); 104 break; 105 } 106 } 107 } else { 108 println("ERROR: Field 'annotatedValue' not found."); 109 } 110 111 Method method = ClassReflection.getDeclaredMethod(AnnotatedClass.class, "annotatedMethod"); 112 if (method != null) { 113 Annotation[] annotations = method.getDeclaredAnnotations(); 114 for (Annotation a : annotations) { 115 if (a.getAnnotationType().equals(TestAnnotation.class)) { 116 TestAnnotation annotationInstance = a.getAnnotation(TestAnnotation.class); 117 println("Method annotation:\n name=" + annotationInstance.name() + ",\n values=" 118 + Arrays.toString(annotationInstance.values()) + ",\n enum=" + annotationInstance.someEnum().toString()); 119 break; 120 } 121 } 122 } else { 123 println("ERROR: Method 'annotatedMethod' not found."); 124 } 125 126 println("Class annotations w/@Inherit:"); 127 Annotation[] annotations = ClassReflection.getAnnotations(InheritClassB.class); 128 for (Annotation a : annotations) { 129 println(" name=" + a.getAnnotationType().getSimpleName()); 130 } 131 if (!ClassReflection.isAnnotationPresent(InheritClassB.class, TestInheritAnnotation.class)) { 132 println("ERROR: Inherited class annotation not found."); 133 } 134 } catch (Exception e) { 135 println("FAILED: " + e.getMessage()); 136 message += e.getClass(); 137 } 138 } 139 println(String line)140 private void println (String line) { 141 message += line + "\n"; 142 } 143 144 @Override render()145 public void render () { 146 Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 147 batch.begin(); 148 font.draw(batch, message, 20, Gdx.graphics.getHeight() - 20); 149 batch.end(); 150 } 151 152 @Override dispose()153 public void dispose () { 154 batch.dispose(); 155 font.dispose(); 156 } 157 158 } 159