Skip to content
This repository was archived by the owner on Mar 3, 2026. It is now read-only.

Commit f708465

Browse files
committed
Code cleanup and refactor
1 parent 4fb9194 commit f708465

40 files changed

Lines changed: 793 additions & 428 deletions

examples/src/main/java/jooby/MyApp.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,9 @@
203203
*/
204204
package jooby;
205205

206-
import com.google.common.collect.ImmutableMap;
206+
import jooby.mvc.Viewable;
207207

208+
import com.google.common.collect.ImmutableMap;
208209

209210
public class MyApp extends Jooby {
210211

@@ -214,11 +215,19 @@ public class MyApp extends Jooby {
214215
use(new Jackson());
215216
use(new Hbs());
216217

217-
get("/", (req, resp) -> {
218+
get("/api", (req, resp) -> {
218219
ImmutableMap<Object, Object> model = ImmutableMap.builder()
219-
.put("name", "K")
220-
.build();
221-
resp.send(model);
220+
.put("name", "K")
221+
.build();
222+
223+
resp.when("text/html", () -> new Viewable("index", model))
224+
.send(() -> model);
225+
226+
});
227+
228+
post("/inline", (req, resp) -> {
229+
User body = req.body(User.class);
230+
resp.send(body);
222231
});
223232

224233
route(Resource.class);
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
package jooby;
22

3+
import jooby.mvc.Body;
34
import jooby.mvc.GET;
5+
import jooby.mvc.POST;
46
import jooby.mvc.Path;
5-
import jooby.mvc.Produces;
67

78
import com.google.common.collect.ImmutableMap;
89

910
@Path("/resource")
1011
public class Resource {
1112

1213
@GET
13-
// @Produces({"text/html", "application/json"})
14-
@Produces({"application/json" })
15-
// @Produces({"*/*" })
1614
public Object index(final String name) {
1715
return ImmutableMap.builder()
1816
.put("name", name)
1917
.build();
2018
}
19+
20+
public @POST Object user(final @Body User user) {
21+
return user;
22+
}
2123
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package jooby;
2+
3+
public class User {
4+
5+
private String firstName;
6+
7+
private String lastName;
8+
9+
public String getFirstName() {
10+
return firstName;
11+
}
12+
13+
public String getLastName() {
14+
return lastName;
15+
}
16+
17+
public void setFirstName(final String firstName) {
18+
this.firstName = firstName;
19+
}
20+
21+
public void setLastName(final String lastName) {
22+
this.lastName = lastName;
23+
}
24+
25+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package jooby;
2+
3+
import java.util.List;
4+
5+
import com.google.common.collect.Multimap;
6+
7+
public interface BodyMapper {
8+
9+
List<MediaType> types();
10+
11+
<T> T read(Class<T> type, BodyReader reader) throws Exception;
12+
13+
void write(Object message, BodyWriter writer, Multimap<String, String> headers) throws Exception;
14+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package jooby;
2+
3+
import static com.google.common.base.Preconditions.checkState;
4+
5+
import java.util.HashMap;
6+
import java.util.List;
7+
import java.util.Map;
8+
import java.util.Optional;
9+
import java.util.Set;
10+
import java.util.TreeMap;
11+
12+
import javax.inject.Inject;
13+
import javax.inject.Singleton;
14+
15+
import jooby.MediaType.Matcher;
16+
import jooby.internal.ForwardingMessageConverter;
17+
18+
import com.google.common.base.Joiner;
19+
20+
@Singleton
21+
public class BodyMapperSelector {
22+
23+
private Set<BodyMapper> converters;
24+
25+
private Map<MediaType, BodyMapper> converterMap = new HashMap<>();
26+
27+
@Inject
28+
public BodyMapperSelector(final Set<BodyMapper> converters) {
29+
checkState(converters != null && converters.size() > 0, "No message converters were found.");
30+
this.converters = converters;
31+
converters.forEach(c -> c.types().forEach(t -> converterMap.put(t, c)));
32+
}
33+
34+
public Optional<BodyMapper> get(final Class<?> type, final List<MediaType> supported) {
35+
for (BodyMapper converter : converters) {
36+
for (MediaType it : supported) {
37+
if (converter.types().contains(it)) {
38+
return Optional.of(converter);
39+
}
40+
}
41+
}
42+
return Optional.empty();
43+
}
44+
45+
public BodyMapper getOrThrow(final Iterable<MediaType> candidates, final HttpStatus status) {
46+
return get(candidates)
47+
.orElseThrow(
48+
() -> new HttpException(status, Joiner.on(", ").join(candidates))
49+
);
50+
}
51+
52+
public Optional<BodyMapper> get(final Iterable<MediaType> candidates) {
53+
for (MediaType mediaType : candidates) {
54+
BodyMapper converter = converterMap.get(mediaType);
55+
if (converter != null) {
56+
return Optional.of(converter);
57+
}
58+
}
59+
// degrade lookup
60+
Matcher matcher = MediaType.matcher(candidates);
61+
TreeMap<MediaType, BodyMapper> matches = new TreeMap<>();
62+
for (BodyMapper converter : converters) {
63+
matcher.first(converter.types()).ifPresent((m) -> matches.putIfAbsent(m, converter));
64+
}
65+
if (matches.isEmpty()) {
66+
return Optional.empty();
67+
}
68+
Map.Entry<MediaType, BodyMapper> entry = matches.firstEntry();
69+
return Optional.of(new ForwardingMessageConverter(entry.getValue(), entry.getKey()));
70+
}
71+
72+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package jooby;
2+
3+
import java.io.InputStream;
4+
import java.io.Reader;
5+
6+
public interface BodyReader {
7+
8+
interface Binary {
9+
Object read(InputStream in) throws Exception;
10+
}
11+
12+
interface Text {
13+
Object read(Reader reader) throws Exception;
14+
}
15+
16+
<T> T text(Text text) throws Exception;
17+
18+
<T> T bytes(Binary bin) throws Exception;
19+
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package jooby;
2+
3+
import java.io.OutputStream;
4+
import java.io.Writer;
5+
6+
public interface BodyWriter {
7+
8+
public interface Binary {
9+
void write(OutputStream out) throws Exception;
10+
}
11+
12+
public interface Text {
13+
void write(Writer writer) throws Exception;
14+
}
15+
16+
void text(Text text) throws Exception;
17+
18+
void bytes(Binary bin) throws Exception;
19+
20+
}

jooby-core/src/main/java/jooby/Jooby.java

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@
2727

2828
public class Jooby {
2929

30-
private Set<RouteDefinition> routes = new LinkedHashSet<>();
31-
32-
private Set<Class<?>> routeClasses = new LinkedHashSet<>();
30+
private Set<Object> routes = new LinkedHashSet<>();
3331

3432
private Set<JoobyModule> modules = new LinkedHashSet<>();
3533

@@ -39,8 +37,12 @@ public RouteDefinition get(final String path, final Route route) {
3937
return route(new RouteDefinition("GET", path, route));
4038
}
4139

40+
public RouteDefinition post(final String path, final Route route) {
41+
return route(new RouteDefinition("POST", path, route));
42+
}
43+
4244
public void route(final Class<?> route) {
43-
routeClasses.add(route);
45+
routes.add(route);
4446
}
4547

4648
public RouteDefinition route(final RouteDefinition route) {
@@ -83,15 +85,15 @@ public void configure(final Binder binder) {
8385
bindConfig(binder, config);
8486

8587
// bind mode
86-
Mode mode = mode(config.getString("application.mode"));
88+
Mode mode = mode(config.getString("application.mode").toLowerCase());
8789
binder.bind(Mode.class).toInstance(mode);
8890

8991
// bind charset
9092
binder.bind(Charset.class).toInstance(charset);
9193

9294
// bind readers & writers
93-
Multibinder<MessageConverter> converters = Multibinder
94-
.newSetBinder(binder, MessageConverter.class);
95+
Multibinder<BodyMapper> converters = Multibinder
96+
.newSetBinder(binder, BodyMapper.class);
9597

9698
// Routes
9799
Multibinder<RouteDefinition> definitions = Multibinder
@@ -107,8 +109,15 @@ public void configure(final Binder binder) {
107109
});
108110

109111
// Routes
110-
routes.forEach(route -> definitions.addBinding().toInstance(route));
111-
install(new Routes(routeClasses), mode, config, binder);
112+
routes.forEach(route -> {
113+
if (route instanceof RouteDefinition) {
114+
definitions.addBinding().toInstance((RouteDefinition) route);
115+
} else {
116+
Routes.route(mode, (Class<?>) route)
117+
.forEach(mvcRoute -> definitions.addBinding().toInstance(mvcRoute)
118+
);
119+
}
120+
});
112121

113122
converters.addBinding().toInstance(new StringMessageConverter(MediaType.plain));
114123
}

jooby-core/src/main/java/jooby/MediaType.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import java.util.Optional;
1111
import java.util.SortedSet;
1212
import java.util.TreeSet;
13-
import java.util.stream.Collectors;
1413

1514
import com.google.common.collect.ImmutableList;
1615
import com.google.common.collect.ImmutableMap;
@@ -20,9 +19,9 @@ public class MediaType implements Comparable<MediaType> {
2019

2120
public static class Matcher {
2221

23-
private List<MediaType> acceptable;
22+
private Iterable<MediaType> acceptable;
2423

25-
Matcher(final List<MediaType> acceptable) {
24+
Matcher(final Iterable<MediaType> acceptable) {
2625
this.acceptable = acceptable;
2726
}
2827

@@ -38,11 +37,11 @@ public Optional<MediaType> first(final MediaType candidate) {
3837
return first(ImmutableList.of(candidate));
3938
}
4039

41-
public Optional<MediaType> first(final List<MediaType> candidates) {
40+
public Optional<MediaType> first(final Iterable<MediaType> candidates) {
4241
return Optional.ofNullable(doFirst(candidates));
4342
}
4443

45-
public List<MediaType> filter(final List<MediaType> candidates) {
44+
public List<MediaType> filter(final Iterable<MediaType> candidates) {
4645
List<MediaType> result = new ArrayList<>();
4746
for (MediaType accept : acceptable) {
4847
for (MediaType candidate : candidates) {
@@ -122,7 +121,7 @@ public String subtype() {
122121
return subtype;
123122
}
124123

125-
public String toContentType() {
124+
public String name() {
126125
return type + "/" + subtype;
127126
}
128127

@@ -190,8 +189,7 @@ public int hashCode() {
190189

191190
@Override
192191
public final String toString() {
193-
return type + "/" + subtype + ";"
194-
+ params.entrySet().stream().map(e -> e.toString()).collect(Collectors.joining(";"));
192+
return name();
195193
}
196194

197195
public static MediaType valueOf(final String mediaType) {
@@ -233,7 +231,7 @@ public static Matcher matcher(final MediaType acceptable) {
233231
return matcher(ImmutableList.of(acceptable));
234232
}
235233

236-
public static Matcher matcher(final List<MediaType> acceptable) {
234+
public static Matcher matcher(final Iterable<MediaType> acceptable) {
237235
return new Matcher(acceptable);
238236
}
239237

jooby-core/src/main/java/jooby/MessageConverter.java

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)