Skip to content

Commit 475b825

Browse files
committed
low level parser and render can't be overwritten by application specific parser or renderer
1 parent 8a660b4 commit 475b825

File tree

7 files changed

+155
-152
lines changed

7 files changed

+155
-152
lines changed

coverage-report/src/test/java/org/jooby/ParserOrder2Feature.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public String toString() {
3939
@Override
4040
public Object parse(final TypeLiteral<?> type, final Context ctx) throws Exception {
4141
assertEquals(
42-
"[p2, p1, p3, Basic, Collection, Optional, Enum, Upload, byte[], Date, LocalDate, Locale, bean, valueOf(String), fromString(String), forName(String), init(String)]",
42+
"[Basic, Collection, Optional, Enum, Upload, byte[], p2, p1, p3, Date, LocalDate, Locale, bean, valueOf(String), fromString(String), forName(String), init(String)]",
4343
ctx.toString());
4444
return ctx.next();
4545
}
@@ -74,6 +74,6 @@ public void order() throws Exception {
7474
request()
7575
.get("/parser/order")
7676
.expect(
77-
"[p2, p1, p3, Basic, Collection, Optional, Enum, Upload, byte[], Date, LocalDate, Locale, bean, valueOf(String), fromString(String), forName(String), init(String)]");
77+
"[Basic, Collection, Optional, Enum, Upload, byte[], p2, p1, p3, Date, LocalDate, Locale, bean, valueOf(String), fromString(String), forName(String), init(String)]");
7878
}
7979
}

coverage-report/src/test/java/org/jooby/ParserOrderFeature.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public class ParserOrderFeature extends ServerFeature {
2323
@Override
2424
public Object parse(final TypeLiteral<?> type, final Context ctx) throws Exception {
2525
assertEquals(
26-
"[p1, p2, p3, Basic, Collection, Optional, Enum, Upload, byte[], Date, LocalDate, Locale, bean, valueOf(String), fromString(String), forName(String), init(String)]",
26+
"[Basic, Collection, Optional, Enum, Upload, byte[], p1, p2, p3, Date, LocalDate, Locale, bean, valueOf(String), fromString(String), forName(String), init(String)]",
2727
ctx.toString());
2828
return ctx.next();
2929
}
@@ -75,6 +75,6 @@ public void order() throws Exception {
7575
request()
7676
.get("/parser/order")
7777
.expect(
78-
"[p1, p2, p3, Basic, Collection, Optional, Enum, Upload, byte[], Date, LocalDate, Locale, bean, valueOf(String), fromString(String), forName(String), init(String)]");
78+
"[Basic, Collection, Optional, Enum, Upload, byte[], p1, p2, p3, Date, LocalDate, Locale, bean, valueOf(String), fromString(String), forName(String), init(String)]");
7979
}
8080
}

coverage-report/src/test/java/org/jooby/RendererOrder2Feature.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public String toString() {
3737

3838
@Override
3939
public void render(final Object object, final Context ctx) throws Exception {
40-
assertEquals("[r2, r1, r3, Asset, byte[], ByteBuffer, File, CharBuffer, InputStream, Reader, FileChannel, default.err, toString()]",
40+
assertEquals("[Asset, byte[], ByteBuffer, File, CharBuffer, InputStream, Reader, FileChannel, r2, r1, r3, default.err, toString()]",
4141
ctx.toString());
4242
}
4343

@@ -67,6 +67,6 @@ public String toString() {
6767
public void order() throws Exception {
6868
request()
6969
.get("/renderer/order")
70-
.expect("[r2, r1, r3, Asset, byte[], ByteBuffer, File, CharBuffer, InputStream, Reader, FileChannel, default.err, toString()]");
70+
.expect("[Asset, byte[], ByteBuffer, File, CharBuffer, InputStream, Reader, FileChannel, r2, r1, r3, default.err, toString()]");
7171
}
7272
}

coverage-report/src/test/java/org/jooby/RendererOrderFeature.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public class RendererOrderFeature extends ServerFeature {
2222

2323
@Override
2424
public void render(final Object object, final Context ctx) throws Exception {
25-
assertEquals("[r1, r2, r3, Asset, byte[], ByteBuffer, File, CharBuffer, InputStream, Reader, FileChannel, default.err, toString()]",
25+
assertEquals("[Asset, byte[], ByteBuffer, File, CharBuffer, InputStream, Reader, FileChannel, r1, r2, r3, default.err, toString()]",
2626
ctx.toString());
2727
}
2828

@@ -67,6 +67,6 @@ public String toString() {
6767
public void order() throws Exception {
6868
request()
6969
.get("/renderer/order")
70-
.expect("[r1, r2, r3, Asset, byte[], ByteBuffer, File, CharBuffer, InputStream, Reader, FileChannel, default.err, toString()]");
70+
.expect("[Asset, byte[], ByteBuffer, File, CharBuffer, InputStream, Reader, FileChannel, r1, r2, r3, default.err, toString()]");
7171
}
7272
}

jooby/src/main/java/org/jooby/Jooby.java

Lines changed: 141 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@
8080
import org.jooby.Session.Store;
8181
import org.jooby.handlers.AssetHandler;
8282
import org.jooby.internal.AppPrinter;
83+
import org.jooby.internal.AssetProxy;
8384
import org.jooby.internal.BuiltinParser;
8485
import org.jooby.internal.BuiltinRenderer;
8586
import org.jooby.internal.DefaulErrRenderer;
86-
import org.jooby.internal.AssetProxy;
8787
import org.jooby.internal.HttpHandlerImpl;
8888
import org.jooby.internal.JvmInfo;
8989
import org.jooby.internal.LifecycleProcessor;
@@ -2896,152 +2896,155 @@ private Injector bootstrap() throws Exception {
28962896
callback.getValue().forEach(it -> it.accept(config));
28972897
}
28982898
}
2899-
// dependency injection
2899+
/** dependency injection */
29002900
@SuppressWarnings("unchecked")
29012901
Injector injector = Guice.createInjector(stage, binder -> {
29022902

2903-
// type converters
2904-
new TypeConverters().configure(binder);
2905-
2906-
// bind config
2907-
bindConfig(binder, config);
2908-
2909-
// bind env
2910-
binder.bind(Env.class).toInstance(env);
2911-
2912-
// bind charset
2913-
binder.bind(Charset.class).toInstance(charset);
2914-
2915-
// bind locale
2916-
binder.bind(Locale.class).toInstance(locale);
2917-
2918-
// bind time zone
2919-
binder.bind(ZoneId.class).toInstance(zoneId);
2920-
binder.bind(TimeZone.class).toInstance(TimeZone.getTimeZone(zoneId));
2921-
2922-
// bind date format
2923-
binder.bind(DateTimeFormatter.class).toInstance(dateTimeFormatter);
2924-
2925-
// bind number format
2926-
binder.bind(NumberFormat.class).toInstance(numberFormat);
2927-
binder.bind(DecimalFormat.class).toInstance(numberFormat);
2928-
2929-
// bind managed
2930-
LifecycleProcessor lifecycleProcessor = new LifecycleProcessor();
2931-
binder.bind(LifecycleProcessor.class).toInstance(lifecycleProcessor);
2932-
binder.bindListener(Matchers.any(), lifecycleProcessor);
2933-
2934-
// Routes
2935-
Multibinder<Route.Definition> definitions = Multibinder
2936-
.newSetBinder(binder, Route.Definition.class);
2937-
2938-
// Web Sockets
2939-
Multibinder<WebSocket.Definition> sockets = Multibinder
2940-
.newSetBinder(binder, WebSocket.Definition.class);
2941-
2942-
// tmp dir
2943-
File tmpdir = new File(config.getString("application.tmpdir"));
2944-
tmpdir.mkdirs();
2945-
binder.bind(File.class).annotatedWith(Names.named("application.tmpdir"))
2946-
.toInstance(tmpdir);
2947-
2948-
RouteMetadata classInfo = new RouteMetadata(env);
2949-
binder.bind(ParameterNameProvider.class).toInstance(classInfo);
2950-
2951-
// err handler
2952-
Multibinder<Err.Handler> ehandlers = Multibinder
2953-
.newSetBinder(binder, Err.Handler.class);
2954-
2955-
// parsers & renderers
2956-
Multibinder<Parser> parsers = Multibinder
2957-
.newSetBinder(binder, Parser.class);
2958-
2959-
Multibinder<Renderer> renderers = Multibinder
2960-
.newSetBinder(binder, Renderer.class);
2961-
2962-
// modules, routes, parsers, renderers and websockets
2963-
bag.forEach(candidate -> {
2964-
if (candidate instanceof Jooby.Module) {
2965-
install((Jooby.Module) candidate, env, config, binder);
2966-
} else if (candidate instanceof Route.Definition) {
2967-
definitions.addBinding().toInstance((Route.Definition) candidate);
2968-
} else if (candidate instanceof Route.Namespace) {
2969-
((Route.Namespace) candidate).routes()
2970-
.forEach(r -> definitions.addBinding().toInstance(r));
2971-
} else if (candidate instanceof WebSocket.Definition) {
2972-
sockets.addBinding().toInstance((WebSocket.Definition) candidate);
2973-
} else if (candidate instanceof Parser) {
2974-
parsers.addBinding().toInstance((Parser) candidate);
2975-
} else if (candidate instanceof Renderer) {
2976-
renderers.addBinding().toInstance((Renderer) candidate);
2977-
} else if (candidate instanceof Err.Handler) {
2978-
ehandlers.addBinding().toInstance((Err.Handler) candidate);
2979-
} else {
2980-
binder.bind((Class<?>) candidate);
2981-
MvcRoutes.routes(env, classInfo, (Class<?>) candidate)
2982-
.forEach(route -> definitions.addBinding().toInstance(route));
2983-
}
2984-
});
2985-
2986-
parsers.addBinding().toInstance(BuiltinParser.Basic);
2987-
parsers.addBinding().toInstance(BuiltinParser.Collection);
2988-
parsers.addBinding().toInstance(BuiltinParser.Optional);
2989-
parsers.addBinding().toInstance(BuiltinParser.Enum);
2990-
parsers.addBinding().toInstance(BuiltinParser.Upload);
2991-
parsers.addBinding().toInstance(BuiltinParser.Bytes);
2992-
parsers.addBinding().toInstance(new DateParser(dateFormat));
2993-
parsers.addBinding().toInstance(new LocalDateParser(dateTimeFormatter));
2994-
parsers.addBinding().toInstance(new LocaleParser());
2995-
parsers.addBinding().toInstance(new BeanParser());
2996-
parsers.addBinding().toInstance(new StaticMethodParser("valueOf"));
2997-
parsers.addBinding().toInstance(new StaticMethodParser("fromString"));
2998-
parsers.addBinding().toInstance(new StaticMethodParser("forName"));
2999-
parsers.addBinding().toInstance(new StringConstructorParser());
3000-
3001-
binder.bind(ParserExecutor.class).in(Singleton.class);
3002-
3003-
// renderer
3004-
renderers.addBinding().toInstance(BuiltinRenderer.Asset);
3005-
renderers.addBinding().toInstance(BuiltinRenderer.Bytes);
3006-
renderers.addBinding().toInstance(BuiltinRenderer.ByteBuffer);
3007-
renderers.addBinding().toInstance(BuiltinRenderer.File);
3008-
renderers.addBinding().toInstance(BuiltinRenderer.CharBuffer);
3009-
renderers.addBinding().toInstance(BuiltinRenderer.InputStream);
3010-
renderers.addBinding().toInstance(BuiltinRenderer.Reader);
3011-
renderers.addBinding().toInstance(BuiltinRenderer.FileChannel);
3012-
renderers.addBinding().toInstance(new DefaulErrRenderer());
3013-
renderers.addBinding().toInstance(BuiltinRenderer.ToString);
3014-
3015-
binder.bind(HttpHandler.class).to(HttpHandlerImpl.class).in(Singleton.class);
3016-
3017-
RequestScope requestScope = new RequestScope();
3018-
binder.bind(RequestScope.class).toInstance(requestScope);
3019-
binder.bindScope(RequestScoped.class, requestScope);
3020-
3021-
// session manager
3022-
binder.bind(SessionManager.class).asEagerSingleton();
3023-
binder.bind(Session.Definition.class).toInstance(session);
3024-
Object sstore = session.store();
3025-
if (sstore instanceof Class) {
3026-
binder.bind(Session.Store.class).to((Class<? extends Store>) sstore)
3027-
.asEagerSingleton();
2903+
/** type converters */
2904+
new TypeConverters().configure(binder);
2905+
2906+
/** bind config */
2907+
bindConfig(binder, config);
2908+
2909+
/** bind env */
2910+
binder.bind(Env.class).toInstance(env);
2911+
2912+
/** bind charset */
2913+
binder.bind(Charset.class).toInstance(charset);
2914+
2915+
/** bind locale */
2916+
binder.bind(Locale.class).toInstance(locale);
2917+
2918+
/** bind time zone */
2919+
binder.bind(ZoneId.class).toInstance(zoneId);
2920+
binder.bind(TimeZone.class).toInstance(TimeZone.getTimeZone(zoneId));
2921+
2922+
/** bind date format */
2923+
binder.bind(DateTimeFormatter.class).toInstance(dateTimeFormatter);
2924+
2925+
/** bind number format */
2926+
binder.bind(NumberFormat.class).toInstance(numberFormat);
2927+
binder.bind(DecimalFormat.class).toInstance(numberFormat);
2928+
2929+
/** bind managed */
2930+
LifecycleProcessor lifecycleProcessor = new LifecycleProcessor();
2931+
binder.bind(LifecycleProcessor.class).toInstance(lifecycleProcessor);
2932+
binder.bindListener(Matchers.any(), lifecycleProcessor);
2933+
2934+
/** routes */
2935+
Multibinder<Route.Definition> definitions = Multibinder
2936+
.newSetBinder(binder, Route.Definition.class);
2937+
2938+
/** web sockets */
2939+
Multibinder<WebSocket.Definition> sockets = Multibinder
2940+
.newSetBinder(binder, WebSocket.Definition.class);
2941+
2942+
/** tmp dir */
2943+
File tmpdir = new File(config.getString("application.tmpdir"));
2944+
tmpdir.mkdirs();
2945+
binder.bind(File.class).annotatedWith(Names.named("application.tmpdir"))
2946+
.toInstance(tmpdir);
2947+
2948+
RouteMetadata classInfo = new RouteMetadata(env);
2949+
binder.bind(ParameterNameProvider.class).toInstance(classInfo);
2950+
2951+
/** err handler */
2952+
Multibinder<Err.Handler> ehandlers = Multibinder
2953+
.newSetBinder(binder, Err.Handler.class);
2954+
2955+
/** parsers & renderers */
2956+
Multibinder<Parser> parsers = Multibinder
2957+
.newSetBinder(binder, Parser.class);
2958+
2959+
Multibinder<Renderer> renderers = Multibinder
2960+
.newSetBinder(binder, Renderer.class);
2961+
2962+
/** basic parser */
2963+
parsers.addBinding().toInstance(BuiltinParser.Basic);
2964+
parsers.addBinding().toInstance(BuiltinParser.Collection);
2965+
parsers.addBinding().toInstance(BuiltinParser.Optional);
2966+
parsers.addBinding().toInstance(BuiltinParser.Enum);
2967+
parsers.addBinding().toInstance(BuiltinParser.Upload);
2968+
parsers.addBinding().toInstance(BuiltinParser.Bytes);
2969+
2970+
/** basic render */
2971+
renderers.addBinding().toInstance(BuiltinRenderer.Asset);
2972+
renderers.addBinding().toInstance(BuiltinRenderer.Bytes);
2973+
renderers.addBinding().toInstance(BuiltinRenderer.ByteBuffer);
2974+
renderers.addBinding().toInstance(BuiltinRenderer.File);
2975+
renderers.addBinding().toInstance(BuiltinRenderer.CharBuffer);
2976+
renderers.addBinding().toInstance(BuiltinRenderer.InputStream);
2977+
renderers.addBinding().toInstance(BuiltinRenderer.Reader);
2978+
renderers.addBinding().toInstance(BuiltinRenderer.FileChannel);
2979+
2980+
/** modules, routes, parsers, renderers and websockets */
2981+
bag.forEach(candidate -> {
2982+
if (candidate instanceof Jooby.Module) {
2983+
install((Jooby.Module) candidate, env, config, binder);
2984+
} else if (candidate instanceof Route.Definition) {
2985+
definitions.addBinding().toInstance((Route.Definition) candidate);
2986+
} else if (candidate instanceof Route.Namespace) {
2987+
((Route.Namespace) candidate).routes()
2988+
.forEach(r -> definitions.addBinding().toInstance(r));
2989+
} else if (candidate instanceof WebSocket.Definition) {
2990+
sockets.addBinding().toInstance((WebSocket.Definition) candidate);
2991+
} else if (candidate instanceof Parser) {
2992+
parsers.addBinding().toInstance((Parser) candidate);
2993+
} else if (candidate instanceof Renderer) {
2994+
renderers.addBinding().toInstance((Renderer) candidate);
2995+
} else if (candidate instanceof Err.Handler) {
2996+
ehandlers.addBinding().toInstance((Err.Handler) candidate);
30282997
} else {
3029-
binder.bind(Session.Store.class).toInstance((Store) sstore);
3030-
;
2998+
binder.bind((Class<?>) candidate);
2999+
MvcRoutes.routes(env, classInfo, (Class<?>) candidate)
3000+
.forEach(route -> definitions.addBinding().toInstance(route));
30313001
}
3002+
});
3003+
3004+
parsers.addBinding().toInstance(new DateParser(dateFormat));
3005+
parsers.addBinding().toInstance(new LocalDateParser(dateTimeFormatter));
3006+
parsers.addBinding().toInstance(new LocaleParser());
3007+
parsers.addBinding().toInstance(new BeanParser());
3008+
parsers.addBinding().toInstance(new StaticMethodParser("valueOf"));
3009+
parsers.addBinding().toInstance(new StaticMethodParser("fromString"));
3010+
parsers.addBinding().toInstance(new StaticMethodParser("forName"));
3011+
parsers.addBinding().toInstance(new StringConstructorParser());
3012+
3013+
binder.bind(ParserExecutor.class).in(Singleton.class);
3014+
3015+
/** override(able) renderer */
3016+
renderers.addBinding().toInstance(new DefaulErrRenderer());
3017+
renderers.addBinding().toInstance(BuiltinRenderer.ToString);
3018+
3019+
binder.bind(HttpHandler.class).to(HttpHandlerImpl.class).in(Singleton.class);
3020+
3021+
RequestScope requestScope = new RequestScope();
3022+
binder.bind(RequestScope.class).toInstance(requestScope);
3023+
binder.bindScope(RequestScoped.class, requestScope);
3024+
3025+
/** session manager */
3026+
binder.bind(SessionManager.class).asEagerSingleton();
3027+
binder.bind(Session.Definition.class).toInstance(session);
3028+
Object sstore = session.store();
3029+
if (sstore instanceof Class) {
3030+
binder.bind(Session.Store.class).to((Class<? extends Store>) sstore)
3031+
.asEagerSingleton();
3032+
} else {
3033+
binder.bind(Session.Store.class).toInstance((Store) sstore);
3034+
}
30323035

3033-
binder.bind(Request.class).toProvider(Providers.outOfScope(Request.class))
3034-
.in(RequestScoped.class);
3036+
binder.bind(Request.class).toProvider(Providers.outOfScope(Request.class))
3037+
.in(RequestScoped.class);
30353038

3036-
binder.bind(Response.class).toProvider(Providers.outOfScope(Response.class))
3037-
.in(RequestScoped.class);
3039+
binder.bind(Response.class).toProvider(Providers.outOfScope(Response.class))
3040+
.in(RequestScoped.class);
30383041

3039-
binder.bind(Session.class).toProvider(Providers.outOfScope(Session.class))
3040-
.in(RequestScoped.class);
3042+
binder.bind(Session.class).toProvider(Providers.outOfScope(Session.class))
3043+
.in(RequestScoped.class);
30413044

3042-
// def err
3043-
ehandlers.addBinding().toInstance(new Err.DefHandler());
3044-
});
3045+
/** def err */
3046+
ehandlers.addBinding().toInstance(new Err.DefHandler());
3047+
});
30453048

30463049
return injector;
30473050
}

0 commit comments

Comments
 (0)