Skip to content

Commit 0ca8740

Browse files
authored
feat: duplicate key notice dynamic fieldName and fieldValue (#1994)
1 parent ecaa3f6 commit 0ca8740

File tree

2 files changed

+54
-23
lines changed

2 files changed

+54
-23
lines changed

main/src/test/java/org/mobilitydata/gtfsvalidator/validator/OverlappingFrequencyValidatorTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public void overlappingIncludedSameStart() {
9090
createFrequency(2, "t0", "05:00:00", "07:00:00", 600),
9191
createFrequency(3, "t0", "05:00:00", "06:30:00", 300)))
9292
.containsExactly(
93-
new DuplicateKeyNotice("frequencies.txt", 3, 2, "trip_id,start_time", "t0,05:00:00"),
93+
new DuplicateKeyNotice("frequencies.txt", 2, 3, "trip_id,start_time", "t0,05:00:00"),
9494
new OverlappingFrequencyNotice(
9595
3, GtfsTime.fromString("06:30:00"), 2, GtfsTime.fromString("05:00:00"), "t0"));
9696
}
@@ -125,7 +125,7 @@ public void overlappingThreeIntervals() {
125125
createFrequency(3, "t0", "05:00:00", "05:15:00", 300),
126126
createFrequency(4, "t0", "05:20:00", "05:40:00", 300)))
127127
.containsExactly(
128-
new DuplicateKeyNotice("frequencies.txt", 3, 2, "trip_id,start_time", "t0,05:00:00"),
128+
new DuplicateKeyNotice("frequencies.txt", 2, 3, "trip_id,start_time", "t0,05:00:00"),
129129
new OverlappingFrequencyNotice(
130130
3, GtfsTime.fromString("05:15:00"), 2, GtfsTime.fromString("05:00:00"), "t0"),
131131
new OverlappingFrequencyNotice(

processor/src/main/java/org/mobilitydata/gtfsvalidator/processor/TableContainerIndexGenerator.java

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,7 @@
1313
import com.google.common.collect.ImmutableMap;
1414
import com.google.common.collect.ListMultimap;
1515
import com.google.common.collect.Multimaps;
16-
import com.squareup.javapoet.ClassName;
17-
import com.squareup.javapoet.CodeBlock;
18-
import com.squareup.javapoet.FieldSpec;
19-
import com.squareup.javapoet.MethodSpec;
20-
import com.squareup.javapoet.ParameterSpec;
21-
import com.squareup.javapoet.ParameterizedTypeName;
22-
import com.squareup.javapoet.TypeName;
23-
import com.squareup.javapoet.TypeSpec;
16+
import com.squareup.javapoet.*;
2417
import java.util.ArrayList;
2518
import java.util.HashMap;
2619
import java.util.List;
@@ -321,18 +314,9 @@ private MethodSpec generateSetupIndicesMethod() {
321314
.beginControlFlow("if (oldEntity != null)")
322315
.addStatement(
323316
"noticeContainer.addValidationNotice(new $T(\n"
324-
+ "gtfsFilename(), newEntity.csvRowNumber(), "
325-
+ "oldEntity.csvRowNumber(),\n"
326-
+ "$L,\n$L))",
327-
DuplicateKeyNotice.class,
328-
fileDescriptor.primaryKeys().stream()
329-
.map(
330-
(field) ->
331-
CodeBlock.of("$T.$L", gtfsEntityType, fieldNameField(field.name())))
332-
.collect(CodeBlock.joining(" + \",\" + \n")),
333-
fileDescriptor.primaryKeys().stream()
334-
.map((field) -> CodeBlock.of("oldEntity.$L()", field.name()))
335-
.collect(CodeBlock.joining(" + \",\" + \n")))
317+
+ "gtfsFilename(), oldEntity.csvRowNumber(), newEntity.csvRowNumber(),\n"
318+
+ "key.getDefinedKeys(oldEntity), key.getDefinedValues(oldEntity)))",
319+
DuplicateKeyNotice.class)
336320
.nextControlFlow("else")
337321
.addStatement("$L.put(key, newEntity)", BY_COMPOSITE_KEY_MAP_FIELD_NAME)
338322
.endControlFlow()
@@ -353,7 +337,7 @@ private MethodSpec generateSetupIndicesMethod() {
353337
.beginControlFlow("if (oldEntity != null)")
354338
.addStatement(
355339
"noticeContainer.addValidationNotice(new $T(gtfsFilename(),"
356-
+ " newEntity.csvRowNumber(), oldEntity.csvRowNumber(), $T.$L, newEntity.$L()))",
340+
+ " oldEntity.csvRowNumber(), newEntity.csvRowNumber(), $T.$L, newEntity.$L()))",
357341
DuplicateKeyNotice.class,
358342
gtfsEntityType,
359343
fieldNameField(primaryKey.name()),
@@ -412,6 +396,53 @@ private TypeSpec compositeKeyClass() {
412396
keySpec.addMethod(getter.build());
413397
}
414398

399+
// Generic method to return only defined keys (using has<FieldName>() checks)
400+
TypeName gtfsEntityType = classNames.entityImplementationTypeName();
401+
MethodSpec.Builder getDefinedKeysMethod =
402+
MethodSpec.methodBuilder("getDefinedKeys")
403+
.addModifiers(Modifier.PUBLIC)
404+
.returns(String.class)
405+
.addParameter(gtfsEntityType, "entity")
406+
.addStatement("List<String> keys = new ArrayList<>()");
407+
408+
// Generic method to return only defined values (using has<FieldName>() checks)
409+
MethodSpec.Builder getDefinedValuesMethod =
410+
MethodSpec.methodBuilder("getDefinedValues")
411+
.addModifiers(Modifier.PUBLIC)
412+
.returns(Object.class)
413+
.addParameter(gtfsEntityType, "entity")
414+
.addStatement("List<Object> values = new ArrayList<>()");
415+
416+
// Iterate over primary keys and use has<FieldName>() checks
417+
for (GtfsFieldDescriptor keyField : fileDescriptor.primaryKeys()) {
418+
String hasMethodName = FieldNameConverter.hasMethodName(keyField.name());
419+
String fieldGetter = keyField.name();
420+
String columnName = FieldNameConverter.fieldNameField(keyField.name());
421+
422+
getDefinedKeysMethod
423+
.beginControlFlow("if (entity.$L())", hasMethodName)
424+
.addStatement(
425+
"keys.add($T.$L)",
426+
gtfsEntityType, // First placeholder for `$T`
427+
columnName // Second placeholder for `$L`
428+
)
429+
.endControlFlow();
430+
431+
getDefinedValuesMethod
432+
.beginControlFlow("if (entity.$L())", hasMethodName)
433+
.addStatement(
434+
"values.add(entity.$L())", fieldGetter // Third placeholder for entity method call
435+
)
436+
.endControlFlow();
437+
}
438+
439+
getDefinedKeysMethod.addStatement("return String.join(\",\", keys)");
440+
getDefinedValuesMethod.addStatement(
441+
"return values.stream().reduce((a, b) -> (a.toString() + \",\" + b.toString())).orElse(null)");
442+
443+
keySpec.addMethod(getDefinedKeysMethod.build());
444+
keySpec.addMethod(getDefinedValuesMethod.build());
445+
415446
TypeSpec.Builder valueBuilderTypeSpec =
416447
TypeSpec.classBuilder("Builder")
417448
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.ABSTRACT)

0 commit comments

Comments
 (0)