Skip to content

Commit df00a14

Browse files
committed
Allows to extension/module to provide a custom response type handler + rocker implementation
1 parent 2191cf2 commit df00a14

45 files changed

Lines changed: 486 additions & 169 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

jooby/src/main/java/io/jooby/Context.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.io.PrintWriter;
2828
import java.nio.ByteBuffer;
2929
import java.nio.channels.FileChannel;
30+
import java.nio.channels.ReadableByteChannel;
3031
import java.nio.charset.Charset;
3132
import java.nio.charset.StandardCharsets;
3233
import java.nio.file.Path;
@@ -463,6 +464,8 @@ default long getContentLength() {
463464
return sendBytes(data.nioBuffer());
464465
}
465466

467+
@Nonnull Context sendBytes(@Nonnull ReadableByteChannel channel);
468+
466469
@Nonnull Context sendStream(@Nonnull InputStream input);
467470

468471
default @Nonnull Context sendAttachment(@Nonnull AttachedFile file) {

jooby/src/main/java/io/jooby/Jooby.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,11 @@ public Jooby errorCode(@Nonnull Class<? extends Throwable> type,
272272
return LoggerFactory.getLogger(getClass());
273273
}
274274

275+
@Nonnull @Override public Jooby responseHandler(ResponseHandler handler) {
276+
router.responseHandler(handler);
277+
return this;
278+
}
279+
275280
@Nonnull @Override public ErrorHandler getErrorHandler() {
276281
return router.getErrorHandler();
277282
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*
14+
* Copyright 2014 Edgar Espina
15+
*/
16+
package io.jooby;
17+
18+
import java.lang.reflect.Type;
19+
20+
public interface ResponseHandler {
21+
22+
boolean matches(Type type);
23+
24+
Route.Handler create(Route.Handler next);
25+
}

jooby/src/main/java/io/jooby/Route.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package io.jooby;
1717

1818
import javax.annotation.Nonnull;
19+
import javax.annotation.Nullable;
1920
import java.io.Serializable;
2021
import java.lang.reflect.Type;
2122
import java.util.List;
@@ -61,6 +62,10 @@ public interface After {
6162

6263
public interface Handler extends Serializable {
6364

65+
default @Nullable Handler next() {
66+
return null;
67+
}
68+
6469
@Nonnull Object apply(@Nonnull Context ctx) throws Exception;
6570

6671
@Nonnull default Object execute(@Nonnull Context ctx) {

jooby/src/main/java/io/jooby/Router.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import javax.inject.Provider;
2222
import java.nio.file.Path;
2323
import java.util.ArrayList;
24-
import java.util.Arrays;
2524
import java.util.Collections;
2625
import java.util.List;
2726
import java.util.Map;
@@ -224,6 +223,8 @@ default Router error(@Nonnull Predicate<StatusCode> predicate,
224223

225224
@Nonnull Logger getLog();
226225

226+
@Nonnull Router responseHandler(ResponseHandler factory);
227+
227228
static @Nonnull String normalizePath(@Nonnull String path, boolean caseSensitive,
228229
boolean ignoreTrailingSlash) {
229230
if (path == null || path.length() == 0 || path.equals("/")) {

jooby/src/main/java/io/jooby/internal/Pipeline.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import io.jooby.Reified;
2222
import io.jooby.Route;
2323
import io.jooby.Route.Handler;
24+
import io.jooby.ResponseHandler;
2425
import io.jooby.internal.handler.KotlinJobHandler;
2526
import io.jooby.internal.handler.SendAttachment;
2627
import io.jooby.internal.handler.SendByteArray;
@@ -46,18 +47,21 @@
4647

4748
import java.io.File;
4849
import java.io.InputStream;
50+
import java.lang.reflect.Type;
4951
import java.nio.ByteBuffer;
5052
import java.nio.channels.FileChannel;
5153
import java.nio.file.Path;
54+
import java.util.List;
5255
import java.util.Optional;
5356
import java.util.concurrent.CompletionStage;
5457
import java.util.concurrent.Executor;
5558

5659
public class Pipeline {
5760

5861
public static Handler compute(ClassLoader loader, Route route, ExecutionMode mode,
59-
Executor executor) {
60-
Class<?> type = Reified.rawType(route.getReturnType());
62+
Executor executor, List<ResponseHandler> responseHandler) {
63+
Type returnType = route.getReturnType();
64+
Class<?> type = Reified.rawType(returnType);
6165
if (CompletionStage.class.isAssignableFrom(type)) {
6266
return completableFuture(mode, route, executor);
6367
}
@@ -171,6 +175,14 @@ public static Handler compute(ClassLoader loader, Route route, ExecutionMode mod
171175
return next(mode, executor, new SendByteBuf(route.getPipeline()), true);
172176
}
173177

178+
if (responseHandler != null) {
179+
return responseHandler.stream().filter(it -> it.matches(returnType))
180+
.findFirst()
181+
.map(factory ->
182+
next(mode, executor, factory.create(route.getPipeline()), true)
183+
)
184+
.orElseGet(() -> next(mode, executor, new DefaultHandler(route.getPipeline()), true));
185+
}
174186
return next(mode, executor, new DefaultHandler(route.getPipeline()), true);
175187
}
176188

jooby/src/main/java/io/jooby/internal/RouterImpl.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import io.jooby.Router;
2929
import io.jooby.StatusCode;
3030
import io.jooby.Throwing;
31+
import io.jooby.ResponseHandler;
3132
import io.jooby.internal.asm.ClassSource;
3233
import io.jooby.internal.mvc.MvcCompiler;
3334
import io.jooby.internal.mvc.MvcMetadata;
@@ -151,6 +152,8 @@ public Stack executor(Executor executor) {
151152

152153
private AttributeMap attributes = new AttributeMap(new ConcurrentHashMap<>());
153154

155+
private List<ResponseHandler> handlers = new ArrayList<>();
156+
154157
private ClassSource source;
155158

156159
public RouterImpl(ClassLoader loader) {
@@ -389,7 +392,7 @@ private Route route(@Nonnull String method, @Nonnull String pattern,
389392
if (route.getReturnType() == null) {
390393
route.setReturnType(analyzer.returnType(route.getHandle()));
391394
}
392-
Route.Handler pipeline = Pipeline.compute(source.getLoader(), route, mode, executor);
395+
Route.Handler pipeline = Pipeline.compute(source.getLoader(), route, mode, executor, handlers);
393396
route.setPipeline(pipeline);
394397
}
395398
// unwrap executor
@@ -467,6 +470,11 @@ public void destroy() {
467470
return StatusCode.SERVER_ERROR;
468471
}
469472

473+
@Nonnull @Override public Router responseHandler(ResponseHandler handler) {
474+
handlers.add(handler);
475+
return this;
476+
}
477+
470478
@Override public String toString() {
471479
StringBuilder buff = new StringBuilder();
472480
int size = IntStream.range(0, routes.size())

jooby/src/main/java/io/jooby/internal/handler/CompletionStageHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import java.util.concurrent.CompletableFuture;
2323
import java.util.concurrent.CompletionStage;
2424

25-
public class CompletionStageHandler implements NextHandler {
25+
public class CompletionStageHandler implements Route.Handler {
2626

2727
private final Route.Handler next;
2828

jooby/src/main/java/io/jooby/internal/handler/DefaultHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
import javax.annotation.Nonnull;
2222

23-
public class DefaultHandler implements NextHandler {
23+
public class DefaultHandler implements Route.Handler {
2424

2525
private Route.Handler next;
2626

jooby/src/main/java/io/jooby/internal/handler/DetachHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
import javax.annotation.Nonnull;
2222

23-
public class DetachHandler implements NextHandler {
23+
public class DetachHandler implements Route.Handler {
2424
private final Route.Handler next;
2525

2626
public DetachHandler(Route.Handler next) {

0 commit comments

Comments
 (0)