1+ /**
2+ * Licensed to the Apache Software Foundation (ASF) under one
3+ * or more contributor license agreements. See the NOTICE file
4+ * distributed with this work for additional information
5+ * regarding copyright ownership. The ASF licenses this file
6+ * to you under the Apache License, Version 2.0 (the
7+ * "License"); you may not use this file except in compliance
8+ * with the License. You may obtain a copy of the License at
9+ *
10+ * http://www.apache.org/licenses/LICENSE-2.0
11+ *
12+ * Unless required by applicable law or agreed to in writing,
13+ * software distributed under the License is distributed on an
14+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+ * KIND, either express or implied. See the License for the
16+ * specific language governing permissions and limitations
17+ * under the License.
18+ */
119package org .jooby ;
220
321import java .io .OutputStream ;
725
826import com .google .common .collect .ImmutableList ;
927
28+ /**
29+ * Write a value into the HTTP response and apply a format, if need it.
30+ *
31+ * Renderers are executed in the order they were registered. The first renderer that write a
32+ * response wins!
33+ *
34+ * There are two ways of registering a rendering:
35+ *
36+ * <pre>
37+ * {
38+ * renderer((value, ctx) {@literal ->} {
39+ * ...
40+ * });
41+ * }
42+ * </pre>
43+ *
44+ * Or from inside a module:
45+ *
46+ * <pre>
47+ * {
48+ * use((env, conf, binder) {@literal ->} {
49+ * Multibinder.newSetBinder(binder, Renderer.class)
50+ * .addBinding()
51+ * .toInstance(renderer((value, ctx) {@literal ->} {
52+ * ...
53+ * }));
54+ * });
55+ * }
56+ * </pre>
57+ *
58+ * Inside a {@link Renderer} you can do whatever you want. For example you can check for a specific
59+ * type:
60+ *
61+ * <pre>
62+ * renderer((value, ctx) {@literal ->} {
63+ * if (value instanceof MyObject) {
64+ * ctx.text(value.toString());
65+ * }
66+ * });
67+ * </pre>
68+ *
69+ * For check for the <code>Accept</code> header:
70+ *
71+ * <pre>
72+ * renderer((value, ctx) {@literal ->} {
73+ * if (ctx.accepts("json")) {
74+ * ctx.text(toJson(value));
75+ * }
76+ * });
77+ * </pre>
78+ *
79+ * API is simply and powerful! It is so powerful that you can override any of the existing built-in
80+ * renderers, because application specific renderers has precedence over built-in renderers.
81+ *
82+ * @author edgar
83+ * @since 0.6.0
84+ */
1085public interface Renderer {
1186
1287 /**
@@ -47,18 +122,39 @@ interface Text {
47122 void write (java .io .Writer writer ) throws Exception ;
48123 }
49124
125+ /**
126+ * Contains a few utility methods for doing the actual rendering and writing.
127+ *
128+ * @author edgar
129+ * @since 0.6.0
130+ */
50131 interface Context {
51132
133+ /**
134+ * @return Request attributes.
135+ */
52136 Map <String , Object > locals ();
53137
138+ /**
139+ * @param type The type to check for.
140+ * @return True if the given type matches the <code>Accept</code> header.
141+ */
54142 default boolean accepts (final String type ) {
55143 return accepts (MediaType .valueOf (type ));
56144 }
57145
146+ /**
147+ * @param type The type to check for.
148+ * @return True if the given type matches the <code>Accept</code> header.
149+ */
58150 default boolean accepts (final MediaType type ) {
59151 return accepts (ImmutableList .of (type ));
60152 }
61153
154+ /**
155+ * @param types Types to check for.
156+ * @return True if the given type matches the <code>Accept</code> header.
157+ */
62158 boolean accepts (List <MediaType > types );
63159
64160 /**
@@ -71,14 +167,17 @@ default boolean accepts(final MediaType type) {
71167 Context type (MediaType type );
72168
73169 /**
74- * Set the <code>Content-Length</code> header IF and ONLY IF, no <code>Content-Length</code>
75- * was set yet.
170+ * Set the <code>Content-Length</code> header IF and ONLY IF, no <code>Content-Length</code> was
171+ * set yet.
76172 *
77173 * @param length A suggested length to use if one is missing.
78174 * @return This context.
79175 */
80176 Context length (long length );
81177
178+ /**
179+ * @return Charset to use while writing text responses.
180+ */
82181 Charset charset ();
83182
84183 /**
@@ -100,5 +199,13 @@ default boolean accepts(final MediaType type) {
100199
101200 }
102201
202+ /**
203+ * Render the given value and write the response (if possible). If no response is written, the
204+ * next renderer in the chain will be invoked.
205+ *
206+ * @param object Object to render.
207+ * @param ctx Rendering context.
208+ * @throws Exception If rendering fails.
209+ */
103210 void render (Object object , Context ctx ) throws Exception ;
104211}
0 commit comments