Skip to content

Commit 61922db

Browse files
committed
Tagged profile. Support new types of relationships
1 parent 6bf2604 commit 61922db

File tree

2 files changed

+72
-14
lines changed

2 files changed

+72
-14
lines changed

tagged-structure-merger/src/main/java/org/verapdf/tools/tagged/StructureRuleCreator.java

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ public class StructureRuleCreator {
3535
private static final String ZERO_OR_ONE_DESCRIPTION_FORMAT = "%s shall contain at most one %s";
3636
private static final String ZERO_OR_ONE_ERROR_FORMAT = "%s contains more than one %s";
3737

38+
private static final String ZERO_OR_ONE_IF_PARENT_IS_GROUPING_DESCRIPTION_FORMAT = "%s, when used as a grouping element, shall contain at most one %s";
39+
private static final String ZERO_OR_ONE_IF_PARENT_IS_GROUPING_ERROR_FORMAT = "%s is used as a grouping element, but contains more than one %s";
40+
private static final String FORBIDDEN_IF_PARENT_IS_NOT_GROUPING_DESCRIPTION_FORMAT = "%s, when used as a non-grouping element, shall not contain %s";
41+
private static final String FORBIDDEN_IF_PARENT_IS_NOT_GROUPING_ERROR_FORMAT = "%s is used as a non-grouping element, but contains %s";
42+
3843
private static final String ONE_DESCRIPTION_FORMAT = "%s shall contain exactly one %s";
3944
private static final String ONE_ERROR_FORMAT = "%s either doesn't contain or contains more than one %s";
4045

@@ -76,16 +81,19 @@ public SortedSet<Rule> generateRules(List<ParsedRelationStructure> relations) {
7681
this.pdfVersion.getIso(), "Annex_L"));
7782
for (ParsedRelationStructure relation : relations) {
7883
if (shallProcess(relation)) {
79-
RuleData data = getRuleData(relation);
80-
if (data == null) {
84+
List<RuleData> datas = getRuleDatas(relation);
85+
if (datas == null || datas.isEmpty()) {
8186
System.err.println("Missing rule for " + relation.getDescriptionString());
8287
continue;
8388
}
84-
RuleId id = Profiles.ruleIdFromValues(PDFAFlavour.Specification.ISO_32005,
85-
getClause(relation), 1);
86-
ErrorDetails error = Profiles.errorFromValues(data.errorMessage, Collections.emptyList());
87-
res.add(Profiles.ruleFromValues(id, data.object, null, StructureTag.getTags(relation), data.description,
88-
data.test, error, annex_l_reference));
89+
int testNumber = 1;
90+
for (RuleData data : datas) {
91+
RuleId id = Profiles.ruleIdFromValues(PDFAFlavour.Specification.ISO_32005,
92+
getClause(relation), testNumber++);
93+
ErrorDetails error = Profiles.errorFromValues(data.errorMessage, Collections.emptyList());
94+
res.add(Profiles.ruleFromValues(id, data.object, null, StructureTag.getTags(relation), data.description,
95+
data.test, error, annex_l_reference));
96+
}
8997
}
9098
}
9199
return res;
@@ -252,16 +260,24 @@ private boolean shallProcess(ParsedRelationStructure relation) {
252260
&& (TaggedPDFHelper.getPdf17StandardRoleTypes().contains(child) || child.equals(HN) || child.equals(CONTENT_ITEM));
253261
}
254262

255-
private RuleData getRuleData(ParsedRelationStructure rel) {
263+
private List<RuleData> getRuleDatas(ParsedRelationStructure rel) {
256264
switch (rel.getRelation()) {
257265
case FORBIDDEN:
258-
return constructForbidden(rel);
266+
return Collections.singletonList(constructForbidden(rel));
259267
case AT_LEAST_ONE:
260-
return constructAtLeastOne(rel);
261-
case ZERO_OR_ONE:
262-
return constructZeroOrOne(rel);
263-
case ONE:
264-
return constructOne(rel);
268+
return Collections.singletonList(constructAtLeastOne(rel));
269+
case ZERO_OR_ONE: {
270+
RuleData data = constructZeroOrOne(rel);
271+
return data != null ? Collections.singletonList(data) : null;
272+
}
273+
case ZERO_OR_ONE_IF_PARENT_IS_GROUPING:
274+
return constructZeroOrOneIfParentIsGrouping(rel);
275+
case ANY_AMOUNT_IF_PARENT_IS_GROUPING:
276+
return Collections.singletonList(constructForbiddenIfParentIsNotGrouping(rel));
277+
case ONE: {
278+
RuleData data = constructOne(rel);
279+
return data != null ? Collections.singletonList(data) : null;
280+
}
265281
case FORBIDDEN_FOR_NON_GROUPING_CHILD:
266282
case DEPENDS_ON_STRUCTURE:
267283
case RUBY:
@@ -292,6 +308,46 @@ private RuleData constructZeroOrOne(ParsedRelationStructure rel) {
292308
getDescriptionOrErrorMessage(ZERO_OR_ONE_ERROR_FORMAT, parent, child));
293309
}
294310

311+
private List<RuleData> constructZeroOrOneIfParentIsGrouping(ParsedRelationStructure rel) {
312+
String child = rel.getChild();
313+
if (child.equals(CONTENT_ITEM)) {
314+
return null;
315+
}
316+
317+
String parent = rel.getParent();
318+
String testObj = getTestObject(parent);
319+
320+
List<RuleData> result = new ArrayList<>();
321+
String childTest = "isGrouping == false || " + constructChildElemAmountPart(child) + " <= 1";
322+
result.add(new RuleData(testObj, childTest,
323+
getDescriptionOrErrorMessage(ZERO_OR_ONE_IF_PARENT_IS_GROUPING_DESCRIPTION_FORMAT, parent, child),
324+
getDescriptionOrErrorMessage(ZERO_OR_ONE_IF_PARENT_IS_GROUPING_ERROR_FORMAT, parent, child)));
325+
childTest = "isGrouping == true || " + constructChildElemAmountPart(child) + " == 0";
326+
result.add(new RuleData(testObj, childTest,
327+
getDescriptionOrErrorMessage(FORBIDDEN_IF_PARENT_IS_NOT_GROUPING_DESCRIPTION_FORMAT, parent, child),
328+
getDescriptionOrErrorMessage(FORBIDDEN_IF_PARENT_IS_NOT_GROUPING_ERROR_FORMAT, parent, child)));
329+
return result;
330+
}
331+
332+
private RuleData constructForbiddenIfParentIsNotGrouping(ParsedRelationStructure rel) {
333+
String parent = rel.getParent();
334+
String child = rel.getChild();
335+
336+
String childTest;
337+
String testObj = getTestObject(parent);
338+
switch (child) {
339+
case CONTENT_ITEM:
340+
childTest = "isGrouping == true || hasContentItems == false";
341+
break;
342+
default:
343+
childTest = "isGrouping == true || " + constructChildElemAmountPart(child) + " == 0";
344+
}
345+
346+
return new RuleData(testObj, childTest,
347+
getDescriptionOrErrorMessage(FORBIDDEN_IF_PARENT_IS_NOT_GROUPING_DESCRIPTION_FORMAT, parent, child),
348+
getDescriptionOrErrorMessage(FORBIDDEN_IF_PARENT_IS_NOT_GROUPING_ERROR_FORMAT, parent, child));
349+
}
350+
295351
private RuleData constructOne(ParsedRelationStructure rel) {
296352
String child = rel.getChild();
297353
if (child.equals(CONTENT_ITEM)) {

tagged-structure-merger/src/main/java/org/verapdf/tools/tagged/enums/ChildrenRelation.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ public enum ChildrenRelation {
77
FORBIDDEN("∅"),
88
FORBIDDEN_FOR_NON_GROUPING_CHILD("∅*"),
99
ANY_AMOUNT("0..n"),
10+
ANY_AMOUNT_IF_PARENT_IS_GROUPING("0..n*"),
1011
AT_LEAST_ONE("1..n"),
1112
ZERO_OR_ONE("0..1"),
13+
ZERO_OR_ONE_IF_PARENT_IS_GROUPING("0..1*"),
1214
DEPENDS_ON_STRUCTURE("‡"),
1315
RUBY("[a]"),
1416
WARICHU("[b]"),

0 commit comments

Comments
 (0)