Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public FilingInformationDocassembleJacksonDeserializer(
* @throws FilingError
*/
private static List<Person> collectPeople(
JsonNode topObj, String potentialMember, InfoCollector collector) throws FilingError {
JsonNode topObj, String potentialMember, CodesParser parser, InfoCollector collector)
throws FilingError {
if (!topObj.has(potentialMember)) {
return List.of(); // Just an empty list: we don't know if it's required
}
Expand All @@ -77,7 +78,7 @@ private static List<Person> collectPeople(
JsonNode personJson = peopleElements.get(i);
collector.pushAttributeStack(potentialMember + "[" + i + "]");
Result<Person, FilingError> per =
PersonDocassembleJacksonDeserializer.fromNode(personJson, collector);
PersonDocassembleJacksonDeserializer.fromNode(personJson, parser, collector);
collector.popAttributeStack();
if (per.isErr()) {
FilingError ex = per.unwrapErrOrElseThrow();
Expand All @@ -103,8 +104,8 @@ public FilingInformation fromNode(JsonNode node, InfoCollector collector) throws
boolean isInitialFiling =
entities.getPreviousCaseId().isEmpty() && entities.getCaseDocketNumber().isEmpty();

List<Person> users = collectPeople(node, "users", collector);
List<Person> otherParties = collectPeople(node, "other_parties", collector);
List<Person> users = collectPeople(node, "users", parser, collector);
List<Person> otherParties = collectPeople(node, "other_parties", parser, collector);

var varToPartyId = new HashMap<String, PartyId>();
int perIdx = 0;
Expand Down Expand Up @@ -323,7 +324,8 @@ public FilingInformation fromNode(JsonNode node, InfoCollector collector) throws
} else {
collector.pushAttributeStack("lead_contact");
Result<Person, FilingError> per =
PersonDocassembleJacksonDeserializer.fromNode(node.get("lead_contact"), collector);
PersonDocassembleJacksonDeserializer.fromNode(
node.get("lead_contact"), parser, collector);
collector.popAttributeStack();
if (per.isErr()) {
FilingError ex = per.unwrapErrOrElseThrow();
Expand Down Expand Up @@ -544,7 +546,8 @@ private Optional<LowerCourtInfo> extractLowerCourt(JsonNode node, InfoCollector
} else if (jsonLowerCase.get("judge").isObject()) {
collector.pushAttributeStack("judge");
judgeName =
NameDocassembleDeserializer.fromNode(jsonLowerCase.get("judge"), collector).getFullName();
NameDocassembleDeserializer.fromNode(jsonLowerCase.get("judge"), parser, collector)
.getFullName();
collector.popAttributeStack();
}
Optional<String> title = JsonHelpers.getStringMember(jsonLowerCase, "title");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.NullNode;
import com.hubspot.algebra.Result;
import edu.suffolk.litlab.efsp.model.Name;
import edu.suffolk.litlab.efsp.server.ecf4.CodesParser;
import edu.suffolk.litlab.efsp.server.ecf4.CodesParser.CodeError;
import edu.suffolk.litlab.efsp.server.ecf4.CodesParser.TextVarError;
import edu.suffolk.litlab.efsp.utils.FilingError;
import edu.suffolk.litlab.efsp.utils.InfoCollector;
import edu.suffolk.litlab.efsp.utils.InterviewVariable;
import edu.suffolk.litlab.efsp.utils.InterviewVariable.VarBuilder;

public class NameDocassembleDeserializer {

public static Name fromNode(JsonNode node, InfoCollector collector) throws FilingError {
public static Name fromNode(JsonNode node, CodesParser parser, InfoCollector collector)
throws FilingError {
if (node == null || node.isNull()) {
InterviewVariable var =
collector.requestVar("name", "The full name of the person", "IndividualName");
Expand All @@ -33,17 +39,66 @@ public static Name fromNode(JsonNode node, InfoCollector collector) throws Filin
"name.first", "The first name of a person / name of a business", "text");
collector.addRequired(var);
}
var firstBuilder =
collector
.varBuilder()
.name("name.first")
.description("The first name of a person / name of a business")
.datatype("text");
String firstName =
unwrap(parser.vetFirstName(getStringMember(node, "first")), collector, firstBuilder);
var middleBuilder =
collector
.varBuilder()
.name("name.middle")
.description("The middle name of a person")
.datatype("text");
String middleName =
unwrap(parser.vetMiddleName(getStringMember(node, "middle")), collector, middleBuilder);
var lastBuilder =
collector
.varBuilder()
.name("name.last")
.description("The last name of a person")
.datatype("text");
String lastName =
unwrap(parser.vetLastName(getStringMember(node, "last")), collector, lastBuilder);

var suffixBuilder =
collector.varBuilder().name("name.suffix").description("The suffix of a person's name");
var suffix =
unwrapCode(parser.vetSuffix(getStringMember(node, "suffix")), collector, suffixBuilder);

Name name =
new Name(
"", // TODO(#55): where should we handle prefixes? Are they always empty?
getStringMember(node, "first").orElse(""),
getStringMember(node, "middle").orElse(""),
getStringMember(node, "last").orElse(""),
getStringMember(node, "suffix").orElse(""),
firstName,
middleName,
lastName,
suffix,
"" // TODO(#55): where would Maiden name go, if asked for?
);

return name;
}

private static String unwrap(
Result<String, TextVarError> res, InfoCollector collector, VarBuilder varBuilder)
throws FilingError {
if (res.isErr()) {
collector.addTextError(res.unwrapErrOrElseThrow(), varBuilder);
return "";
}
return res.unwrapOrElseThrow();
}

private static String unwrapCode(
Result<String, CodeError> res, InfoCollector collector, VarBuilder varBuilder)
throws FilingError {
if (res.isErr()) {
collector.addCodeError(res.unwrapErrOrElseThrow(), varBuilder);
return "";
}
return res.unwrapOrElseThrow();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import edu.suffolk.litlab.efsp.model.ContactInformation;
import edu.suffolk.litlab.efsp.model.Name;
import edu.suffolk.litlab.efsp.model.Person;
import edu.suffolk.litlab.efsp.server.ecf4.CodesParser;
import edu.suffolk.litlab.efsp.utils.FilingError;
import edu.suffolk.litlab.efsp.utils.InfoCollector;
import edu.suffolk.litlab.efsp.utils.InterviewVariable;
Expand All @@ -31,8 +32,8 @@ protected PersonDocassembleJacksonDeserializer() {}
*
* @throws FilingError
*/
public static Result<Person, FilingError> fromNode(JsonNode node, InfoCollector collector)
throws FilingError {
public static Result<Person, FilingError> fromNode(
JsonNode node, CodesParser parser, InfoCollector collector) throws FilingError {
if (!node.isObject()) {
FilingError err =
FilingError.malformedInterview(
Expand Down Expand Up @@ -112,7 +113,7 @@ public static Result<Person, FilingError> fromNode(JsonNode node, InfoCollector
})
.orElse(Optional.<LocalDate>empty());
collector.pushAttributeStack("name");
Name name = NameDocassembleDeserializer.fromNode(node.get("name"), collector);
Name name = NameDocassembleDeserializer.fromNode(node.get("name"), parser, collector);
collector.popAttributeStack();
boolean isPer = !name.getMiddleName().isBlank() || !name.getLastName().isBlank();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import edu.suffolk.litlab.efsp.utils.FilingError;
import java.util.List;
import java.util.Optional;
import java.util.regex.Pattern;

public interface CodesParser {
// Types specifically for errors.
Expand All @@ -16,6 +17,11 @@ public sealed interface CodeError {}
public record NoMatchingCode(String given, List<String> options) implements CodeError {}
public record RequiredCodeNotPresent(List<String> options) implements CodeError {}
public record BadCode(FilingError err) implements CodeError {}

public sealed interface TextVarError {}
public record MissingVar(Pattern regex) implements TextVarError {}
public record WrongVar(String given, Pattern regex) implements TextVarError {}
public record TooLongVar(String given, int length) implements TextVarError {}
// spotless:on

// Methods
Expand All @@ -33,4 +39,12 @@ public Result<List<FilingCode>, BadCode> retrieveFilingOptions(

public Result<Optional<FilingCode>, CodeError> vetFilingType(
Optional<String> filingCode, List<FilingCode> filingOptions);

public Result<String, CodeError> vetSuffix(Optional<String> suffix);

public Result<String, TextVarError> vetFirstName(Optional<String> name);

public Result<String, TextVarError> vetMiddleName(Optional<String> name);

public Result<String, TextVarError> vetLastName(Optional<String> name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -502,80 +502,17 @@ public ecf4.latest.gov.niem.niem.niem_core._2.PersonNameType serializeNameType(
return t;
};
PersonNameType personName = niemObjFac.createPersonNameType();
personName.setPersonGivenName(
checkName(
name.getFirstName(),
allDataFields.getFieldRow("PartyFirstName"),
collector,
collector.requestVar(
"name.first",
"First name of a case party",
"text",
List.of(),
Optional.of(name.getFirstName()))));
personName.setPersonGivenName(wrapName.apply(name.getFirstName()));
personName.setPersonMaidenName(wrapName.apply(name.getMaidenName()));
personName.setPersonMiddleName(
checkName(
name.getMiddleName(),
allDataFields.getFieldRow("PartyMiddleName"),
collector,
collector.requestVar("name.middle", "Middle name of the case party", "text")));
personName.setPersonSurName(
checkName(
name.getLastName(),
allDataFields.getFieldRow("PartyLastName"),
collector,
collector.requestVar("name.last", "Last name of the case party", "text")));
personName.setPersonMiddleName(wrapName.apply(name.getMiddleName()));
personName.setPersonSurName(wrapName.apply(name.getLastName()));
personName.setPersonNamePrefixText(wrapName.apply(name.getPrefix()));
DataFieldRow suffixRow = allDataFields.getFieldRow("PartyNameSuffix");
if (suffixRow.isvisible) {
List<NameAndCode> suffixes = cd.getNameSuffixes(this.court.code);
InterviewVariable var =
collector.requestVar(
"name.suffix",
"Suffix of the name of the party",
"choices",
suffixes.stream().map(s -> s.getName()).collect(Collectors.toList()),
Optional.of(name.getSuffix()));
if (name.getSuffix().isBlank()) {
if (suffixRow.isrequired) {
// TODO(brycew-later):
log.error(
"DEV WARNING: why would you ever require a suffix? There aren't empty suffix codes at"
+ " all.");
collector.addRequired(var);
} else {
personName.setPersonNameSuffixText(wrapName.apply(name.getSuffix()));
}
} else {
Optional<NameAndCode> suffix =
suffixes.stream()
.filter(s -> s.getName().equalsIgnoreCase(name.getSuffix()))
.findFirst();
if (suffix.isEmpty()) {
collector.addWrong(var);
} else {
personName.setPersonNameSuffixText(wrapName.apply(name.getSuffix()));
}
}
if (!name.getSuffix().isBlank()) {
personName.setPersonNameSuffixText(wrapName.apply(name.getSuffix()));
}
return personName;
}

private PersonNameTextType checkName(
String name, DataFieldRow row, InfoCollector collector, InterviewVariable var)
throws FilingError {
if (!row.matchRegex(name)) {
collector.addWrong(var.appendDesc(": must match regex: " + row.regularexpression));
}
if (name.length() > 100) {
collector.addWrong(var.appendDesc(": can't exceed 100 characters"));
}
PersonNameTextType t = niemObjFac.createPersonNameTextType();
t.setValue(name);
return t;
}

public JAXBElement<DocumentType> filingDocToXml(
FilingDoc doc,
boolean isInitialFiling,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,61 @@ public Result<Optional<FilingCode>, CodeError> vetFilingType(
}
return Result.ok(maybeCode);
}

public Result<String, CodeError> vetSuffix(Optional<String> maybeSuffix) {
DataFieldRow suffixRow = allDataFields.getFieldRow("PartyNameSuffix");
if (suffixRow.isvisible) {
List<NameAndCode> suffixes = cd.getNameSuffixes(this.court.code);
if ((maybeSuffix.isEmpty() || maybeSuffix.get().isBlank()) && suffixRow.isrequired) {
// TODO(brycew-later):
log.error(
"DEV WARNING: Court {}: WHY would you ever require a suffix? There aren't empty suffix codes at all.",
this.court.code);
}
String suffix = maybeSuffix.orElse("");
Optional<NameAndCode> suffixMatch =
suffixes.stream().filter(s -> s.getName().equalsIgnoreCase(suffix)).findFirst();
if (suffixMatch.isEmpty()) {
return Result.err(
new NoMatchingCode(suffix, suffixes.stream().map(s -> s.getName()).toList()));
} else {
return Result.ok(suffixMatch.get().getName());
}
}
return Result.ok(maybeSuffix.orElse(""));
}

/**
* Doesn't return optional because we can set the People names to null / blank.
*
* @param name
* @param row
* @return
*/
private Result<String, TextVarError> vetName(Optional<String> maybeName, DataFieldRow row) {
var name = maybeName.orElse("");
if (!row.matchRegex(name)) {
return Result.err(new WrongVar(name, row.regularexpression));
}
if (name.length() > 100) {
return Result.err(new TooLongVar(name, 100));
}
return Result.ok(name);
}

public Result<String, TextVarError> vetFirstName(Optional<String> name) {
var dataField = allDataFields.getFieldRow("PartyFirstName");
if (name.isEmpty() || name.get().isBlank()) {
return Result.err(new MissingVar(dataField.regularexpression));
}
return vetName(name, dataField);
}

public Result<String, TextVarError> vetMiddleName(Optional<String> name) {
return vetName(name, allDataFields.getFieldRow("PartyMiddleName"));
}

public Result<String, TextVarError> vetLastName(Optional<String> name) {
return vetName(name, allDataFields.getFieldRow("PartyLastName"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

import edu.suffolk.litlab.efsp.server.ecf4.CodesParser.BadCode;
import edu.suffolk.litlab.efsp.server.ecf4.CodesParser.CodeError;
import edu.suffolk.litlab.efsp.server.ecf4.CodesParser.MissingVar;
import edu.suffolk.litlab.efsp.server.ecf4.CodesParser.NoMatchingCode;
import edu.suffolk.litlab.efsp.server.ecf4.CodesParser.RequiredCodeNotPresent;
import edu.suffolk.litlab.efsp.server.ecf4.CodesParser.TextVarError;
import edu.suffolk.litlab.efsp.server.ecf4.CodesParser.TooLongVar;
import edu.suffolk.litlab.efsp.server.ecf4.CodesParser.WrongVar;
import edu.suffolk.litlab.efsp.utils.InterviewVariable.VarBuilder;
import java.util.ArrayList;
import java.util.EmptyStackException;
Expand Down Expand Up @@ -104,6 +108,32 @@ public InterviewVariable addCodeError(CodeError err, VarBuilder varBuilder) thro
return null;
}

public InterviewVariable addTextError(TextVarError err, VarBuilder varBuilder)
throws FilingError {
switch (err) {
case MissingVar missing -> {
varBuilder.appendDesc(", missing, must also match regex: " + missing.regex());
var interviewVar = varBuilder.build();
addRequired(interviewVar);
return interviewVar;
}
case WrongVar wrong -> {
varBuilder.appendDesc(": must match regex: " + wrong.regex()).currentVal(wrong.given());
var interviewVar = varBuilder.build();
addWrong(interviewVar);
return interviewVar;
}
case TooLongVar tooLong -> {
varBuilder
.appendDesc(": can't exceed " + tooLong.length() + " characters")
.currentVal(tooLong.given());
var interviewVar = varBuilder.build();
addWrong(interviewVar);
return interviewVar;
}
}
}

public void pushAttributeStack(String variableName) {
variableAttributes.push(variableName);
}
Expand Down
Loading
Loading