/
GlobalCommandResponseRegistry.java
106 lines (90 loc) · 4.38 KB
/
GlobalCommandResponseRegistry.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
* Copyright (c) 2019 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.ditto.signals.commands.base;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.concurrent.Immutable;
import org.atteo.classindex.ClassIndex;
import org.eclipse.ditto.json.JsonObject;
import org.eclipse.ditto.model.base.headers.DittoHeaders;
import org.eclipse.ditto.model.base.json.JsonParsableCommandResponse;
import org.eclipse.ditto.signals.base.AbstractJsonParsableRegistry;
import org.eclipse.ditto.signals.base.DeserializationStrategyNotFoundError;
import org.eclipse.ditto.signals.base.JsonParsable;
import org.eclipse.ditto.signals.base.JsonTypeNotParsableException;
/**
* Contains all strategies to deserialize subclasses of {@link Command} from a combination of
* {@link JsonObject} and {@link DittoHeaders}.
*/
@Immutable
public final class GlobalCommandResponseRegistry extends AbstractJsonParsableRegistry<CommandResponse>
implements CommandResponseRegistry<CommandResponse> {
private static final GlobalCommandResponseRegistry INSTANCE =
new GlobalCommandResponseRegistry(new JsonParsableCommandResponseRegistry());
private GlobalCommandResponseRegistry(final JsonParsableCommandResponseRegistry jsonParsableRegistry) {
super(jsonParsableRegistry.getParseRegistries());
}
/**
* Gets an INSTANCE of GlobalCommandResponseRegistry.
*
* @return the INSTANCE of GlobalCommandResponseRegistry.
*/
public static GlobalCommandResponseRegistry getInstance() {
return INSTANCE;
}
/**
* Contains all strategies to deserialize {@link CommandResponse} annotated with {@link JsonParsableCommandResponse}
* from a combination of {@link JsonObject} and {@link DittoHeaders}.
*/
private static final class JsonParsableCommandResponseRegistry {
private static final Class<?> JSON_OBJECT_PARAMETER = JsonObject.class;
private static final Class<?> DITTO_HEADERS_PARAMETER = DittoHeaders.class;
private final Map<String, JsonParsable<CommandResponse>> parseRegistries = new HashMap<>();
private JsonParsableCommandResponseRegistry() {
final Iterable<Class<?>> jsonParsableCommandResponses =
ClassIndex.getAnnotated(JsonParsableCommandResponse.class);
jsonParsableCommandResponses.forEach(parsableCommandResponse -> {
final JsonParsableCommandResponse fromJsonAnnotation =
parsableCommandResponse.getAnnotation(JsonParsableCommandResponse.class);
try {
final String methodName = fromJsonAnnotation.method();
final String type = fromJsonAnnotation.type();
final Method method = parsableCommandResponse.getMethod(methodName, JSON_OBJECT_PARAMETER,
DITTO_HEADERS_PARAMETER);
appendMethodToParseStrategies(type, method);
} catch (final NoSuchMethodException e) {
throw new DeserializationStrategyNotFoundError(parsableCommandResponse, e);
}
});
}
private void appendMethodToParseStrategies(final String type, final Method method) {
parseRegistries.put(type, (jsonObject, dittoHeaders) -> {
try {
return (CommandResponse) method.invoke(null, jsonObject, dittoHeaders);
} catch (final IllegalAccessException | InvocationTargetException e) {
throw JsonTypeNotParsableException.newBuilder(type, getClass().getSimpleName())
.dittoHeaders(dittoHeaders).build();
}
});
}
private Map<String, JsonParsable<CommandResponse>> getParseRegistries() {
return new HashMap<>(parseRegistries);
}
}
@Override
protected String resolveType(final JsonObject jsonObject) {
return jsonObject.getValueOrThrow(CommandResponse.JsonFields.TYPE);
}
}