Created
January 27, 2021 19:59
-
-
Save bion/d114a99887582777f5b5e6968460f8c8 to your computer and use it in GitHub Desktop.
JsonPath approach
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// <input name="applicant.employments[2].employerName" type="text" /> | |
// employer.name | |
// employer.address.zip | |
// employer.address.street | |
class Update { | |
UpdatePath path; | |
Value value; | |
} | |
class UpdatePath { | |
// { applicant, pet's names, 1 } | |
// e.g. "applicant.dependents[1].employers[2].address.zip" | |
// becomes | |
// { applicant, dependents, 1, employers, 2, address, zip } | |
List<String> path; | |
List<String> getParentPath() { | |
return path.subList(0, path.size() - 1); | |
} | |
String getPropertyName() { | |
return Iterables.last(path); | |
} | |
} | |
class UpdateResult { | |
boolean success; | |
Map<String, String> validationMessages; | |
UpdateResult(success, validationMessages) { | |
// etc. | |
} | |
boolean isSuccess() { | |
return success; | |
} | |
} | |
class UpdateStrategyFactory { | |
UpdateStrategy strategyFor(ApplicationVersion version, String path) { | |
// get the specific application version out of the questions table | |
// use that to figure out which type this path corresponds to | |
// get the update strategy for that type | |
} | |
} | |
// Processing a form submission | |
// ************************************************************************* | |
DynamicForm requestData = formFactory.form().bindFromRequest(request); | |
// form submissions include a list of updates | |
List<Update> updates = requestData | |
.getFields() | |
.stream() | |
.map(field -> new Update(field.getName(), field.getValue())); | |
// updates are applied | |
Applicant applicant = Ebean.find(Applicant.class) | |
.email.equalTo("rob@foo.bar") | |
.findOne(); | |
DocumentContext applicantData = applicant.getObject(); | |
List<UpdateStrategy> strategies = new ArrayList(); | |
updates.forEach(update -> { | |
String parentPath = update.getParentJsonPath(); | |
JsonNode node = applicantData.get(parentJsonPath); | |
if (node == null) { | |
// gets the JSON object for this path. if the path is | |
// invalid, it throws | |
node = answerNodeFactory.getNodeForPath(parentPath); | |
} | |
UpdateStrategy strategy = updateStrategyFactory | |
.strategyFor(applicant.getApplicationVersion(), parentPath); | |
strategy.setTargetNode(node); | |
strategy.setUpdate(update); | |
strategy.updateTarget(); | |
}); | |
// run validations on all "dirty" objects | |
Result result = ValidatorFactory.runAllFor(strategies); | |
// if validations pass, new state is persisted | |
if (result.isSuccess()) { | |
applicant.save(); | |
return ok(...); | |
} else { | |
// or something like this, messages will need to be mapped to form input elements | |
return badRequest(formState, result.errorMessages); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment