Java21 and some refactoring.
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			This commit is contained in:
		
							parent
							
								
									ba85f54b16
								
							
						
					
					
						commit
						dbdfb0c8a4
					
				
					 14 changed files with 101 additions and 87 deletions
				
			
		|  | @ -0,0 +1,9 @@ | |||
| package ch.fritteli.maze.server; | ||||
| 
 | ||||
| import org.wildfly.common.annotation.NotNull; | ||||
| 
 | ||||
| public class InvalidRequestParameterException extends RuntimeException { | ||||
|     public InvalidRequestParameterException(@NotNull final String s) { | ||||
|         super(s); | ||||
|     } | ||||
| } | ||||
|  | @ -6,17 +6,18 @@ import ch.fritteli.maze.server.handler.RenderV2Handler; | |||
| import io.undertow.Undertow; | ||||
| import io.undertow.server.RoutingHandler; | ||||
| import io.vavr.control.Try; | ||||
| import java.net.InetSocketAddress; | ||||
| import lombok.NonNull; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.wildfly.common.annotation.NotNull; | ||||
| 
 | ||||
| import java.net.InetSocketAddress; | ||||
| 
 | ||||
| @Slf4j | ||||
| public class MazeServer { | ||||
| 
 | ||||
|     @NonNull | ||||
|     @NotNull | ||||
|     private final Undertow undertow; | ||||
| 
 | ||||
|     private MazeServer(@NonNull final ServerConfig config) { | ||||
|     private MazeServer(@NotNull final ServerConfig config) { | ||||
|         final String hostAddress = config.getAddress().getHostAddress(); | ||||
|         final int port = config.getPort(); | ||||
|         log.info("Starting Server at http://{}:{}/", hostAddress, port); | ||||
|  | @ -31,14 +32,14 @@ public class MazeServer { | |||
|                 .build(); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     @NotNull | ||||
|     public static Try<MazeServer> createAndStartServer() { | ||||
|         return Try.of(ServerConfig::init) | ||||
|                 .flatMapTry(MazeServer::createAndStartServer); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     public static Try<MazeServer> createAndStartServer(@NonNull final ServerConfig config) { | ||||
|     @NotNull | ||||
|     public static Try<MazeServer> createAndStartServer(@NotNull final ServerConfig config) { | ||||
|         return Try.of(() -> new MazeServer(config)) | ||||
|                 .peek(MazeServer::start); | ||||
|     } | ||||
|  |  | |||
|  | @ -1,17 +1,17 @@ | |||
| package ch.fritteli.maze.server; | ||||
| 
 | ||||
| import ch.fritteli.maze.generator.model.Maze; | ||||
| import ch.fritteli.maze.generator.renderer.html.HTMLRenderer; | ||||
| import ch.fritteli.maze.generator.renderer.json.JsonRenderer; | ||||
| import ch.fritteli.maze.generator.renderer.pdf.PDFRenderer; | ||||
| import ch.fritteli.maze.generator.renderer.text.TextRenderer; | ||||
| import ch.fritteli.maze.generator.serialization.v1.SerializerDeserializerV1; | ||||
| import ch.fritteli.maze.generator.serialization.v2.SerializerDeserializerV2; | ||||
| import ch.fritteli.maze.generator.model.Maze; | ||||
| import io.vavr.collection.List; | ||||
| import io.vavr.collection.Stream; | ||||
| import io.vavr.control.Option; | ||||
| import lombok.Getter; | ||||
| import lombok.NonNull; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
| import org.jetbrains.annotations.Nullable; | ||||
| 
 | ||||
| import java.nio.charset.StandardCharsets; | ||||
|  | @ -67,24 +67,24 @@ public enum OutputType { | |||
|             "v", | ||||
|             "binaryv2"); | ||||
|     @Getter | ||||
|     @NonNull | ||||
|     @NotNull | ||||
|     private final String contentType; | ||||
|     @Getter | ||||
|     @NonNull | ||||
|     @NotNull | ||||
|     private final String fileExtension; | ||||
|     @NonNull | ||||
|     @NotNull | ||||
|     private final Function<Maze, byte[]> render; | ||||
|     @Getter | ||||
|     private final boolean attachment; | ||||
|     @Getter | ||||
|     @NonNull | ||||
|     @NotNull | ||||
|     private final List<String> names; | ||||
| 
 | ||||
|     OutputType(@NonNull final String contentType, | ||||
|                @NonNull final String fileExtension, | ||||
|                @NonNull final Function<Maze, byte[]> render, | ||||
|     OutputType(@NotNull final String contentType, | ||||
|                @NotNull final String fileExtension, | ||||
|                @NotNull final Function<Maze, byte[]> render, | ||||
|                final boolean attachment, | ||||
|                @NonNull final String... names) { | ||||
|                @NotNull final String... names) { | ||||
|         this.contentType = contentType; | ||||
|         this.render = render; | ||||
|         this.fileExtension = fileExtension; | ||||
|  | @ -92,7 +92,7 @@ public enum OutputType { | |||
|         this.names = List.of(names); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     @NotNull | ||||
|     public static Option<OutputType> ofString(@Nullable final String name) { | ||||
|         return Option.of(name) | ||||
|                 .map(String::toLowerCase) | ||||
|  | @ -101,14 +101,14 @@ public enum OutputType { | |||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     @NotNull | ||||
|     @Override | ||||
|     public String toString() { | ||||
|         return this.names.last(); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     public byte[] render(@NonNull final Maze maze) { | ||||
|     @NotNull | ||||
|     public byte[] render(@NotNull final Maze maze) { | ||||
|         return this.render.apply(maze); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -3,10 +3,10 @@ package ch.fritteli.maze.server; | |||
| import io.vavr.control.Try; | ||||
| import lombok.AccessLevel; | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.NonNull; | ||||
| import lombok.Value; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.jetbrains.annotations.Nullable; | ||||
| import org.wildfly.common.annotation.NotNull; | ||||
| 
 | ||||
| import java.net.InetAddress; | ||||
| 
 | ||||
|  | @ -17,7 +17,7 @@ public class ServerConfig { | |||
|     public static final String SYSPROP_HOST = "fritteli.maze.server.host"; | ||||
|     public static final String SYSPROP_PORT = "fritteli.maze.server.port"; | ||||
| 
 | ||||
|     @NonNull | ||||
|     @NotNull | ||||
|     InetAddress address; | ||||
|     int port; | ||||
| 
 | ||||
|  | @ -27,7 +27,7 @@ public class ServerConfig { | |||
|         log.debug("host={}, port={}", this.address, this.port); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     @NotNull | ||||
|     public static ServerConfig init() throws ConfigurationException { | ||||
|         final String host = System.getProperty(SYSPROP_HOST); | ||||
|         final String portString = System.getProperty(SYSPROP_PORT); | ||||
|  | @ -35,7 +35,7 @@ public class ServerConfig { | |||
|         return new ServerConfig(host, port); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     @NotNull | ||||
|     private static InetAddress validateAddress(@Nullable final String address) { | ||||
|         return Try.of(() -> InetAddress.getByName(address)) | ||||
|                 .getOrElseThrow(cause -> new ConfigurationException( | ||||
|  |  | |||
|  | @ -3,8 +3,8 @@ package ch.fritteli.maze.server.handler; | |||
| import io.undertow.server.HttpHandler; | ||||
| import io.undertow.server.HttpServerExchange; | ||||
| import io.undertow.util.StatusCodes; | ||||
| import lombok.NonNull; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
| import org.slf4j.MDC; | ||||
| 
 | ||||
| import java.time.Instant; | ||||
|  | @ -14,7 +14,7 @@ import java.util.UUID; | |||
| @Slf4j | ||||
| public abstract class AbstractHttpHandler implements HttpHandler { | ||||
|     @Override | ||||
|     public final void handleRequest(@NonNull final HttpServerExchange exchange) { | ||||
|     public final void handleRequest(@NotNull final HttpServerExchange exchange) { | ||||
|         final Instant start = Instant.now(); | ||||
|         try (final MDC.MDCCloseable closeable = MDC.putCloseable("correlationId", UUID.randomUUID().toString())) { | ||||
| 
 | ||||
|  | @ -25,7 +25,7 @@ public abstract class AbstractHttpHandler implements HttpHandler { | |||
|             } | ||||
|             try { | ||||
|                 this.handle(exchange); | ||||
|             } catch (@NonNull final Exception e) { | ||||
|             } catch (final Exception e) { | ||||
|                 log.error("Error handling request", e); | ||||
|                 exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR) | ||||
|                         .getResponseSender() | ||||
|  | @ -35,5 +35,5 @@ public abstract class AbstractHttpHandler implements HttpHandler { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     protected abstract void handle(@NonNull final HttpServerExchange exchange) throws Exception; | ||||
|     protected abstract void handle(@NotNull final HttpServerExchange exchange) throws Exception; | ||||
| } | ||||
|  |  | |||
|  | @ -1,21 +1,22 @@ | |||
| package ch.fritteli.maze.server.handler; | ||||
| 
 | ||||
| import ch.fritteli.maze.server.OutputType; | ||||
| import ch.fritteli.maze.generator.model.Maze; | ||||
| import ch.fritteli.maze.server.InvalidRequestParameterException; | ||||
| import ch.fritteli.maze.server.OutputType; | ||||
| import io.undertow.server.HttpServerExchange; | ||||
| import io.undertow.util.Headers; | ||||
| import io.undertow.util.HttpString; | ||||
| import io.undertow.util.StatusCodes; | ||||
| import io.vavr.Tuple2; | ||||
| import io.vavr.control.Try; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
| import org.slf4j.MDC; | ||||
| 
 | ||||
| import java.nio.ByteBuffer; | ||||
| import java.time.Instant; | ||||
| import java.time.temporal.ChronoUnit; | ||||
| import java.util.Deque; | ||||
| import java.util.Map; | ||||
| import lombok.NonNull; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.slf4j.MDC; | ||||
| 
 | ||||
| @Slf4j | ||||
| public class CreateHandler extends AbstractHttpHandler { | ||||
|  | @ -23,27 +24,29 @@ public class CreateHandler extends AbstractHttpHandler { | |||
|     public static final String PATH_TEMPLATE = "/create/{output}"; | ||||
| 
 | ||||
|     @Override | ||||
|     protected void handle(@NonNull final HttpServerExchange exchange) { | ||||
|     protected void handle(@NotNull final HttpServerExchange exchange) { | ||||
|         final Instant start = Instant.now(); | ||||
|         log.debug("Handling create request"); | ||||
|         this.createMazeFromRequestParameters(exchange.getQueryParameters()) | ||||
|                 .onFailure(e -> { | ||||
|                     log.error("Error creating maze from request", e); | ||||
|                     exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR) | ||||
|                             .setReasonPhrase(StatusCodes.INTERNAL_SERVER_ERROR_STRING) | ||||
|                             .getResponseSender() | ||||
|                     if (e instanceof InvalidRequestParameterException) { | ||||
|                         exchange.setStatusCode(StatusCodes.BAD_REQUEST); | ||||
|                     } else { | ||||
|                         exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR); | ||||
|                     } | ||||
|                     exchange.getResponseSender() | ||||
|                             .send(e.getMessage()); | ||||
|                 }) | ||||
|                 .forEach(tuple -> { | ||||
|                     final OutputType outputType = tuple._1(); | ||||
|                     final Maze maze = tuple._2(); | ||||
|                 .forEach(generatedMaze -> { | ||||
|                     final OutputType outputType = generatedMaze.outputType(); | ||||
|                     final Maze maze = generatedMaze.maze(); | ||||
|                     final byte[] bytes; | ||||
|                     try { | ||||
|                         bytes = outputType.render(maze); | ||||
|                     } catch (@NonNull final Exception e) { | ||||
|                     } catch (final Exception e) { | ||||
|                         log.error("Error rendering Maze", e); | ||||
|                         exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR) | ||||
|                                 .setReasonPhrase(StatusCodes.INTERNAL_SERVER_ERROR_STRING) | ||||
|                                 .getResponseSender() | ||||
|                                 .send("Error creating the maze. Please contact the administrator. Request id=%s".formatted(MDC.get("correlationId"))); | ||||
|                         return; | ||||
|  | @ -54,8 +57,7 @@ public class CreateHandler extends AbstractHttpHandler { | |||
|                             .put(HttpString.tryFromString("X-Maze-ID"), String.valueOf(maze.getRandomSeed())) | ||||
|                             .put(HttpString.tryFromString("X-Maze-Width"), String.valueOf(maze.getWidth())) | ||||
|                             .put(HttpString.tryFromString("X-Maze-Height"), String.valueOf(maze.getHeight())) | ||||
|                             // TODO read the algorithm from the maze once this is supported. | ||||
|                             .put(HttpString.tryFromString("X-Maze-Algorithm"), "RandomDepthFirst") | ||||
|                             .put(HttpString.tryFromString("X-Maze-Algorithm"), generatedMaze.generatorName()) | ||||
|                             .put(HttpString.tryFromString("X-Maze-Generation-Duration-millis"), String.valueOf(durationMillis)); | ||||
|                     if (outputType.isAttachment()) { | ||||
|                         exchange.getResponseHeaders() | ||||
|  | @ -71,8 +73,8 @@ public class CreateHandler extends AbstractHttpHandler { | |||
|                 }); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     private Try<Tuple2<OutputType, Maze>> createMazeFromRequestParameters(final Map<String, Deque<String>> queryParameters) { | ||||
|     @NotNull | ||||
|     private Try<ParametersToMazeExtractor.GeneratedMaze> createMazeFromRequestParameters(final Map<String, Deque<String>> queryParameters) { | ||||
|         return new ParametersToMazeExtractor(queryParameters).createMaze(); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,16 +1,15 @@ | |||
| package ch.fritteli.maze.server.handler; | ||||
| 
 | ||||
| import ch.fritteli.maze.server.OutputType; | ||||
| import ch.fritteli.maze.generator.algorithm.RandomDepthFirst; | ||||
| import ch.fritteli.maze.generator.model.Maze; | ||||
| import ch.fritteli.maze.generator.model.Position; | ||||
| import io.vavr.Tuple; | ||||
| import io.vavr.Tuple2; | ||||
| import ch.fritteli.maze.server.InvalidRequestParameterException; | ||||
| import ch.fritteli.maze.server.OutputType; | ||||
| import io.vavr.collection.Stream; | ||||
| import io.vavr.control.Option; | ||||
| import io.vavr.control.Try; | ||||
| import lombok.NonNull; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
| 
 | ||||
| import java.util.Deque; | ||||
| import java.util.Map; | ||||
|  | @ -19,11 +18,11 @@ import java.util.Random; | |||
| @RequiredArgsConstructor | ||||
| class ParametersToMazeExtractor { | ||||
| 
 | ||||
|     @NonNull | ||||
|     @NotNull | ||||
|     private final Map<String, Deque<String>> queryParameters; | ||||
| 
 | ||||
|     @NonNull | ||||
|     Try<Tuple2<OutputType, Maze>> createMaze() { | ||||
|     @NotNull | ||||
|     Try<GeneratedMaze> createMaze() { | ||||
|         final Option<OutputType> output = getParameterValue(RequestParameter.OUTPUT); | ||||
|         final Option<Integer> width = getParameterValue(RequestParameter.WIDTH); | ||||
|         final Option<Integer> height = getParameterValue(RequestParameter.HEIGHT); | ||||
|  | @ -32,7 +31,7 @@ class ParametersToMazeExtractor { | |||
|         final Option<Position> end = getParameterValue(RequestParameter.END); | ||||
| 
 | ||||
|         if (output.isEmpty()) { | ||||
|             return Try.failure(new IllegalArgumentException("Path parameter %s is required and must be one of: %s".formatted( | ||||
|             return Try.failure(new InvalidRequestParameterException("Path parameter %s is required and must be one of: %s".formatted( | ||||
|                     RequestParameter.OUTPUT.getNames().mkString("'", " / ", "'"), | ||||
|                     Stream.of(OutputType.values()) | ||||
|                             .flatMap(OutputType::getNames) | ||||
|  | @ -40,12 +39,12 @@ class ParametersToMazeExtractor { | |||
|             ))); | ||||
|         } | ||||
|         if (width.isEmpty()) { | ||||
|             return Try.failure(new IllegalArgumentException("Query parameter %s is required and must be a positive integer value".formatted( | ||||
|             return Try.failure(new InvalidRequestParameterException("Query parameter %s is required and must be a positive integer value".formatted( | ||||
|                     RequestParameter.WIDTH.getNames().mkString("'", " / ", "'") | ||||
|             ))); | ||||
|         } | ||||
|         if (height.isEmpty()) { | ||||
|             return Try.failure(new IllegalArgumentException("Query parameter %s is required and must be a positive integer value".formatted( | ||||
|             return Try.failure(new InvalidRequestParameterException("Query parameter %s is required and must be a positive integer value".formatted( | ||||
|                     RequestParameter.HEIGHT.getNames().mkString("'", " / ", "'") | ||||
|             ))); | ||||
|         } | ||||
|  | @ -58,12 +57,15 @@ class ParametersToMazeExtractor { | |||
|                 maze = new Maze(width.get(), height.get(), id.getOrElse(() -> new Random().nextLong())); | ||||
|             } | ||||
|             new RandomDepthFirst(maze).run(); | ||||
|             return Tuple.of(output.get(), maze); | ||||
|             return new GeneratedMaze(maze, output.get(), RandomDepthFirst.class.getSimpleName()); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     private <T> Option<T> getParameterValue(@NonNull final RequestParameter parameter) { | ||||
|     @NotNull | ||||
|     private <T> Option<T> getParameterValue(@NotNull final RequestParameter parameter) { | ||||
|         return parameter.getParameterValue(this.queryParameters); | ||||
|     } | ||||
| 
 | ||||
|     public record GeneratedMaze(@NotNull Maze maze, @NotNull OutputType outputType, @NotNull String generatorName) { | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,14 +1,14 @@ | |||
| package ch.fritteli.maze.server.handler; | ||||
| 
 | ||||
| import ch.fritteli.maze.server.OutputType; | ||||
| import ch.fritteli.maze.generator.model.Maze; | ||||
| import ch.fritteli.maze.generator.serialization.v1.SerializerDeserializerV1; | ||||
| import ch.fritteli.maze.server.OutputType; | ||||
| import io.undertow.server.HttpServerExchange; | ||||
| import io.undertow.util.HeaderValues; | ||||
| import io.undertow.util.Headers; | ||||
| import io.undertow.util.StatusCodes; | ||||
| import lombok.NonNull; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
| 
 | ||||
| import java.nio.ByteBuffer; | ||||
| 
 | ||||
|  | @ -18,7 +18,7 @@ public class RenderV1Handler extends AbstractHttpHandler { | |||
|     public static final String PATH_TEMPLATE = "/render/v1/{output}"; | ||||
| 
 | ||||
|     @Override | ||||
|     public void handle(final HttpServerExchange exchange) { | ||||
|     public void handle(@NotNull final HttpServerExchange exchange) { | ||||
|         log.debug("Handling render request"); | ||||
| 
 | ||||
|         if (exchange.isInIoThread()) { | ||||
|  | @ -47,8 +47,8 @@ public class RenderV1Handler extends AbstractHttpHandler { | |||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     private OutputType getOutputType(@NonNull final HttpServerExchange httpServerExchange) { | ||||
|     @NotNull | ||||
|     private OutputType getOutputType(@NotNull final HttpServerExchange httpServerExchange) { | ||||
|         return RequestParameter.OUTPUT.<OutputType>getParameterValue(httpServerExchange.getQueryParameters()) | ||||
|                 .getOrElse(() -> { | ||||
|                     final HeaderValues accept = httpServerExchange.getRequestHeaders().get(Headers.ACCEPT); | ||||
|  |  | |||
|  | @ -1,14 +1,14 @@ | |||
| package ch.fritteli.maze.server.handler; | ||||
| 
 | ||||
| import ch.fritteli.maze.server.OutputType; | ||||
| import ch.fritteli.maze.generator.model.Maze; | ||||
| import ch.fritteli.maze.generator.serialization.v2.SerializerDeserializerV2; | ||||
| import ch.fritteli.maze.server.OutputType; | ||||
| import io.undertow.server.HttpServerExchange; | ||||
| import io.undertow.util.HeaderValues; | ||||
| import io.undertow.util.Headers; | ||||
| import io.undertow.util.StatusCodes; | ||||
| import lombok.NonNull; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
| 
 | ||||
| import java.nio.ByteBuffer; | ||||
| 
 | ||||
|  | @ -18,7 +18,7 @@ public class RenderV2Handler extends AbstractHttpHandler { | |||
|     public static final String PATH_TEMPLATE = "/render/v2/{output}"; | ||||
| 
 | ||||
|     @Override | ||||
|     public void handle(final HttpServerExchange exchange) { | ||||
|     public void handle(@NotNull final HttpServerExchange exchange) { | ||||
|         log.debug("Handling render request"); | ||||
| 
 | ||||
|         if (exchange.isInIoThread()) { | ||||
|  | @ -47,8 +47,8 @@ public class RenderV2Handler extends AbstractHttpHandler { | |||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     private OutputType getOutputType(@NonNull final HttpServerExchange httpServerExchange) { | ||||
|     @NotNull | ||||
|     private OutputType getOutputType(@NotNull final HttpServerExchange httpServerExchange) { | ||||
|         return RequestParameter.OUTPUT.<OutputType>getParameterValue(httpServerExchange.getQueryParameters()) | ||||
|                 .getOrElse(() -> { | ||||
|                     final HeaderValues accept = httpServerExchange.getRequestHeaders().get(Headers.ACCEPT); | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| package ch.fritteli.maze.server.handler; | ||||
| 
 | ||||
| import ch.fritteli.maze.server.OutputType; | ||||
| import ch.fritteli.maze.generator.model.Position; | ||||
| import ch.fritteli.maze.server.OutputType; | ||||
| import io.vavr.Tuple2; | ||||
| import io.vavr.collection.HashMap; | ||||
| import io.vavr.collection.HashSet; | ||||
|  | @ -9,8 +9,8 @@ import io.vavr.collection.Set; | |||
| import io.vavr.control.Option; | ||||
| import io.vavr.control.Try; | ||||
| import lombok.Getter; | ||||
| import lombok.NonNull; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
| 
 | ||||
| import java.util.Deque; | ||||
| import java.util.Map; | ||||
|  | @ -45,24 +45,24 @@ enum RequestParameter { | |||
|             }) | ||||
|             .toOption() | ||||
|             .onEmpty(() -> log.debug("Unparseable value for parameter 'end': '{}'", p)), "e", "end"); | ||||
|     @NonNull | ||||
|     @NotNull | ||||
|     private final Function<String, Option<?>> extractor; | ||||
|     @Getter | ||||
|     @NonNull | ||||
|     @NotNull | ||||
|     private final Set<String> names; | ||||
| 
 | ||||
|     RequestParameter(@NonNull final Function<String, Option<?>> extractor, @NonNull final String... names) { | ||||
|     RequestParameter(@NotNull final Function<String, Option<?>> extractor, @NotNull final String... names) { | ||||
|         this.extractor = extractor; | ||||
|         this.names = HashSet.of(names); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     Option<?> extractParameterValue(@NonNull final String parameter) { | ||||
|     @NotNull | ||||
|     Option<?> extractParameterValue(@NotNull final String parameter) { | ||||
|         return this.extractor.apply(parameter); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     public <T> Option<T> getParameterValue(@NonNull final Map<String, Deque<String>> queryParameters) { | ||||
|     @NotNull | ||||
|     public <T> Option<T> getParameterValue(@NotNull final Map<String, Deque<String>> queryParameters) { | ||||
|         return (Option<T>) HashMap.ofAll(queryParameters) | ||||
|                 .filterKeys(this.names::contains) | ||||
|                 .flatMap(Tuple2::_2) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue