1 /*
2  * Copyright (c) 2011, 2013, 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 /* @test
25  * @summary tests for class-specific values
26  * @compile ClassValueTest.java
27  * @run testng/othervm test.java.lang.invoke.ClassValueTest
28  */
29 
30 package test.java.lang.invoke;
31 
32 import org.testng.*;
33 import static org.testng.AssertJUnit.*;
34 import org.testng.annotations.*;
35 
36 /**
37  * @author jrose
38  */
39 public class ClassValueTest {
nameForCV1(Class<?> type)40     static String nameForCV1(Class<?> type) {
41         return "CV1:" + type.getName();
42     }
43     int countForCV1;
44     final ClassValue<String> CV1 = new CV1();
45     private class CV1 extends ClassValue<String> {
computeValue(Class<?> type)46         protected String computeValue(Class<?> type) {
47             countForCV1++;
48             return nameForCV1(type);
49         }
50     }
51 
52     static final Class<?>[] CLASSES = {
53         String.class,
54         Integer.class,
55         int.class,
56         boolean[].class,
57         char[][].class,
58         ClassValueTest.class
59     };
60 
61     @Test
testGet()62     public void testGet() {
63         countForCV1 = 0;
64         for (Class<?> c : CLASSES) {
65             assertEquals(nameForCV1(c), CV1.get(c));
66         }
67         assertEquals(CLASSES.length, countForCV1);
68         for (Class<?> c : CLASSES) {
69             assertEquals(nameForCV1(c), CV1.get(c));
70         }
71         assertEquals(CLASSES.length, countForCV1);
72     }
73 
74     @Test
testRemove()75     public void testRemove() {
76         for (Class<?> c : CLASSES) {
77             CV1.get(c);
78         }
79         countForCV1 = 0;
80         int REMCOUNT = 3;
81         for (int i = 0; i < REMCOUNT; i++) {
82             CV1.remove(CLASSES[i]);
83         }
84         assertEquals(0, countForCV1);  // no change
85         for (Class<?> c : CLASSES) {
86             assertEquals(nameForCV1(c), CV1.get(c));
87         }
88         assertEquals(REMCOUNT, countForCV1);
89     }
90 
nameForCVN(Class<?> type, int n)91     static String nameForCVN(Class<?> type, int n) {
92         return "CV[" + n + "]" + type.getName();
93     }
94     int countForCVN;
95     class CVN extends ClassValue<String> {
96         final int n;
CVN(int n)97         CVN(int n) { this.n = n; }
computeValue(Class<?> type)98         protected String computeValue(Class<?> type) {
99             countForCVN++;
100             return nameForCVN(type, n);
101         }
102     };
103 
104     @Test
testGetMany()105     public void testGetMany() {
106         int CVN_COUNT1 = 100, CVN_COUNT2 = 100;
107         CVN cvns[] = new CVN[CVN_COUNT1 * CVN_COUNT2];
108         for (int n = 0; n < cvns.length; n++) {
109             cvns[n] = new CVN(n);
110         }
111         countForCVN = 0;
112         for (int pass = 0; pass <= 2; pass++) {
113             for (int i1 = 0; i1 < CVN_COUNT1; i1++) {
114                 eachClass:
115                 for (Class<?> c : CLASSES) {
116                     for (int i2 = 0; i2 < CVN_COUNT2; i2++) {
117                         int n = i1*CVN_COUNT2 + i2;
118                         assertEquals(0, countForCVN);
119                         assertEquals(nameForCVN(c, n), cvns[n].get(c));
120                         cvns[n].get(c);  //get it again
121                         //System.out.println("getting "+n+":"+cvns[n].get(c));
122                         boolean doremove = (((i1 + i2) & 3) == 0);
123                         switch (pass) {
124                         case 0:
125                             assertEquals(1, countForCVN);
126                             break;
127                         case 1:
128                             // remove on middle pass
129                             assertEquals(0, countForCVN);
130                             if (doremove) {
131                                 //System.out.println("removing "+n+":"+cvns[n].get(c));
132                                 cvns[n].remove(c);
133                                 assertEquals(0, countForCVN);
134                             }
135                             break;
136                         case 2:
137                             assertEquals(doremove ? 1 : 0, countForCVN);
138                             break;
139                         }
140                         countForCVN = 0;
141                         if (i1 > i2 && i1 < i2+5)  continue eachClass;  // leave diagonal gap
142                     }
143                 }
144             }
145         }
146         assertEquals(countForCVN, 0);
147         System.out.println("[rechecking values]");
148         for (int i = 0; i < cvns.length * 10; i++) {
149             int n = i % cvns.length;
150             for (Class<?> c : CLASSES) {
151                 assertEquals(nameForCVN(c, n), cvns[n].get(c));
152             }
153         }
154     }
155 }
156