/* * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.Dictionary; import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.Properties; /* * @test * @bug 8029891 * @summary Test that the Properties class overrides all public+protected * methods of all ancestor classes and interfaces * @run main CheckOverrides * @author bchristi */ public class CheckOverrides { private static List pMethods; private static boolean isMethodOfInterest(Method method) { int mods = method.getModifiers(); return !Modifier.isStatic(mods) && (Modifier.isPublic(mods) || Modifier.isProtected(mods)); } public static void main(String[] args) { // Create list of all non-static, public/protected Properties methods Class propsClass = Properties.class; Method[] pMethodArray = propsClass.getDeclaredMethods(); pMethods = new ArrayList<>(pMethodArray.length); for (Method method : pMethodArray ) { if (isMethodOfInterest(method)) { pMethods.add(new SameMethodNoClass(method)); } } System.out.println(pMethods.size() + " non-static, public/protected" + " methods in " + propsClass); // Assemble list of all interfaces and classes to check List classesToCheck = new ArrayList<>(); classesToCheck.addAll(Arrays.asList(propsClass.getInterfaces())); Class superClass = propsClass.getSuperclass(); while (!superClass.equals(Object.class)) { classesToCheck.add(superClass); classesToCheck.addAll(Arrays.asList(superClass.getInterfaces())); superClass = superClass.getSuperclass(); } boolean passed = true; for (Class toCheck : classesToCheck) { passed = checkClass(toCheck) && passed; } if (!passed) { throw new RuntimeException("Test failed"); } System.out.println("Test passed"); } /** * Check Properties for methods in the given class. * Return true if all found, false otherwise */ private static boolean checkClass(Class clazz) { boolean passed = true; // For each non-static, public/protected method, confirm // that it's in the list. Method[] methods = clazz.getDeclaredMethods(); int numPubProcMethods = 0; for (Method method : methods) { if (isMethodOfInterest(method)) { numPubProcMethods++; boolean contains = pMethods.contains(new SameMethodNoClass(method)); if (!contains) { passed = false; System.out.println("Properties does not contain: " + method); System.out.println(" from: " + clazz); } } } System.out.println("Checked " + numPubProcMethods + " public/protected " + "methods in " + clazz); return passed; } /* * Wrapper to compare Methods, ignoring declaring Class */ private static class SameMethodNoClass { public Method method; public SameMethodNoClass(Method method) { this.method = method; } @Override public boolean equals(Object other) { if (other instanceof SameMethodNoClass) { SameMethodNoClass smnc = (SameMethodNoClass)other; return this.method.getName().equals(smnc.method.getName()) && this.method.getReturnType().equals(smnc.method.getReturnType()) && Arrays.equals(this.method.getParameterTypes(), smnc.method.getParameterTypes()) && Arrays.equals(this.method.getExceptionTypes(), smnc.method.getExceptionTypes()); } return false; } @Override public int hashCode() { return method.hashCode(); } @Override public String toString() { return method.toString(); } } }