J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright 2004-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| 20 | * CA 95054 USA or visit www.sun.com if you need additional information or |
| 21 | * have any questions. |
| 22 | */ |
| 23 | |
| 24 | /* |
| 25 | * @test |
| 26 | * @bug 4847959 6191402 |
| 27 | * @summary Test newly-generified APIs |
| 28 | * @author Eamonn McManus |
| 29 | * @run clean GenericTest |
| 30 | * @run build GenericTest |
| 31 | * @run main GenericTest |
| 32 | */ |
| 33 | |
| 34 | import java.lang.management.ManagementFactory; |
| 35 | import java.lang.reflect.*; |
| 36 | import java.util.*; |
| 37 | import javax.management.*; |
| 38 | import javax.management.openmbean.*; |
| 39 | import javax.management.relation.*; |
| 40 | import javax.management.timer.Timer; |
| 41 | import javax.management.timer.TimerMBean; |
| 42 | |
| 43 | public class GenericTest { |
| 44 | private static int failures; |
| 45 | |
| 46 | public static void main(String[] args) throws Exception { |
| 47 | MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); |
| 48 | |
| 49 | // Check we are really using the generified version |
| 50 | boolean generic; |
| 51 | Method findmbs = MBeanServerFactory.class.getMethod("findMBeanServer", |
| 52 | String.class); |
| 53 | Type findmbstype = findmbs.getGenericReturnType(); |
| 54 | if (!(findmbstype instanceof ParameterizedType)) { |
| 55 | System.out.println("FAILURE: API NOT GENERIC!"); |
| 56 | System.out.println(" MBeanServerFactory.findMBeanServer -> " + |
| 57 | findmbstype); |
| 58 | failures++; |
| 59 | generic = false; |
| 60 | } else { |
| 61 | System.out.println("OK: this API is generic"); |
| 62 | generic = true; |
| 63 | } |
| 64 | |
| 65 | ArrayList<MBeanServer> mbsList1 = |
| 66 | MBeanServerFactory.findMBeanServer(null); |
| 67 | checked(mbsList1, MBeanServer.class); |
| 68 | ArrayList mbsList2 = MBeanServerFactory.findMBeanServer(null); |
| 69 | check("ArrayList<MBeanServer> findMBeanServer", mbsList1.size() == 1); |
| 70 | check("ArrayList findMBeanServer", mbsList1.equals(mbsList2)); |
| 71 | |
| 72 | Set<ObjectName> names1 = |
| 73 | checked(mbs.queryNames(null, null), ObjectName.class); |
| 74 | Set names2 = mbs.queryNames(null, null); |
| 75 | Set<ObjectName> names3 = |
| 76 | checked(((MBeanServerConnection) mbs).queryNames(null, null), |
| 77 | ObjectName.class); |
| 78 | check("Set<ObjectName> MBeanServer.queryNames", names1.size() >= 1); |
| 79 | check("Set MBeanServer.queryNames", names2.size() >= 1); |
| 80 | check("Set<ObjectName> MBeanServerConnection.queryNames", |
| 81 | names3.size() >= 1); |
| 82 | check("queryNames sets same", |
| 83 | names1.equals(names2) && names2.equals(names3)); |
| 84 | |
| 85 | Set<ObjectInstance> mbeans1 = |
| 86 | checked(mbs.queryMBeans(null, null), ObjectInstance.class); |
| 87 | Set mbeans2 = mbs.queryMBeans(null, null); |
| 88 | Set<ObjectInstance> mbeans3 = |
| 89 | checked(((MBeanServerConnection) mbs).queryMBeans(null, null), |
| 90 | ObjectInstance.class); |
| 91 | check("Set<ObjectInstsance> MBeanServer.queryMBeans", |
| 92 | mbeans1.size() >= 1); |
| 93 | check("Set MBeanServer.queryMBeans", mbeans2.size() >= 1); |
| 94 | check("Set<ObjectInstsance> MBeanServerConnection.queryMBeans", |
| 95 | mbeans3.size() >= 1); |
| 96 | check("queryMBeans sets same", |
| 97 | mbeans1.equals(mbeans2) && mbeans2.equals(mbeans3)); |
| 98 | |
| 99 | |
| 100 | AttributeChangeNotificationFilter acnf = |
| 101 | new AttributeChangeNotificationFilter(); |
| 102 | acnf.enableAttribute("foo"); |
| 103 | Vector<String> acnfs = acnf.getEnabledAttributes(); |
| 104 | checked(acnfs, String.class); |
| 105 | check("Vector<String> AttributeChangeNotificationFilter.getEnabled" + |
| 106 | "Attributes", acnfs.equals(Arrays.asList(new String[] {"foo"}))); |
| 107 | |
| 108 | if (generic) { |
| 109 | Attribute a = new Attribute("foo", "bar"); |
| 110 | AttributeList al1 = new AttributeList(); |
| 111 | al1.add(a); |
| 112 | AttributeList al2 = |
| 113 | new AttributeList(Arrays.asList(new Attribute[] {a})); |
| 114 | check("new AttributeList(List<Attribute>)", al1.equals(al2)); |
| 115 | List<Attribute> al3 = checked(al1.asList(), Attribute.class); |
| 116 | al3.remove(a); |
| 117 | check("List<Attribute> AttributeList.asList()", |
| 118 | al1.equals(al3) && al1.isEmpty()); |
| 119 | } |
| 120 | |
| 121 | List<ObjectName> namelist1 = new ArrayList<ObjectName>(names1); |
| 122 | Role role = new Role("rolename", namelist1); |
| 123 | List<ObjectName> namelist2 = |
| 124 | checked(role.getRoleValue(), ObjectName.class); |
| 125 | check("new Role(String,List<ObjectName>).getRoleValue() -> " + |
| 126 | "List<ObjectName>", namelist1.equals(namelist2)); |
| 127 | |
| 128 | RoleList rl1 = new RoleList(); |
| 129 | rl1.add(role); |
| 130 | RoleList rl2 = new RoleList(Arrays.asList(new Role[] {role})); |
| 131 | check("new RoleList(List<Role>)", rl1.equals(rl2)); |
| 132 | if (generic) { |
| 133 | List<Role> rl3 = checked(rl1.asList(), Role.class); |
| 134 | rl3.remove(role); |
| 135 | check("List<Role> RoleList.asList()", |
| 136 | rl1.equals(rl3) && rl1.isEmpty()); |
| 137 | } |
| 138 | |
| 139 | RoleUnresolved ru = |
| 140 | new RoleUnresolved("rolename", namelist1, |
| 141 | RoleStatus.LESS_THAN_MIN_ROLE_DEGREE); |
| 142 | List<ObjectName> namelist3 = |
| 143 | checked(ru.getRoleValue(), ObjectName.class); |
| 144 | check("new RoleUnresolved(...List<ObjectName>...).getRoleValue() -> " + |
| 145 | "List<ObjectName>", namelist1.equals(namelist3)); |
| 146 | |
| 147 | RoleUnresolvedList rul1 = new RoleUnresolvedList(); |
| 148 | rul1.add(ru); |
| 149 | RoleUnresolvedList rul2 = |
| 150 | new RoleUnresolvedList(Arrays.asList(new RoleUnresolved[] {ru})); |
| 151 | check("new RoleUnresolvedList(List<RoleUnresolved>", rul1.equals(rul2)); |
| 152 | if (generic) { |
| 153 | List<RoleUnresolved> rul3 = |
| 154 | checked(rul1.asList(), RoleUnresolved.class); |
| 155 | rul3.remove(ru); |
| 156 | check("List<RoleUnresolved> RoleUnresolvedList.asList()", |
| 157 | rul1.equals(rul3) && rul1.isEmpty()); |
| 158 | } |
| 159 | |
| 160 | // This case basically just tests that we can compile this sort of thing |
| 161 | OpenMBeanAttributeInfo ombai1 = |
| 162 | new OpenMBeanAttributeInfoSupport("a", "a descr", |
| 163 | SimpleType.INTEGER, |
| 164 | true, true, false); |
| 165 | CompositeType ct = |
| 166 | new CompositeType("ct", "ct descr", new String[] {"item1"}, |
| 167 | new String[] {"item1 descr"}, |
| 168 | new OpenType[] {SimpleType.INTEGER}); |
| 169 | OpenMBeanAttributeInfo ombai2 = |
| 170 | new OpenMBeanAttributeInfoSupport("a", "a descr", |
| 171 | ct, true, true, false); |
| 172 | TabularType tt = |
| 173 | new TabularType("tt", "tt descr", ct, new String[] {"item1"}); |
| 174 | OpenMBeanAttributeInfo ombai3 = |
| 175 | new OpenMBeanAttributeInfoSupport("a", "a descr", |
| 176 | tt, true, true, false); |
| 177 | ArrayType<String[][]> at = |
| 178 | new ArrayType<String[][]>(2, SimpleType.STRING); |
| 179 | OpenMBeanAttributeInfo ombai4 = |
| 180 | new OpenMBeanAttributeInfoSupport("a", "a descr", |
| 181 | at, true, true, false); |
| 182 | OpenMBeanAttributeInfo ombai4a = |
| 183 | new OpenMBeanAttributeInfoSupport("a", "a descr", |
| 184 | (ArrayType) at, |
| 185 | true, true, false); |
| 186 | OpenMBeanAttributeInfo ombai5 = |
| 187 | new OpenMBeanAttributeInfoSupport("a", "a descr", |
| 188 | SimpleType.INTEGER, |
| 189 | true, true, false, |
| 190 | 5, 1, 9); |
| 191 | OpenMBeanAttributeInfo ombai6 = |
| 192 | new OpenMBeanAttributeInfoSupport("a", "a descr", |
| 193 | SimpleType.INTEGER, |
| 194 | true, true, false, |
| 195 | 5, new Integer[] {1, 5}); |
| 196 | |
| 197 | OpenMBeanInfo ombi = |
| 198 | new OpenMBeanInfoSupport("a.a", "a.a descr", |
| 199 | new OpenMBeanAttributeInfo[] { |
| 200 | ombai1, ombai2, ombai3, ombai4, |
| 201 | ombai5, ombai6, |
| 202 | }, |
| 203 | null, null, null); |
| 204 | |
| 205 | Map<String,Integer> itemMap = |
| 206 | checked(singletonMap("item1", 5), |
| 207 | String.class, Integer.class); |
| 208 | CompositeData cd = |
| 209 | new CompositeDataSupport(ct, itemMap); |
| 210 | check("CompositeDataSupport(CompositeType, Map<String,?>", |
| 211 | cd.get("item1").equals(5)); |
| 212 | |
| 213 | Set<String> ctkeys = checked(ct.keySet(), String.class); |
| 214 | check("Set<String> CompositeType.keySet()", |
| 215 | ctkeys.equals(singleton("item1"))); |
| 216 | |
| 217 | List<String> ttindex = checked(tt.getIndexNames(), String.class); |
| 218 | check("Set<String> TabularType.getIndexNames()", |
| 219 | ttindex.equals(singletonList("item1"))); |
| 220 | |
| 221 | TabularData td = new TabularDataSupport(tt); |
| 222 | td.putAll(new CompositeData[] {cd}); |
| 223 | List<Integer> tdkey = checked(singletonList(5), Integer.class); |
| 224 | Set<List<Integer>> tdkeys = checked(singleton(tdkey), |
| 225 | (Class<List<Integer>>) tdkey.getClass()); |
| 226 | Collection<CompositeData> tdvalues = checked(singleton(cd), |
| 227 | CompositeData.class); |
| 228 | check("Set<List<?>> TabularDataSupport.keySet()", |
| 229 | td.keySet().equals(tdkeys)); |
| 230 | check("Collection<CompositeData> TabularDataSupport.values()", |
| 231 | td.values().iterator().next().equals(tdvalues.iterator().next())); |
| 232 | |
| 233 | ObjectName stupidName = new ObjectName("stupid:a=b"); |
| 234 | mbs.registerMBean(new Stupid(), stupidName); |
| 235 | StupidMBean proxy = |
| 236 | MBeanServerInvocationHandler.newProxyInstance(mbs, |
| 237 | stupidName, |
| 238 | StupidMBean.class, |
| 239 | false); |
| 240 | check("MBeanServerInvocationHandler.newProxyInstance", |
| 241 | proxy.getFive() == 5); |
| 242 | mbs.unregisterMBean(stupidName); |
| 243 | |
| 244 | mbs.registerMBean(new StandardMBean(new Stupid(), StupidMBean.class), |
| 245 | stupidName); |
| 246 | check("<T> StandardMBean(T impl, Class<T> intf)", |
| 247 | proxy.getFive() == 5); |
| 248 | |
| 249 | // Following is based on the package.html for javax.management.relation |
| 250 | // Create the Relation Service MBean |
| 251 | ObjectName relSvcName = new ObjectName(":type=RelationService"); |
| 252 | RelationService relSvcObject = new RelationService(true); |
| 253 | mbs.registerMBean(relSvcObject, relSvcName); |
| 254 | |
| 255 | // Create an MBean proxy for easier access to the Relation Service |
| 256 | RelationServiceMBean relSvc = |
| 257 | MBeanServerInvocationHandler.newProxyInstance(mbs, relSvcName, |
| 258 | RelationServiceMBean.class, |
| 259 | false); |
| 260 | |
| 261 | // Define the DependsOn relation type |
| 262 | RoleInfo[] dependsOnRoles = { |
| 263 | new RoleInfo("dependent", Module.class.getName()), |
| 264 | new RoleInfo("dependedOn", Module.class.getName()) |
| 265 | }; |
| 266 | relSvc.createRelationType("DependsOn", dependsOnRoles); |
| 267 | |
| 268 | // Now define a relation instance "moduleA DependsOn moduleB" |
| 269 | |
| 270 | ObjectName moduleA = new ObjectName(":type=Module,name=A"); |
| 271 | ObjectName moduleB = new ObjectName(":type=Module,name=B"); |
| 272 | |
| 273 | // Following two lines added to example: |
| 274 | mbs.registerMBean(new Module(), moduleA); |
| 275 | mbs.registerMBean(new Module(), moduleB); |
| 276 | |
| 277 | Role dependent = new Role("dependent", singletonList(moduleA)); |
| 278 | Role dependedOn = new Role("dependedOn", singletonList(moduleB)); |
| 279 | Role[] roleArray = {dependent, dependedOn}; |
| 280 | RoleList roles = new RoleList(Arrays.asList(roleArray)); |
| 281 | relSvc.createRelation("A-DependsOn-B", "DependsOn", roles); |
| 282 | |
| 283 | // Query the Relation Service to find what modules moduleA depends on |
| 284 | Map<ObjectName,List<String>> dependentAMap = |
| 285 | relSvc.findAssociatedMBeans(moduleA, "DependsOn", "dependent"); |
| 286 | Set<ObjectName> dependentASet = dependentAMap.keySet(); |
| 287 | dependentASet = checked(dependentASet, ObjectName.class); |
| 288 | // Set of ObjectName containing moduleB |
| 289 | check("Map<ObjectName,List<String>> RelationService.findAssociatedMBeans", |
| 290 | dependentAMap.size() == 1 && |
| 291 | dependentASet.equals(singleton(moduleB))); |
| 292 | |
| 293 | Map<String,List<String>> refRels = |
| 294 | relSvc.findReferencingRelations(moduleA, "DependsOn", "dependent"); |
| 295 | List<String> refRoles = |
| 296 | checked(refRels.get("A-DependsOn-B"), String.class); |
| 297 | check("Map<String,List<String>> RelationService.findReferencingRelations", |
| 298 | refRoles.equals(singletonList("dependent"))); |
| 299 | |
| 300 | List<String> relsOfType = relSvc.findRelationsOfType("DependsOn"); |
| 301 | relsOfType = checked(relsOfType, String.class); |
| 302 | check("List<String> RelationService.findRelationsOfType", |
| 303 | relsOfType.equals(singletonList("A-DependsOn-B"))); |
| 304 | |
| 305 | List<String> allRelIds = relSvc.getAllRelationIds(); |
| 306 | allRelIds = checked(allRelIds, String.class); |
| 307 | check("List<String> RelationService.getAllRelationIds()", |
| 308 | allRelIds.equals(singletonList("A-DependsOn-B"))); |
| 309 | |
| 310 | List<String> allRelTypes = relSvc.getAllRelationTypeNames(); |
| 311 | allRelTypes = checked(allRelTypes, String.class); |
| 312 | check("List<String> RelationService.getAllRelationTypeNames", |
| 313 | allRelTypes.equals(singletonList("DependsOn"))); |
| 314 | |
| 315 | Map<ObjectName,List<String>> refdMBeans = |
| 316 | relSvc.getReferencedMBeans("A-DependsOn-B"); |
| 317 | check("Map<ObjectName,List<String>> RelationService.getReferencedMBeans", |
| 318 | refdMBeans.get(moduleA).equals(singletonList("dependent")) && |
| 319 | refdMBeans.get(moduleB).equals(singletonList("dependedOn"))); |
| 320 | |
| 321 | List<ObjectName> roleContents = |
| 322 | checked(relSvc.getRole("A-DependsOn-B", "dependent"), |
| 323 | ObjectName.class); |
| 324 | check("List<ObjectName> RelationService.getRole", |
| 325 | roleContents.equals(singletonList(moduleA))); |
| 326 | |
| 327 | RoleInfo roleInfoDependent = |
| 328 | relSvc.getRoleInfo("DependsOn", "dependent"); |
| 329 | RoleInfo roleInfoDependedOn = |
| 330 | relSvc.getRoleInfo("DependsOn", "dependedOn"); |
| 331 | List<RoleInfo> expectedRoleInfos = |
| 332 | Arrays.asList(new RoleInfo[] {roleInfoDependent, roleInfoDependedOn}); |
| 333 | List<RoleInfo> roleInfos = |
| 334 | checked(relSvc.getRoleInfos("DependsOn"), RoleInfo.class); |
| 335 | check("List<RoleInfo> RelationService.getRoleInfos", |
| 336 | equalListContents(expectedRoleInfos, roleInfos)); |
| 337 | |
| 338 | RelationType relType = |
| 339 | new RelationTypeSupport("DependsOn", dependsOnRoles); |
| 340 | List<RoleInfo> relTypeRoleInfos = |
| 341 | checked(relType.getRoleInfos(), RoleInfo.class); |
| 342 | // Since there's no RoleInfo.equals and since the RelationTypeSupport |
| 343 | // constructor clones the RoleInfos passed to it, it's tricky to |
| 344 | // test equality here so we check type and size and have done with it |
| 345 | check("List<RoleInfo> RelationType.getRoleInfos", |
| 346 | relTypeRoleInfos.size() == 2); |
| 347 | |
| 348 | MBeanServerNotificationFilter mbsnf = |
| 349 | new MBeanServerNotificationFilter(); |
| 350 | mbsnf.enableObjectName(moduleA); |
| 351 | check("Vector<ObjectName> MBeanServerNotificationFilter." + |
| 352 | "getEnabledObjectNames", |
| 353 | mbsnf.getEnabledObjectNames().equals(Arrays.asList(moduleA))); |
| 354 | mbsnf.enableAllObjectNames(); |
| 355 | mbsnf.disableObjectName(moduleB); |
| 356 | check("Vector<ObjectName> MBeanServerNotificationFilter." + |
| 357 | "getDisabledObjectNames", |
| 358 | mbsnf.getDisabledObjectNames().equals(Arrays.asList(moduleB))); |
| 359 | |
| 360 | RelationService unusedRelSvc = new RelationService(false); |
| 361 | RelationNotification rn1 = |
| 362 | new RelationNotification(RelationNotification.RELATION_MBEAN_REMOVAL, |
| 363 | unusedRelSvc, 0L, 0L, "yo!", |
| 364 | "A-DependsOn-B", "DependsOn", null, |
| 365 | singletonList(moduleA)); |
| 366 | List<ObjectName> toUnreg = |
| 367 | checked(rn1.getMBeansToUnregister(), ObjectName.class); |
| 368 | check("List<ObjectName> RelationNotification.getMBeansToUnregister", |
| 369 | toUnreg.equals(singletonList(moduleA))); |
| 370 | |
| 371 | RelationNotification rn2 = |
| 372 | new RelationNotification(RelationNotification.RELATION_MBEAN_UPDATE, |
| 373 | unusedRelSvc, 0L, 0L, "yo!", |
| 374 | "A-DependsOn-B", "DependsOn", null, |
| 375 | "dependent", singletonList(moduleA), |
| 376 | singletonList(moduleB)); |
| 377 | check("List<ObjectName> RelationNotification.getOldRoleValue", |
| 378 | checked(rn2.getOldRoleValue(), ObjectName.class) |
| 379 | .equals(singletonList(moduleB))); |
| 380 | check("List<ObjectName> RelationNotification.getNewRoleValue", |
| 381 | checked(rn2.getNewRoleValue(), ObjectName.class) |
| 382 | .equals(singletonList(moduleA))); |
| 383 | |
| 384 | ObjectName timerName = new ObjectName(":type=timer"); |
| 385 | mbs.registerMBean(new Timer(), timerName); |
| 386 | TimerMBean timer = |
| 387 | MBeanServerInvocationHandler.newProxyInstance(mbs, |
| 388 | timerName, |
| 389 | TimerMBean.class, |
| 390 | false); |
| 391 | Date doomsday = new Date(Long.MAX_VALUE); |
| 392 | int timer1 = timer.addNotification("one", "one", null, doomsday); |
| 393 | int timer2 = timer.addNotification("two", "two", null, doomsday); |
| 394 | Vector<Integer> idsOne = timer.getNotificationIDs("one"); |
| 395 | check("Vector<Integer> TimerMBean.getNotificationIDs", |
| 396 | idsOne.equals(singletonList(timer1))); |
| 397 | Vector<Integer> allIds = timer.getAllNotificationIDs(); |
| 398 | check("Vector<Integer> TimerMBean.getAllNotificationIDs", |
| 399 | equalListContents(allIds, |
| 400 | Arrays.asList(new Integer[]{timer1, timer2}))); |
| 401 | |
| 402 | // ADD NEW TEST CASES ABOVE THIS COMMENT |
| 403 | |
| 404 | if (failures == 0) |
| 405 | System.out.println("All tests passed"); |
| 406 | else { |
| 407 | System.out.println("TEST FAILURES: " + failures); |
| 408 | System.exit(1); |
| 409 | } |
| 410 | |
| 411 | // DO NOT ADD NEW TEST CASES HERE, ADD THEM ABOVE THE PREVIOUS COMMENT |
| 412 | } |
| 413 | |
| 414 | public static interface StupidMBean { |
| 415 | public int getFive(); |
| 416 | } |
| 417 | |
| 418 | public static class Stupid implements StupidMBean { |
| 419 | public int getFive() { |
| 420 | return 5; |
| 421 | } |
| 422 | } |
| 423 | |
| 424 | public static class Module extends StandardMBean implements StupidMBean { |
| 425 | public Module() throws NotCompliantMBeanException { |
| 426 | super(StupidMBean.class); |
| 427 | } |
| 428 | |
| 429 | public int getFive() { |
| 430 | return 5; |
| 431 | } |
| 432 | } |
| 433 | |
| 434 | private static <E> List<E> singletonList(E value) { |
| 435 | return Collections.singletonList(value); |
| 436 | } |
| 437 | |
| 438 | private static <E> Set<E> singleton(E value) { |
| 439 | return Collections.singleton(value); |
| 440 | } |
| 441 | |
| 442 | private static <K,V> Map<K,V> singletonMap(K key, V value) { |
| 443 | return Collections.singletonMap(key, value); |
| 444 | } |
| 445 | |
| 446 | private static <E> List<E> checked(List<E> c, Class<E> type) { |
| 447 | List<E> unchecked = new ArrayList<E>(); |
| 448 | List<E> checked = Collections.checkedList(unchecked, type); |
| 449 | checked.addAll(c); |
| 450 | return Collections.checkedList(c, type); |
| 451 | } |
| 452 | |
| 453 | private static <E> Set<E> checked(Set<E> c, Class<E> type) { |
| 454 | Set<E> unchecked = new HashSet<E>(); |
| 455 | Set<E> checked = Collections.checkedSet(unchecked, type); |
| 456 | checked.addAll(c); |
| 457 | return Collections.checkedSet(c, type); |
| 458 | } |
| 459 | |
| 460 | private static <K,V> Map<K,V> checked(Map<K,V> m, |
| 461 | Class<K> keyType, |
| 462 | Class<V> valueType) { |
| 463 | Map<K,V> unchecked = new HashMap<K,V>(); |
| 464 | Map<K,V> checked = Collections.checkedMap(unchecked, keyType, valueType); |
| 465 | checked.putAll(m); |
| 466 | return Collections.checkedMap(m, keyType, valueType); |
| 467 | } |
| 468 | |
| 469 | /* The fact that we have to call this method is a clear signal that |
| 470 | * the API says List where it means Set. |
| 471 | */ |
| 472 | private static <E> boolean equalListContents(List<E> l1, List<E> l2) { |
| 473 | return new HashSet<E>(l1).equals(new HashSet<E>(l2)); |
| 474 | } |
| 475 | |
| 476 | private static void check(String what, boolean cond) { |
| 477 | if (cond) |
| 478 | System.out.println("OK: " + what); |
| 479 | else { |
| 480 | System.out.println("FAILED: " + what); |
| 481 | failures++; |
| 482 | } |
| 483 | } |
| 484 | } |