Skip to content

Commit

Permalink
Support records as inputs on the client side
Browse files Browse the repository at this point in the history
  • Loading branch information
jmartisk committed Sep 14, 2021
1 parent f9a6c18 commit 7e1f928
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,31 @@ Object read() {
}

private Object readObject() {
Object instance = newInstance();
type.fields().forEach(field -> {
Object fieldValue = buildValue(location, value, field);
field.set(instance, fieldValue);
});
return instance;
if (!type.isRecord()) {
Object instance = newInstance();
type.fields().forEach(field -> {
Object fieldValue = buildValue(location, value, field);
field.set(instance, fieldValue);
});
return instance;
} else {
Object[] values = type.fields().map(field -> buildValue(location, value, field)).toArray(Object[]::new);
return newInstance(values);
}
}

private Object newInstance() {
private Object newInstance(Object[] parameters) {
try {
return type.newInstance();
return type.newInstance(parameters);
} catch (Exception e) {
throw new GraphQLClientException("can't create " + location, e);
}
}

private Object newInstance() {
return newInstance(new Object[0]);
}

private Object buildValue(Location location, JsonObject value, FieldInfo field) {
String fieldName = field.getAlias().orElseGet(field::getName);
Location fieldLocation = new Location(field.getType(), location.getDescription() + "." + fieldName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Arrays;
import java.util.Collection;
import java.util.Optional;
import java.util.function.Predicate;
Expand Down Expand Up @@ -150,6 +151,10 @@ public boolean isErrorOr() {
return ErrorOr.class.equals(getRawType());
}

public boolean isRecord() {
return rawType.getSuperclass().getName().equals("java.lang.Record");
}

public boolean isScalar() {
return isPrimitive()
|| Number.class.isAssignableFrom(getRawType())
Expand Down Expand Up @@ -194,22 +199,42 @@ private boolean hasOneStringParameter(Executable executable) {
return executable.getParameterCount() == 1 && CharSequence.class.isAssignableFrom(executable.getParameterTypes()[0]);
}

public Object newInstance() {
public Object newInstance(Object[] args) {
try {
Constructor<?> noArgsConstructor = getDeclaredConstructor(getRawType());
noArgsConstructor.setAccessible(true);
return noArgsConstructor.newInstance();
if (args.length == 0) {
Constructor<?> noArgsConstructor = getDeclaredConstructor(getRawType());
noArgsConstructor.setAccessible(true);
return noArgsConstructor.newInstance();
} else {
Class<?> rawType = getRawType();
Optional<Constructor<?>> constructor = Arrays.stream(rawType.getDeclaredConstructors())
.filter(c -> !c.getDeclaringClass().equals(Class.class))
.filter(c -> c.getParameterCount() == args.length)
.findAny();
if (constructor.isPresent()) {
Constructor<?> c = constructor.get();
c.setAccessible(true);
return c.newInstance(args);
} else {
throw new RuntimeException("Could not find a suitable constructor of type " + type);
}
}
} catch (ReflectiveOperationException e) {
throw new RuntimeException("can't instantiate " + type, e);
}
}

private Constructor<?> getDeclaredConstructor(Class<?> type) throws NoSuchMethodException {
return getDeclaredConstructor(type, new Class[0]);
}

private Constructor<?> getDeclaredConstructor(Class<?> type, Class<?>[] parameters) throws NoSuchMethodException {
if (System.getSecurityManager() == null) {
return type.getDeclaredConstructor();
return type.getDeclaredConstructor(parameters);
}
try {
return AccessController.doPrivileged((PrivilegedExceptionAction<Constructor<?>>) type::getDeclaredConstructor);
return AccessController
.doPrivileged((PrivilegedExceptionAction<Constructor<?>>) () -> type.getDeclaredConstructor(parameters));
} catch (PrivilegedActionException pae) {
if (pae.getCause() instanceof NoSuchMethodException) {
throw (NoSuchMethodException) pae.getCause();
Expand Down

0 comments on commit 7e1f928

Please sign in to comment.