* @throws ProcessingException (possibly {@link MappableException mappable})
* container exception in case the invocation failed.
*/
final Object invoke(final Object resource, final Object... args) throws ProcessingException {
try {
final ConfiguredValidator validator = validatorProvider.get();
// Validate resource class & method input parameters.
if (validator != null) {
validator.validateResourceAndInputParams(resource, resourceMethod, args);
}
final ContainerRequest containerRequest = request.get();
final PrivilegedAction invokeMethodAction = new PrivilegedAction() {
@Override
public Object run() {
final TracingLogger tracingLogger = TracingLogger.getInstance(containerRequest);
final long timestamp = tracingLogger.timestamp(ServerTraceEvent.METHOD_INVOKE);
try {
return methodHandler.invoke(resource, method, args);
} catch (IllegalAccessException ex) {
throw new ProcessingException(LocalizationMessages.ERROR_RESOURCE_JAVA_METHOD_INVOCATION(), ex);
} catch (IllegalArgumentException ex) {
throw new ProcessingException(LocalizationMessages.ERROR_RESOURCE_JAVA_METHOD_INVOCATION(), ex);
} catch (UndeclaredThrowableException ex) {
throw new ProcessingException(LocalizationMessages.ERROR_RESOURCE_JAVA_METHOD_INVOCATION(), ex);
} catch (InvocationTargetException ex) {
throw mapTargetToRuntimeEx(ex.getCause());
} catch (Throwable t) {
throw new ProcessingException(t);
} finally {
tracingLogger.logDuration(ServerTraceEvent.METHOD_INVOKE, timestamp, resource, method);
}
}
};
final SecurityContext securityContext = containerRequest.getSecurityContext();
final Object invocationResult = (securityContext instanceof SubjectSecurityContext) ?
((SubjectSecurityContext) securityContext).doAsSubject(invokeMethodAction) : invokeMethodAction.run();
// Validate response entity.
if (validator != null) {
validator.validateResult(resource, resourceMethod, invocationResult);
}
return invocationResult;
} catch (ValidationException ex) { // handle validation exceptions -> potentially mappable
throw new MappableException(ex);