1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 8038994
  27  * @summary Test that getAnnotatedBounds().getType() match getBounds()
  28  * @run testng TypeVariableBounds
  29  */
  30 
  31 import java.io.Serializable;
  32 import java.lang.annotation.*;
  33 import java.lang.reflect.*;
  34 import java.util.concurrent.Callable;
  35 import java.util.Arrays;
  36 import java.util.List;
  37 import java.util.Set;
  38 import org.testng.annotations.DataProvider;
  39 import org.testng.annotations.Test;
  40 
  41 import static org.testng.Assert.*;
  42 
  43 public class TypeVariableBounds {
  44     @DataProvider
  45     public Object[][] data() { return TESTS; }
  46 
  47 
  48     @Test(dataProvider = "data")
  49     public void testClass(Class<?> c, String method) throws Exception {
  50         if (c.getTypeParameters().length == 0)
  51             return;
  52 
  53         TypeVariable[] tv = c.getTypeParameters();
  54 
  55         for(TypeVariable t : tv)
  56             testTv(t);
  57 
  58     }
  59 
  60     @Test(dataProvider = "data")
  61     public void testMethod(Class<?>c, String method) throws Exception {
  62         if ("".equals(method))
  63             return;
  64 
  65         Method m = c.getMethod(method);
  66         TypeVariable[] tv = m.getTypeParameters();
  67 
  68         for(TypeVariable t : tv)
  69             testTv(t);
  70 
  71     }
  72 
  73     public void testTv(TypeVariable<?> tv) {
  74         Type[] t = tv.getBounds();
  75         AnnotatedType[] at = tv.getAnnotatedBounds();
  76 
  77         assertEquals(t.length, at.length, Arrays.asList(t) + " and " + Arrays.asList(at) + " should be the same length");
  78 
  79         for (int i = 0; i < t.length; i++)
  80             assertSame(at[i].getType(), t[i], "T: " + t[i] + ", AT: " + at[i] + ", AT.getType(): " + at[i].getType() + "\n");
  81     }
  82 
  83     public static final Object[][] TESTS = {
  84         { Case1.class, "" },
  85         { Case2.class, "" },
  86         { Case3.class, "aMethod" },
  87         { Case4.class, "aMethod" },
  88         { Case5.class, "aMethod" },
  89         { Case6.class, "aMethod" },
  90     };
  91 
  92     // Class typ var
  93     public static class Case1<C1T1, C1T2 extends AnnotatedElement, C1T3 extends AnnotatedElement & Type & Serializable> {}
  94     public static class Case2<@TA C2T1 extends Type, C2T2 extends @TB AnnotatedElement, C2T3 extends AnnotatedElement & @TB Type & Serializable> {}
  95 
  96     // Method type var
  97     public static class Case3 { public <C3T1, C3T2 extends AnnotatedElement, C3T3 extends AnnotatedElement & Type & Serializable> void aMethod() {}}
  98     public static class Case4 { public <@TA C4T1 extends List, C4T2 extends @TB Set, C4T3 extends Set & @TB Callable & Serializable> void aMethod() {}}
  99 
 100     // Both
 101     public static class Case5 <C5CT1, C5CT2 extends Runnable> {
 102         public <C5MT1,
 103                C5MT2 extends AnnotatedElement,
 104                C5MT3 extends AnnotatedElement & Type & Serializable,
 105                C5MT4 extends C5CT2>
 106                    void aMethod() {}}
 107 
 108     public static class Case6 <@TA C6CT1, C6CT2 extends @TB Runnable> {
 109         public <@TA C6MT1,
 110                C6MT2 extends @TB AnnotatedElement,
 111                C6MT3 extends @TB AnnotatedElement & @TB2 Type & Serializable,
 112                C6MT4 extends @TB2 C6CT2>
 113                    void aMethod() {}}
 114 
 115     @Retention(RetentionPolicy.RUNTIME)
 116     @Target(ElementType.TYPE_PARAMETER)
 117     public @interface TA {}
 118 
 119     @Retention(RetentionPolicy.RUNTIME)
 120     @Target(ElementType.TYPE_USE)
 121     public @interface TB {}
 122 
 123     @Retention(RetentionPolicy.RUNTIME)
 124     @Target(ElementType.TYPE_USE)
 125     public @interface TB2 {}
 126 }