1   /***************************************************************************************
2    * Copyright (c) Jonas Bon?r, Alexandre Vasseur. All rights reserved.                 *
3    * http://aspectwerkz.codehaus.org                                                    *
4    * ---------------------------------------------------------------------------------- *
5    * The software in this package is published under the terms of the LGPL license      *
6    * a copy of which has been included with this distribution in the license.txt file.  *
7    **************************************************************************************/
8   package test.annotation;
9   
10  
11  import org.codehaus.aspectwerkz.annotation.expression.ast.AnnotationParser;
12  import org.codehaus.aspectwerkz.annotation.expression.AnnotationVisitor;
13  import org.codehaus.aspectwerkz.annotation.Java5AnnotationInvocationHandler;
14  import org.codehaus.aspectwerkz.annotation.AnnotationElement;
15  import junit.framework.TestCase;
16  
17  import java.util.Map;
18  import java.util.HashMap;
19  
20  /***
21   * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur</a>
22   * @author <a href="mailto:the_mindstorm@evolva.ro">Alex Popescu</a>
23   */
24  public class AnnotationParserTest extends TestCase {
25  
26  	protected static final AnnotationParser s_parser = Helper.getAnnotationParser();
27  
28  	private Object getElementValue(Object o) {
29  		AnnotationElement element = (AnnotationElement) o;
30  		return element.resolveValueHolderFrom(AnnotationParserTest.class.getClassLoader());
31  
32  	}
33  
34  	private void check(Map elements, String key, Object expected) {
35  		Object o = elements.get(key);
36  		if(o == null) {
37  			fail("No such element - " + key);
38  		} else {
39  			assertEquals(expected, getElementValue(o));
40  		}
41  	}
42  
43  	public void testSimple() {
44  		try {
45  			Map elements = new HashMap();
46  			AnnotationVisitor.parse(elements, "@Simple(val=\"foo\")", Simple.class);
47  			check(elements, "val", "foo");
48  			AnnotationVisitor.parse(elements, "@Simple(val=\"foo bar\")", Simple.class);
49  			AnnotationVisitor.parse(elements, "@Simple (val=\"foo bar\")", Simple.class);
50  			AnnotationVisitor.parse(elements, "@Simple(val=\"foo bar\"       )", Simple.class);
51  
52  			elements = new HashMap();
53  			AnnotationVisitor.parse(elements, "@Simple(s=\"foo\")", Simple.class);
54  			check(elements, "s", "foo");
55  
56  			AnnotationVisitor.parse(elements, "@Simple(val=\"hello //\" alex\")", Simple.class);
57  			check(elements, "val", "hello \" alex");
58  
59  			AnnotationVisitor.parse(elements, "@Simple(s=\"foo bar\")", Simple.class);
60  			AnnotationVisitor.parse(elements, "@Simple (s=\"foo bar\")", Simple.class);
61  			AnnotationVisitor.parse(elements, "@Simple(s=\"foo bar\"       )", Simple.class);
62  
63  			elements = new HashMap();
64  			AnnotationVisitor.parse(elements, "@Simple(s=\"foo\", val=\"bar\")", Simple.class);
65  			check(elements, "s", "foo");
66  			check(elements, "val", "bar");
67  
68  			elements = new HashMap();
69  			AnnotationVisitor.parse(elements, "@Void()", VoidTyped.class);
70  			assertEquals(0, elements.size());
71  			AnnotationVisitor.parse(elements, "@Void", VoidTyped.class);
72  			assertEquals(0, elements.size());
73  		} catch(Throwable t) {
74  			fail(t.toString());
75  		}
76  	}
77  
78  	public void testSimpleNested() {
79  		try {
80  			Map elements = new HashMap();
81  			AnnotationVisitor.parse(elements, "@SimpleNested(nested=@Simple(val=\"foo\"))",
82  					SimpleNested.class);
83  			Simple nested = (Simple) getElementValue(elements.get("nested"));
84  			assertEquals("foo", nested.val());
85  
86  			elements = new HashMap();
87  			AnnotationVisitor.parse(elements,
88  					"@SimpleNested(nested=@Simple( s=\"bar\", val=\"foo\"))", SimpleNested.class);
89  			nested = (Simple) getElementValue(elements.get("nested"));
90  			assertEquals("bar", nested.s());
91  			assertEquals("foo", nested.val());
92  
93  			elements = new HashMap();
94  			AnnotationVisitor
95  					.parse(
96  							elements,
97  							"@SimpleStringArrayNested(nested=@StringArray(i=42, ss={\"one\", \"two\", \"three\"}))",
98  							SimpleStringArrayNested.class);
99  			StringArray sarr = (StringArray) getElementValue(elements.get("nested"));
100 			assertEquals(42, sarr.i());
101 			assertEquals("one", sarr.ss()[0]);
102 			assertEquals("two", sarr.ss()[1]);
103 			assertEquals("three", sarr.ss()[2]);
104 		} catch(Throwable t) {
105 			fail(t.toString());
106 		}
107 	}
108 
109 	public void testComplexNested() {
110 		try {
111 			Map elements = new HashMap();
112 			AnnotationVisitor.parse(elements,
113 					"@ComplexNested(nesteds={@Simple(val=\"foo\"), @Simple(val=\"bar\")})",
114 					ComplexNested.class);
115 			Simple[] nesteds = (Simple[]) getElementValue(elements.get("nesteds"));
116 			assertEquals("foo", nesteds[0].val());
117 			assertEquals("bar", nesteds[1].val());
118 
119 			elements = new HashMap();
120 			AnnotationVisitor.parse(elements,
121 					"@ComplexNested(nesteds={@Simple(s=\"bar\", val=\"foo\"), @Simple(val=\"bar\")})",
122 					ComplexNested.class);
123 			nesteds = (Simple[]) getElementValue(elements.get("nesteds"));
124 			assertEquals("foo", nesteds[0].val());
125 			assertEquals("bar", nesteds[0].s());
126 			assertEquals("bar", nesteds[1].val());
127 
128 		} catch(Throwable t) {
129 			fail(t.toString());
130 		}
131 	}
132 
133 	public void testDefault() {
134 		try {
135 			Map elements = new HashMap();
136 			AnnotationVisitor.parse(elements, "@DefaultString(\"foo\")", DefaultString.class);
137 			check(elements, "value", "foo");
138 
139 			elements = new HashMap();
140 			AnnotationVisitor.parse(elements, "@DefaultInt(3)", DefaultInt.class);
141 			check(elements, "value", new Integer(3));
142 
143 			elements = new HashMap();
144 			AnnotationVisitor.parse(elements, "@SimpleDefaultNested(nested=@DefaultString(\"bar\"))",
145 					SimpleDefaultNested.class);
146 			DefaultString ds = (DefaultString) getElementValue(elements.get("nested"));
147 			assertEquals("bar", ds.value());
148 
149 			elements = new HashMap();
150 			AnnotationVisitor.parse(elements, "@SimpleValueDefaultNested(@DefaultString(\"bar\"))",
151 					SimpleValueDefaultNested.class);
152 			check(elements, "value", "bar");
153 		} catch(Throwable t) {
154 			fail(t.toString());
155 		}
156 	}
157 
158 	// note that for correct long type handling, it is mandatory to have the l or L suffix
159 	public void testComplex() {
160 		try {
161 			Map elements = new HashMap();
162 			AnnotationVisitor.parse(elements,
163 					"@Complex(i=3,  ls={1l,2l,6L},  klass=java.lang.String.class)", Complex.class);
164 			check(elements, "i", new Integer(3));
165 			long[] ls = new long[] {1L, 2L, 6L};
166 			long[] lsGet = (long[]) getElementValue(elements.get("ls"));
167 			for(int i = 0; i < ls.length; i++) {
168 				assertEquals(ls[i], lsGet[i]);
169 			}
170 			// TODO change when support for LazyClass is there
171 			check(elements, "klass", String.class);
172 		} catch(Throwable t) {
173 			fail(t.toString());
174 		}
175 	}
176 
177 	public void testStringArray() {
178 		try {
179 			Map elements = new HashMap();
180 			AnnotationVisitor.parse(elements, "@StringArray(i=3,  ss={\"hello\", \"foo\"})",
181 					StringArray.class);
182 			check(elements, "i", new Integer(3));
183 			String[] ss = new String[] {"hello", "foo"};
184 			String[] ssGet = (String[]) getElementValue(elements.get("ss"));
185 			for(int i = 0; i < ss.length; i++) {
186 				assertEquals(ss[i], ssGet[i]);
187 			}
188 		} catch(Throwable t) {
189 			fail(t.toString());
190 		}
191 	}
192 
193 	public static class Helper extends AnnotationVisitor {
194 		public Helper(final Map annotationValues, final Class annotationClass) {
195 			super(annotationValues, annotationClass);
196 		}
197 
198 		public static AnnotationParser getAnnotationParser() {
199 			return PARSER;
200 		}
201 	}
202 
203 	public static interface VoidTyped {
204 	}
205 
206 	public static interface Simple {
207 
208 		public String val();
209 
210 		public String s();
211 	}
212 
213 	public static interface SimpleNested {
214 
215 		public Simple nested();
216 	}
217 
218 	public static interface SimpleDefaultNested {
219 		public DefaultString nested();
220 	}
221 
222 	public static interface SimpleValueDefaultNested {
223 		public DefaultString value();
224 	}
225 
226 	public static interface SimpleStringArrayNested {
227 		public StringArray nested();
228 	}
229 
230 	public static interface ComplexNested {
231 
232 		public Simple[] nesteds();
233 	}
234 
235 	public static interface DefaultString {
236 
237 		public String value();
238 	}
239 
240 	public static interface DefaultInt {
241 
242 		public int value();
243 	}
244 
245 	public static interface Complex {
246 
247 		public int i();
248 
249 		public long[] ls();
250 
251 		public Class klass();
252 
253 		public Class[] klass2();
254 
255 		public int field();
256 
257 	}
258 
259 	public static interface StringArray {
260 		public int i();
261 
262 		public String[] ss();
263 	}
264 
265 	public static interface Untyped {
266 		public String value();
267 	}
268 }