diff --git a/pom.xml b/pom.xml
index c0f35cf..cdbf4f6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -309,7 +309,7 @@
org.fusesource.jansi
jansi
- 1.15
+ 1.17.1
diff --git a/src/main/java/io/sinistral/proteus/modules/ConfigModule.java b/src/main/java/io/sinistral/proteus/modules/ConfigModule.java
index 20d5b4a..71ec00f 100644
--- a/src/main/java/io/sinistral/proteus/modules/ConfigModule.java
+++ b/src/main/java/io/sinistral/proteus/modules/ConfigModule.java
@@ -38,6 +38,7 @@
public class ConfigModule extends AbstractModule
{
private static Logger log = LoggerFactory.getLogger(ConfigModule.class.getCanonicalName());
+
protected String configFile = null;
protected URL configURL = null;
protected Config config = null;
diff --git a/src/main/java/io/sinistral/proteus/server/Extractors.java b/src/main/java/io/sinistral/proteus/server/Extractors.java
index 6909d33..2883dd2 100644
--- a/src/main/java/io/sinistral/proteus/server/Extractors.java
+++ b/src/main/java/io/sinistral/proteus/server/Extractors.java
@@ -3,12 +3,14 @@
*/
package io.sinistral.proteus.server;
+import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
+import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.util.Arrays;
@@ -166,12 +168,16 @@ public static java.util.Optional offsetDateTime(final HttpServer
}
+
public static java.util.Optional zonedDateTime(final HttpServerExchange exchange,final String name) {
- return string(exchange, name).map( ZonedDateTime::parse );
-
+ return string(exchange, name).map( ZonedDateTime::parse );
}
+ public static java.util.Optional instant(final HttpServerExchange exchange,final String name) {
+
+ return string(exchange, name).map( Instant::parse );
+ }
public static java.util.Optional any(final HttpServerExchange exchange )
{
@@ -222,7 +228,12 @@ public static java.util.Optional string(final HttpServerExchange exchan
public static java.util.Optional filePath(final HttpServerExchange exchange, final String name)
{
- return java.util.Optional.ofNullable(exchange.getAttachment(FormDataParser.FORM_DATA).get(name)).map(Deque::getFirst).map( fv -> fv.getPath());
+ return java.util.Optional.ofNullable(exchange.getAttachment(FormDataParser.FORM_DATA).get(name)).map(Deque::getFirst).map( fv -> fv.getFileItem().getFile());
+ }
+
+ public static java.util.Optional file(final HttpServerExchange exchange, final String name)
+ {
+ return java.util.Optional.ofNullable(exchange.getAttachment(FormDataParser.FORM_DATA).get(name)).map(Deque::getFirst).map( fv -> fv.getFileItem().getFile().toFile());
}
public static java.util.Optional byteBuffer(final HttpServerExchange exchange, final String name)
@@ -363,7 +374,18 @@ public static Path filePath(final HttpServerExchange exchange, final String nam
{
try
{
- return exchange.getAttachment(FormDataParser.FORM_DATA).get(name).getFirst().getPath();
+ return exchange.getAttachment(FormDataParser.FORM_DATA).get(name).getFirst().getFileItem().getFile();
+ } catch(NullPointerException e)
+ {
+ throw new IllegalArgumentException("Missing parameter " + name, e);
+ }
+ }
+
+ public static File file(final HttpServerExchange exchange, final String name) throws java.lang.IllegalArgumentException
+ {
+ try
+ {
+ return exchange.getAttachment(FormDataParser.FORM_DATA).get(name).getFirst().getFileItem().getFile().toFile();
} catch(NullPointerException e)
{
throw new IllegalArgumentException("Missing parameter " + name, e);
@@ -419,6 +441,11 @@ public static Long longValue(final HttpServerExchange exchange, final String na
{
return Long.parseLong( string(exchange, name) );
}
+
+ public static Instant instant(final HttpServerExchange exchange, final String name) throws java.lang.IllegalArgumentException
+ {
+ return Instant.parse( string(exchange, name) );
+ }
public static Integer integerValue(final HttpServerExchange exchange, final String name) throws java.lang.IllegalArgumentException
{
@@ -453,7 +480,6 @@ public static T model(final HttpServerExchange exchange, final Class typ
{
if( ServerPredicates.XML_PREDICATE.resolve(exchange) )
{
-
return xmlModel(exchange,type);
}
else
diff --git a/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java b/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java
index 651fb20..72555fd 100644
--- a/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java
+++ b/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java
@@ -599,6 +599,8 @@ else if (t.equals(HttpServerExchange.class) || t.equals(ServerRequest.class))
{
Type type = p.getParameterizedType();
+
+
try
{
diff --git a/src/main/java/io/sinistral/proteus/server/handlers/TypeHandler.java b/src/main/java/io/sinistral/proteus/server/handlers/TypeHandler.java
index 2b6019a..5f8eb38 100644
--- a/src/main/java/io/sinistral/proteus/server/handlers/TypeHandler.java
+++ b/src/main/java/io/sinistral/proteus/server/handlers/TypeHandler.java
@@ -40,11 +40,16 @@ public enum TypeHandler
// StatementParameterType.TYPE,
// StatementParameterType.LITERAL,io.sinistral.proteus.server.Extractors.class,
// StatementParameterType.TYPE, StatementParameterType.STRING),
+
+ FileType("$T $L = $T.file(exchange,$S)", true, java.io.File.class, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.class, StatementParameterType.STRING),
+
ByteBufferType("$T $L = $T.byteBuffer(exchange,$S)", true, java.nio.ByteBuffer.class, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.class, StatementParameterType.STRING),
DateType("$T $L = $T.date(exchange,$S)", false, java.util.Date.class, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.class, StatementParameterType.STRING),
ZonedDateTimeType("$T $L = $T.zonedDateTime(exchange,$S)", false, java.time.ZonedDateTime.class, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.class, StatementParameterType.STRING),
OffsetDateTimeType("$T $L = $T.offsetDateTime(exchange,$S)", false, java.time.OffsetDateTime.class, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.class, StatementParameterType.STRING),
+ InstantType("$T $L = $T.instant(exchange,$S)", false, java.time.Instant.class, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.class, StatementParameterType.STRING),
+
FloatType("Integer $L = $T.floatValue(exchange,$S)", false, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.class, StatementParameterType.STRING),
DoubleType("Integer $L = $T.doubleValue(exchange,$S)", false, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.class, StatementParameterType.STRING),
@@ -93,6 +98,8 @@ public enum TypeHandler
OptionalByteBufferType("$T<$T> $L = $T.byteBuffer(exchange,$S)", true, Optional.class, java.nio.ByteBuffer.class, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.Optional.class, StatementParameterType.STRING),
+ OptionalFileType("$T<$T> $L = $T.file(exchange,$S)", true, Optional.class, java.io.File.class, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.Optional.class, StatementParameterType.STRING),
+
OptionalFloatType("$T $L = $T.floatValue(exchange,$S)", false, Optional.class, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.Optional.class, StatementParameterType.STRING),
OptionalDoubleType("$T $L = $T.doubleValue(exchange,$S)", false, Optional.class, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.Optional.class, StatementParameterType.STRING),
@@ -100,7 +107,7 @@ public enum TypeHandler
OptionalInstantType("$T<$T> $L = $T.instant(exchange,$S)", false, Optional.class, java.time.Instant.class, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.Optional.class, StatementParameterType.STRING),
OptionalZonedDateTimeType("$T<$T> $L = $T.zonedDateTime(exchange,$S)", false, Optional.class, java.time.ZonedDateTime.class, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.Optional.class, StatementParameterType.STRING),
OptionalOffsetDateTimeType("$T<$T> $L = $T.offsetDateTime(exchange,$S)", false, Optional.class, java.time.OffsetDateTime.class, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.Optional.class, StatementParameterType.STRING),
-
+
OptionalModelType("java.util.Optional<$L> $L = $T.model(exchange,$L)", false, StatementParameterType.LITERAL, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.Optional.class, StatementParameterType.LITERAL),
OptionalValueOfType("$T<$T> $L = $T.string(exchange,$S).map($T::valueOf)", false, Optional.class, StatementParameterType.RAW, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.Optional.class, StatementParameterType.STRING, StatementParameterType.RAW),
@@ -501,6 +508,14 @@ else if (type.equals(java.nio.file.Path.class))
{
return FilePathType;
}
+ else if (type.equals(java.io.File.class))
+ {
+ return FileType;
+ }
+ else if (type.equals(java.time.Instant.class))
+ {
+ return InstantType;
+ }
else if (type.equals(java.util.Date.class))
{
return DateType;
@@ -508,7 +523,7 @@ else if (type.equals(java.util.Date.class))
else if (type.equals(java.time.ZonedDateTime.class))
{
return ZonedDateTimeType;
- }
+ }
else if (type.equals(java.time.OffsetDateTime.class))
{
return OffsetDateTimeType;
@@ -539,6 +554,10 @@ else if (type.getTypeName().contains("java.time.OffsetDateTime"))
{
return OptionalOffsetDateTimeType;
}
+ else if (type.getTypeName().contains("java.time.Instant"))
+ {
+ return OptionalInstantType;
+ }
else if (type.getTypeName().contains("java.time.ZonedDateTime"))
{
return ZonedDateTimeType;
@@ -567,6 +586,10 @@ else if (type.getTypeName().contains("java.nio.ByteBuffer"))
{
return OptionalByteBufferType;
}
+ else if (type.getTypeName().contains("java.io.File"))
+ {
+ return OptionalFileType;
+ }
else
{
try
diff --git a/src/test/java/io/sinistral/proteus/test/controllers/Tests.java b/src/test/java/io/sinistral/proteus/test/controllers/Tests.java
index 1ee1ef3..593735d 100644
--- a/src/test/java/io/sinistral/proteus/test/controllers/Tests.java
+++ b/src/test/java/io/sinistral/proteus/test/controllers/Tests.java
@@ -5,7 +5,10 @@
import static io.sinistral.proteus.server.ServerResponse.response;
+import java.io.File;
import java.nio.ByteBuffer;
+import java.sql.Timestamp;
+import java.time.Instant;
import java.time.OffsetDateTime;
import java.util.HashMap;
import java.util.List;
@@ -283,10 +286,36 @@ public ServerResponse> listConversion( ServerRequest request, @BeanPa
return response( ids ).applicationJson();
+ }
+
+ @GET
+ @Path("/response/parse/timestamp")
+ @Blocking
+ @Produces(MediaType.TEXT_PLAIN)
+ @Operation(description = "Convert timestamp")
+ public ServerResponse timestampConversion( ServerRequest request, @QueryParam("timestamp") Timestamp timestamp ) throws Exception
+ {
+
+ return response().body(timestamp.toString()).textPlain();
+
+
+ }
+
+ @GET
+ @Path("/response/parse/instant")
+ @Blocking
+ @Produces(MediaType.TEXT_PLAIN)
+ @Operation(description = "Convert instant")
+ public ServerResponse instantConversion( ServerRequest request, @QueryParam("instant") Instant instant ) throws Exception
+ {
+
+ return response().body(instant.toString()).textPlain();
+
+
}
@POST
- @Path("/response/file/bytebuffer")
+ @Path("/response/bytebuffer")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
@Consumes("*/*")
@Operation(description = "Upload file path endpoint")
@@ -296,6 +325,22 @@ public ServerResponse responseUploadByteBuffer(ServerRequest request
return response(file).applicationOctetStream();
+ }
+
+ @POST
+ @Path("/response/file")
+ @Produces(MediaType.APPLICATION_OCTET_STREAM)
+ @Consumes("*/*")
+ @Operation(description = "Upload file path endpoint")
+ public ServerResponse responseUploadFile(ServerRequest request, @FormParam("file") File file ) throws Exception
+ {
+
+ ByteBuffer response = ByteBuffer.wrap(Files.asByteSource(file).read());
+
+
+ return response(response).applicationOctetStream();
+
+
}
@GET
diff --git a/src/test/java/io/sinistral/proteus/test/server/TestControllerEndpoints.java b/src/test/java/io/sinistral/proteus/test/server/TestControllerEndpoints.java
index c648ad5..cb31e42 100644
--- a/src/test/java/io/sinistral/proteus/test/server/TestControllerEndpoints.java
+++ b/src/test/java/io/sinistral/proteus/test/server/TestControllerEndpoints.java
@@ -14,6 +14,8 @@
import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
+import java.sql.Timestamp;
+import java.time.Instant;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@@ -287,7 +289,32 @@ public void responseUploadByteBufferParameter()
try
{
- final InputStream is = given().multiPart("file", file).accept(ContentType.ANY).when().post("tests/response/file/bytebuffer").asInputStream();
+ final InputStream is = given().multiPart("file", file).accept(ContentType.ANY).when().post("tests/response/bytebuffer").asInputStream();
+
+ final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ IOUtils.copy(is, byteArrayOutputStream);
+ IOUtils.closeQuietly(byteArrayOutputStream);
+ IOUtils.closeQuietly(is);
+
+ assertThat(byteArrayOutputStream.size(), equalTo(Long.valueOf(file.length()).intValue()));
+
+ } catch (Exception e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+
+ @SuppressWarnings("resource")
+ @Test
+ public void responseUploadFileParameter()
+ {
+
+ try
+ {
+
+ final InputStream is = given().multiPart("file", file).accept(ContentType.ANY).when().post("tests/response/file").asInputStream();
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
IOUtils.copy(is, byteArrayOutputStream);
@@ -304,6 +331,46 @@ public void responseUploadByteBufferParameter()
}
+ @Test
+ public void responseParseInstant()
+ {
+
+
+ Instant instant = Instant.now();
+
+ given()
+
+
+
+ .queryParam("instant", instant.toString())
+
+ .when()
+
+ .get("tests/response/parse/instant").
+
+ then().statusCode(200).and().body(containsString(instant.toString()));
+
+
+ }
+
+ @Test
+ public void responseParseTimestamp()
+ {
+
+
+ Timestamp ts = new Timestamp(System.currentTimeMillis());
+
+ given()
+
+ .queryParam("timestamp", ts.toString())
+ .when()
+
+ .get("tests/response/parse/timestamp").
+ then().statusCode(200).and().body(containsString(ts.toString()));
+
+
+ }
+
@Test
public void responseComplexParameters()
{