use of java.lang.reflect.Modifier in project LanternServer by LanternPowered.
the class FieldAccessFactory method createSetter.
/**
* Creates a setter {@link BiConsumer} for the given {@link Field}.
*
* @param field The field
* @param <T> The target object type
* @param <V> The field value type
* @return The bi consumer
*/
public static <T, V> BiConsumer<T, V> createSetter(Field field) {
checkNotNull(field, "field");
field.setAccessible(true);
boolean isFinal = Modifier.isFinal(field.getModifiers());
// Better check is somebody changed the final modifier already
if (!isFinal) {
final Field[] fields = field.getDeclaringClass().getDeclaredFields();
boolean isFound = false;
for (Field field1 : fields) {
// The same signature, now check if somebody tinkered with the field
if (field.getName().equals(field1.getName()) && field.getType().equals(field1.getType())) {
isFinal = Modifier.isFinal(field1.getModifiers());
isFound = true;
break;
}
}
if (!isFound) {
throw new IllegalStateException("Something funky happened with: " + field.getName());
}
} else {
try {
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
// Final fields don't allow direct access, so MethodHandles will do the trick.
if (isFinal) {
try {
final MethodHandle methodHandle = MethodHandleMagic.trustedLookup().in(field.getDeclaringClass()).unreflectSetter(field).asType(setterMethodType);
return (a, b) -> {
try {
methodHandle.invokeExact(a, b);
} catch (Throwable throwable) {
throw new IllegalStateException(throwable);
}
};
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
final ClassWriter cw = new ClassWriter(0);
final String className = field.getName().replace('.', '/') + "$$LanternSetter$" + setterCounter.incrementAndGet();
cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, className, "Ljava/lang/Object;Ljava/util/function/BiConsumer<Ljava/lang/Object;Ljava/lang/Object;>;", "java/lang/Object", new String[] { "java/util/function/BiConsumer" });
// Add a empty constructor
BytecodeUtils.visitEmptyConstructor(cw);
// Generate the apply method
final MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "accept", "(Ljava/lang/Object;Ljava/lang/Object;)V", null, null);
mv.visitCode();
final String descriptor = Type.getDescriptor(field.getType());
final String targetName = Type.getInternalName(field.getDeclaringClass());
final boolean isStatic = Modifier.isStatic(field.getModifiers());
if (!isStatic) {
// Load the target parameter
mv.visitVarInsn(ALOAD, 1);
// Cast it
mv.visitTypeInsn(CHECKCAST, targetName);
}
// Load the value parameter
mv.visitVarInsn(ALOAD, 2);
// Unbox the values in case they are primitives, otherwise cast
GeneratorUtils.visitUnboxingMethod(mv, Type.getType(field.getType()));
// Put the value into the field
if (isStatic) {
mv.visitFieldInsn(PUTSTATIC, targetName, field.getName(), descriptor);
} else {
mv.visitFieldInsn(PUTFIELD, targetName, field.getName(), descriptor);
}
// Return
mv.visitInsn(RETURN);
mv.visitMaxs(2, 3);
mv.visitEnd();
// Finish class generation
cw.visitEnd();
// Define the class and create a function instance
final MethodHandles.Lookup lookup = MethodHandleMagic.trustedLookup().in(field.getDeclaringClass());
final Class<?> functionClass = MethodHandleMagic.defineNestmateClass(lookup, cw.toByteArray());
try {
return (BiConsumer<T, V>) functionClass.newInstance();
} catch (Exception e) {
throw new IllegalStateException("Something went wrong!", e);
}
}
use of java.lang.reflect.Modifier in project flow by vaadin.
the class SchemaGenerator method getFieldsAndOptionalMap.
/**
* Because it's not possible to check the `transient` modifier and
* annotation of a field using JavaParser API. We need this method to
* reflect the type and get those information from the reflected object.
*
* @param type
* type of the class to get fields information
* @return set of fields' name that we should generate.
*/
private Map<String, Boolean> getFieldsAndOptionalMap(GeneratorType type) {
ResolvedReferenceType resolvedReferenceType = type.asResolvedType().asReferenceType();
Optional<ResolvedReferenceTypeDeclaration> typeDeclaration = resolvedReferenceType.getTypeDeclaration();
if (!typeDeclaration.filter(td -> td.isClass() && !td.isAnonymousClass()).isPresent()) {
return Collections.emptyMap();
}
HashMap<String, Boolean> validFields = new HashMap<>();
try {
Class<?> aClass = openApiObjectGenerator.getClassFromReflection(type);
Arrays.stream(aClass.getDeclaredFields()).filter(field -> {
int modifiers = field.getModifiers();
return !Modifier.isStatic(modifiers) && !Modifier.isTransient(modifiers) && !field.isAnnotationPresent(JsonIgnore.class);
}).forEach(field -> validFields.put(field.getName(), !ExplicitNullableTypeChecker.isRequired(field)));
} catch (ClassNotFoundException e) {
String message = String.format("Can't get list of fields from class '%s'." + "Please make sure that class '%s' is in your project's compile classpath. " + "As the result, the generated TypeScript file will be empty.", resolvedReferenceType.getQualifiedName(), resolvedReferenceType.getQualifiedName());
getLogger().info(message);
getLogger().debug(message, e);
}
return validFields;
}
use of java.lang.reflect.Modifier in project flink by apache.
the class UserDefinedFunctionHelper method validateImplementationMethod.
/**
* Validates an implementation method such as {@code eval()} or {@code accumulate()}.
*/
private static void validateImplementationMethod(Class<? extends UserDefinedFunction> clazz, boolean rejectStatic, boolean isOptional, String... methodNameOptions) {
final Set<String> nameSet = new HashSet<>(Arrays.asList(methodNameOptions));
final List<Method> methods = getAllDeclaredMethods(clazz);
boolean found = false;
for (Method method : methods) {
if (!nameSet.contains(method.getName())) {
continue;
}
found = true;
final int modifier = method.getModifiers();
if (!Modifier.isPublic(modifier)) {
throw new ValidationException(String.format("Method '%s' of function class '%s' is not public.", method.getName(), clazz.getName()));
}
if (Modifier.isAbstract(modifier)) {
throw new ValidationException(String.format("Method '%s' of function class '%s' must not be abstract.", method.getName(), clazz.getName()));
}
if (rejectStatic && Modifier.isStatic(modifier)) {
throw new ValidationException(String.format("Method '%s' of function class '%s' must not be static.", method.getName(), clazz.getName()));
}
}
if (!found && !isOptional) {
throw new ValidationException(String.format("Function class '%s' does not implement a method named %s.", clazz.getName(), nameSet.stream().map(s -> "'" + s + "'").collect(Collectors.joining(" or "))));
}
}
Aggregations