I have a class SessionFlowModel that I can easily serialize. However, due to the use of ObservableLists, which is the model for a JavaFX tableView where the user can select certain cells
public class SessionFlowModel {
@JsonDeserialize(using = JsonObservableListAdapter.class)
protected ObservableList<ObservableList<Boolean>> selectableMatrix; // matrix indicating whether a transition between two exercises is possible or not
protected ObservableList<Exercise> exercises; // the list of exercises for the x-axis and y-axis
@JsonIgnore
protected DynamicSessionCtrl ctrl; // reference to the UI controller to inform the UI on necessary updates
// getter and setter here
}
In a class that manages persistance I defined
public void saveFlow(File file, SessionFlowModel flowModel) {
try {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writeValue(file, flowModel);
} catch (Exception e) {
debugLogger.fine("Cannot save flowModel to " + file.getAbsolutePath());
e.printStackTrace();
}
}
public void loadFlow(File file, SessionFlowModel flowModel) {
try {
ObjectMapper objectMapper = new ObjectMapper();
SessionFlowModel readModel = objectMapper.readValue(file,SessionFlowModel.class);
flowModel.setExercises(readModel.getExercises());
flowModel.setObservableSelectableMatrix(readModel.getSelectableMatrix());
} catch (Exception e) {
debugLogger.fine("Cannot load flowModel from " + file.getAbsolutePath());
e.printStackTrace();
}
}
While the method saveFlow works fine, the loadFlow method is not triggering the below JsonObservableListAdapter class deserialize method as annotated in SessionFlowModel selectableMatrix attribute (see above).
public class JsonObservableListAdapter extends JsonDeserializer<ObservableList<ObservableList<Boolean>>> {
public JsonObservableListAdapter() {
}
@Override
public ObservableList<ObservableList<Boolean>> deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException, JacksonException {
ObservableList<ObservableList<Boolean>> matrix = FXCollections.observableArrayList();
ObjectMapper objectMapper = (ObjectMapper) parser.getCodec();
JsonNode node = objectMapper.readTree(parser);
JsonNode childList = node.get("selectableMatrix");
for (Iterator<JsonNode> i = childList.iterator(); i.hasNext();) {
JsonNode childNode = i.next();
}
return matrix;
}
}
What am I missing?
If the approach with the annotation @JsonDeserialize
does not work, you can try the other approach possible using the class SimpleModule
to register your custom deserializer (JsonObservableListAdapter
) with the ObjectMapper. Getting Started with Custom Deserialization in Jackson.
public void loadFlow(File file, SessionFlowModel flowModel) {
try {
ObjectMapper objectMapper = new ObjectMapper();
// Register the custom deserializer
SimpleModule module = new SimpleModule();
//module.addDeserializer(ObservableList.class, new JsonObservableListAdapter());
module.addDeserializer(new TypeReference<ObservableList<ObservableList<Boolean>>>() {}, new JsonObservableListAdapter());
objectMapper.registerModule(module);
SessionFlowModel readModel = objectMapper.readValue(file,SessionFlowModel.class);
flowModel.setExercises(readModel.getExercises());
flowModel.setObservableSelectableMatrix(readModel.getSelectableMatrix());
} catch (Exception e) {
debugLogger.fine("Cannot load flowModel from " + file.getAbsolutePath());
e.printStackTrace();
}
}