List of usage examples for java.lang.invoke MethodHandle invokeExact
@HotSpotIntrinsicCandidate public final native @PolymorphicSignature Object invokeExact(Object... args) throws Throwable;
From source file:me.rojo8399.placeholderapi.impl.utils.TypeUtils.java
@SuppressWarnings("unchecked") public static <T> Optional<T> tryCast(Object val, final Class<T> expected) { if (val == null) { return Optional.empty(); }/*from www . j a v a 2 s . c om*/ if (expected == null) { throw new IllegalArgumentException("Must provide an expected class!"); } if (val instanceof BaseValue<?> && !BaseValue.class.isAssignableFrom(expected)) { return tryCast(((BaseValue<?>) val).get(), expected); } if (val instanceof Supplier) { Supplier<?> fun = (Supplier<?>) val; return tryCast(fun.get(), expected); } if (Text.class.isAssignableFrom(expected)) { if (val instanceof Text) { return TypeUtils.tryOptional(() -> expected.cast(val)); } else { if (val instanceof ItemStack) { return TypeUtils.tryOptional(() -> expected.cast(TextUtils.ofItem((ItemStack) val))); } if (val instanceof Instant) { return TypeUtils.tryOptional(() -> expected.cast(TextSerializers.FORMATTING_CODE .deserialize(PlaceholderAPIPlugin.getInstance().formatter() .format(LocalDateTime.ofInstant((Instant) val, ZoneId.systemDefault()))))); } if (val instanceof Duration) { String dur = formatDuration((Duration) val); return TypeUtils .tryOptional(() -> expected.cast(TextSerializers.FORMATTING_CODE.deserialize(dur))); } if (val instanceof LocalDateTime) { return TypeUtils.tryOptional(() -> expected.cast(TextSerializers.FORMATTING_CODE.deserialize( PlaceholderAPIPlugin.getInstance().formatter().format((LocalDateTime) val)))); } if (val instanceof CommandSource) { return TypeUtils.tryOptional(() -> expected.cast(TextSerializers.FORMATTING_CODE .deserialize(String.valueOf(((CommandSource) val).getName())))); } if (val.getClass().isArray()) { List<Text> l2 = unboxPrimitiveArray(val).stream() .map(o -> tryCast(o, (Class<? extends Text>) expected)).flatMap(unmapOptional()) .collect(Collectors.toList()); return TypeUtils.tryOptional(() -> expected.cast(Text.joinWith(Text.of(", "), l2))); } if (val instanceof Iterable) { Iterable<?> l = (Iterable<?>) val; // should be safe cause we already checked assignability @SuppressWarnings("serial") final List<Text> l2 = new ArrayList<Object>() { { for (Object o : l) { add(o); } } }.stream().map(o -> tryCast(o, (Class<? extends Text>) expected)).flatMap(unmapOptional()) .collect(Collectors.toList()); return TypeUtils.tryOptional(() -> expected.cast(Text.joinWith(Text.of(", "), l2))); } return TypeUtils.tryOptional( () -> expected.cast(TextSerializers.FORMATTING_CODE.deserialize(String.valueOf(val)))); } } if (val instanceof String) { if (String.class.isAssignableFrom(expected)) { return tryOptional(() -> expected.cast(val)); } if (expected.isArray() && String.class.isAssignableFrom(expected.getComponentType())) { String v = (String) val; if (v.isEmpty()) { return Optional.empty(); } if (!v.contains("_")) { return tryOptional(() -> expected.cast(new String[] { v })); } String[] x = v.split("_"); if (x.length == 0) { return Optional.empty(); } boolean ne = false; for (String s : x) { ne = ne || !s.isEmpty(); } if (!ne) { return Optional.empty(); } return tryOptional(() -> expected.cast(x)); } if (List.class.isAssignableFrom(expected) && String.class.isAssignableFrom(expected.getTypeParameters()[0].getGenericDeclaration())) { String v = (String) val; if (v.isEmpty()) { return Optional.empty(); } if (!v.contains("_")) { return tryOptional(() -> expected.cast(Collections.singletonList(v))); } String[] x = v.split("_"); if (x.length == 0) { return Optional.empty(); } boolean ne = false; for (String s : x) { ne = ne || !s.isEmpty(); } if (!ne) { return Optional.empty(); } return tryOptional(() -> expected.cast(Arrays.asList(x))); } Optional<T> opt = tryOptional(() -> convertPrimitive((String) val, expected)); if (opt.isPresent()) { return opt; } opt = deserializers.entrySet().stream() .filter(e -> e.getKey().isSubtypeOf(expected) || e.getKey().getRawType().equals(expected)) .map(Map.Entry::getValue).map(f -> tryOptional(() -> f.apply((String) val))) .flatMap(unmapOptional()).findAny().flatMap(o -> tryOptional(() -> expected.cast(o))); if (opt.isPresent()) { return opt; } try { // should theoretically match any string -> object conversions, such as deser // for now im filtering against method names as well just to avoid issues where // expected result is not obtained due to weird methods, might change in future Method method = Arrays.stream(expected.getDeclaredMethods()) .filter(m -> Modifier.isStatic(m.getModifiers()) && Modifier.isPublic(m.getModifiers())) .filter(m -> Arrays.stream(m.getParameterTypes()).anyMatch(c -> c.equals(String.class))) .filter(m -> m.getReturnType().equals(expected) || m.getReturnType().equals(Optional.class)) .filter(m -> STRING_TO_VAL_PATTERN.matcher(m.getName()).find()).findAny().get(); // error if no Object valout = method.invoke(null, (String) val); if (valout == null) { return Optional.empty(); } if (expected.isInstance(valout)) { // Register a new deserializer once we confirm it works. Should prevent // extremely long parsing from happening multiple times. final MethodHandle mh = MethodHandles.publicLookup().unreflect(method); PlaceholderServiceImpl.get().registerTypeDeserializer(TypeToken.of(expected), str -> { try { return expected.cast(mh.invokeExact((String) val)); } catch (Throwable e1) { throw new RuntimeException(e1); } }); return tryOptional(() -> expected.cast(valout)); } if (valout instanceof Optional) { Optional<?> valopt = (Optional<?>) valout; if (!valopt.isPresent()) { return Optional.empty(); } Object v = valopt.get(); if (expected.isInstance(v)) { // Register a new deserializer once we confirm it works. Should prevent // extremely long parsing from happening multiple times. final MethodHandle mh = MethodHandles.publicLookup().unreflect(method); PlaceholderServiceImpl.get().registerTypeDeserializer(TypeToken.of(expected), str -> { try { Optional<?> optx = (Optional<?>) mh.invokeExact((String) val); return expected.cast(optx.get()); } catch (Throwable e1) { throw new RuntimeException(e1); } }); return tryOptional(() -> expected.cast(v)); } else { return Optional.empty(); } } return Optional.empty(); } catch (Exception e) { // fires if no method found, if invoke throws, if something else goes wrong return Optional.empty(); } } return TypeUtils.tryOptional(() -> expected.cast(val)); }
From source file:com.almende.eve.protocol.jsonrpc.JSONRpc.java
/** * Invoke a method on an object.//from www . j a v a 2s . c om * * @param destination * the destination * @param request * A request in JSON-RPC format * @param requestParams * Optional request parameters * @param auth * the auth * @return the jSON response */ public static JSONResponse invoke(final Object destination, final JSONRequest request, final RequestParams requestParams, final Authorizor auth) { final JSONResponse resp = new JSONResponse(request.getId(), null); try { final CallTuple tuple = NamespaceUtil.get(destination, request.getMethod()); final Object realDest = tuple.getDestination(); final AnnotatedMethod annotatedMethod = tuple.getMethod(); if (!isAvailable(annotatedMethod, realDest, requestParams, auth)) { throw new JSONRPCException(JSONRPCException.CODE.METHOD_NOT_FOUND, "Method '" + request.getMethod() + "' not found. The method does not exist or you are not authorized."); } final MethodHandle methodHandle = annotatedMethod.getMethodHandle(); final Method method = annotatedMethod.getActualMethod(); Object result; if (Defines.HASMETHODHANDLES) { final Object[] params = castParams(realDest, request.getParams(), annotatedMethod.getParams(), requestParams); result = methodHandle.invokeExact(params); } else { final Object[] params = castParams(request.getParams(), annotatedMethod.getParams(), requestParams); result = method.invoke(realDest, params); } if (result == null) { result = JOM.createNullNode(); } resp.setResult(result); } catch (final JSONRPCException err) { resp.setError(err); } catch (final Throwable err) { final Throwable cause = err.getCause(); if (cause instanceof JSONRPCException) { resp.setError((JSONRPCException) cause); } else { if (err instanceof InvocationTargetException && cause != null) { LOG.log(Level.WARNING, "Exception raised, returning its cause as JSONRPCException. Request:" + request, cause); final JSONRPCException jsonError = new JSONRPCException(JSONRPCException.CODE.INTERNAL_ERROR, getMessage(cause), cause); jsonError.setData(cause); resp.setError(jsonError); } else { LOG.log(Level.WARNING, "Exception raised, returning it as JSONRPCException. Request:" + request, err); final JSONRPCException jsonError = new JSONRPCException(JSONRPCException.CODE.INTERNAL_ERROR, getMessage(err), err); jsonError.setData(err); resp.setError(jsonError); } } } if (resp.getId() == null || resp.getId().isNull()) { return null; } else { return resp; } }
From source file:com.almende.eve.rpc.jsonrpc.JSONRPC.java
/** * Invoke a method on an object.//www. j a v a2 s. c o m * * @param destination * the destination * @param request * A request in JSON-RPC format * @param requestParams * Optional request parameters * @param auth * the auth * @return the jSON response */ public static JSONResponse invoke(final Object destination, final JSONRequest request, final RequestParams requestParams, final JSONAuthorizor auth) { final JSONResponse resp = new JSONResponse(request.getId(), null); try { final CallTuple tuple = NamespaceUtil.get(destination, request.getMethod()); final Object realDest = tuple.getDestination(); final AnnotatedMethod annotatedMethod = tuple.getMethod(); if (!isAvailable(annotatedMethod, realDest, requestParams, auth)) { throw new JSONRPCException(JSONRPCException.CODE.METHOD_NOT_FOUND, "Method '" + request.getMethod() + "' not found. The method does not exist or you are not authorized."); } final MethodHandle methodHandle = annotatedMethod.getMethodHandle(); final Method method = annotatedMethod.getActualMethod(); Object result; if (USEMETHODHANDLE) { final Object[] params = castParams(realDest, request.getParams(), annotatedMethod.getParams(), requestParams); result = methodHandle.invokeExact(params); } else { final Object[] params = castParams(request.getParams(), annotatedMethod.getParams(), requestParams); result = method.invoke(realDest, params); } if (result == null) { result = JOM.createNullNode(); } resp.setResult(result); } catch (final JSONRPCException err) { resp.setError(err); } catch (final Throwable err) { final Throwable cause = err.getCause(); if (cause instanceof JSONRPCException) { resp.setError((JSONRPCException) cause); } else { if (err instanceof InvocationTargetException && cause != null) { LOG.log(Level.WARNING, "Exception raised, returning its cause as JSONRPCException. Request:" + request, cause); final JSONRPCException jsonError = new JSONRPCException(JSONRPCException.CODE.INTERNAL_ERROR, getMessage(cause), cause); jsonError.setData(cause); resp.setError(jsonError); } else { LOG.log(Level.WARNING, "Exception raised, returning it as JSONRPCException. Request:" + request, err); final JSONRPCException jsonError = new JSONRPCException(JSONRPCException.CODE.INTERNAL_ERROR, getMessage(err), err); jsonError.setData(err); resp.setError(jsonError); } } } return resp; }