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;
032:
033: import java.io.*;
034: import java.lang.reflect.*;
035: import java.util.*;
036: import net.sf.retrotranslator.tests.TestCaseBase;
037:
038: /**
039: * @author Taras Puchko
040: */
041: @MyFormatter(tabPositions={},numbers={1})
042: public class _ClassTestCase extends TestCaseBase {
043:
044: private static final Class<?> PROXY_CLASS = Proxy.getProxyClass(
045: _ClassTestCase.class.getClassLoader(), Comparable.class);
046:
047: private static boolean initialized;
048:
049: private final Class<_ClassTestCase> this Class = _ClassTestCase.class;
050:
051: @MyStyle("bold")
052: @MyFormatter(lang="uk")
053: private static class A<T> {
054: }
055:
056: private static class B<T> extends A {
057: }
058:
059: @MyStyle("italic")
060: private static class C extends A {
061: static {
062: initialized = true;
063: }
064: }
065:
066: protected List<Class<?>> getClasses() {
067: return Arrays.asList(Collection.class, Set.class, List.class,
068: Queue.class, Map.class, SortedSet.class,
069: SortedMap.class,
070: java.util.concurrent.BlockingQueue.class,
071: java.util.concurrent.ConcurrentMap.class,
072: HashSet.class, TreeSet.class, ArrayList.class,
073: LinkedList.class, PriorityQueue.class, HashMap.class,
074: TreeMap.class, Vector.class, Hashtable.class,
075: WeakHashMap.class,
076: java.util.concurrent.CopyOnWriteArrayList.class,
077: java.util.concurrent.CopyOnWriteArraySet.class,
078: EnumSet.class, EnumMap.class,
079: java.util.concurrent.ConcurrentLinkedQueue.class,
080: java.util.concurrent.LinkedBlockingQueue.class,
081: java.util.concurrent.ArrayBlockingQueue.class,
082: java.util.concurrent.PriorityBlockingQueue.class,
083: java.util.concurrent.DelayQueue.class,
084: java.util.concurrent.SynchronousQueue.class,
085: java.util.concurrent.ConcurrentHashMap.class,
086: AbstractCollection.class, AbstractSet.class,
087: AbstractList.class, AbstractSequentialList.class,
088: AbstractQueue.class, AbstractMap.class,
089: Enumeration.class, Iterator.class, ListIterator.class,
090: Comparable.class, Comparator.class);
091: }
092:
093: public void testAsSubclass() throws Exception {
094: B.class.asSubclass(A.class);
095: try {
096: A.class.asSubclass(B.class);
097: fail();
098: } catch (ClassCastException e) {
099: //ok
100: }
101: assertEquals(Integer[].class, Integer[].class
102: .asSubclass(Number[].class));
103: assertEquals(void.class, void.class.asSubclass(void.class));
104: assertEquals(boolean[].class, boolean[].class
105: .asSubclass(boolean[].class));
106: }
107:
108: public void testCast() throws Exception {
109: String str = "a";
110: assertSame(str, String.class.cast(str));
111: try {
112: Integer.class.cast(str);
113: fail();
114: } catch (ClassCastException e) {
115: //ok
116: }
117: try {
118: int.class.cast(5);
119: fail();
120: } catch (ClassCastException e) {
121: //ok
122: }
123:
124: Integer[].class.cast(new Integer[] {});
125: try {
126: boolean[].class.cast(boolean[].class);
127: fail();
128: } catch (ClassCastException e) {
129: //ok
130: }
131: }
132:
133: public void testGetAnnotation() throws Exception {
134: assertNotInitialized();
135: assertEquals(0, _ClassTestCase.class.getAnnotation(
136: MyFormatter.class).tabPositions().length);
137:
138: assertEquals("bold", A.class.getAnnotation(MyStyle.class)
139: .value());
140: assertEquals("uk", A.class.getAnnotation(MyFormatter.class)
141: .lang());
142:
143: assertEquals("bold", B.class.getAnnotation(MyStyle.class)
144: .value());
145: assertNull(B.class.getAnnotation(MyFormatter.class));
146: assertEquals("italic", C.class.getAnnotation(MyStyle.class)
147: .value());
148: assertNull(C.class.getAnnotation(MyFormatter.class));
149:
150: assertNull(int.class.getAnnotation(MyFormatter.class));
151: assertNull(boolean[].class.getAnnotation(MyFormatter.class));
152: assertNull(String[][].class.getAnnotation(MyFormatter.class));
153:
154: assertNull(PROXY_CLASS.getAnnotation(MyFormatter.class));
155: assertNotInitialized();
156: }
157:
158: private void assertNotInitialized() throws Exception {
159: InputStream stream = getClass().getResourceAsStream(
160: getClass().getSimpleName() + ".class");
161: if (stream == null) {
162: return;
163: }
164: stream.close();
165: assertFalse(initialized);
166: }
167:
168: public void testGetAnnotations() throws Exception {
169: assertEqualElements(A.class.getAnnotations(), A.class
170: .getAnnotation(MyStyle.class), A.class
171: .getAnnotation(MyFormatter.class));
172: assertEqualElements(B.class.getAnnotations(), B.class
173: .getAnnotation(MyStyle.class));
174: assertEqualElements(C.class.getAnnotations(), C.class
175: .getAnnotation(MyStyle.class));
176: assertEquals(0, void.class.getAnnotations().length);
177: assertEquals(0, PROXY_CLASS.getAnnotations().length);
178: }
179:
180: public void testGetCanonicalName() throws Exception {
181: class Test {
182: }
183: Serializable anonymous = new Serializable() {
184: };
185: assertEquals(this Class.getName(), this Class.getCanonicalName());
186: assertEquals(this Class.getName() + ".A", A.class
187: .getCanonicalName());
188: assertNull(Test.class.getCanonicalName());
189: assertNull(anonymous.getClass().getCanonicalName());
190: assertEquals("java.lang.String[]", String[].class
191: .getCanonicalName());
192: assertNull(Test[].class.getCanonicalName());
193: assertEquals("void", void.class.getCanonicalName());
194: assertEquals("boolean[][]", boolean[][].class
195: .getCanonicalName());
196: assertEquals(PROXY_CLASS.getName(), PROXY_CLASS
197: .getCanonicalName());
198: }
199:
200: public void testGetDeclaredAnnotations() throws Exception {
201: assertEqualElements(A.class.getDeclaredAnnotations(), A.class
202: .getAnnotation(MyStyle.class), A.class
203: .getAnnotation(MyFormatter.class));
204: assertEquals(0, B.class.getDeclaredAnnotations().length);
205: assertEqualElements(C.class.getAnnotations(), C.class
206: .getAnnotation(MyStyle.class));
207: assertEquals(0, int[][].class.getDeclaredAnnotations().length);
208: assertEquals(0, PROXY_CLASS.getDeclaredAnnotations().length);
209: }
210:
211: public void testGetDeclaredMethod() throws Exception {
212: abstract class Getter<T> {
213: abstract T get();
214: }
215: class GetterImpl extends Getter<String> {
216: public String get() {
217: throw new UnsupportedOperationException();
218: }
219: }
220: assertEquals(String.class, GetterImpl.class.getDeclaredMethod(
221: "get").getReturnType());
222: try {
223: GetterImpl.class.getDeclaredMethod("get", int.class);
224: fail();
225: } catch (NoSuchMethodException e) {
226: //ok
227: }
228: assertEquals(int.class, PROXY_CLASS.getDeclaredMethod(
229: "compareTo", Object.class).getReturnType());
230: }
231:
232: class TestGetEnclosingClass {
233: class Inner {
234: }
235: }
236:
237: public void testGetEnclosingClass() throws Exception {
238: class Test {
239: class Inner {
240: }
241: }
242: assertEquals(this Class, Test.class.getEnclosingClass());
243: assertEquals(Test.class, Test.Inner.class.getEnclosingClass());
244: assertEquals(this Class, TestGetEnclosingClass.class
245: .getEnclosingClass());
246: assertEquals(TestGetEnclosingClass.class,
247: TestGetEnclosingClass.Inner.class.getEnclosingClass());
248:
249: Object anonymous = new Object() {
250: };
251: assertEquals(this Class, anonymous.getClass()
252: .getEnclosingClass());
253: assertNull(void.class.getEnclosingClass());
254: assertNull(int[][].class.getEnclosingClass());
255: assertNull(PROXY_CLASS.getEnclosingClass());
256: }
257:
258: public void testGetEnclosingConstructor() throws Exception {
259: class Test {
260: public Test() {
261: class Inner {
262: }
263: assertEquals(Test.class.getName(), Inner.class
264: .getEnclosingConstructor().getName());
265: }
266: }
267: new Test();
268: assertNull(float.class.getEnclosingConstructor());
269: assertNull(PROXY_CLASS.getEnclosingConstructor());
270: }
271:
272: public void testGetEnclosingMethod() throws Exception {
273: class Inner {
274: }
275: assertEquals("testGetEnclosingMethod", Inner.class
276: .getEnclosingMethod().getName());
277: Object anonymous = new Object() {
278: };
279: assertEquals("testGetEnclosingMethod", anonymous.getClass()
280: .getEnclosingMethod().getName());
281: assertNull(double.class.getEnclosingMethod());
282: assertNull(PROXY_CLASS.getEnclosingMethod());
283: }
284:
285: public void testGetEnumConstants() throws Exception {
286: MyColor[] constants = MyColor.class.getEnumConstants();
287: assertEqualElements(constants, MyColor.RED, MyColor.GREEN,
288: MyColor.BLUE);
289: assertNull(void.class.getEnumConstants());
290: assertNull(int[].class.getEnumConstants());
291: assertNull(PROXY_CLASS.getEnumConstants());
292: }
293:
294: public void testGetGenericInterfaces_Parameterized()
295: throws Exception {
296: class Test implements Comparable<String> {
297: public int compareTo(String o) {
298: return 0;
299: }
300: }
301: ParameterizedType type = (ParameterizedType) singleton(Test.class
302: .getGenericInterfaces());
303: assertEquals(Comparable.class, type.getRawType());
304: assertNull(type.getOwnerType());
305: assertEquals(String.class, singleton(type
306: .getActualTypeArguments()));
307: }
308:
309: public void testGetGenericInterfaces_NotParameterized()
310: throws Exception {
311: class Test implements Comparable {
312: public int compareTo(Object o) {
313: return 0;
314: }
315: }
316: assertEquals(Comparable.class, singleton(Test.class
317: .getGenericInterfaces()));
318: assertEquals(0, void.class.getGenericInterfaces().length);
319: assertEquals(Comparable.class, singleton(PROXY_CLASS
320: .getGenericInterfaces()));
321: }
322:
323: public void testGetGenericInterfaces_Classes14() throws Exception {
324: for (Class aClass : getClasses()) {
325: Class[] interfaces = aClass.getInterfaces();
326: Type[] genericInterfaces = aClass.getGenericInterfaces();
327: assertEquals(aClass.getName(), interfaces.length,
328: genericInterfaces.length);
329: for (int i = 0; i < interfaces.length; i++) {
330: assertEqualClasses(aClass, interfaces[i],
331: genericInterfaces[i]);
332: }
333: }
334: }
335:
336: public void testGetGenericSuperclass_Classes14() throws Exception {
337: for (Class aClass : getClasses()) {
338: Class super class = aClass.getSuperclass();
339: Type genericSuperclass = aClass.getGenericSuperclass();
340: if (super class != null || genericSuperclass != null) {
341: assertEqualClasses(aClass, super class,
342: genericSuperclass);
343: }
344: }
345: }
346:
347: private void assertEqualClasses(Class owner, Class rawClass,
348: Type genericType) {
349: if (genericType instanceof ParameterizedType) {
350: Type rawType = ((ParameterizedType) genericType)
351: .getRawType();
352: assertSame(owner.getName(), rawClass, rawType);
353: } else {
354: assertSame(owner.getName(), rawClass, genericType);
355: assertTrue(owner.getName() + " has raw "
356: + rawClass.getName(), isAllowed(owner, rawClass));
357: }
358: }
359:
360: private boolean isAllowed(Class owner, Class rawClass) {
361: return rawClass == Object.class
362: || rawClass == Cloneable.class
363: || rawClass == Serializable.class
364: || rawClass.getName().equals("java.util.RandomAccess")
365: || (!isJava14AtLeast() && owner == PriorityQueue.class && rawClass
366: .getName().endsWith("java.util.Queue"));
367: }
368:
369: public void testGetGenericSuperclass_FullyParameterized()
370: throws Exception {
371: class Test extends ThreadLocal<Comparable<String>> {
372: }
373: ParameterizedType threadLocal = (ParameterizedType) Test.class
374: .getGenericSuperclass();
375: assertEquals(ThreadLocal.class, threadLocal.getRawType());
376: assertNull(threadLocal.getOwnerType());
377: ParameterizedType comparable = (ParameterizedType) singleton(threadLocal
378: .getActualTypeArguments());
379: assertEquals(Comparable.class, comparable.getRawType());
380: assertNull(comparable.getOwnerType());
381: assertEquals(String.class, singleton(comparable
382: .getActualTypeArguments()));
383: }
384:
385: public void testGetGenericSuperclass_PartlyParameterized()
386: throws Exception {
387: class Test extends ThreadLocal<Comparable> {
388: }
389: ParameterizedType threadLocal = (ParameterizedType) Test.class
390: .getGenericSuperclass();
391: assertEquals(ThreadLocal.class, threadLocal.getRawType());
392: assertNull(threadLocal.getOwnerType());
393: assertEquals(Comparable.class, singleton(threadLocal
394: .getActualTypeArguments()));
395: assertEquals(Proxy.class, PROXY_CLASS.getGenericSuperclass());
396: }
397:
398: public void testGetMethod() throws Exception {
399: class StringList extends ArrayList<String> {
400: public String get(int index) {
401: return super .get(index);
402: }
403: }
404: if (!System.getProperty("java.vm.version").equals("1.4.1-b21")) {
405: //fails on JDK 1.4.1-b21
406: assertEquals(String.class, StringList.class.getMethod(
407: "get", int.class).getReturnType());
408: }
409: try {
410: StringList.class.getMethod("get", long.class);
411: fail();
412: } catch (NoSuchMethodException e) {
413: //ok
414: }
415: }
416:
417: public void testGetSimpleName() throws Exception {
418: class Test {
419: }
420: Serializable anonymous = new Serializable() {
421: };
422: assertEquals("_ClassTestCase", this Class.getSimpleName());
423: assertEquals("A", A.class.getSimpleName());
424: assertEquals("Test", Test.class.getSimpleName());
425: assertEquals("", anonymous.getClass().getSimpleName());
426: assertEquals("String[]", String[].class.getSimpleName());
427: assertEquals("void", void.class.getSimpleName());
428: assertEquals("boolean[]", boolean[].class.getSimpleName());
429: assertEquals(PROXY_CLASS.getName(), PROXY_CLASS.getSimpleName());
430: }
431:
432: public void testGetTypeParameters() throws Exception {
433: class Test<A, B extends String & Comparable<String>> {
434: }
435: TypeVariable<Class<Test>>[] parameters = Test.class
436: .getTypeParameters();
437: assertEquals(2, parameters.length);
438:
439: TypeVariable<Class<Test>> a = parameters[0];
440: assertEquals("A", a.getName());
441: assertEquals(Test.class, a.getGenericDeclaration());
442: assertEquals(Object.class, singleton(a.getBounds()));
443:
444: TypeVariable<Class<Test>> b = parameters[1];
445: assertEquals("B", b.getName());
446: assertEquals(Test.class, b.getGenericDeclaration());
447: Type[] bBounds = b.getBounds();
448: assertEquals(2, bBounds.length);
449: assertEquals(String.class, bBounds[0]);
450: ParameterizedType comparable = (ParameterizedType) bBounds[1];
451: assertEquals(Comparable.class, comparable.getRawType());
452: assertNull(comparable.getOwnerType());
453: assertEquals(String.class, singleton(comparable
454: .getActualTypeArguments()));
455: }
456:
457: public void testGetTypeParameters_NoParams() throws Exception {
458: class Test {
459: }
460: assertEquals(0, Test.class.getTypeParameters().length);
461: assertEquals(0, boolean[].class.getTypeParameters().length);
462: assertEquals(0, PROXY_CLASS.getTypeParameters().length);
463: }
464:
465: public void testIsAnnotation() throws Exception {
466: assertTrue(MyStyle.class.isAnnotation());
467: assertFalse(MyColor.class.isAnnotation());
468: assertFalse(void.class.isAnnotation());
469: assertFalse(int[].class.isAnnotation());
470: assertFalse(PROXY_CLASS.isAnnotation());
471: }
472:
473: public void testIsAnnotationPresent() throws Exception {
474: assertTrue(A.class.isAnnotationPresent(MyStyle.class));
475: assertTrue(A.class.isAnnotationPresent(MyFormatter.class));
476:
477: assertTrue(B.class.isAnnotationPresent(MyStyle.class));
478: assertFalse(B.class.isAnnotationPresent(MyFormatter.class));
479:
480: assertTrue(C.class.isAnnotationPresent(MyStyle.class));
481: assertFalse(C.class.isAnnotationPresent(MyFormatter.class));
482:
483: assertFalse(void.class.isAnnotationPresent(MyStyle.class));
484: assertFalse(long[].class.isAnnotationPresent(MyFormatter.class));
485: assertFalse(PROXY_CLASS.isAnnotationPresent(MyFormatter.class));
486: }
487:
488: public void testIsAnonymousClass() throws Exception {
489: class Test {
490: }
491: Serializable anonymous = new Serializable() {
492: };
493: assertTrue(anonymous.getClass().isAnonymousClass());
494: assertFalse(Test.class.isAnonymousClass());
495: assertFalse(A.class.isAnonymousClass());
496: assertFalse(_ClassTestCase.class.isAnonymousClass());
497: assertFalse(void.class.isAnonymousClass());
498: assertFalse(short[].class.isAnonymousClass());
499: assertFalse(PROXY_CLASS.isAnonymousClass());
500: }
501:
502: enum Case {
503: UPPER {
504: String toCase() {
505: return this .name().toUpperCase();
506: }
507: },
508: LOWER {
509: String toCase() {
510: return this .name().toLowerCase();
511: }
512: };
513:
514: abstract String toCase();
515: }
516:
517: public void testIsEnum() throws Exception {
518: assertTrue(MyColor.class.isEnum());
519: assertTrue(MyColor.BLUE.getClass().isEnum());
520: assertFalse(MyStyle.class.isEnum());
521: assertFalse(void.class.isEnum());
522: assertFalse(short[].class.isEnum());
523: assertTrue(Case.class.isEnum());
524: assertFalse(Case.UPPER.getClass().isEnum());
525: assertFalse(PROXY_CLASS.isEnum());
526: }
527:
528: public void testIsLocalClass() throws Exception {
529: class Test {
530: }
531: Serializable anonymous = new Serializable() {
532: };
533: assertTrue(Test.class.isLocalClass());
534: assertFalse(anonymous.getClass().isLocalClass());
535: assertFalse(A.class.isLocalClass());
536: assertFalse(_ClassTestCase.class.isLocalClass());
537: assertFalse(void.class.isLocalClass());
538: assertFalse(short[].class.isLocalClass());
539: assertFalse(PROXY_CLASS.isLocalClass());
540: }
541:
542: public void testIsMemberClass() throws Exception {
543: class Test {
544: }
545: Serializable anonymous = new Serializable() {
546: };
547: assertTrue(A.class.isMemberClass());
548: assertFalse(Test.class.isMemberClass());
549: assertFalse(anonymous.getClass().isMemberClass());
550: assertFalse(_ClassTestCase.class.isMemberClass());
551: assertFalse(void.class.isMemberClass());
552: assertFalse(short[].class.isMemberClass());
553: assertFalse(PROXY_CLASS.isMemberClass());
554: }
555:
556: }
|