Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.dynalink/share/classes/jdk/dynalink/beans/StaticClassLinker.java
41161 views
1
/*
2
* Copyright (c) 2010, 2013, 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
26
/*
27
* This file is available under and governed by the GNU General Public
28
* License version 2 only, as published by the Free Software Foundation.
29
* However, the following notice accompanied the original version of this
30
* file, and Oracle licenses the original version of this file under the BSD
31
* license:
32
*/
33
/*
34
Copyright 2009-2013 Attila Szegedi
35
36
Redistribution and use in source and binary forms, with or without
37
modification, are permitted provided that the following conditions are
38
met:
39
* Redistributions of source code must retain the above copyright
40
notice, this list of conditions and the following disclaimer.
41
* Redistributions in binary form must reproduce the above copyright
42
notice, this list of conditions and the following disclaimer in the
43
documentation and/or other materials provided with the distribution.
44
* Neither the name of the copyright holder nor the names of
45
contributors may be used to endorse or promote products derived from
46
this software without specific prior written permission.
47
48
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
49
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
50
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
51
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
52
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
53
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
54
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
55
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
56
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
57
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
58
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59
*/
60
61
package jdk.dynalink.beans;
62
63
import java.lang.invoke.MethodHandle;
64
import java.lang.invoke.MethodHandles;
65
import java.lang.invoke.MethodType;
66
import java.lang.reflect.Array;
67
import java.util.Arrays;
68
import java.util.Set;
69
import jdk.dynalink.CallSiteDescriptor;
70
import jdk.dynalink.NamedOperation;
71
import jdk.dynalink.StandardNamespace;
72
import jdk.dynalink.StandardOperation;
73
import jdk.dynalink.beans.GuardedInvocationComponent.ValidationType;
74
import jdk.dynalink.linker.GuardedInvocation;
75
import jdk.dynalink.linker.LinkRequest;
76
import jdk.dynalink.linker.LinkerServices;
77
import jdk.dynalink.linker.TypeBasedGuardingDynamicLinker;
78
import jdk.dynalink.linker.support.Lookup;
79
80
/**
81
* Provides a linker for the {@link StaticClass} objects.
82
*/
83
class StaticClassLinker implements TypeBasedGuardingDynamicLinker {
84
private static final ClassValue<SingleClassStaticsLinker> linkers = new ClassValue<>() {
85
@Override
86
protected SingleClassStaticsLinker computeValue(final Class<?> clazz) {
87
return new SingleClassStaticsLinker(clazz);
88
}
89
};
90
91
private static class SingleClassStaticsLinker extends AbstractJavaLinker {
92
private final DynamicMethod constructor;
93
94
SingleClassStaticsLinker(final Class<?> clazz) {
95
super(clazz, IS_CLASS.bindTo(clazz));
96
// Map "staticClassObject.class" to StaticClass.getRepresentedClass(). Some adventurous soul could subclass
97
// StaticClass, so we use INSTANCE_OF validation instead of EXACT_CLASS.
98
setPropertyGetter("class", GET_CLASS, ValidationType.INSTANCE_OF);
99
constructor = createConstructorMethod(clazz);
100
}
101
102
/**
103
* Creates a dynamic method containing all overloads of a class' public constructor
104
* @param clazz the target class
105
* @return a dynamic method containing all overloads of a class' public constructor. If the class has no public
106
* constructors, returns null.
107
*/
108
private static DynamicMethod createConstructorMethod(final Class<?> clazz) {
109
if(clazz.isArray()) {
110
final MethodHandle boundArrayCtor = ARRAY_CTOR.bindTo(clazz.getComponentType());
111
return new SimpleDynamicMethod(StaticClassIntrospector.editConstructorMethodHandle(
112
boundArrayCtor.asType(boundArrayCtor.type().changeReturnType(clazz))), clazz, "<init>");
113
}
114
if(CheckRestrictedPackage.isRestrictedClass(clazz)) {
115
return null;
116
}
117
return createDynamicMethod(Arrays.asList(clazz.getConstructors()), clazz, "<init>");
118
}
119
120
@Override
121
FacetIntrospector createFacetIntrospector() {
122
return new StaticClassIntrospector(clazz);
123
}
124
125
@Override
126
public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices)
127
throws Exception {
128
final GuardedInvocation gi = super.getGuardedInvocation(request, linkerServices);
129
if(gi != null) {
130
return gi;
131
}
132
final CallSiteDescriptor desc = request.getCallSiteDescriptor();
133
if(NamedOperation.getBaseOperation(desc.getOperation()) == StandardOperation.NEW && constructor != null) {
134
final MethodHandle ctorInvocation = constructor.getInvocation(desc, linkerServices);
135
if(ctorInvocation != null) {
136
return new GuardedInvocation(ctorInvocation, getClassGuard(desc.getMethodType()));
137
}
138
}
139
return null;
140
}
141
142
@Override
143
protected GuardedInvocationComponent getGuardedInvocationComponent(final ComponentLinkRequest req) throws Exception {
144
final GuardedInvocationComponent superGic = super.getGuardedInvocationComponent(req);
145
if (superGic != null) {
146
return superGic;
147
}
148
if (!req.namespaces.isEmpty()
149
&& req.namespaces.get(0) == StandardNamespace.ELEMENT
150
&& (req.baseOperation == StandardOperation.GET || req.baseOperation == StandardOperation.SET))
151
{
152
// StaticClass doesn't behave as a collection
153
return getNextComponent(req.popNamespace());
154
}
155
return null;
156
}
157
158
@Override
159
SingleDynamicMethod getConstructorMethod(final String signature) {
160
return constructor != null? constructor.getMethodForExactParamTypes(signature) : null;
161
}
162
}
163
164
static Object getConstructorMethod(final Class<?> clazz, final String signature) {
165
return linkers.get(clazz).getConstructorMethod(signature);
166
}
167
168
static Set<String> getReadableStaticPropertyNames(final Class<?> clazz) {
169
return linkers.get(clazz).getReadablePropertyNames();
170
}
171
172
static Set<String> getWritableStaticPropertyNames(final Class<?> clazz) {
173
return linkers.get(clazz).getWritablePropertyNames();
174
}
175
176
static Set<String> getStaticMethodNames(final Class<?> clazz) {
177
return linkers.get(clazz).getMethodNames();
178
}
179
180
@Override
181
public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) throws Exception {
182
final Object receiver = request.getReceiver();
183
if(receiver instanceof StaticClass) {
184
return linkers.get(((StaticClass)receiver).getRepresentedClass()).getGuardedInvocation(request,
185
linkerServices);
186
}
187
return null;
188
}
189
190
@Override
191
public boolean canLinkType(final Class<?> type) {
192
return type == StaticClass.class;
193
}
194
195
/*private*/ static final MethodHandle GET_CLASS;
196
/*private*/ static final MethodHandle IS_CLASS;
197
/*private*/ static final MethodHandle ARRAY_CTOR = Lookup.PUBLIC.findStatic(Array.class, "newInstance",
198
MethodType.methodType(Object.class, Class.class, int.class));
199
200
static {
201
final Lookup lookup = new Lookup(MethodHandles.lookup());
202
GET_CLASS = lookup.findVirtual(StaticClass.class, "getRepresentedClass", MethodType.methodType(Class.class));
203
IS_CLASS = lookup.findOwnStatic("isClass", Boolean.TYPE, Class.class, Object.class);
204
}
205
206
@SuppressWarnings("unused")
207
private static boolean isClass(final Class<?> clazz, final Object obj) {
208
return obj instanceof StaticClass && ((StaticClass)obj).getRepresentedClass() == clazz;
209
}
210
}
211
212