Skip to content

Commit b153e03

Browse files
committed
decorator are now different from before/after filters
1 parent 0f66743 commit b153e03

File tree

11 files changed

+92
-58
lines changed

11 files changed

+92
-58
lines changed

TODO

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
* tests and coverage
22

3-
* flash scope
43
* make reset headers on error configurable
54

65
* websockets

docs/asciidoc/responses.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -609,9 +609,9 @@ Jooby allows you to use this experimental API by setting the `coroutineStart` op
609609

610610
=== Send methods
611611

612-
Jooby provides a family of `sendXXX()` methods that produces a response via side effects.
612+
Jooby provides a family of `send()` methods that produces a response via side effects.
613613

614-
.sendString example
614+
.send text
615615
[source,java,role="primary"]
616616
----
617617
{

docs/asciidoc/routing.adoc

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -334,17 +334,11 @@ interface Decorator {
334334
<3> Compute and print latency
335335
<4> Returns a response
336336

337-
[NOTE]
338-
====
339-
A `decorator` lacks of a `path pattern`. Sound strange? It is explained in the <<router-pipeline, pipeline>> section.
340-
====
341-
342-
==== Before Decorator
337+
==== Before
343338

344-
The javadoc:Route.Before[text=before] decorator is a specialized decorator that runs before a
345-
`handler`.
339+
The javadoc:Route.Before[text=before] filter runs before a `handler` or `decorator`.
346340

347-
A `before` decorator takes a `context` as argument and don't produces a response. It expected to operate
341+
A `before` filter takes a `context` as argument and don't produces a response. It expected to operates
348342
via side effects (usually modifying the HTTP response).
349343

350344
[source,java]
@@ -382,18 +376,18 @@ interface Before {
382376
}
383377
----
384378

385-
==== After Decorator
379+
==== After
386380

387-
The javadoc:Route.After[text=after] decorator is a specialized decorator that runs after a
388-
`handler`.
381+
The javadoc:Route.After[text=after] filter runs after a `handler` or `decorator`.
389382

390-
An `after` decorator takes two arguments. The first argument is the `HTTP context`, while the second
391-
argument is the result/response from a `handler`.
383+
An `after` filter takes two arguments. The first argument is the `HTTP context`, while the second
384+
argument is the result/response from a `handler` and don't produces a response. It expected to operates
385+
via side effects (usually modifying the HTTP response).
392386

393387
[source,java]
394388
----
395389
interface After {
396-
Object apply(Context ctx, Object result);
390+
void apply(Context ctx, Object result);
397391
}
398392
----
399393

@@ -402,7 +396,7 @@ interface After {
402396
----
403397
{
404398
after((ctx, result) -> {
405-
return "Hello " + result;
399+
System.out.println(result);
406400
});
407401
408402
get("/", ctx -> {
@@ -416,7 +410,7 @@ interface After {
416410
----
417411
{
418412
after {
419-
"Hello $result"
413+
println("Hello $result")
420414
}
421415
422416
get("/") {
@@ -526,7 +520,7 @@ sequentially one by one. The following `filter` is always executed in Jooby 1.x
526520
}
527521
----
528522
529-
Suppose there is bot trying to access and causing lot of `404` responses (path doesn't exist).
523+
Suppose there is a bot trying to access and causing lot of `404` responses (path doesn't exist).
530524
In Jooby 1.x the `filter` is executed for every single request sent by the bot just to realize
531525
there is NO matching route and all we need is a `404`.
532526
@@ -590,7 +584,7 @@ Output:
590584

591585
==== Scoped Decorator
592586

593-
The javadoc:Router[route, java.lang.Runnable] and javadoc:Router[path, java.lang.Runnable] operators
587+
The javadoc:Router[route, java.lang.Runnable] and javadoc:Router[path, java.lang.String, java.lang.Runnable] operators
594588
are used to group one or more routes.
595589

596590
A `scoped decorator` looks like:
@@ -684,7 +678,7 @@ and allows you to selectively apply one or more routes.
684678

685679
Route operator is for grouping one or more routes and apply cross cutting concerns to all them.
686680

687-
In similar fashin the javadoc:Router[path, java.lang.String, java.lang.Runnable] operator groups
681+
In similar fashion the javadoc:Router[path, java.lang.String, java.lang.Runnable] operator groups
688682
one or more routes under a common path pattern.
689683

690684
.Routes with path prefix:

docs/src/main/java/io/jooby/adoc/JavadocProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public Object process(ContentNode parent, String clazz, Map<String, Object> attr
7171
index += 1;
7272

7373
if (attributes.get(String.valueOf(index)) != null) {
74-
link.append(",");
74+
link.append("-");
7575
text.append(",");
7676
}
7777
}

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

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public class Route {
5050
* @author edgar
5151
* @since 2.0.0
5252
*/
53-
public interface Decorator {
53+
public interface Decorator extends Serializable {
5454
/**
5555
* Chain the decorator within next handler.
5656
*
@@ -86,7 +86,7 @@ public interface Decorator {
8686
* @author edgar
8787
* @since 2.0.0
8888
*/
89-
public interface Before {
89+
public interface Before extends Serializable {
9090
/**
9191
* Execute application code before next handler.
9292
*
@@ -128,7 +128,7 @@ public interface Before {
128128
* @author edgar
129129
* @since 2.0.0
130130
*/
131-
public interface After {
131+
public interface After extends Serializable {
132132

133133
/**
134134
* Chain this decorator with next one and produces a new after decorator.
@@ -226,6 +226,8 @@ public interface Handler extends Serializable {
226226

227227
private Before before;
228228

229+
private Decorator decorator;
230+
229231
private Handler handler;
230232

231233
private After after;
@@ -261,6 +263,7 @@ public Route(@Nonnull String method,
261263
@Nonnull Type returnType,
262264
@Nonnull Handler handler,
263265
@Nullable Before before,
266+
@Nullable Decorator decorator,
264267
@Nullable After after,
265268
@Nonnull Renderer renderer,
266269
@Nonnull Map<String, Parser> parsers) {
@@ -269,13 +272,18 @@ public Route(@Nonnull String method,
269272
this.returnType = returnType;
270273
this.handler = handler;
271274
this.before = before;
275+
this.decorator = decorator;
272276
this.after = after;
273277
this.renderer = renderer;
274278
this.pathKeys = pathKeys;
275279
this.parsers = parsers;
276280
this.handle = handler;
277281

278282
this.pipeline = handler;
283+
284+
if (decorator != null) {
285+
this.pipeline = decorator.then(pipeline);
286+
}
279287
if (before != null) {
280288
this.pipeline = before.then(pipeline);
281289
}
@@ -292,6 +300,7 @@ public Route(@Nonnull String method,
292300
* @param returnType Return type.
293301
* @param handler Route handler.
294302
* @param before Before pipeline.
303+
* @param decorator Decorator pipeline.
295304
* @param after After pipeline.
296305
* @param renderer Route renderer.
297306
* @param parsers Route parsers.
@@ -301,10 +310,12 @@ public Route(@Nonnull String method,
301310
@Nonnull Type returnType,
302311
@Nonnull Handler handler,
303312
@Nullable Before before,
313+
@Nullable Decorator decorator,
304314
@Nullable After after,
305315
@Nonnull Renderer renderer,
306316
@Nonnull Map<String, Parser> parsers) {
307-
this(method, pattern, Router.pathKeys(pattern), returnType, handler, before, after, renderer,
317+
this(method, pattern, Router.pathKeys(pattern), returnType, handler, before, decorator, after,
318+
renderer,
308319
parsers);
309320
}
310321

@@ -382,6 +393,10 @@ public Route(@Nonnull String method,
382393
return after;
383394
}
384395

396+
public @Nullable Decorator getDecorator() {
397+
return decorator;
398+
}
399+
385400
/**
386401
* Set route handle instance, required when handle is different from {@link #getHandler()}.
387402
*

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

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -62,41 +62,41 @@ public class RouterImpl implements Router {
6262
private static class Stack {
6363
private String pattern;
6464
private Executor executor;
65-
private List<Route.Decorator> filters = new ArrayList<>();
65+
private List<Route.Decorator> decoratorList = new ArrayList<>();
6666
private List<Route.Before> beforeList = new ArrayList<>();
67-
private List<Route.After> afters = new ArrayList<>();
67+
private List<Route.After> afterList = new ArrayList<>();
6868

6969
public Stack(String pattern) {
7070
this.pattern = pattern;
7171
}
7272

7373
public void then(Route.Decorator filter) {
74-
filters.add(filter);
74+
decoratorList.add(filter);
7575
}
7676

7777
public void then(Route.After after) {
78-
afters.add(after);
78+
afterList.add(after);
7979
}
8080

8181
public void then(Route.Before before) {
8282
beforeList.add(before);
8383
}
8484

85-
public Stream<Route.Decorator> toFilter() {
86-
return filters.stream();
85+
public Stream<Route.Decorator> toDecorator() {
86+
return decoratorList.stream();
8787
}
8888

8989
public Stream<Route.After> toAfter() {
90-
return afters.stream();
90+
return afterList.stream();
9191
}
9292

9393
public Stream<Route.Before> toBefore() {
9494
return beforeList.stream();
9595
}
9696

9797
public void clear() {
98-
this.filters.clear();
99-
this.afters.clear();
98+
this.decoratorList.clear();
99+
this.afterList.clear();
100100
this.beforeList.clear();
101101
executor = null;
102102
}
@@ -356,32 +356,26 @@ private Route defineRoute(@Nonnull String method, @Nonnull String pattern,
356356
stack.stream().filter(it -> it.pattern != null).forEach(it -> pat.append(it.pattern));
357357
pat.append(pattern);
358358

359-
/** Decorators: */
360-
List<Route.Decorator> filters = stack.stream()
361-
.flatMap(Stack::toFilter)
362-
.collect(Collectors.toList());
363-
364359
/** Before: */
365360
Route.Before before = stack.stream()
366361
.flatMap(Stack::toBefore)
367362
.reduce(null, (it, next) -> it == null ? next : it.then(next));
368363

369-
/** Pipeline: */
370-
// Route.Handler pipeline = before == null ? handler : before.then(handler);
364+
/** Decorator: */
365+
Route.Decorator decorator = stack.stream()
366+
.flatMap(Stack::toDecorator)
367+
.reduce(null, (it, next) -> it == null ? next : it.then(next));
371368

372369
/** After: */
373370
Route.After after = stack.stream()
374371
.flatMap(Stack::toAfter)
375372
.reduce(null, (it, next) -> it == null ? next : it.then(next));
376373

377-
// if (after != null) {
378-
// pipeline = pipeline.then(after);
379-
// }
380-
381374
/** Route: */
382375
String safePattern = normalizePath(pat.toString(), options.isCaseSensitive(),
383376
options.isIgnoreTrailingSlash());
384-
Route route = new Route(method, safePattern, null, handler, before, after, renderer, parsers);
377+
Route route = new Route(method, safePattern, null, handler, before, decorator, after, renderer,
378+
parsers);
385379
Stack stack = this.stack.peekLast();
386380
if (stack.executor != null) {
387381
routeExecutor.put(route, stack.executor);
@@ -422,11 +416,20 @@ private Route defineRoute(@Nonnull String method, @Nonnull String pattern,
422416
if (route.getConsumes().size() > 0) {
423417
before = before == null ? SUPPORT_MEDIA_TYPE : SUPPORT_MEDIA_TYPE.then(before);
424418
}
425-
Route.Handler pipeline = route.getHandler();
419+
420+
Route.Decorator decorator = route.getDecorator();
421+
Route.Handler handler = route.getHandler();
422+
Route.Handler pipeline;
423+
if (decorator == null) {
424+
pipeline = handler;
425+
} else {
426+
pipeline = decorator.then(handler);
427+
}
426428

427429
if (before != null) {
428430
pipeline = before.then(pipeline);
429431
}
432+
430433
Route.After after = route.getAfter();
431434
if (after != null) {
432435
pipeline = pipeline.then(after);
@@ -558,8 +561,8 @@ public void destroy() {
558561
}
559562

560563
private Router newStack(@Nonnull String pattern, @Nonnull Runnable action,
561-
Route.Decorator... filter) {
562-
return newStack(push(pattern), action, filter);
564+
Route.Decorator... decorator) {
565+
return newStack(push(pattern), action, decorator);
563566
}
564567

565568
private Stack push() {
@@ -638,7 +641,8 @@ private void find(String prefix, Class type, Sneaky.Consumer<MvcMethod> consumer
638641
if (executor == null) {
639642
// TODO: replace with usage exception
640643
throw new IllegalArgumentException(
641-
"Missing executor: " + executorKey + ", required by: " + mvc.getMethod().getDeclaringClass().getName() + "." + mvc.getMethod()
644+
"Missing executor: " + executorKey + ", required by: " + mvc.getMethod()
645+
.getDeclaringClass().getName() + "." + mvc.getMethod()
642646
.getName() + ", at line: " + mvc.getLine());
643647
}
644648
dispatch(executor, () -> consumer.accept(mvc));

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public RouterMatch missing(String method, String path, Renderer renderer) {
8484
} else {
8585
h = this.handler;
8686
}
87-
this.route = new Route(method, path, emptyList(), String.class, h, null, null, renderer, emptyMap());
87+
this.route = new Route(method, path, emptyList(), String.class, h, null, null, null, renderer, emptyMap());
8888
return this;
8989
}
9090
}

jooby/src/test/java/io/jooby/internal/ChiBenchmark.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public void setup() {
6363
}
6464

6565
private Route route(String method, String pattern) {
66-
return new Route(method, pattern, String.class, null, null, null, null, null);
66+
return new Route(method, pattern, String.class, null, null, null, null, null, null);
6767
}
6868

6969
@Benchmark

jooby/src/test/java/io/jooby/internal/ChiTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ private Route.Handler stringHandler(String foo) {
9494
}
9595

9696
private Route route(String method, String pattern, Route.Handler handler) {
97-
return new Route(method, pattern, String.class, handler, null, null,
97+
return new Route(method, pattern, String.class, handler, null, null, null,
9898
Renderer.TO_STRING, Collections.emptyMap());
9999
}
100100

jooby/src/test/java/io/jooby/internal/PipelineTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ private Route.Handler pipeline(Route route, ExecutionMode mode, Executor executo
224224
}
225225

226226
private Route route(Type returnType, Route.Handler handler) {
227-
return new Route("GET", "/", returnType, handler, null, null,
227+
return new Route("GET", "/", returnType, handler, null, null, null,
228228
Renderer.TO_STRING, Collections.emptyMap());
229229
}
230230
}

0 commit comments

Comments
 (0)