001: /***
002: * Retrotranslator: a Java bytecode transformer that translates Java classes
003: * compiled with JDK 5.0 into classes that can be run on JVM 1.4.
004: *
005: * Copyright (c) 2005 - 2008 Taras Puchko
006: * All rights reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: * 3. Neither the name of the copyright holders nor the names of its
017: * contributors may be used to endorse or promote products derived from
018: * this software without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
021: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
022: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
023: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
024: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
025: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
026: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
027: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
028: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
029: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
030: * THE POSSIBILITY OF SUCH DAMAGE.
031: */package net.sf.retrotranslator.runtime.java.lang.reflect;
032:
033: import java.lang.annotation.Annotation;
034: import java.lang.reflect.*;
035: import java.text.SimpleDateFormat;
036: import java.util.*;
037: import net.sf.retrotranslator.runtime.java.lang.*;
038: import net.sf.retrotranslator.tests.TestCaseBase;
039:
040: /**
041: * @author Taras Puchko
042: */
043: public class _FieldTestCase extends TestCaseBase {
044:
045: @MyFormatter(pattern="aabbcc",format=SimpleDateFormat.class,backgroundColor=MyColor.BLUE,backgroundStyle=@MyStyle("italic"),tabPositions={10,20,30},keywords={"my","formatter"},colors={MyColor.RED,MyColor.GREEN},styles={@MyStyle("bold"),@MyStyle("small")})
046: protected String message;
047:
048: private Field field;
049:
050: protected void setUp() throws Exception {
051: super .setUp();
052: field = getClass().getDeclaredField("message");
053: }
054:
055: private MyFormatter getAnnotation() {
056: return field.getAnnotation(MyFormatter.class);
057: }
058:
059: public void testGetAnnotation() {
060: MyFormatter formatter = getAnnotation();
061: assertEquals("aabbcc", formatter.pattern());
062: assertEquals("en", formatter.lang());
063: assertEquals(SimpleDateFormat.class, formatter.format());
064: assertEquals(MyColor.BLUE, formatter.backgroundColor());
065: assertEquals("italic", formatter.backgroundStyle().value());
066:
067: int[] tabPositions = formatter.tabPositions();
068: assertEquals(3, tabPositions.length);
069: assertEquals(10, tabPositions[0]);
070: assertEquals(20, tabPositions[1]);
071: assertEquals(30, tabPositions[2]);
072:
073: String[] keywords = formatter.keywords();
074: assertEquals(2, keywords.length);
075: assertEquals("my", keywords[0]);
076: assertEquals("formatter", keywords[1]);
077:
078: MyColor[] colors = formatter.colors();
079: assertEquals(2, colors.length);
080: assertSame(MyColor.RED, colors[0]);
081: assertSame(MyColor.GREEN, colors[1]);
082:
083: MyStyle[] styles = formatter.styles();
084: assertEquals(2, styles.length);
085: assertEquals("bold", styles[0].value());
086: assertEquals("small", styles[1].value());
087: assertNull(getProxyField().getAnnotation(MyFormatter.class));
088: }
089:
090: public void testGetAnnotation_Equals() throws Exception {
091: MyFormatter first = getAnnotation();
092: MyFormatter second = getAnnotation();
093: assertEquals(first, second);
094: assertEquals(getAnnotation(), pump(getAnnotation()));
095: }
096:
097: public void testGetAnnotation_HashCode() {
098: int first = getAnnotation().hashCode();
099: int second = getAnnotation().hashCode();
100: assertEquals(first, second);
101: }
102:
103: public void testGetAnnotation_ToString() throws Exception {
104: StringBuffer buffer = new StringBuffer(getAnnotation()
105: .toString());
106: delete(buffer, "pattern=aabbcc");
107: delete(buffer, "lang=en");
108: delete(buffer, "format=class java.text.SimpleDateFormat");
109: delete(buffer, "backgroundColor=BLUE");
110: delete(buffer, "backgroundStyle=@" + MyStyle.class.getName()
111: + "(value=italic)");
112: delete(buffer, "tabPositions=[10, 20, 30]");
113: delete(buffer, "keywords=[my, formatter]");
114: delete(buffer, "colors=[RED, GREEN]");
115: delete(buffer, "styles=[@" + MyStyle.class.getName()
116: + "(value=bold), @" + MyStyle.class.getName()
117: + "(value=small)]");
118: delete(buffer, "numbers=[1, 2, 3]");
119: delete(buffer, "isPlain=false");
120: assertEquals("@" + MyFormatter.class.getName()
121: + "(, , , , , , , , , , )", buffer.toString());
122: }
123:
124: private static void delete(StringBuffer buffer, String substring) {
125: String s = buffer.toString();
126: int index = s.indexOf(substring);
127: if (index == -1) {
128: substring = removeSpaces(substring);
129: index = s.indexOf(substring);
130: }
131: assertFalse("Cannot find: " + substring + " in " + buffer,
132: index == -1);
133: buffer.delete(index, index + substring.length());
134: }
135:
136: private static String removeSpaces(String s) {
137: int index;
138: while ((index = s.indexOf(' ')) >= 0) {
139: s = s.substring(0, index) + s.substring(index + 1);
140: }
141: return s;
142: }
143:
144: public void testGetAnnotations() throws Exception {
145: Annotation[] annotations = field.getAnnotations();
146: assertEquals(1, annotations.length);
147: assertEquals(getAnnotation(), annotations[0]);
148: assertEquals(0, getProxyField().getAnnotations().length);
149: }
150:
151: public void testGetDeclaredAnnotations() throws Exception {
152: assertTrue(Arrays.equals(field.getDeclaredAnnotations(), field
153: .getAnnotations()));
154: assertEquals(0, getProxyField().getDeclaredAnnotations().length);
155: }
156:
157: public void testGetGenericType() throws Exception {
158: class Outer {
159: class Top<A> {
160: class Middle<B> {
161: class Bottom {
162: }
163: }
164: }
165: }
166:
167: class Test<T> {
168: public Outer.Top<Comparable<? super Integer>>.Middle<List<?>>.Bottom f;
169: }
170: Field field = Test.class.getField("f");
171: ParameterizedType bottom = (ParameterizedType) field
172: .getGenericType();
173: assertEquals(Outer.Top.Middle.Bottom.class, bottom.getRawType());
174: assertEquals(0, bottom.getActualTypeArguments().length);
175: ParameterizedType middle = (ParameterizedType) bottom
176: .getOwnerType();
177: assertEquals(Outer.Top.Middle.class, middle.getRawType());
178:
179: ParameterizedType list = (ParameterizedType) singleton(middle
180: .getActualTypeArguments());
181: assertEquals(List.class, list.getRawType());
182: assertNull(list.getOwnerType());
183: WildcardType listParam = (WildcardType) singleton(list
184: .getActualTypeArguments());
185: assertEquals(Object.class,
186: singleton(listParam.getUpperBounds()));
187: assertEquals(0, listParam.getLowerBounds().length);
188:
189: ParameterizedType top = (ParameterizedType) middle
190: .getOwnerType();
191: assertEquals(Outer.Top.class, top.getRawType());
192: ParameterizedType comparable = (ParameterizedType) singleton(top
193: .getActualTypeArguments());
194: assertEquals(Comparable.class, comparable.getRawType());
195: assertNull(comparable.getOwnerType());
196:
197: WildcardType comparableParam = (WildcardType) singleton(comparable
198: .getActualTypeArguments());
199: assertEquals(Object.class, singleton(comparableParam
200: .getUpperBounds()));
201: assertEquals(Integer.class, singleton(comparableParam
202: .getLowerBounds()));
203: assertEquals(Outer.class, top.getOwnerType());
204: Field proxyField = getProxyField();
205: assertEquals(proxyField.getType(), proxyField.getGenericType());
206: }
207:
208: public void testIsAnnotationPresent() throws Exception {
209: assertTrue(field.isAnnotationPresent(MyFormatter.class));
210: assertFalse(field.isAnnotationPresent(MyStyle.class));
211: assertFalse(getProxyField().isAnnotationPresent(MyStyle.class));
212: }
213:
214: public void testIsEnumConstant() throws Exception {
215: assertTrue(MyColor.class.getField(MyColor.BLUE.name())
216: .isEnumConstant());
217: assertFalse(field.isEnumConstant());
218: assertFalse(getProxyField().isEnumConstant());
219: }
220:
221: public void testIsSynthetic() throws Exception {
222: class Test {
223: }
224: assertTrue(Test.class.getDeclaredFields()[0].isSynthetic());
225: assertFalse(getProxyField().isSynthetic());
226: }
227:
228: static class Test<T extends Map> {
229: public Comparable<T>[] c;
230: public static boolean b;
231: public static Test<HashMap>.Inner i;
232:
233: public class Inner {
234: }
235: }
236:
237: public void testToGenericString() throws Exception {
238: String name = this .getClass().getName();
239: assertEquals("public java.lang.Comparable<T>[] " + name
240: + "$Test.c", Test.class.getField("c").toGenericString());
241: assertEquals("public static boolean " + name + "$Test.b",
242: Test.class.getField("b").toGenericString());
243: assertEquals("public static " + name + "." + name
244: + "$Test<java.util.HashMap>.Inner " + name + "$Test.i",
245: Test.class.getField("i").toGenericString());
246: Field proxyField = getProxyField();
247: assertEquals(proxyField.toString(), proxyField
248: .toGenericString());
249: }
250:
251: private Field getProxyField() {
252: return Proxy.getProxyClass(getClass().getClassLoader(),
253: Comparable.class).getDeclaredFields()[0];
254: }
255:
256: }
|