001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.openide.util;
043:
044: import java.io.ByteArrayInputStream;
045: import java.io.ByteArrayOutputStream;
046: import java.io.IOException;
047: import java.io.ObjectInputStream;
048: import java.io.ObjectOutputStream;
049: import java.net.URL;
050: import java.util.ArrayList;
051: import java.util.Arrays;
052: import java.util.Collections;
053: import java.util.Enumeration;
054: import java.util.HashMap;
055: import java.util.HashSet;
056: import java.util.Iterator;
057: import java.util.LinkedList;
058: import java.util.List;
059: import java.util.Map;
060: import java.util.NoSuchElementException;
061: import java.util.Scanner;
062: import java.util.Set;
063: import java.util.logging.Level;
064: import org.netbeans.junit.NbTestCase;
065:
066: /**
067: * @author Jesse Glick
068: */
069: @SuppressWarnings("unchecked")
070: public class NbCollectionsTest extends NbTestCase {
071:
072: public NbCollectionsTest(String name) {
073: super (name);
074: }
075:
076: protected Level logLevel() {
077: return Level.SEVERE;
078: }
079:
080: public void testCheckedSetByCopy() throws Exception {
081: Set s = new HashSet();
082: s.add(1);
083: s.add(2);
084: Set<Integer> checked = NbCollections.checkedSetByCopy(s,
085: Integer.class, true);
086: assertEquals(s, checked);
087: s.add("three");
088: try {
089: NbCollections.checkedSetByCopy(s, Integer.class, true);
090: fail();
091: } catch (ClassCastException e) {/*OK*/
092: }
093: assertEquals(checked, NbCollections.checkedSetByCopy(s,
094: Integer.class, false));
095: s.remove("three");
096: s.add(null);
097: checked = NbCollections
098: .checkedSetByCopy(s, Integer.class, true);
099: assertEquals("nulls preserved", s, checked);
100: s.clear();
101: s.add(5);
102: assertEquals("modifications to original not reflected", 3,
103: checked.size());
104: }
105:
106: public void testCheckedListByCopy() throws Exception {
107: doTestCheckedListByCopy(new ArrayList());
108: doTestCheckedListByCopy(new LinkedList());
109: }
110:
111: private void doTestCheckedListByCopy(List l) {
112: l.add(1);
113: l.add(2);
114: List<Integer> checked = NbCollections.checkedListByCopy(l,
115: Integer.class, true);
116: assertEquals(l, checked);
117: l.add("three");
118: try {
119: NbCollections.checkedListByCopy(l, Integer.class, true);
120: fail();
121: } catch (ClassCastException e) {/*OK*/
122: }
123: assertEquals(checked, NbCollections.checkedListByCopy(l,
124: Integer.class, false));
125: l.remove("three");
126: l.add(null);
127: checked = NbCollections.checkedListByCopy(l, Integer.class,
128: true);
129: assertEquals("nulls preserved", l, checked);
130: l.clear();
131: l.add(5);
132: assertEquals("modifications to original not reflected", 3,
133: checked.size());
134: }
135:
136: public void testCheckedMapByCopy() throws Exception {
137: Map m = new HashMap();
138: m.put(1, "hello");
139: m.put(2, "goodbye");
140: Map<Integer, String> checked = NbCollections.checkedMapByCopy(
141: m, Integer.class, String.class, true);
142: assertEquals(m, checked);
143: m.put(2, new Object());
144: try {
145: NbCollections.checkedMapByCopy(m, Integer.class,
146: String.class, true);
147: fail();
148: } catch (ClassCastException e) {/*OK*/
149: }
150: assertEquals(Collections.singletonMap(1, "hello"),
151: NbCollections.checkedMapByCopy(m, Integer.class,
152: String.class, false));
153: m.remove(2);
154: Long three = 3L;
155: m.put(three, "oops!");
156: try {
157: NbCollections.checkedMapByCopy(m, Integer.class,
158: String.class, true);
159: fail();
160: } catch (ClassCastException e) {/*OK*/
161: }
162: assertEquals(Collections.singletonMap(1, "hello"),
163: NbCollections.checkedMapByCopy(m, Integer.class,
164: String.class, false));
165: m.remove(three);
166: m.put(null, null);
167: checked = NbCollections.checkedMapByCopy(m, Integer.class,
168: String.class, true);
169: assertEquals("nulls preserved", m, checked);
170: m.clear();
171: m.put(5, "new");
172: assertEquals("modifications to original not reflected", 2,
173: checked.size());
174: }
175:
176: public void testCheckedIteratorByFilter() throws Exception {
177: Iterator raw = Arrays.asList("one", 2, "three").iterator();
178: Iterator<String> strings = NbCollections
179: .checkedIteratorByFilter(raw, String.class, false);
180: assertTrue(strings.hasNext());
181: assertEquals("one", strings.next());
182: assertTrue(strings.hasNext());
183: assertEquals("three", strings.next());
184: assertFalse(strings.hasNext());
185: raw = Arrays.asList("one", 2, "three").iterator();
186: strings = NbCollections.checkedIteratorByFilter(raw,
187: String.class, true);
188: try {
189: while (strings.hasNext()) {
190: strings.next();
191: }
192: fail();
193: } catch (ClassCastException e) {/*OK*/
194: }
195: raw = Arrays.asList("one", "three").iterator();
196: strings = NbCollections.checkedIteratorByFilter(raw,
197: String.class, true);
198: assertTrue(strings.hasNext());
199: assertEquals("one", strings.next());
200: assertTrue(strings.hasNext());
201: assertEquals("three", strings.next());
202: assertFalse(strings.hasNext());
203: List l = new ArrayList(Arrays.asList(new Object[] { "one", 2,
204: "three" }));
205: raw = l.iterator();
206: strings = NbCollections.checkedIteratorByFilter(raw,
207: String.class, false);
208: assertTrue(strings.hasNext());
209: assertEquals("one", strings.next());
210: strings.remove();
211: assertEquals(2, l.size());
212: assertTrue(strings.hasNext());
213: assertEquals("three", strings.next());
214: assertFalse(strings.hasNext());
215: }
216:
217: public void testCheckedSetByFilter() throws Exception {
218: Set s = new HashSet();
219: s.add("hello");
220: s.add("there");
221: s.add(1);
222: s.add("goodbye");
223: s.add(2);
224: Set<String> s2 = NbCollections.checkedSetByFilter(s,
225: String.class, false);
226: assertEquals(3, s2.size());
227: assertEquals(new HashSet(Arrays.asList(new String[] { "hello",
228: "there", "goodbye" })), s2);
229: assertTrue(s2.contains("hello"));
230: assertFalse(s2.contains("nowhere"));
231: try {
232: s2.contains(2);
233: fail();
234: } catch (ClassCastException e) {/*OK*/
235: }
236: Iterator<String> it = s2.iterator();
237: while (it.hasNext()) {
238: if (it.next().equals("hello")) {
239: it.remove();
240: }
241: }
242: assertEquals(2, s2.size());
243: assertEquals(new HashSet(Arrays.asList(new String[] { "there",
244: "goodbye" })), s2);
245: assertEquals(4, s.size());
246: it = s2.iterator();
247: while (it.hasNext()) {
248: it.next();
249: it.remove();
250: }
251: assertEquals(0, s2.size());
252: assertEquals(Collections.emptySet(), s2);
253: assertEquals(
254: new HashSet(Arrays.asList(new Integer[] { 1, 2 })), s);
255: s.clear();
256: s.add("new");
257: assertEquals("modifications to original found", Collections
258: .singleton("new"), s2);
259: assertTrue(s2.add("additional"));
260: assertEquals("original set modified too", new HashSet(Arrays
261: .asList(new String[] { "new", "additional" })), s);
262: try {
263: ((Set) s2).add(13);
264: fail();
265: } catch (ClassCastException e) {/*OK*/
266: }
267: // Other:
268: assertEquals("preserved by serialization", s2,
269: cloneBySerialization(s2));
270: assertEquals("empty set filtered as empty", Collections
271: .emptySet(), NbCollections.checkedSetByFilter(
272: Collections.emptySet(), String.class, false));
273: assertEquals("empty set from wholly wrong set", Collections
274: .emptySet(), NbCollections.checkedSetByFilter(
275: Collections.singleton(5), String.class, false));
276: // Make sure iterator behaves fully acc. to contract:
277: Set<Integer> s3 = NbCollections.checkedSetByFilter(new HashSet(
278: Collections.singleton(1)), Integer.class, false);
279: Iterator<Integer> it3 = s3.iterator();
280: assertTrue(it3.hasNext());
281: assertTrue(it3.hasNext());
282: assertEquals(new Integer(1), it3.next());
283: assertFalse(it3.hasNext());
284: assertFalse(it3.hasNext());
285: try {
286: it3.next();
287: fail();
288: } catch (NoSuchElementException e) {/*OK*/
289: }
290: it3 = s3.iterator();
291: try {
292: it3.remove();
293: fail();
294: } catch (IllegalStateException e) {/*OK*/
295: }
296: it3 = s3.iterator();
297: it3.next();
298: it3.remove();
299: try {
300: it3.remove();
301: fail();
302: } catch (IllegalStateException e) {/*OK*/
303: }
304: }
305:
306: public void testCheckedSetByFilterStrict() throws Exception {
307: Set s = new HashSet();
308: s.add("hello");
309: s.add("there");
310: s.add(1);
311: s.add("goodbye");
312: s.add(2);
313: Set<String> s2 = NbCollections.checkedSetByFilter(s,
314: String.class, true);
315: try {
316: s2.size();
317: fail();
318: } catch (ClassCastException x) {/*OK*/
319: }
320: try {
321: new HashSet<String>(s2);
322: fail();
323: } catch (ClassCastException x) {/*OK*/
324: }
325: s.remove(1);
326: s.remove(2);
327: assertEquals(3, s2.size());
328: assertTrue(s2.contains("hello"));
329: try {
330: s2.contains(2);
331: fail();
332: } catch (ClassCastException e) {/*OK*/
333: }
334: }
335:
336: public void testCheckedMapByFilter() throws Exception {
337: Map m = new HashMap();
338: m.put(1, "one");
339: m.put(2, "two");
340: m.put("three", "three");
341: m.put(4, 4);
342: Map<Integer, String> m2 = NbCollections.checkedMapByFilter(m,
343: Integer.class, String.class, false);
344: assertEquals(2, m2.size());
345: assertEquals("one", m2.get(1));
346: try {
347: m2.get("three");
348: fail();
349: } catch (ClassCastException e) {/*OK*/
350: }
351: assertEquals(null, m2.get(4));
352: assertTrue(m2.containsKey(1));
353: assertFalse(m2.containsKey(5));
354: try {
355: m2.containsKey("three");
356: fail();
357: } catch (ClassCastException e) {/*OK*/
358: }
359: assertFalse(m2.containsKey(4));
360: assertTrue(m2.containsValue("one"));
361: assertFalse(m2.containsValue("five"));
362: try {
363: m2.containsValue(3);
364: fail();
365: } catch (ClassCastException e) {/*OK*/
366: }
367: assertFalse(m2.containsValue("three"));
368: assertEquals(2, m2.entrySet().size());
369: assertEquals(2, m2.keySet().size());
370: assertEquals(2, m2.values().size());
371: assertTrue(m2.keySet().contains(1));
372: assertFalse(m2.keySet().contains(5));
373: try {
374: m2.keySet().contains("three");
375: fail();
376: } catch (ClassCastException e) {/*OK*/
377: }
378: assertFalse(m2.keySet().contains(4));
379: assertTrue(m2.values().contains("one"));
380: assertFalse(m2.values().contains("five"));
381: try {
382: m2.values().contains(4);
383: fail();
384: } catch (ClassCastException e) {/*OK*/
385: }
386: assertFalse(m2.values().contains("three"));
387: // Destructive operations:
388: m2.put(1, "#one");
389: assertEquals("#one", m2.get(1));
390: assertEquals("#one", m.get(1));
391: try {
392: ((Map) m2).put("five", "five");
393: fail();
394: } catch (ClassCastException e) {/*OK*/
395: }
396: try {
397: ((Map) m2).put(5, 5);
398: fail();
399: } catch (ClassCastException e) {/*OK*/
400: }
401: m2.remove(1);
402: assertEquals(Collections.singletonMap(2, "two"), m2);
403: assertEquals(3, m.size());
404: m2.entrySet().clear();
405: assertTrue(m2.isEmpty());
406: assertEquals(2, m.size());
407: m.clear();
408: m.put(1, "one");
409: m.put(2, "two");
410: m.put(3, 3);
411: m.put("four", "four");
412: assertTrue(m2.keySet().remove(1));
413: assertFalse(m2.keySet().remove(3));
414: assertFalse(m2.keySet().remove("four"));
415: assertEquals(Collections.singletonMap(2, "two"), m2);
416: m.put(1, "one");
417: assertTrue(m2.values().remove("one"));
418: assertFalse(m2.values().remove(3));
419: assertFalse(m2.values().remove("four"));
420: assertEquals(Collections.singletonMap(2, "two"), m2);
421: assertEquals(3, m.size());
422: // Other:
423: assertEquals(m2, cloneBySerialization(m2));
424: assertEquals(Collections.emptyMap(), NbCollections
425: .checkedMapByFilter(Collections.emptyMap(),
426: String.class, String.class, false));
427: assertEquals(Collections.emptyMap(), NbCollections
428: .checkedMapByFilter(Collections.singletonMap(1, "two"),
429: String.class, String.class, false));
430: assertEquals(Collections.emptyMap(), NbCollections
431: .checkedMapByFilter(Collections.singletonMap("one", 2),
432: String.class, String.class, false));
433: // Misc. return values have to reflect nature of view:
434: m.clear();
435: m.put(1, 1);
436: assertEquals(null, m2.put(1, "one"));
437: m.put(1, 1);
438: assertEquals(null, m2.remove(1));
439: m.put(1, "one");
440: assertEquals("one", m2.put(1, "#one"));
441: assertEquals("#one", m2.remove(1));
442: }
443:
444: public void testCheckedMapByFilterStrict() throws Exception {
445: Map m = new HashMap();
446: m.put(1, "one");
447: m.put(2, "two");
448: m.put("three", "three");
449: m.put(4, 4);
450: Map<Integer, String> m2 = NbCollections.checkedMapByFilter(m,
451: Integer.class, String.class, true);
452: try {
453: m2.size();
454: fail();
455: } catch (ClassCastException e) {/*OK*/
456: }
457: try {
458: new HashMap<Integer, String>(m2);
459: fail();
460: } catch (ClassCastException e) {/*OK*/
461: }
462: try {
463: m2.get("three");
464: fail();
465: } catch (ClassCastException e) {/*OK*/
466: }
467: m.remove("three");
468: try {
469: m2.size();
470: fail();
471: } catch (ClassCastException e) {/*OK*/
472: }
473: m.remove(4);
474: m.put("three", "three");
475: try {
476: m2.size();
477: fail();
478: } catch (ClassCastException e) {/*OK*/
479: }
480: m.remove("three");
481: assertEquals(2, m2.size());
482: assertEquals("one", m2.get(1));
483: }
484:
485: public void testCheckedEnumerationByFilter() throws Exception {
486: Enumeration raw = Collections.enumeration(Arrays.asList("one",
487: 2, "three"));
488: Enumeration<String> strings = NbCollections
489: .checkedEnumerationByFilter(raw, String.class, false);
490: assertTrue(strings.hasMoreElements());
491: assertEquals("one", strings.nextElement());
492: assertTrue(strings.hasMoreElements());
493: assertEquals("three", strings.nextElement());
494: assertFalse(strings.hasMoreElements());
495: }
496:
497: public void testCheckedEnumerationByFilterStrict() throws Exception {
498: Enumeration raw = Collections.enumeration(Arrays.asList("one",
499: 2, "three"));
500: Enumeration<String> strings = NbCollections
501: .checkedEnumerationByFilter(raw, String.class, true);
502: try {
503: Collections.list(strings);
504: fail();
505: } catch (ClassCastException e) {/*OK*/
506: }
507: raw = Collections.enumeration(Arrays.asList("one", "three"));
508: strings = NbCollections.checkedEnumerationByFilter(raw,
509: String.class, true);
510: assertTrue(strings.hasMoreElements());
511: assertEquals("one", strings.nextElement());
512: assertTrue(strings.hasMoreElements());
513: assertEquals("three", strings.nextElement());
514: assertFalse(strings.hasMoreElements());
515: }
516:
517: static Object cloneBySerialization(Object o) throws IOException,
518: ClassNotFoundException {
519: ByteArrayOutputStream baos = new ByteArrayOutputStream();
520: ObjectOutputStream oos = new ObjectOutputStream(baos);
521: oos.writeObject(o);
522: oos.close();
523: ByteArrayInputStream bais = new ByteArrayInputStream(baos
524: .toByteArray());
525: return new ObjectInputStream(bais).readObject();
526: }
527:
528: public void testIterable() throws Exception {
529: String text = "hello kitty!";
530: List<String> l1 = new ArrayList<String>();
531: for (String token : NbCollections.iterable(new Scanner(text))) {
532: l1.add(token);
533: }
534: assertEquals(Arrays.asList("hello", "kitty!"), l1);
535: for (String token : NbCollections.iterable(new Scanner(""))) {
536: fail();
537: }
538: try {
539: NbCollections.iterable((Iterator<?>) null);
540: fail();
541: } catch (NullPointerException x) {/* OK */
542: }
543: List<URL> l2 = new ArrayList<URL>();
544: for (URL u : NbCollections.iterable(NbCollections.class
545: .getClassLoader().getResources(
546: NbCollections.class.getName().replace('.', '/')
547: + ".class"))) {
548: assertNotNull(u);
549: l2.add(u);
550: }
551: assertFalse(l2.isEmpty()); // permissible to have >1 element in case JAR doubly added to CP
552: for (URL u : NbCollections.iterable(NbCollections.class
553: .getClassLoader().getResources("nonexistent"))) {
554: fail();
555: }
556: try {
557: NbCollections.iterable((Enumeration<?>) null);
558: fail();
559: } catch (NullPointerException x) {/* OK */
560: }
561: }
562:
563: }
|