/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package java.lang.invoke;
import java.security.*;
import java.lang.reflect.*;
import java.lang.invoke.
MethodHandleNatives.
Constants;
import java.lang.invoke.
MethodHandles.
Lookup;
import static java.lang.invoke.
MethodHandleStatics.*;
/*
* Auxiliary to MethodHandleInfo, wants to nest in MethodHandleInfo but must be non-public.
*/
/*non-public*/
final
class
InfoFromMemberName implements
MethodHandleInfo {
private final
MemberName member;
private final int
referenceKind;
InfoFromMemberName(
Lookup lookup,
MemberName member, byte
referenceKind) {
assert(
member.
isResolved() ||
member.
isMethodHandleInvoke());
assert(
member.
referenceKindIsConsistentWith(
referenceKind));
this.
member =
member;
this.
referenceKind =
referenceKind;
}
@
Override
public
Class<?>
getDeclaringClass() {
return
member.
getDeclaringClass();
}
@
Override
public
String getName() {
return
member.
getName();
}
@
Override
public
MethodType getMethodType() {
return
member.
getMethodOrFieldType();
}
@
Override
public int
getModifiers() {
return
member.
getModifiers();
}
@
Override
public int
getReferenceKind() {
return
referenceKind;
}
@
Override
public
String toString() {
return
MethodHandleInfo.
toString(
getReferenceKind(),
getDeclaringClass(),
getName(),
getMethodType());
}
@
Override
public <T extends
Member> T
reflectAs(
Class<T>
expected,
Lookup lookup) {
if (
member.
isMethodHandleInvoke() && !
member.
isVarargs()) {
// This member is an instance of a signature-polymorphic method, which cannot be reflected
// A method handle invoker can come in either of two forms:
// A generic placeholder (present in the source code, and varargs)
// and a signature-polymorphic instance (synthetic and not varargs).
// For more information see comments on {@link MethodHandleNatives#linkMethod}.
throw new
IllegalArgumentException("cannot reflect signature polymorphic method");
}
Member mem =
AccessController.
doPrivileged(new
PrivilegedAction<
Member>() {
public
Member run() {
try {
return
reflectUnchecked();
} catch (
ReflectiveOperationException ex) {
throw new
IllegalArgumentException(
ex);
}
}
});
try {
Class<?>
defc =
getDeclaringClass();
byte
refKind = (byte)
getReferenceKind();
lookup.
checkAccess(
refKind,
defc,
convertToMemberName(
refKind,
mem));
} catch (
IllegalAccessException ex) {
throw new
IllegalArgumentException(
ex);
}
return
expected.
cast(
mem);
}
private
Member reflectUnchecked() throws
ReflectiveOperationException {
byte
refKind = (byte)
getReferenceKind();
Class<?>
defc =
getDeclaringClass();
boolean
isPublic =
Modifier.
isPublic(
getModifiers());
if (
MethodHandleNatives.
refKindIsMethod(
refKind)) {
if (
isPublic)
return
defc.
getMethod(
getName(),
getMethodType().
parameterArray());
else
return
defc.
getDeclaredMethod(
getName(),
getMethodType().
parameterArray());
} else if (
MethodHandleNatives.
refKindIsConstructor(
refKind)) {
if (
isPublic)
return
defc.
getConstructor(
getMethodType().
parameterArray());
else
return
defc.
getDeclaredConstructor(
getMethodType().
parameterArray());
} else if (
MethodHandleNatives.
refKindIsField(
refKind)) {
if (
isPublic)
return
defc.
getField(
getName());
else
return
defc.
getDeclaredField(
getName());
} else {
throw new
IllegalArgumentException("referenceKind="+
refKind);
}
}
private static
MemberName convertToMemberName(byte
refKind,
Member mem) throws
IllegalAccessException {
if (
mem instanceof
Method) {
boolean
wantSpecial = (
refKind ==
REF_invokeSpecial);
return new
MemberName((
Method)
mem,
wantSpecial);
} else if (
mem instanceof
Constructor) {
return new
MemberName((
Constructor)
mem);
} else if (
mem instanceof
Field) {
boolean
isSetter = (
refKind ==
REF_putField ||
refKind ==
REF_putStatic);
return new
MemberName((
Field)
mem,
isSetter);
}
throw new
InternalError(
mem.
getClass().
getName());
}
}