All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.factoryfx.jetty.builder.ResourceBuilder Maven / Gradle / Ivy

There is a newer version: 3.2.1
Show newest version
package io.github.factoryfx.jetty.builder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

import org.glassfish.jersey.logging.LoggingFeature;

import com.fasterxml.jackson.databind.ObjectMapper;

import io.github.factoryfx.factory.AttributelessFactory;
import io.github.factoryfx.factory.FactoryBase;
import io.github.factoryfx.factory.builder.FactoryContext;
import io.github.factoryfx.factory.builder.FactoryTemplateId;
import io.github.factoryfx.factory.builder.FactoryTreeBuilder;
import io.github.factoryfx.factory.builder.Scope;
import io.github.factoryfx.jetty.AllExceptionMapper;
import io.github.factoryfx.jetty.DefaultObjectMapper;
import io.github.factoryfx.jetty.JerseyServletFactory;
import io.github.factoryfx.jetty.ServletAndPathFactory;
import io.github.factoryfx.jetty.Slf4LoggingFeature;
import jakarta.ws.rs.ext.ExceptionMapper;

/**
 * Builder for a jersey REST resource
 * @param  Rootfactory
 */
public class ResourceBuilder> {

    private String pathSpec="/*";
    private Map jerseyProperties=new HashMap<>();

    FactoryBase objectMapper= AttributelessFactory.create(DefaultObjectMapper.class);
    FactoryBase loggingFeature = AttributelessFactory.create(Slf4LoggingFeature.class);
    FactoryBase,R> exceptionMapper = AttributelessFactory.create(AllExceptionMapper.class);

    List> resources= new ArrayList<>();
    List> jaxrsComponents= new ArrayList<>();

    private FactoryTemplateId> servletAndPathFactoryTemplateId;
    private FactoryTemplateId> jerseyServletFactoryTemplateId;
    private FactoryTemplateId,R>> exceptionMapperTemplateId;
    private FactoryTemplateId> objectMapperTemplateId;
    private FactoryTemplateId> loggingFeatureTemplateId;

    public ResourceBuilder(FactoryTemplateId> factoryTemplateId) {
        this.servletAndPathFactoryTemplateId = factoryTemplateId;

        this.jerseyServletFactoryTemplateId = new FactoryTemplateId<>(servletAndPathFactoryTemplateId.name + "JerseyServlet", JerseyServletFactory.class);
        this.exceptionMapperTemplateId = new FactoryTemplateId<>(servletAndPathFactoryTemplateId.name + "ExceptionMapper", FactoryBase.class);
        this.objectMapperTemplateId = new FactoryTemplateId<>(servletAndPathFactoryTemplateId.name + "ObjectMapper", FactoryBase.class);
        this.loggingFeatureTemplateId = new FactoryTemplateId<>(servletAndPathFactoryTemplateId.name + "LoggingFeature", FactoryBase.class);
    }

    /**
     * set the base pathSpec for resources default is: /*
     * @param pathSpec servlet pathSpec
     * @return builder
     */
    public ResourceBuilder withPathSpec(String pathSpec){
        this.pathSpec=pathSpec;
        return this;
    }

    /**
     * jersey properties {@link org.glassfish.jersey.server.ResourceConfig#addProperties}
     * @param jerseyProperties properties e.g (ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true)
     * @return builder
     */
    public ResourceBuilder withJerseyProperties(Map jerseyProperties){
        this.jerseyProperties=jerseyProperties;
        return this;
    }

    /**
     * add resource factory, resource is a class with jaxrs annotations
     * @param resource resource factory
     * @return builder
     */
    public ResourceBuilder withResource(FactoryBase resource){
        resources.add(resource);
        return this;
    }

    /**
     * jaxrs component is comparable to resource but is more generalised e.g. MessageBodyWriter
     * @param jaxrsComponent jaxrsComponent
     * @return builder
     */
    public ResourceBuilder withJaxrsComponent(FactoryBase jaxrsComponent){
        jaxrsComponents.add(jaxrsComponent);
        return this;
    }

    /**
     * configure the REST logging default: {@link Slf4LoggingFeature}
     * @param loggingFeature exceptionMapper factory, shortcut {@code withLoggingFeature(AttributelessFactory.create(Slf4LoggingFeature.class))}
     * @return builder
     */
    public ResourceBuilder withLoggingFeature(FactoryBase loggingFeature){
        this.loggingFeature =loggingFeature;
        return this;
    }

    /**
     * set objectMapper used for all resources default: {@link DefaultObjectMapper}
     * @param objectMapper objectMapper factory, shortcut {@code withObjectMapper(AttributelessFactory.create(DefaultObjectMapper.class))}
     * @return builder
     */
    public ResourceBuilder withObjectMapper(FactoryBase objectMapper){
        this.objectMapper=objectMapper;
        return this;
    }

    /**
     * set the exceptionMapper for all resources. (maps exception to http response)
     * @param exceptionMapper exceptionMapper factory, shortcut {@code withExceptionMapper(AttributelessFactory.create(AllExceptionMapper.class))}
     * @return builder
     */
    public ResourceBuilder withExceptionMapper(FactoryBase,R> exceptionMapper) {
        this.exceptionMapper =exceptionMapper;
        return this;
    }

    FactoryTemplateId> getServletAndPathFactoryTemplateId(){
        return servletAndPathFactoryTemplateId;
    }

    boolean match(ResourceBuilder resourceBuilder) {
        return this.pathSpec.equals(resourceBuilder.pathSpec);
    }

    private > void addFactory(FactoryTreeBuilder builder, FactoryTemplateId templateId, Scope scope, Function, F> creator){
        builder.removeFactory(templateId);
        builder.addFactory(templateId,scope,creator);
    }

    void build(FactoryTreeBuilder builder) {
        addFactory(builder,servletAndPathFactoryTemplateId, Scope.PROTOTYPE, (ctx) -> {
            ServletAndPathFactory servletAndPathFactory = new ServletAndPathFactory<>();
            servletAndPathFactory.pathSpec.set(pathSpec);
            servletAndPathFactory.servlet.set(ctx.get(jerseyServletFactoryTemplateId));
            return servletAndPathFactory;
        });


        addFactory(builder,jerseyServletFactoryTemplateId, Scope.PROTOTYPE, (ctx) -> {
            JerseyServletFactory jerseyServlet = new JerseyServletFactory<>();
            jerseyServlet.exceptionMapper.set(ctx.get(exceptionMapperTemplateId));
            jerseyServlet.objectMapper.set(ctx.get(objectMapperTemplateId));
            jerseyServlet.restLogging.set(ctx.get(loggingFeatureTemplateId));
            jerseyServlet.jerseyProperties.set(jerseyProperties);

            jerseyServlet.resources.addAll(resources);
            jerseyServlet.additionalJaxrsComponents.addAll(jaxrsComponents);
            return jerseyServlet;
        });

        addFactory(builder,exceptionMapperTemplateId, Scope.PROTOTYPE, (ctx) -> exceptionMapper);

        addFactory(builder,objectMapperTemplateId, Scope.PROTOTYPE, (ctx) -> objectMapper);

        addFactory(builder,loggingFeatureTemplateId, Scope.PROTOTYPE, (ctx) -> loggingFeature);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy