Reputation: 7875
I have a class that has a field of type Map
. I'm creating a CompactSerializer
to read and write this class to a map in Hazelcast (version 5.1). But I can't figure out how to serialize the map field. There are no methods on the CompactReader
or CompactWriter
that work with Maps.
Here's a simplified version of the class and it's incomplete serializer:
data class User(
val id: String,
val authoritiesByOrgId: Map<String, Set<String>>
)
class UserSerializer: CompactSerializer<User> {
override fun read(reader: CompactReader): User {
val id = reader.readString("id")
val authoritiesByOrgId = // What goes here?
return User(
id,
authoritiesByOrgId
)
}
override fun write(writer: CompactWriter, user: User) {
writer.apply {
writeString("id", user.id)
write???("authoritiesByOrgId", user.authoritiesByOrgId) // TODO What goes here?
}
}
}
Upvotes: 1
Views: 492
Reputation: 266
This is a bit hard because of two things. Right now, Compact related APIs do not support
However, there are workarounds. One could write a Compact serializer for your class as below:
class UserSerializer implements CompactSerializer<User> {
@Override
public User read(CompactReader reader) {
String id = reader.readString("id");
String[] keys = reader.readArrayOfString("orgIds");
SetWrapper[] values = reader.readArrayOfCompact("authorities", SetWrapper.class);
HashMap<String, Set<String>> authoritiesByOrgId = new HashMap<>(keys.length);
for (int i = 0; i < keys.length; i++) {
authoritiesByOrgId.put(keys[i], values[i].getSet());
}
return new User(id, authoritiesByOrgId);
}
@Override
public void write(CompactWriter writer, User object) {
// Write id as it is
writer.writeString("id", object.getId());
// Serialize map as 2 arrays, one for keys, one for values
Map<String, Set<String>> authoritiesByOrgId = object.getAuthoritiesByOrgId();
// keys
writer.writeArrayOfString("orgIds",
authoritiesByOrgId.keySet().toArray(new String[0]));
// Since arrays of arrays are not supported yet, wrap the array in
// another type
writer.writeArrayOfCompact("authorities",
authoritiesByOrgId.values().stream()
.map(SetWrapper::new)
.toArray());
}
@Override
public String getTypeName() {
return "user";
}
@Override
public Class<User> getCompactClass() {
return User.class;
}
}
class SetWrapperSerializer implements CompactSerializer<SetWrapper> {
@Override
public SetWrapper read(CompactReader reader) {
String[] set = reader.readArrayOfString("set");
return new SetWrapper(new HashSet<>(Arrays.asList(set)));
}
@Override
public void write(CompactWriter writer, SetWrapper object) {
object.getSet().toArray(new String[0]);
writer.writeArrayOfString("set", object.getSet().toArray(new String[0]));
}
@Override
public String getTypeName() {
return "set-wrapper";
}
@Override
public Class<SetWrapper> getCompactClass() {
return SetWrapper.class;
}
}
class SetWrapper {
private final Set<String> set;
SetWrapper(Set<String> set) {
this.set = set;
}
public Set<String> getSet() {
return set;
}
}
class User {
private final String id;
private final Map<String, Set<String>> authoritiesByOrgId;
User(String id, Map<String, Set<String>> authoritiesByOrgId) {
this.id = id;
this.authoritiesByOrgId = authoritiesByOrgId;
}
public String getId() {
return id;
}
public Map<String, Set<String>> getAuthoritiesByOrgId() {
return authoritiesByOrgId;
}
}
So, the core ideas are
Upvotes: 2