--- /dev/null 2016-10-03 16:29:56.482600995 +0200
+++ new/test/java/lang/reflect/AccessControl/util/MemberFactory.java 2016-10-18 13:06:45.819954648 +0200
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+package util;
+
+import java.lang.reflect.AccessibleObject;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import static util.MemberFactory.Kind.CONSTRUCTOR;
+import static util.MemberFactory.Kind.FIELD;
+import static util.MemberFactory.Kind.METHOD;
+
+/**
+ * Enumeration of:
+ *
+ * {private, package, protected, public} x {instance, static} x {field, method}
+ *
+ * and:
+ *
+ * {private, package, protected, public} x {constructor},
+ *
+ * with each element acting as a factory of AccessibleObject(s)
+ * declared by given declaringClass(es).
+ */
+public enum MemberFactory implements Function, AccessibleObject> {
+ // instance fields
+ PRIVATE_INSTANCE_FIELD(FIELD, "privateInstance"),
+ PACKAGE_INSTANCE_FIELD(FIELD, "packageInstance"),
+ PROTECTED_INSTANCE_FIELD(FIELD, "protectedInstance"),
+ PUBLIC_INSTANCE_FIELD(FIELD, "publicInstance"),
+ // instance methods
+ PRIVATE_INSTANCE_METHOD(METHOD, "privateInstance"),
+ PACKAGE_INSTANCE_METHOD(METHOD, "packageInstance"),
+ PROTECTED_INSTANCE_METHOD(METHOD, "protectedInstance"),
+ PUBLIC_INSTANCE_METHOD(METHOD, "publicInstance"),
+ // static fields
+ PRIVATE_STATIC_FIELD(FIELD, "privateStatic"),
+ PACKAGE_STATIC_FIELD(FIELD, "packageStatic"),
+ PROTECTED_STATIC_FIELD(FIELD, "protectedStatic"),
+ PUBLIC_STATIC_FIELD(FIELD, "publicStatic"),
+ // static methods
+ PRIVATE_STATIC_METHOD(METHOD, "privateStatic"),
+ PACKAGE_STATIC_METHOD(METHOD, "packageStatic"),
+ PROTECTED_STATIC_METHOD(METHOD, "protectedStatic"),
+ PUBLIC_STATIC_METHOD(METHOD, "publicStatic"),
+ // constructors
+ PRIVATE_CONSTRUCTOR(CONSTRUCTOR, null, Void.class, Void.class, Void.class),
+ PACKAGE_CONSTRUCTOR(CONSTRUCTOR, null, Void.class, Void.class),
+ PROTECTED_CONSTRUCTOR(CONSTRUCTOR, null, Void.class),
+ PUBLIC_CONSTRUCTOR(CONSTRUCTOR, null),;
+
+ final Kind kind;
+ final String name;
+ final Class>[] parameterTypes;
+
+ MemberFactory(Kind kind, String name, Class>... parameterTypes) {
+ this.kind = kind;
+ this.name = name;
+ this.parameterTypes = parameterTypes;
+ }
+
+ @Override
+ public AccessibleObject apply(Class> declaringClass) {
+ return kind.apply(declaringClass, this);
+ }
+
+ public static EnumSet asSet(MemberFactory... members) {
+ return members.length == 0 ? EnumSet.noneOf(MemberFactory.class)
+ : EnumSet.copyOf(Arrays.asList(members));
+ }
+
+ /**
+ * @param members the set of MemberFactory(s) to convert to set of
+ * MemberFactory.Group(s).
+ * @return a set of groups that cover all elements of the members set if
+ * such set of groups exists or null if it doesn't.
+ */
+ public static EnumSet membersToGroupsOrNull(EnumSet members) {
+ EnumSet mSet = members.clone();
+ EnumSet gSet = EnumSet.allOf(Group.class);
+ Iterator gIter = gSet.iterator();
+ while (gIter.hasNext()) {
+ Group g = gIter.next();
+ if (mSet.containsAll(g.members)) {
+ mSet.removeAll(g.members);
+ } else {
+ gIter.remove();
+ }
+ }
+ return mSet.isEmpty() ? gSet : null;
+ }
+
+ /**
+ * @param groups the set of MemberFactory.Group(s) to convert to set of
+ * MemberFactory(s).
+ * @return a set of members as a union of members of all groups.
+ */
+ public static EnumSet groupsToMembers(EnumSet groups) {
+ EnumSet mSet = EnumSet.noneOf(MemberFactory.class);
+ for (Group g : groups) {
+ mSet.addAll(g.members);
+ }
+ return mSet;
+ }
+
+ enum Kind implements BiFunction, MemberFactory, AccessibleObject> {
+ FIELD {
+ @Override
+ public AccessibleObject apply(Class> declaringClass, MemberFactory factory) {
+ assert factory.kind == this;
+ try {
+ return declaringClass.getDeclaredField(factory.name);
+ } catch (NoSuchFieldException e) {
+ // a fault in test - fail fast
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ },
+ METHOD {
+ @Override
+ public AccessibleObject apply(Class> declaringClass, MemberFactory factory) {
+ assert factory.kind == this;
+ try {
+ return declaringClass.getDeclaredMethod(factory.name, factory.parameterTypes);
+ } catch (NoSuchMethodException e) {
+ // a fault in test - fail fast
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ },
+ CONSTRUCTOR {
+ @Override
+ public AccessibleObject apply(Class> declaringClass, MemberFactory factory) {
+ assert factory.kind == this;
+ try {
+ return declaringClass.getDeclaredConstructor(factory.parameterTypes);
+ } catch (NoSuchMethodException e) {
+ // a fault in test - fail fast
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ }
+ }
+
+ /**
+ * We define groups of MemberFactory(s) for members that commonly
+ * exhibit same access restrictions in various cases in order to allow
+ * specifying groups instead of individual members in the test cases,
+ * making them less verbose.
+ */
+ public enum Group {
+ // all members
+ ALL(MemberFactory.values()),
+ // all private members
+ PRIVATE_MEMBERS(PRIVATE_INSTANCE_FIELD, PRIVATE_INSTANCE_METHOD,
+ PRIVATE_STATIC_FIELD, PRIVATE_STATIC_METHOD,
+ PRIVATE_CONSTRUCTOR),
+ // all package members
+ PACKAGE_MEMBERS(PACKAGE_INSTANCE_FIELD, PACKAGE_INSTANCE_METHOD,
+ PACKAGE_STATIC_FIELD, PACKAGE_STATIC_METHOD,
+ PACKAGE_CONSTRUCTOR),
+ // all protected members
+ PROTECTED_MEMBERS(PROTECTED_INSTANCE_FIELD, PROTECTED_INSTANCE_METHOD,
+ PROTECTED_STATIC_FIELD, PROTECTED_STATIC_METHOD,
+ PROTECTED_CONSTRUCTOR),
+ // all public members
+ PUBLIC_MEMBERS(PUBLIC_INSTANCE_FIELD, PUBLIC_INSTANCE_METHOD,
+ PUBLIC_STATIC_FIELD, PUBLIC_STATIC_METHOD,
+ PUBLIC_CONSTRUCTOR),
+ // instance field and method pairs
+ PRIVATE_INSTANCE_F_M(PRIVATE_INSTANCE_FIELD, PRIVATE_INSTANCE_METHOD),
+ PACKAGE_INSTANCE_F_M(PACKAGE_INSTANCE_FIELD, PACKAGE_INSTANCE_METHOD),
+ PROTECTED_INSTANCE_F_M(PROTECTED_INSTANCE_FIELD, PROTECTED_INSTANCE_METHOD),
+ PUBLIC_INSTANCE_F_M(PUBLIC_INSTANCE_FIELD, PUBLIC_INSTANCE_METHOD),
+ // static field and method pairs
+ PRIVATE_STATIC_F_M(PRIVATE_STATIC_FIELD, PRIVATE_STATIC_METHOD),
+ PACKAGE_STATIC_F_M(PACKAGE_STATIC_FIELD, PACKAGE_STATIC_METHOD),
+ PROTECTED_STATIC_F_M(PROTECTED_STATIC_FIELD, PROTECTED_STATIC_METHOD),
+ PUBLIC_STATIC_F_M(PUBLIC_STATIC_FIELD, PUBLIC_STATIC_METHOD),
+ // constructor singles
+ PRIVATE_C(PRIVATE_CONSTRUCTOR),
+ PACKAGE_C(PACKAGE_CONSTRUCTOR),
+ PROTECTED_C(PROTECTED_CONSTRUCTOR),
+ PUBLIC_C(PUBLIC_CONSTRUCTOR);
+
+ final EnumSet members;
+
+ Group(MemberFactory... members) {
+ this.members = EnumSet.copyOf(Arrays.asList(members));
+ }
+
+ public static EnumSet asSet(Group... groups) {
+ return groups.length == 0 ? EnumSet.noneOf(Group.class)
+ : EnumSet.copyOf(Arrays.asList(groups));
+ }
+ }
+}