
com.zandero.rest.RestRouter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rest.vertx Show documentation
Show all versions of rest.vertx Show documentation
JAX-RS REST annotation processor for vert.x verticals
The newest version!
package com.zandero.rest;
import com.zandero.rest.authentication.*;
import com.zandero.rest.authorization.*;
import com.zandero.rest.bean.*;
import com.zandero.rest.cache.*;
import com.zandero.rest.context.*;
import com.zandero.rest.data.*;
import com.zandero.rest.events.*;
import com.zandero.rest.exception.*;
import com.zandero.rest.injection.*;
import com.zandero.rest.reader.*;
import com.zandero.rest.writer.*;
import com.zandero.utils.*;
import io.vertx.core.*;
import io.vertx.core.http.*;
import io.vertx.ext.auth.*;
import io.vertx.ext.auth.authorization.*;
import io.vertx.ext.web.*;
import io.vertx.ext.web.handler.*;
import org.slf4j.*;
import javax.validation.*;
import javax.validation.executable.*;
import java.lang.reflect.*;
import java.util.*;
import static com.zandero.rest.data.ClassUtils.*;
/**
* Builds up a vert.x route based on JAX-RS annotation provided in given class
*/
public class RestRouter {
public static final int ORDER_CORS_HANDLER = -10;
public static final int ORDER_PROVIDER_HANDLER = -5;
private final static Logger log = LoggerFactory.getLogger(RestRouter.class);
private static final ClassForge forge = new ClassForge();
private static final RestEventExecutor eventExecutor = new RestEventExecutor();
private static BeanProvider beanProvider = new DefaultBeanProvider();
@Deprecated(forRemoval = true)
private static javax.validation.Validator validator;
private static jakarta.validation.Validator jakartaValidator;
private static BodyHandler bodyHandler;
/**
* Default authentication / credential and authorization providers
* Used in case no other provider is defined
*/
private static RestAuthenticationProvider defaultAuthenticationProvider;
private static AuthorizationProvider defaultAuthorizationProvider;
/**
* Searches for annotations to register routes ...
*
* @param vertx Vert.X instance
* @param restApi instance to search for annotations
* @return Router new Router with routes as defined in {@code restApi} class
*/
public static Router register(Vertx vertx, Object... restApi) {
Assert.notNull(vertx, "Missing vertx!");
Router router = Router.router(vertx);
return register(router, restApi);
}
/**
* Searches for annotations to register routes ...
*
* @param restApi instance to search for annotations
* @param router to add additional routes from {@code restApi} class
* @return Router with routes as defined in {@code restApi} class
*/
public static Router register(Router router, Object... restApi) {
Assert.notNull(router, "Missing vertx router!");
Assert.isTrue(restApi != null && restApi.length > 0, "Missing REST API class object!");
for (Object api : restApi) {
if (api == null) {
continue;
}
// check if api is an instance of a class or a class type
if (api instanceof Class) {
Class> inspectApi = (Class>) api;
try {
api = ClassFactory.newInstanceOf(inspectApi, getInjectionProvider(), null);
} catch (ClassFactoryException | ContextException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
// if handler than only register and move on
if (api instanceof Handler) {
handler(router, (Handler) api);
continue;
}
// REST endpoints
// Since version 4.3 - handler order must confirm to following order
// PLATFORM: platform handlers (LoggerHandler, FaviconHandler, etc.)
// SECURITY_POLICY: HTTP Security policies (CSPHandler, CorsHandler, etc.)
// BODY: Body parsing (BodyHandler)
// AUTHENTICATION: Authn (JWTAuthHandler, APIKeyHandler, WebauthnHandler, etc.)
// INPUT_TRUST: Input verification (CSRFHandler)
// AUTHORIZATION: Authz (AuthorizationHandler)
//
Map definitions = AnnotationProcessor.get(api.getClass());
for (RouteDefinition definition : definitions.keySet()) {
// bind method execution
Route route;
if (definition.pathIsRegEx()) {
route = router.routeWithRegex(definition.getMethod(), definition.getRoutePath());
} else {
route = router.route(definition.getMethod(), definition.getRoutePath());
}
//
log.info("Registering route: " + definition);
if (definition.getOrder() != 0) {
route.order(definition.getOrder());
}
// add BodyHandler in case request has a body ...
if (definition.requestHasBody()) {
if (bodyHandler == null) {
route.handler(BodyHandler.create());
log.debug("Adding default body handler to route!");
} else {
route.handler(bodyHandler);
log.debug("Adding provided body handler to route!");
}
}
// check body and reader compatibility beforehand
checkBodyReader(definition);
// each route gets ist definition provided via context provider
ContextProvider definitionHandler = request -> definition;
route.handler(getContextHandler(definitionHandler));
//
if (definition.requestHasBody() && definition.getConsumes() != null) { // only register if request with body
for (MediaType item : definition.getConsumes()) {
route.consumes(MediaTypeHelper.getKey(item)); // ignore charset when binding
}
}
if (definition.getProduces() != null) {
for (MediaType item : definition.getProduces()) {
route.produces(MediaTypeHelper.getKey(item)); // ignore charset when binding
}
}
// Authentication
if (definition.getAuthenticationProvider() != null || defaultAuthenticationProvider != null) {
route.handler(getAuthenticationProvider(definition.getAuthenticationProvider(),
definition));
}
// Authorization
if (definition.getAuthorizationProvider() != null || defaultAuthorizationProvider != null) {
route.handler(getAuthorizationHandler(definition.getAuthorizationProvider(),
definition));
} else if (definition.checkSecurity()) {
// for back compatibility purposes
// add security check handler in front of regular route handler
// (in case @PermitAll, @DenyAll or @RolesAllowed is used)
route.handler(getAuthorizationHandler(RoleBasedUserAuthorizationProvider.class,
definition));
}
// bind handler // blocking or async
Handler handler;
Method method = definitions.get(definition);
if (definition.isAsync()) {
handler = getAsyncHandler(api, definition, method);
} else {
checkWriterCompatibility(definition);
handler = getHandler(api, definition, method);
}
route.handler(handler);
}
}
return router;
}
private static void checkWriterCompatibility(RouteDefinition definition) {
try { // no way to know the accept content at this point
forge.getResponseWriter(definition.getReturnType(), definition, null);
} catch (ClassFactoryException e) {
// ignoring instance creation ... but leaving Illegal argument exceptions to pass
}
}
public static void provide(Router output, Class extends ContextProvider>> provider) {
try {
Class> clazz = (Class>) getGenericType(provider);
ContextProvider> instance = getContextProviders().getContextProvider(getInjectionProvider(),
clazz,
provider,
null);
// set before other routes ...
output.route().order(ORDER_PROVIDER_HANDLER).handler(getContextHandler(instance));
} catch (Throwable e) {
throw new IllegalArgumentException(e);
}
}
public static void provide(Router output, ContextProvider> provider) {
output.route().order(ORDER_PROVIDER_HANDLER).handler(getContextHandler(provider));
}
private static Handler getContextHandler(ContextProvider> instance) {
return context -> {
if (instance != null) {
try {
Object provided = instance.provide(context.request());
if (provided instanceof User) {
context.setUser((User) provided);
}
if (provided instanceof Session) {
context.setSession((Session) provided);
}
if (provided != null) { // push provided context into request data
context.data().put(ContextProviderCache.getContextDataKey(provided), provided);
}
} catch (Throwable e) {
handleException(e, context, null); // no definition
}
}
context.next();
};
}
@SuppressWarnings("unchecked")
public static void handler(Router output, Class extends Handler> handler) {
try {
Handler instance = (Handler) ClassFactory.newInstanceOf(handler, getInjectionProvider(), null);
output.route().handler(instance);
} catch (ClassFactoryException | ContextException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
public static void handler(Router output, Handler handler) {
output.route().handler(handler);
}
/**
* Handles not found route for all requests
*
* @param router to add route to
* @param notFound handler
*/
public static void notFound(Router router, Class extends NotFoundResponseWriter> notFound) {
notFound(router, null, notFound);
}
/**
* Handles not found route for all requests
*
* @param router to add route to
* @param notFound handler
*/
public static void notFound(Router router, NotFoundResponseWriter notFound) {
notFound(router, null, notFound);
}
/**
* Handles not found route in case request regExPath mathes given regExPath prefix
*
* @param router to add route to
* @param regExPath prefix
* @param notFound handler
*/
public static void notFound(Router router, String regExPath, NotFoundResponseWriter notFound) {
Assert.notNull(router, "Missing router!");
Assert.notNull(notFound, "Missing not found handler!");
addLastHandler(router, regExPath, getNotFoundHandler(notFound));
}
/**
* Handles not found route in case request regExPath mathes given regExPath prefix
*
* @param router to add route to
* @param regExPath prefix
* @param notFound hander
*/
public static void notFound(Router router, String regExPath, Class extends NotFoundResponseWriter> notFound) {
Assert.notNull(router, "Missing router!");
Assert.notNull(notFound, "Missing not found handler!");
addLastHandler(router, regExPath, getNotFoundHandler(notFound));
}
private static void addLastHandler(Router router, String path, Handler notFoundHandler) {
if (path == null) {
router.route().last().handler(notFoundHandler);
} else {
router.routeWithRegex(path).last().handler(notFoundHandler);
}
}
/**
* @param router to add handler to
* @param allowedOriginPattern origin pattern
* @param allowCredentials allowed credentials
* @param maxAge in seconds
* @param allowedHeaders set of headers or null for none
* @param methods list of methods or empty for all
*/
public static void enableCors(Router router,
String allowedOriginPattern,
boolean allowCredentials,
int maxAge,
Set allowedHeaders,
HttpMethod... methods) {
CorsHandler handler = CorsHandler.create(allowedOriginPattern)
.allowCredentials(allowCredentials)
.maxAgeSeconds(maxAge);
if (methods == null || methods.length == 0) { // if not given than all
methods = HttpMethod.values().toArray(new HttpMethod[]{});
}
for (HttpMethod method : methods) {
handler.allowedMethod(method);
}
handler.allowedHeaders(allowedHeaders);
router.route().order(ORDER_CORS_HANDLER).handler(handler);
}
public static void authenticateWith(Class extends RestAuthenticationProvider> provider) {
try {
Assert.notNull(provider, "Missing authorization provider!");
Assert.isNull(defaultAuthenticationProvider, "Default authentication provider already defined!");
defaultAuthenticationProvider = getAuthenticationProviders().provide(provider, getInjectionProvider(), null);
} catch (Throwable e) {
throw new IllegalArgumentException(e);
}
}
public static void authenticateWith(RestAuthenticationProvider provider) {
Assert.notNull(provider, "Missing authorization provider!");
Assert.isNull(defaultAuthenticationProvider, "Default authentication provider already defined!");
defaultAuthenticationProvider = provider;
}
public static void authorizeWith(Class extends AuthorizationProvider> provider) {
try {
Assert.notNull(provider, "Missing authorization provider!");
Assert.isNull(defaultAuthorizationProvider, "Default authorization provider already defined!");
defaultAuthorizationProvider = getAuthorizationProviders().provide(provider, getInjectionProvider(), null);
} catch (Throwable e) {
throw new IllegalArgumentException(e);
}
}
public static void authorizeWith(AuthorizationProvider provider) {
Assert.notNull(provider, "Missing authorization provider!");
Assert.isNull(defaultAuthorizationProvider, "Default authorization provider already defined!");
defaultAuthorizationProvider = provider;
}
private static void checkBodyReader(RouteDefinition definition) {
if (!definition.requestCanHaveBody() || !definition.hasBodyParameter()) {
return;
}
ValueReader> bodyReader = getReaders().get(definition.getBodyParameter(),
definition.getReader(),
getInjectionProvider(),
null,
definition.getConsumes());
if (bodyReader != null && definition.checkCompatibility()) {
Type readerType = getGenericType(bodyReader.getClass());
MethodParameter bodyParameter = definition.getBodyParameter();
checkIfCompatibleType(bodyParameter.getDataType(), readerType,
definition.toString().trim() + " - Parameter type: '" +
bodyParameter.getDataType() + "' not matching reader type: '" +
readerType + "' in: '" + bodyReader.getClass() + "'!");
}
}
private static Handler getAuthenticationProvider(Class extends RestAuthenticationProvider> authenticatorProviderClass,
RouteDefinition definition) {
return context -> {
try {
RestAuthenticationProvider authenticator = authenticatorProviderClass != null ?
getAuthenticationProviders().provide(authenticatorProviderClass, getInjectionProvider(), context) :
defaultAuthenticationProvider;
authenticator.authenticate(context, userAsyncResult -> {
if (userAsyncResult.failed()) {
Throwable ex = (userAsyncResult.cause() != null ?
userAsyncResult.cause() :
new UnauthorizedException(context.user()));
handleException(ex, context, definition);
} else {
context.setUser(userAsyncResult.result());
context.next();
}
});
} catch (Throwable e) {
log.error("Authentication failed: " + e.getMessage(), e);
handleException(e, context, definition);
}
};
}
private static Handler getAuthorizationHandler(Class extends AuthorizationProvider> providerClass, RouteDefinition definition) {
return context -> {
try {
AuthorizationProvider provider = providerClass != null ?
getAuthorizationProviders().provide(providerClass, getInjectionProvider(), context) :
defaultAuthorizationProvider;
provider.getAuthorizations(context.user(), userAuthorizationResult -> {
if (userAuthorizationResult.failed()) {
Throwable ex = (userAuthorizationResult.cause() != null ?
userAuthorizationResult.cause() :
new ForbiddenException(context.user()));
handleException(ex, context, definition);
} else {
context.next();
}
});
} catch (Throwable e) {
log.error("Authorization failed: " + e.getMessage(), e);
handleException(e, context, definition);
}
};
}
private static Handler getHandler(final Object toInvoke, final RouteDefinition definition, final Method method) {
return context -> context.vertx().executeBlocking(
fut -> {
try {
log.info(definition.getMethod().name() + " " + definition.getPath());
Object[] args = ArgumentProvider.getArguments(method,
definition,
context,
getReaders(),
getContextProviders(),
getInjectionProvider(),
beanProvider);
// TODO: remove on next version
if (validator != null) {
validate(method, definition, validator, toInvoke, args);
}
if (jakartaValidator != null) {
validate(method, definition, jakartaValidator, toInvoke, args);
}
fut.complete(method.invoke(toInvoke, args));
} catch (Throwable e) {
fut.fail(e);
}
},
definition.executeBlockingOrdered(), // false by default
res -> {
if (res.succeeded()) {
try {
Object result = res.result();
Class returnType = result != null ? result.getClass() : definition.getReturnType();
HttpResponseWriter writer = forge.getResponseWriter(returnType,
definition,
context);
// TODO: to be removed
if (validator != null) {
validateResult(result, method, definition, validator, toInvoke);
}
if (jakartaValidator != null) {
validateResult(result, method, definition, jakartaValidator, toInvoke);
}
produceResponse(result, context, definition, writer);
} catch (Throwable e) {
handleException(e, context, definition);
}
} else {
handleException(res.cause(), context, definition);
}
}
);
}
private static Handler getAsyncHandler(final Object toInvoke, final RouteDefinition definition, final Method method) {
return context -> {
try {
log.info(definition.getMethod().name() + " " + definition.getPath());
Object[] args = ArgumentProvider.getArguments(method, definition, context, getReaders(), getContextProviders(), getInjectionProvider(), beanProvider);
if (validator != null) {
validate(method, definition, validator, toInvoke, args);
}
if (jakartaValidator != null) {
validate(method, definition, jakartaValidator, toInvoke, args);
}
Object result = method.invoke(toInvoke, args);
// get future from promise ...
if (result instanceof Promise) {
Promise> pro = (Promise) result;
result = pro.future();
}
if (result instanceof Future) {
Future> fut = (Future) result;
// wait for future to complete ... don't block vertx event bus in the mean time
fut.onComplete(handler -> {
if (fut.succeeded()) {
try {
Object futureResult = fut.result();
HttpResponseWriter writer;
if (futureResult != null) { // get writer from result type otherwise we don't know
writer = forge.getResponseWriter(futureResult.getClass(),
definition,
context);
} else { // due to limitations of Java generics we can't tell the type if response is null
Class> writerClass = definition.getWriter() == null ? GenericResponseWriter.class : definition.getWriter();
writer = (HttpResponseWriter) ClassFactory.newInstanceOf(writerClass);
}
// TODO: to be removed
if (validator != null) {
validateResult(futureResult, method, definition, validator, toInvoke);
}
if (jakartaValidator != null) {
validateResult(futureResult, method, definition, jakartaValidator, toInvoke);
}
produceResponse(futureResult, context, definition, writer);
} catch (Throwable e) {
handleException(e, context, definition);
}
} else {
handleException(fut.cause(), context, definition);
}
});
}
} catch (Throwable e) {
handleException(e, context, definition);
}
};
}
private static void validate(Method method, RouteDefinition definition, Validator validator, Object toInvoke, Object[] args) {
// check method params first (if any)
if (validator != null && args != null) {
ExecutableValidator executableValidator = validator.forExecutables();
Set> result = executableValidator.validateParameters(toInvoke, method, args);
if (result != null && !result.isEmpty()) {
throw new ConstraintException(definition, result);
}
}
}
private static void validateResult(Object result, Method method, RouteDefinition definition, Validator validator, Object toInvoke) {
if (validator != null) {
ExecutableValidator executableValidator = validator.forExecutables();
Set> validationResult = executableValidator.validateReturnValue(toInvoke, method, result);
if (validationResult != null && !validationResult.isEmpty()) {
throw new ConstraintException(definition, validationResult);
}
}
}
private static void validate(Method method, RouteDefinition definition, jakarta.validation.Validator validator, Object toInvoke, Object[] args) {
// check method params first (if any)
if (validator != null && args != null) {
jakarta.validation.executable.ExecutableValidator executableValidator = validator.forExecutables();
Set> result = executableValidator.validateParameters(toInvoke, method, args);
if (result != null && !result.isEmpty()) {
throw new ValidationConstraintException(definition, result);
}
}
}
private static void validateResult(Object result, Method method, RouteDefinition definition, jakarta.validation.Validator validator, Object toInvoke) {
if (validator != null) {
jakarta.validation.executable.ExecutableValidator executableValidator = validator.forExecutables();
Set> validationResult = executableValidator.validateReturnValue(toInvoke, method, result);
if (validationResult != null && !validationResult.isEmpty()) {
throw new ValidationConstraintException(definition, validationResult);
}
}
}
@SuppressWarnings("unchecked")
private static Handler getNotFoundHandler(Object notFoundWriter) {
return context -> {
try {
// fill up definition (response headers) from request
RouteDefinition definition = new RouteDefinition(context);
HttpResponseWriter> writer;
if (notFoundWriter instanceof Class) {
writer = (HttpResponseWriter>) ClassFactory.getClassInstance((Class extends HttpResponseWriter>>) notFoundWriter, getWriters(), getInjectionProvider(), context);
} else {
writer = (HttpResponseWriter>) notFoundWriter;
}
produceResponse(null, context, definition, writer);
} catch (Throwable e) {
handleException(e, context, null);
}
};
}
private static void handleException(Throwable e, RoutingContext context, final RouteDefinition definition) {
ExecuteException ex = getExecuteException(e);
// get appropriate exception handler/writer ...
ExceptionHandler handler;
try {
Class extends Throwable> clazz;
if (ex.getCause() == null) {
clazz = ex.getClass();
} else {
clazz = ex.getCause().getClass();
}
Class extends ExceptionHandler>[] exHandlers = null;
if (definition != null) {
exHandlers = definition.getExceptionHandlers();
}
handler = getExceptionHandlers().getExceptionHandler(clazz, exHandlers, getInjectionProvider(), context);
} catch (ClassFactoryException classException) {
// Can't provide exception handler ... rethrow
log.error("Can't provide exception handler!", classException);
// fall back to generic ...
handler = new GenericExceptionHandler();
ex = new ExecuteException(500, classException);
} catch (ContextException contextException) {
// Can't provide @Context for handler ... rethrow
log.error("Can't provide @Context!", contextException);
// fall back to generic ...
handler = new GenericExceptionHandler();
ex = new ExecuteException(500, contextException);
}
if (handler instanceof GenericExceptionHandler) {
log.error("Handling exception: ", e);
} else {
log.debug("Handling exception, with: " + handler.getClass().getName(), e);
}
HttpServerResponse response = context.response();
response.setStatusCode(ex.getStatusCode());
HttpServerRequest request = context.request();
MediaType accept = MediaTypeHelper.valueOf(request.getHeader(HttpHeaders.ACCEPT));
handler.addResponseHeaders(definition, accept, response);
try {
handler.write(ex.getCause(), request, response);
eventExecutor.triggerEvents(ex.getCause(), response.getStatusCode(), definition, context,
getInjectionProvider());
} catch (Throwable handlerException) {
// this should not happen
log.error("Failed to write out handled exception: " + e.getMessage(), e);
}
// end response ...
if (!response.ended()) {
response.end();
}
}
private static ExecuteException getExecuteException(Throwable e) {
if (e instanceof ExecuteException) {
ExecuteException ex = (ExecuteException) e;
return new ExecuteException(ex.getStatusCode(), ex.getMessage(), ex);
}
// unwrap invoke exception ...
if (e instanceof IllegalAccessException || e instanceof InvocationTargetException) {
if (e.getCause() != null) {
return getExecuteException(e.getCause());
}
}
if (e instanceof IllegalArgumentException) {
return new ExecuteException(400, e);
}
return new ExecuteException(500, e);
}
@SuppressWarnings("unchecked")
private static void produceResponse(Object result,
RoutingContext context,
RouteDefinition definition,
HttpResponseWriter writer) throws Throwable {
HttpServerResponse response = context.response();
HttpServerRequest request = context.request();
MediaType accept = MediaTypeHelper.valueOf(request.getHeader(HttpHeaders.ACCEPT));
// add default response headers per definition (or from writer definition)
writer.addResponseHeaders(definition, accept, response);
writer.write(result, request, response);
// find and trigger events from // result / response
eventExecutor.triggerEvents(result, response.getStatusCode(), definition, context, getInjectionProvider());
// finish if not finished by writer
// and is not an Async REST (Async RESTs must finish responses on their own)
if (!definition.isAsync() && !response.ended()) {
response.end();
}
}
public static WriterCache getWriters() {
return forge.getWriters();
}
public static ReaderCache getReaders() {
return forge.getReaders();
}
public static ExceptionHandlerCache getExceptionHandlers() {
return forge.getExceptionHandlers();
}
public static ContextProviderCache getContextProviders() {
return forge.getContextProviders();
}
public static AuthenticationProvidersCache getAuthenticationProviders() {
return forge.getAuthenticationProviders();
}
public static AuthorizationProvidersCache getAuthorizationProviders() {
return forge.getAuthorizationProviders();
}
public static InjectionProvider getInjectionProvider() {
return forge.getInjectionProvider();
}
/**
* Clears all cached classes and removes any associated validator and injection provider
* Intended for Unit tests only, should not be called in production code
*/
public static void clearCache() {
forge.clean();
defaultAuthorizationProvider = null;
defaultAuthenticationProvider = null;
validateWith((javax.validation.Validator) null);
validateWith((jakarta.validation.Validator) null);
injectWith((InjectionProvider) null);
}
/**
* Registers a context provider for given type of class
*
* @param provider clazz type to be registered
*/
public static void addProvider(Class extends ContextProvider>> provider) {
Class> clazz = (Class>) getGenericType(provider);
addProvider(clazz, provider);
}
public static void addProvider(Class> clazz, Class extends ContextProvider>> provider) {
Assert.notNull(clazz, "Missing provided class type!");
Assert.notNull(provider, "Missing provider class type!!");
getContextProviders().register(clazz, provider);
log.info("Registering '" + clazz + "' provider '" + provider.getName() + "'");
}
public static void addProvider(ContextProvider> provider) {
Class> clazz = (Class>) getGenericType(provider.getClass());
addProvider(clazz, provider);
}
public static void addProvider(Class> clazz, ContextProvider> provider) {
Assert.notNull(clazz, "Missing provider class type!");
Assert.notNull(provider, "Missing provider instance!");
getContextProviders().register(clazz, provider);
log.info("Registering '" + clazz + "' provider '" + provider.getClass().getName() + "'");
}
public static void pushContext(RoutingContext context, Object object) {
Assert.notNull(context, "Missing context!");
Assert.notNull(object, "Can't push null into context!");
context.put(ContextProviderCache.getContextDataKey(object), object);
}
/**
* Provide an injector to getInstance classes where needed
*
* @param provider to create/inject classes
*/
public static void injectWith(InjectionProvider provider) {
forge.setInjectionProvider(provider);
if (getInjectionProvider() != null) {
log.info("Registered injection provider: " + getInjectionProvider().getClass().getName());
} else {
log.info("No injection provider specified!");
}
}
/**
* Provide an injector to getInstance classes where needed
*
* @param provider class type
*/
public static void injectWith(Class provider) {
try {
forge.setInjectionProvider((InjectionProvider) ClassFactory.newInstanceOf(provider));
log.info("Registered injection provider: " + getInjectionProvider().getClass().getName());
} catch (ClassFactoryException e) {
log.error("Failed to instantiate injection provider: ", e);
throw new IllegalArgumentException(e);
}
}
/**
* Provide an injector to getInstance classes where needed
*
* @param provider to create/inject classes
*/
public static void provideWith(BeanProvider provider) {
beanProvider = provider;
if (beanProvider != null) {
log.info("Registered bean provider: " + beanProvider.getClass().getName());
} else {
log.info("No bean provider specified!");
}
}
/**
* Provide an injector to getInstance classes where needed
*
* @param provider class type
*/
public static void provideWith(Class provider) {
try {
beanProvider = (BeanProvider) ClassFactory.newInstanceOf(provider);
log.info("Registered bean provider: " + beanProvider.getClass().getName());
} catch (ClassFactoryException e) {
log.error("Failed to instantiate bean provider: ", e);
throw new IllegalArgumentException(e);
}
}
/**
* Provide an validator to validate arguments
*
* @param provider to validate
*/
@Deprecated(forRemoval = true)
public static void validateWith(Validator provider) {
validator = provider;
if (validator != null) {
log.info("Registered validation provider: " + validator.getClass().getName());
} else {
log.info("No validation provider specified!");
}
}
/**
* Provide an validator to validate arguments
*
* @param provider class type
*/
public static void validateWith(Class> provider) {
try {
Object newValidator = ClassFactory.newInstanceOf(provider);
if (newValidator instanceof Validator) {
validator = (Validator) newValidator;
}
else if (newValidator instanceof jakarta.validation.Validator) {
jakartaValidator = (jakarta.validation.Validator) ClassFactory.newInstanceOf(provider);
}
else {
throw new IllegalArgumentException("Invalid validator class type proivded, expecting either javax.validation.Validator or jakarta.validation.Validator");
}
log.info("Registered validation provider: " + newValidator.getClass().getName());
} catch (ClassFactoryException e) {
log.error("Failed to instantiate validation provider: ", e);
throw new IllegalArgumentException(e);
}
}
/**
* Provide an validator to validate arguments
*
* @param provider to validate
*/
public static void validateWith(jakarta.validation.Validator provider) {
jakartaValidator = provider;
if (jakartaValidator != null) {
log.info("Registered validation provider: " + jakartaValidator.getClass().getName());
} else {
log.info("No validation provider specified!");
}
}
public static void setBodyHandler(BodyHandler handler) {
if (bodyHandler != null) {
log.error("Body handler already defined, set body handler before any routes!");
return;
}
Assert.notNull(handler, "Missing body handler!");
bodyHandler = handler;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy