Skip to content
Open
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
6 changes: 3 additions & 3 deletions core/src/main/java/org/verapdf/ReleaseDetails.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ public final class ReleaseDetails {
private static final Map<String, ReleaseDetails> DETAILS = initDetailsMap();

@XmlAttribute
private final String id;
private String id;
@XmlAttribute
private final String version;
private String version;
@XmlAttribute
private final Date buildDate;
private Date buildDate;

private ReleaseDetails() {
this("name", "version", new Date()); //$NON-NLS-1$ //$NON-NLS-2$
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ public final class AuditDurationImpl implements AuditDuration {
private static final int minInHour = 60;

@XmlAttribute
private final long start;
private long start;
@XmlAttribute
private final long finish;
private long finish;
Comment on lines 45 to +48

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate files =="
git ls-files | rg '(^|/)AuditDurationImpl\.java$|(^|/)LocationImpl\.java$|fromValues|AuditDuration|Location' || true

echo "== AuditDurationImpl outline =="
if [ -f core/src/main/java/org/verapdf/component/AuditDurationImpl.java ]; then
  ast-grep outline core/src/main/java/org/verapdf/component/AuditDurationImpl.java || true
  wc -l core/src/main/java/org/verapdf/component/AuditDurationImpl.java
  cat -n core/src/main/java/org/verapdf/component/AuditDurationImpl.java
fi

echo "== LocationImpl outline =="
if [ -f core/src/main/java/org/verapdf/pdfa/results/LocationImpl.java ]; then
  ast-grep outline core/src/main/java/org/verapdf/pdfa/results/LocationImpl.java || true
  wc -l core/src/main/java/org/verapdf/pdfa/results/LocationImpl.java
  cat -n core/src/main/java/org/verapdf/pdfa/results/LocationImpl.java
fi

echo "== related interfaces/usages =="
rg -n "AuditDuration|DurationImpl|LocationImpl|fromValues|XmlAttribute|XmlAdapter|XmlJavaTypeAdapter|`@XmlElement`" core/src/main/java -g '*.java' | head -n 300

Repository: veraPDF/veraPDF-library

Length of output: 49453


Run JAXB-popped fields through normal construction validation.

JAXB unmarshalling sets start, finish, level, and context directly, bypassing fromValues. In core/src/main/java/org/verapdf/component/AuditDurationImpl.java this can unmarshal negative or end-before-start durations; in core/src/main/java/org/verapdf/pdfa/results/LocationImpl.java it can skip context derefing such as 0000 (Abcd) becoming 0000 (Abcd in the persisted object. Use a JAXB post-unmarshall callback or adapter path to apply fromValues after field population, not only at construction.

📍 Affects 2 files
  • core/src/main/java/org/verapdf/component/AuditDurationImpl.java#L45-L48 (this comment)
  • core/src/main/java/org/verapdf/pdfa/results/LocationImpl.java#L45-L47
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@core/src/main/java/org/verapdf/component/AuditDurationImpl.java` around lines
45 - 48, Apply JAXB post-unmarshalling validation in AuditDurationImpl and
LocationImpl by routing the populated start/finish/level/context fields through
their existing fromValues construction path. Add the appropriate JAXB callback
or adapter so negative or end-before-start durations are rejected or normalized,
and LocationImpl context dereferencing is applied before the unmarshalled object
is used; update both affected files and preserve normal constructor behavior.


private AuditDurationImpl() {
this(0, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ class ComponentDetailsImpl implements ComponentDetails {
private static final URI defaultId = URI.create("http://component.verapdf.org#default");
private static final ComponentDetailsImpl defaultInstance = new ComponentDetailsImpl();
@XmlAttribute
private final URI id;
private URI id;
@XmlAttribute
private final String name;
private String name;
@XmlAttribute
private final String version;
private String version;
@XmlElement
private final String provider;
private String provider;
@XmlElement
private final String description;
private String description;

private ComponentDetailsImpl() {
this(defaultId, "name", "version", "provider", "description");
Expand Down
6 changes: 3 additions & 3 deletions core/src/main/java/org/verapdf/component/LogImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@

final class LogImpl implements Log {
@XmlAttribute
private final int occurrences;
private int occurrences;
@XmlAttribute
private final String level;
private String level;
@XmlValue
private final String message;
private String message;

private LogImpl(final int occurrences, String level, final String message) {
this.occurrences = occurrences;
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/org/verapdf/component/LogsSummaryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ public final class LogsSummaryImpl implements LogsSummary {
private static final Logger logger = Logger.getLogger(LogsSummaryImpl.class.getCanonicalName());
private static final String logBeginning = "[log]";
@XmlAttribute
private final int logsCount;
private int logsCount;
@XmlElement(name = "logMessage")
private final Set<Log> logs;
private Set<Log> logs;

private LogsSummaryImpl() {
this(0, Collections.emptySet());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ final class FeatureExtractorConfigImpl implements FeatureExtractorConfig {
private static final FeatureExtractorConfig DEFAULT = new FeatureExtractorConfigImpl(EnumSet.of(FeatureObjectType.INFORMATION_DICTIONARY));
@XmlElementWrapper(name="enabledFeatures")
@XmlElement(name="feature")
private final EnumSet<FeatureObjectType> enabledFeatures;
private EnumSet<FeatureObjectType> enabledFeatures;

private FeatureExtractorConfigImpl() {
this(EnumSet.noneOf(FeatureObjectType.class));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ final class FixerConfigImpl implements MetadataFixerConfig {
public static final String DEFAULT_PREFIX = "veraFixMd_"; //$NON-NLS-1$
private static final MetadataFixerConfig defaultInstance = new FixerConfigImpl();
@XmlAttribute
private final String fixesPrefix;
private String fixesPrefix;

private FixerConfigImpl() {
this(DEFAULT_PREFIX); //$NON-NLS-1$
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/org/verapdf/pdfa/results/LocationImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ final class LocationImpl implements Location {
private static final String DEREF_REPL = "\\(";
private static final Pattern DEREF_PATTERN = Pattern.compile(DEREF_REGEX);
@XmlElement
private final String level;
private String level;
@XmlElement
private final String context;
private String context;

private LocationImpl() {
this("level", "context");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@
@XmlRootElement(name = "fixerResult")
public final class MetadataFixerResultImpl implements MetadataFixerResult {
@XmlAttribute
private final RepairStatus status;
private RepairStatus status;
@XmlElementWrapper
@XmlElement(name = "fix")
private final List<String> appliedFixes;
private List<String> appliedFixes;

private MetadataFixerResultImpl() {
this(RepairStatus.NO_ACTION, new ArrayList<>());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,19 @@
final class TestAssertionImpl implements TestAssertion {
private static final TestAssertionImpl DEFAULT = new TestAssertionImpl();
@XmlAttribute
private final int ordinal;
private int ordinal;
@XmlElement
private final RuleId ruleId;
private RuleId ruleId;
@XmlAttribute
private final Status status;
private Status status;
@XmlElement
private final String message;
private String message;
@XmlElement
private final Location location;
private Location location;
@XmlElement
private final String locationContext;
private String locationContext;
@XmlElement
private final String errorMessage;
private String errorMessage;

private final List<ErrorArgument> errorArguments;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,18 @@
final class ValidationResultImpl implements ValidationResult {
private static final ValidationResultImpl DEFAULT = new ValidationResultImpl();
@XmlAttribute
private final PDFAFlavour flavour;
private PDFAFlavour flavour;
@XmlElement
private final ProfileDetails profileDetails;
private ProfileDetails profileDetails;
@XmlAttribute
private final int totalAssertions;
private int totalAssertions;
@XmlElementWrapper
@XmlElement(name = "assertion")
private final List<TestAssertion> assertions;
private List<TestAssertion> assertions;
@XmlAttribute
private final boolean isCompliant;
private boolean isCompliant;
@XmlAttribute
private final JobEndStatus jobEndStatus;
private JobEndStatus jobEndStatus;
Comment on lines +48 to +59

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
fd -a 'ValidationResultImpl.java' . || true

echo "== file stats =="
file=$(fd 'ValidationResultImpl.java' . | head -n 1)
if [ -n "${file:-}" ]; then
  wc -l "$file"
  echo "== relevant sections =="
  sed -n '1,130p' "$file" | cat -n
fi

echo "== search validations/profile usages =="
rg -n "getValidationProfile|validationProfile|validationProfile\(|fromValidationResult|Profiles\.defaultProfile|setValidationProfile|PDFAFlavour|profileDetails" "$(dirname "$file")" "$file" || true

echo "== search unmarshal JAXB annotations on ValidationResultImpl =="
rg -n "^`@XmlRootElement`|^`@XmlAccessorType`|`@XmlTrans`|JAXBContext|migrate|mangle|Unmarsh" -S core src 2>/dev/null || true

Repository: veraPDF/veraPDF-library

Length of output: 22609


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== git diff stat and relevant diff context =="
git diff --stat || true
git diff -- core/src/main/java/org/verapdf/pdfa/results/ValidationResultImpl.java | sed -n '1,220p' || true

echo "== search serialization tests around validationProfile/flavour =="
fd -e java . | rg 'ValidationResult|result|migrate|mangle|report' | head -n 50 || true
pgrep java || true

Repository: veraPDF/veraPDF-library

Length of output: 3923


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="core/src/main/java/org/verapdf/pdfa/results/ValidationResultImpl.java"
echo "== full ValidationResultImpl =="
sed -n '120,175p' "$file" | cat -n
echo "== remaining methods =="
sed -n '175,250p' "$file" | cat -n

echo "== ValidationProfileImpl relevant annotations and construction =="
vp="$(fd 'ValidationProfileImpl.java' . | head -n 1)"
if [ -n "${vp:-}" ]; then
  wc -l "$vp"
  sed -n '1,140p' "$vp" | cat -n
fi

echo "== ProfileDetailsImpl relevant annotations =="
pd="$(fd 'ProfileDetailsImpl.java' . | head -n 1)"
if [ -n "${pd:-}" ]; then
  sed -n '1,140p' "$pd" | cat -n
fi

echo "== Profiles.defaultProfile definition =="
pp="$(fd 'Profiles.java' . | head -n 1)"
rg -n "defaultProfile|defaut|\bProfileDetails\(" "$pp" -A12 -B8

echo "== XmlSerialiser validation test usage around results =="
rg -n "XmlSerialiser|validate|ValidationReport|ValidationResult|resultFromValues|fromValidationResult" core/src/test core/src/main -g '*.java' | head -n 200

echo "== deterministic annotation/invariant scan =="
python3 - <<'PY'
from pathlib import Path
p=Path('core/src/main/java/org/verapdf/pdfa/results/ValidationResultImpl.java')
text=p.read_text()
for name in ['flavour','profileDetails','totalAssertions','assertions','isCompliant','jobEndStatus','failedChecks','validationProfile']:
    idx=text.index(f'private {name}')
    snippet=text[max(0,idx-180):idx+80].splitlines()
    has_xml=any(a.strip() in {'`@XmlAttribute`','`@XmlElement`','`@XmlElementWrapper`'} for a in snippet)
    has_final=' final ' in text[text.index(f'private {name}'):text.index(';', text.index(f'private {name}'))]
    print(f'{name}: fields_nearby_has_annotation={has_xml} field_final={has_final}')

print('default_profile_used_in_default_cctor=', 'Profiles.defaultProfile()' in text[text.index('ValidationResultImpl()'):text.index('ValidationResultImpl(', text.index('private ValidationResultImpl(', text.index('`@XmlAttribute`', text.index('ValidationResultImpl()'))) + 1000) ])
PY

Repository: veraPDF/veraPDF-library

Length of output: 47039


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== ValidationResultTest non-default xml methods =="
sed -n '100,165p' core/src/test/java/org/verapdf/pdfa/results/ValidationResultTest.java | cat -n

echo "== non-default profile XML snippets in repository =="
rg -n "PDFAFlavour|noFlavour|NO_FLAVOUR|profileDetails|resultFromValues|resultFromXmlString|xmlSource|typeFromXml" core/src/test/core/src/main -g '*.java' | rg "ValidationResult|PDFAFlavour|Profiles" | head -n 200 || true

echo "== deterministic Java/annotation/source invariant scan =="
python3 - <<'PY'
from pathlib import Path
v = Path('core/src/main/java/org/verapdf/pdfa/results/ValidationResultImpl.java')
t = v.read_text()
defs = {
    'flavour': t.index('private PDFAFlavour flavour'),
    'profileDetails': t.index('private ProfileDetails profileDetails'),
    'totalAssertions': t.index('private int totalAssertions'),
    'assertions': t.index('private List<TestAssertion> assertions'),
    'isCompliant': t.index('private boolean isCompliant'),
    'jobEndStatus': t.index('private JobEndStatus jobEndStatus'),
    'validationProfile': t.index('private final ValidationProfile validationProfile'),
}
for name, idx in defs.items():
    line = t[:idx].count('\n')+1
    field_line = [l.strip() for l in t[idx:idx+220].splitlines() if 'validationProfile=' in l or name in l and line <= t[:idx+220].count('\n')+1 and t[idx:idx+220].index(name)==0][(0) if True else None]
    before = max(0, idx-220)
    snippet = t[before:idx+220]
    print(f"{name} line {line}: annotations_nearby={any(a.strip() for a in ['`@XmlAttribute`','`@XmlElement`','`@XmlElementWrapper`'] if a.strip() in snippet)}")
print("validationProfile_initialized_default_ctor_contains_defaultProfile=", "Profiles.defaultProfile()" in t[t.index('private ValidationResultImpl()'):t.index('this.validationProfile = validationProfile;')])
PY

Repository: veraPDF/veraPDF-library

Length of output: 3662


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== annotation and constructor invariant scan =="
python3 - <<'PY'
from pathlib import Path
p = Path('core/src/main/java/org/verapdf/pdfa/results/ValidationResultImpl.java')
t = p.read_text()

for name in ['flavour','profileDetails','totalAssertions','assertions','isCompliant','jobEndStatus','failedChecks','validationProfile']:
    idx = t.index(f'private{(" final" if name=="validationProfile" else "")} {name}')
    line = t[:idx].count('\n') + 1
    snippet = t[max(0, idx-200):idx+80]
    xml_tags = [line.strip() for line in ['`@XmlAttribute`','`@XmlElement`','`@XmlElementWrapper`'] if line.strip() in snippet]
    f = 'final ' in snippet[:snippet.index(';', 80)]
    print(f'{name:20} line {line:3} annotations={xml_tags} final={f}')

default_ctor = t.index('private ValidationResultImpl() {')
tail = t.index('super();', default_ctor)
print('default_ctor_uses_defaultProfile_before_super=true', 'Profiles.defaultProfile()' in t[default_ctor:tail])
print('validationProfile_final=true', 'private final ValidationProfile validationProfile' in t)
PY

echo "== only non-default ValidationResult XML serialization tests =="
rg -n "Profiles\.[A-Z]|[A-Z][A-Za-z0-9_]+Flavour|NO_FLAVOUR|resultFromValues|typeFromXml|resultFromXmlString|fromXml|toXml" core/src/test/java/org/verapdf/pdfa/results/ValidationResultTest.java -A 15 -B 10

Repository: veraPDF/veraPDF-library

Length of output: 314


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="core/src/main/java/org/verapdf/pdfa/results/ValidationResultImpl.java"
echo "== exact constructor and field search =="
rg -n "Profiles\.defaultProfile\(|private ValidationResultImpl\(\)|private validationProfile|flavour|profileDetails|totalAssertions|assertions|isCompliant|jobEndStatus|failedChecks" "$file" -A2 -B2

echo "== test XML serialization methods =="
testfile="core/src/test/java/org/verapdf/pdfa/results/ValidationResultTest.java"
rg -n "resultFromValues|Profiles\.[AD-ZA0-9_]|NO_FLAVOUR|typeFromXml|resultFromXmlString|toXml\(" "$testfile" -A 18 -B 8

echo "== deterministic invariant summary =="
python3 - <<'PY'
from pathlib import Path
src = Path('core/src/main/java/org/verapdf/pdfa/results/ValidationResultImpl.java').read_text()
test = Path('core/src/test/java/org/verapdf/pdfa/results/ValidationResultTest.java').read_text()

print("validationProfile_final_present=", "private final ValidationProfile validationProfile" in src)
print("default_ctor_uses_defaultProfile_present=", "Profiles.defaultProfile()" in src)
print("current_tests_use_defaultProfile_only=", "Profiles.defaultProfile()" in test and "Profiles.N" not in test and "Profiles.A" not in test)
print("default_constructors_are_jaxb_accessible=", "private ValidationResultImpl()" in src and "private ValidationResultImpl(final ValidationProfile validationProfile" in src)
PY

Repository: veraPDF/veraPDF-library

Length of output: 11423


Keep validationProfile consistent with JAXB-populated result fields.

The JAXB-deserialized ValidationResultImpl receives flavour and profileDetails, but validationProfile stays as the default profile because the no-argument/JAXB-accessible constructor does not bind it. This makes getValidationProfile(), fromValidationResult(), and stripPassedTests() use a profile that does not match the returned flavour/details, and existing XML tests only cover the default profile. Add a non-default-profile XML round-trip test, then restore the matching profile during unmarshalling or prevent profile-dependent APIs from being used on unmarshalled results.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@core/src/main/java/org/verapdf/pdfa/results/ValidationResultImpl.java` around
lines 48 - 59, Bind validationProfile to the JAXB-deserialized flavour and
profileDetails in ValidationResultImpl, so getValidationProfile(),
fromValidationResult(), and stripPassedTests() use the restored non-default
profile. Add an XML round-trip test using a non-default profile to verify the
unmarshalled result preserves the matching profile and behaviour.


private HashMap<RuleId, Integer> failedChecks = null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@
public final class ErrorArgumentImpl implements ErrorArgument {
private static final ErrorArgumentImpl DEFAULT = new ErrorArgumentImpl();
@XmlValue
private final String argument;
private String argument;
@XmlAttribute(name = "name")
private final String name;
private String name;
private final String argumentValue;

private ErrorArgumentImpl() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@
final class ErrorDetailsImpl implements ErrorDetails {
private static final ErrorDetailsImpl DEFAULT = new ErrorDetailsImpl();
@XmlElement
private final String message;
private String message;
@XmlElementWrapper
@XmlElement(name = "argument")
private final List<ErrorArgument> arguments;
private List<ErrorArgument> arguments;

private ErrorDetailsImpl() {
this("message", Collections.emptyList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@
final class ProfileDetailsImpl implements ProfileDetails {
private static final ProfileDetailsImpl DEFAULT = new ProfileDetailsImpl();
@XmlElement
private final String name;
private String name;
@XmlElement
private final String description;
private String description;
@XmlAttribute
private final String creator;
private String creator;
@XmlAttribute
private final Date created;
private Date created;

private ProfileDetailsImpl() {
this("name", "description", "creator", new Date(0L));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@
final class ReferenceImpl implements Reference {
private static final ReferenceImpl DEFAULT = new ReferenceImpl();
@XmlAttribute
private final String specification;
private String specification;
@XmlAttribute
private final String clause;
private String clause;

private ReferenceImpl() {
this("specification", "clause");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@
final class RuleIdImpl implements RuleId {
private static final RuleIdImpl DEFAULT = new RuleIdImpl();
@XmlAttribute
private final Specification specification;
private Specification specification;
@XmlAttribute
private final String clause;
private String clause;
@XmlAttribute
private final int testNumber;
private int testNumber;

private RuleIdImpl() {
this(Specification.NO_STANDARD, "clause", 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,22 @@
final class RuleImpl implements Rule {
private static final RuleImpl DEFAULT = new RuleImpl();
@XmlElement
private final RuleId id;
private RuleId id;
@XmlAttribute
private final String object;
private String object;
@XmlAttribute
private final Boolean deferred;
private Boolean deferred;
@XmlAttribute
private final String tags;
private String tags;
@XmlElement
private final String description;
private String description;
@XmlElement
private final String test;
private String test;
@XmlElement
private final ErrorDetails error;
private ErrorDetails error;
@XmlElementWrapper
@XmlElement(name = "reference")
private final List<Reference> references = new ArrayList<>();
private List<Reference> references = new ArrayList<>();

private RuleImpl() {
this(RuleIdImpl.defaultInstance(), "object", null, null, "description", "test",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ final class ValidationProfileImpl implements ValidationProfile {
private final Object objectRuleMapAndRuleLookupLock = new Object();

@XmlAttribute
private final PDFAFlavour flavour;
private PDFAFlavour flavour;
@XmlElement
private final ProfileDetails details;
private ProfileDetails details;
@XmlElement
private final String hash;
private String hash;
@XmlElementWrapper
@XmlElement(name = "rule")
private final Set<Rule> rules;
private Set<Rule> rules;
@XmlElementWrapper
@XmlElement(name = "variable")
private final Set<Variable> variables;
private Set<Variable> variables;

private ValidationProfileImpl() {
this(PDFAFlavour.NO_FLAVOUR, ProfileDetailsImpl.defaultInstance(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@
final class VariableImpl implements Variable {
private static final VariableImpl DEFAULT = new VariableImpl();
@XmlAttribute
private final String name;
private String name;
@XmlAttribute
private final String object;
private String object;
@XmlElement
private final String defaultValue;
private String defaultValue;
@XmlElement
private final String value;
private String value;

private VariableImpl() {
this("name", "object", "defaultValue", "value");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,21 @@ final class ValidatorConfigImpl implements ValidatorConfig {
private PDFAFlavour flavour;
private PDFAFlavour defaultFlavour;
@XmlAttribute
private final boolean recordPasses;
private boolean recordPasses;
@XmlAttribute
private final int maxFails;
private int maxFails;
@XmlAttribute
private final boolean debug;
private boolean debug;
@XmlAttribute
private final boolean showErrorMessages;
private boolean showErrorMessages;
@XmlAttribute
private final boolean isLogsEnabled;
private boolean isLogsEnabled;
@XmlAttribute
private final String loggingLevel;
private String loggingLevel;
@XmlAttribute
private final int maxNumberOfDisplayedFailedChecks;
private int maxNumberOfDisplayedFailedChecks;
@XmlAttribute
private final boolean showProgress;
private boolean showProgress;
private final boolean nonPDFExtension;

private ValidatorConfigImpl() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,19 @@ final class ProcessorConfigImpl implements ProcessorConfig {
private static final String defaultMdFolder = ".";
private static final ProcessorConfig defaultInstance = new ProcessorConfigImpl();
@XmlElement
private final EnumSet<TaskType> tasks;
private EnumSet<TaskType> tasks;
@XmlElement
private final ValidatorConfig validatorConfig;
private ValidatorConfig validatorConfig;
@XmlElement
private final FeatureExtractorConfig featureConfig;
private FeatureExtractorConfig featureConfig;
@XmlElement
private final PluginsCollectionConfig pluginsCollectionConfig;
private PluginsCollectionConfig pluginsCollectionConfig;
@XmlElement
private final MetadataFixerConfig fixerConfig;
private MetadataFixerConfig fixerConfig;
@XmlElement
private final ValidationProfile customProfile;
private ValidationProfile customProfile;
@XmlAttribute
private final String mdFolder;
private String mdFolder;

private ProcessorConfigImpl() {
this(ValidatorFactory.defaultConfig(), FeatureFactory.defaultConfig(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,21 +48,21 @@
class ProcessorResultImpl implements ProcessorResult {
private static final ProcessorResult defaultInstance = new ProcessorResultImpl();
@XmlAttribute
private final boolean isPdf;
private boolean isPdf;
@XmlAttribute
private final boolean isEncryptedPdf;
private boolean isEncryptedPdf;
@XmlAttribute
private final boolean isOutOfMemory;
private boolean isOutOfMemory;
@XmlAttribute
private final boolean hasException;
private boolean hasException;
@XmlElement
private final ItemDetails itemDetails;
private final EnumMap<TaskType, TaskResult> taskResults;
private ItemDetails itemDetails;
private EnumMap<TaskType, TaskResult> taskResults;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files:"
git ls-files | rg '(^|/)ProcessorResultImpl\.java$|(^|/)TaskResultImpl\.java$' || true

echo
echo "ProcessorResultImpl outline:"
ast-grep outline core/src/main/java/org/verapdf/processor/ProcessorResultImpl.java || true

echo
echo "TaskResultImpl outline:"
ast-grep outline core/src/main/java/org/verapdf/processor/TaskResultImpl.java || true

echo
echo "Relevant sections:"
sed -n '1,140p' core/src/main/java/org/verapdf/processor/ProcessorResultImpl.java
echo "----"
sed -n '1,140p' core/src/main/java/org/verapdf/processor/TaskResultImpl.java

echo
echo "Search related JAXB annotations/usages:"
rg -n "`@Xml`|getTaskResults|setTaskResults|featuresResult|getFeatures|set|exception|AuditException|taskResults" core/src/main/java/org/verapdf/processor -S

Repository: veraPDF/veraPDF-library

Length of output: 33099


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "ProcessorResult.java:"
cat -n core/src/main/java/org/verapdf/processor/ProcessorResult.java

echo
echo "TaskResult.java:"
cat -n core/src/main/java/org/verapdf/processor/TaskResult.java

echo
echo "Remaining ProcessorResultImpl sections:"
sed -n '140,260p' core/src/main/java/org/verapdf/processor/ProcessorResultImpl.java

echo
echo "Remaining TaskResultImpl sections:"
sed -n '140,260p' core/src/main/java/org/verapdf/processor/TaskResultImpl.java

echo
echo "Find processorResult/taskException serialization handling:"
rg -n "processorResult|taskException|getResultSet|set|features|FeatureExtraction|ExceptionMessage|VeraPDFException" core/src/main/java/core/src/main/java/org/verapdf/processor -S --glob '*.java'

Repository: veraPDF/veraPDF-library

Length of output: 10051


🌐 Web query:

JAXB unmarshalling property setters or field XML annotations setter semantics derived getter property final field

💡 Result:

In Jakarta XML Binding (JAXB), the unmarshalling process depends heavily on how the class is annotated and the configured access type [1][2][3]. Whether JAXB uses setters or direct field access is determined by these factors: Access Type and Semantics JAXB uses XmlAccessorType to control how it interacts with class members [1][3]. - XmlAccessType.FIELD: JAXB ignores properties (getters/setters) and directly accesses the fields, even if they are private [4][5]. If you place annotations on your setters, they will be ignored or may even cause configuration conflicts if the corresponding field is also annotated [4][5][6]. - XmlAccessType.PROPERTY (or default PUBLIC_MEMBER): JAXB prioritizes JavaBean property access (getter/setter pairs) [1][3]. If this mode is active, JAXB will attempt to use the setter method to inject unmarshalled values [5][7]. Forceing Setter Usage To ensure JAXB uses your setter methods (e.g., for custom validation logic), follow these practices: 1. Do not use @XmlAccessorType(XmlAccessType.FIELD) [7]. 2. Place your JAXB annotations (e.g., @XmlElement, @XmlAttribute) on the getter method (or the setter, but not both) [5][7]. 3. Ensure you have a matching getter/setter pair; JAXB generally requires both to identify a property, though it specifically uses the setter to update the value during unmarshalling [7][8]. Final Fields JAXB requires the ability to set the value of a property. Consequently, final fields are generally incompatible with JAXB unmarshalling because they cannot be modified after the object's constructor has finished. If a class requires unmarshalling, those fields must typically be mutable (non-final). Derived Properties Derived properties (properties that have a getter but no corresponding field or setter) are generally ignored by the unmarshaller because JAXB has no way to "set" their value [8]. If you need to map a derived-style property that requires transformation, you can use an @XmlAdapter, which provides a way to convert complex logic into a format JAXB can handle [6]. Collections For collection types, JAXB behavior is specific: it often checks if the collection is null via the getter and initializes it if necessary, then uses standard collection methods (like.add) or the setter to populate it [8]. It does not always replace the entire collection instance via the setter, which is a common point of confusion for developers expecting setter-only behavior [8].

Citations:


Provide mutable JAXB storage for derived processor result properties.

XML unmarshalling cannot restore state through derived getters: getResultSet() returns taskResults.values(), so tasks cannot be bound into the result map, and getFeaturesReport() only derives a wrapper from featuresResult, so feature data is lost. Add read/write JAXB-backed storage and rebuild the derived results. Keep task exception reconstruction in mind as well: the marshalled taskException element is derived from the final exception field, while unmarshalling only writes primitive fields and duration, so unexpected exception text can be written but not read back unless the exception state is stored as well.

📍 Affects 2 files
  • core/src/main/java/org/verapdf/processor/ProcessorResultImpl.java#L60-L60 (this comment)
  • core/src/main/java/org/verapdf/processor/ProcessorResultImpl.java#L63-L63
  • core/src/main/java/org/verapdf/processor/TaskResultImpl.java#L51-L57
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@core/src/main/java/org/verapdf/processor/ProcessorResultImpl.java` at line
60, Update ProcessorResultImpl.java at lines 60 and 63 to provide mutable
JAXB-backed storage for task results and feature-report data, then rebuild
taskResults, resultSet, and featuresResult from the unmarshalled values while
preserving derived getter behavior. Update TaskResultImpl.java lines 51-57 to
retain the marshalled taskException state during unmarshalling and reconstruct
the final exception, including unexpected exception text.

Source: MCP tools

@XmlElement
private final List<ValidationResult> validationResults;
private final FeatureExtractionResult featuresResult;
private List<ValidationResult> validationResults;
private FeatureExtractionResult featuresResult;
@XmlElement
private final MetadataFixerResult fixerResult;
private MetadataFixerResult fixerResult;

private ProcessorResultImpl() {
this(ItemDetails.defaultInstance(), TaskResultImpl.defaultInstance());
Expand Down
Loading
Loading