1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. 5 * 6 * The contents of this file are subject to the terms of either the GNU 7 * General Public License Version 2 only ("GPL") or the Common Development 8 * and Distribution License("CDDL") (collectively, the "License"). You 9 * may not use this file except in compliance with the License. You can obtain 10 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html 11 * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific 12 * language governing permissions and limitations under the License. 13 * 14 * When distributing the software, include this License Header Notice in each 15 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt. 16 * Sun designates this particular file as subject to the "Classpath" exception 17 * as provided by Sun in the GPL Version 2 section of the License file that 18 * accompanied this code. If applicable, add the following below the License 19 * Header, with the fields enclosed by brackets [] replaced by your own 20 * identifying information: "Portions Copyrighted [year] 21 * [name of copyright owner]" 22 * 23 * Contributor(s): 24 * 25 * If you wish your version of this file to be governed by only the CDDL or 26 * only the GPL Version 2, indicate your decision by adding "[Contributor] 27 * elects to include this software in this distribution under the [CDDL or GPL 28 * Version 2] license." If you don't indicate a single choice of license, a 29 * recipient has the option to distribute your version of this file under 30 * either the CDDL, the GPL Version 2 or to extend the choice of license to 31 * its licensees as provided above. However, if you add GPL Version 2 code 32 * and therefore, elected the GPL Version 2 license, then the option applies 33 * only if the new code is made subject to such option by the copyright 34 * holder. 35 */ 36 37 package javax.faces.component; 38 39 import java.util.Collection; 40 import java.util.List; 41 import java.util.Map; 42 import java.util.Set; 43 44 class TypedCollections { 45 46 /** 47 * Dynamically check that the members of the collection are all 48 * instances of the given type (or null). 49 */ 50 private static boolean checkCollectionMembers(Collection<?> c, Class<?> type) { 51 for (Object element : c) { 52 if (element != null && !type.isInstance(element)) { 53 return false; 54 } 55 } 56 return true; 57 } 58 59 /** 60 * Dynamically check that the members of the collection are all 61 * instances of the given type (or null), and that the collection 62 * itself is of the given collection type. 63 * 64 * @param <E> 65 * the collection's element type 66 * @param c 67 * the collection to cast 68 * @param type 69 * the class of the collection's element type. 70 * @return the dynamically-type checked collection. 71 * @throws java.lang.ClassCastException 72 */ 73 @SuppressWarnings("unchecked") 74 static <E,TypedC extends Collection<E>> TypedC dynamicallyCastCollection(Collection<?> c, 75 Class<E> type, 76 Class<TypedC> collectionType) { 77 if (c == null) 78 return null; 79 if (!collectionType.isInstance(c)) 80 throw new ClassCastException(c.getClass().getName()); 81 assert checkCollectionMembers(c, type) : 82 "The collection contains members with a type other than " + type.getName(); 83 84 return collectionType.cast(c); 85 } 86 87 /** 88 * Dynamically check that the members of the list are all instances of 89 * the given type (or null). 90 * 91 * @param <E> 92 * the list's element type 93 * @param list 94 * the list to cast 95 * @param type 96 * the class of the list's element type. 97 * @return the dynamically-type checked list. 98 * @throws java.lang.ClassCastException 99 */ 100 @SuppressWarnings("unchecked") 101 static <E> List<E> dynamicallyCastList(List<?> list, Class<E> type) { 102 return dynamicallyCastCollection(list, type, List.class); 103 } 104 105 /** 106 * Dynamically check that the members of the set are all instances of 107 * the given type (or null). 108 * 109 * @param <E> 110 * the set's element type 111 * @param set 112 * the set to cast 113 * @param type 114 * the class of the set's element type. 115 * @return the dynamically-type checked set. 116 * @throws java.lang.ClassCastException 117 */ 118 @SuppressWarnings("unchecked") 119 static <E> Set<E> dynamicallyCastSet(Set<?> set, 120 Class<E> type) { 121 return dynamicallyCastCollection(set, type, Set.class); 122 } 123 124 /** 125 * Dynamically check that the keys and values in the map are all 126 * instances of the correct types (or null). 127 * 128 * @param <K> 129 * the map's key type 130 * @param <V> 131 * the map's value type 132 * @param map 133 * the map to cast 134 * @param keyType 135 * the class of the map's key type. 136 * @param keyType 137 * the class of the map's key type. 138 * @return the dynamically-type checked map. 139 * @throws java.lang.ClassCastException 140 */ 141 @SuppressWarnings("unchecked") 142 static <K, V> Map<K, V> dynamicallyCastMap(Map<?, ?> map, 143 Class<K> keyType, 144 Class<V> valueType) { 145 if (map == null) { 146 return null; 147 } 148 assert checkCollectionMembers(map.keySet(), keyType) : 149 "The map contains keys with a type other than " + keyType.getName(); 150 assert checkCollectionMembers(map.values(), valueType) : 151 "The map contains values with a type other than " + valueType.getName(); 152 153 return (Map<K, V>) map; 154 } 155 }