1 /*
2  * Copyright (c) 2003, 2017, 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  * @bug 4776783 4778091 4778099
26  * @summary Check various properties of key and selected-key sets
27  *
28  * @run main KeySets
29  */
30 
31 import java.io.*;
32 import java.nio.channels.*;
33 import java.util.*;
34 
35 public class KeySets {
36 
37     static abstract class Catch {
go()38         abstract void go() throws Exception;
Catch(Class xc)39         Catch(Class xc) throws Exception {
40             try {
41                 go();
42             } catch (Exception x) {
43                 if (xc.isInstance(x))
44                     return;
45                 throw new Exception("Wrong exception", x);
46             }
47             throw new Exception("Not thrown as expected: " + xc.getName());
48         }
49     }
50 
51     // 4776783: Closing a selector should make key sets inaccessible
testClose()52     static void testClose() throws Exception {
53 
54         final Selector sel = Selector.open();
55         sel.keys();
56         sel.selectedKeys();
57         sel.close();
58 
59         new Catch(ClosedSelectorException.class) {
60                 void go() throws Exception {
61                     sel.keys();
62                 }};
63 
64         new Catch(ClosedSelectorException.class) {
65                 void go() throws Exception {
66                     sel.selectedKeys();
67                 }};
68     }
69 
testNoAddition(final Set s)70     static void testNoAddition(final Set s) throws Exception {
71         new Catch(UnsupportedOperationException.class) {
72                 void go() throws Exception {
73                     s.add(new Object());
74                 }};
75         new Catch(UnsupportedOperationException.class) {
76                 void go() throws Exception {
77                     ArrayList al = new ArrayList();
78                     al.add(new Object());
79                     s.addAll(al);
80                 }};
81     }
82 
83     static interface Adder {
add()84         void add() throws IOException;
85     }
86 
testNoRemoval(final Set s, final Adder adder)87     static void testNoRemoval(final Set s, final Adder adder)
88         throws Exception
89     {
90         new Catch(UnsupportedOperationException.class) {
91                 void go() throws Exception {
92                     adder.add();
93                     s.clear();
94                 }};
95         new Catch(UnsupportedOperationException.class) {
96                 void go() throws Exception {
97                     adder.add();
98                     Iterator i = s.iterator();
99                     i.next();
100                     i.remove();
101                 }};
102         new Catch(UnsupportedOperationException.class) {
103                 void go() throws Exception {
104                     adder.add();
105                     s.remove(s.iterator().next());
106                 }};
107         new Catch(UnsupportedOperationException.class) {
108                 void go() throws Exception {
109                     adder.add();
110                     HashSet hs = new HashSet();
111                     hs.addAll(s);
112                     s.removeAll(hs);
113                 }};
114         new Catch(UnsupportedOperationException.class) {
115                 void go() throws Exception {
116                     adder.add();
117                     s.retainAll(Collections.EMPTY_SET);
118                 }};
119     }
120 
reg(Selector sel)121     static SelectionKey reg(Selector sel) throws IOException {
122         DatagramChannel dc = DatagramChannel.open();
123         dc.configureBlocking(false);
124         return dc.register(sel, SelectionKey.OP_WRITE);
125     }
126 
testMutability()127     static void testMutability() throws Exception {
128 
129         final Selector sel = Selector.open();
130 
131         // 4778091: Selector.keys() should be immutable
132 
133         testNoRemoval(sel.keys(), new Adder() {
134                 public void add() throws IOException {
135                     reg(sel);
136                 }
137             });
138         testNoAddition(sel.keys());
139 
140         // 4778099: Selector.selectedKeys() should allow removal but not addition
141 
142         sel.select();
143         testNoAddition(sel.selectedKeys());
144         SelectionKey sk = reg(sel);
145         sel.select();
146         int n = sel.selectedKeys().size();
147         sel.selectedKeys().remove(sk);
148         if (sel.selectedKeys().size() != n - 1)
149             throw new Exception("remove failed");
150 
151         HashSet hs = new HashSet();
152         hs.add(reg(sel));
153         sel.select();
154         sel.selectedKeys().retainAll(hs);
155         if (sel.selectedKeys().isEmpty())
156             throw new Exception("retainAll failed");
157         sel.selectedKeys().removeAll(hs);
158         if (!sel.selectedKeys().isEmpty())
159             throw new Exception("removeAll failed");
160 
161         hs.clear();
162         hs.add(reg(sel));
163         sel.select();
164         sel.selectedKeys().clear();
165         if (!sel.selectedKeys().isEmpty())
166             throw new Exception("clear failed");
167     }
168 
main(String[] args)169     public static void main(String[] args) throws Exception {
170         testClose();
171         testMutability();
172     }
173 }
174