1/*
2 * Copyright (c) 2001, 2016, Oracle and/or its affiliates. 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.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package sun.reflect;
27
28import java.io.OptionalDataException;
29import java.lang.invoke.MethodHandle;
30import java.lang.reflect.Constructor;
31import java.lang.reflect.InvocationTargetException;
32import java.security.AccessController;
33import java.security.Permission;
34import java.security.PrivilegedAction;
35
36/**
37 * ReflectionFactory supports custom serialization.
38 * Its methods support the creation of uninitialized objects, invoking serialization
39 * private methods for readObject, writeObject, readResolve, and writeReplace.
40 * <p>
41 * ReflectionFactory access is restricted, if a security manager is active,
42 * unless the permission {@code RuntimePermission("reflectionFactoryAccess")}
43 * is granted.
44 */
45public class ReflectionFactory {
46
47    private static final ReflectionFactory soleInstance = new ReflectionFactory();
48    private static final jdk.internal.reflect.ReflectionFactory delegate = AccessController.doPrivileged(
49            new PrivilegedAction<jdk.internal.reflect.ReflectionFactory>() {
50                public jdk.internal.reflect.ReflectionFactory run() {
51                    return jdk.internal.reflect.ReflectionFactory.getReflectionFactory();
52                }
53            });
54
55    private ReflectionFactory() {}
56
57    private static final Permission REFLECTION_FACTORY_ACCESS_PERM
58            = new RuntimePermission("reflectionFactoryAccess");
59
60    /**
61     * Provides the caller with the capability to instantiate reflective
62     * objects.
63     *
64     * <p> First, if there is a security manager, its {@code checkPermission}
65     * method is called with a {@link java.lang.RuntimePermission} with target
66     * {@code "reflectionFactoryAccess"}.  This may result in a security
67     * exception.
68     *
69     * <p> The returned {@code ReflectionFactory} object should be carefully
70     * guarded by the caller, since it can be used to read and write private
71     * data and invoke private methods, as well as to load unverified bytecodes.
72     * It must never be passed to untrusted code.
73     *
74     * @return the ReflectionFactory
75     * @throws SecurityException if a security manager exists and its
76     *         {@code checkPermission} method doesn't allow access to
77     *         the RuntimePermission "reflectionFactoryAccess".
78     */
79    public static ReflectionFactory getReflectionFactory() {
80        SecurityManager security = System.getSecurityManager();
81        if (security != null) {
82            security.checkPermission(REFLECTION_FACTORY_ACCESS_PERM);
83        }
84        return soleInstance;
85    }
86
87    /**
88     * Returns an accessible constructor capable of creating instances
89     * of the given class, initialized by the given constructor.
90     *
91     * @param cl the class to instantiate
92     * @param constructorToCall the constructor to call
93     * @return an accessible constructor
94     */
95    public Constructor<?> newConstructorForSerialization(Class<?> cl,
96                                                         Constructor<?> constructorToCall)
97    {
98        return delegate.newConstructorForSerialization(cl,
99                                                       constructorToCall);
100    }
101
102    /**
103     * Returns an accessible no-arg constructor for a class.
104     * The no-arg constructor is found searching the class and its supertypes.
105     *
106     * @param cl the class to instantiate
107     * @return a no-arg constructor for the class or {@code null} if
108     *     the class or supertypes do not have a suitable no-arg constructor
109     */
110    public final Constructor<?> newConstructorForSerialization(Class<?> cl)
111    {
112        return delegate.newConstructorForSerialization(cl);
113    }
114
115    /**
116     * Returns an accessible no-arg constructor for an externalizable class to be
117     * initialized using a public no-argument constructor.
118     *
119     * @param cl the class to instantiate
120     * @return A no-arg constructor for the class; returns {@code null} if
121     *     the class does not implement {@link java.io.Externalizable}
122     */
123    public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
124        return delegate.newConstructorForExternalization(cl);
125    }
126
127    /**
128     * Returns a direct MethodHandle for the {@code readObject} method on
129     * a Serializable class.
130     * The first argument of {@link MethodHandle#invoke} is the serializable
131     * object and the second argument is the {@code ObjectInputStream} passed to
132     * {@code readObject}.
133     *
134     * @param cl a Serializable class
135     * @return  a direct MethodHandle for the {@code readObject} method of the class or
136     *          {@code null} if the class does not have a {@code readObject} method
137     */
138    public final MethodHandle readObjectForSerialization(Class<?> cl) {
139        return delegate.readObjectForSerialization(cl);
140    }
141
142    /**
143     * Returns a direct MethodHandle for the {@code readObjectNoData} method on
144     * a Serializable class.
145     * The first argument of {@link MethodHandle#invoke} is the serializable
146     * object and the second argument is the {@code ObjectInputStream} passed to
147     * {@code readObjectNoData}.
148     *
149     * @param cl a Serializable class
150     * @return  a direct MethodHandle for the {@code readObjectNoData} method
151     *          of the class or {@code null} if the class does not have a
152     *          {@code readObjectNoData} method
153     */
154    public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
155        return delegate.readObjectNoDataForSerialization(cl);
156    }
157
158    /**
159     * Returns a direct MethodHandle for the {@code writeObject} method on
160     * a Serializable class.
161     * The first argument of {@link MethodHandle#invoke} is the serializable
162     * object and the second argument is the {@code ObjectOutputStream} passed to
163     * {@code writeObject}.
164     *
165     * @param cl a Serializable class
166     * @return  a direct MethodHandle for the {@code writeObject} method of the class or
167     *          {@code null} if the class does not have a {@code writeObject} method
168     */
169    public final MethodHandle writeObjectForSerialization(Class<?> cl) {
170        return delegate.writeObjectForSerialization(cl);
171    }
172
173    /**
174     * Returns a direct MethodHandle for the {@code readResolve} method on
175     * a serializable class.
176     * The single argument of {@link MethodHandle#invoke} is the serializable
177     * object.
178     *
179     * @param cl the Serializable class
180     * @return  a direct MethodHandle for the {@code readResolve} method of the class or
181     *          {@code null} if the class does not have a {@code readResolve} method
182     */
183    public final MethodHandle readResolveForSerialization(Class<?> cl) {
184        return delegate.readResolveForSerialization(cl);
185    }
186
187    /**
188     * Returns a direct MethodHandle for the {@code writeReplace} method on
189     * a serializable class.
190     * The single argument of {@link MethodHandle#invoke} is the serializable
191     * object.
192     *
193     * @param cl the Serializable class
194     * @return  a direct MethodHandle for the {@code writeReplace} method of the class or
195     *          {@code null} if the class does not have a {@code writeReplace} method
196     */
197    public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
198        return delegate.writeReplaceForSerialization(cl);
199    }
200
201    /**
202     * Returns true if the class has a static initializer.
203     * The presence of a static initializer is used to compute the serialVersionUID.
204     * @param cl a serializable class
205     * @return {@code true} if the class has a static initializer,
206     *          otherwise {@code false}
207     */
208    public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
209        return delegate.hasStaticInitializerForSerialization(cl);
210    }
211
212    /**
213     * Returns a new OptionalDataException with {@code eof} set to {@code true}
214     * or {@code false}.
215     * @param bool the value of {@code eof} in the created OptionalDataException
216     * @return  a new OptionalDataException
217     */
218    public final OptionalDataException newOptionalDataExceptionForSerialization(boolean bool) {
219        Constructor<OptionalDataException> cons = delegate.newOptionalDataExceptionForSerialization();
220        try {
221            return cons.newInstance(bool);
222        } catch (InstantiationException|IllegalAccessException|InvocationTargetException ex) {
223            throw new InternalError("unable to create OptionalDataException", ex);
224        }
225    }
226}
227
228