### Compile Source with Maven
Source: https://github.com/verapdf/verapdf-library/blob/integration/README.md
Use Maven to clean and install the veraPDF-library project after obtaining the source code.
```bash
mvn clean install
```
--------------------------------
### Maven Dependency Setup for veraPDF
Source: https://context7.com/verapdf/verapdf-library/llms.txt
Add the veraPDF core API and a parser implementation (like Greenfield) to your project's pom.xml. Ensure the parser is on the classpath for provider registration.
```xml
org.verapdf
core
1.30.1
org.verapdf
validation-model
1.30.1
```
--------------------------------
### Create GPL Source Headed Branch and Apply Headers
Source: https://github.com/verapdf/verapdf-library/blob/integration/LICENSE-HEADERS.md
Create a new branch for GPL licensed source files and apply the GPL headers using Maven. This involves invoking the Maven license plugin with the GPL profile.
```bash
git checkout -b release-0.8-gpl origin/release-0.8
mvn license:format -P apply-gpl-header
mvn clean install
git add .
git commit -m "Added GPL source headers."
```
--------------------------------
### Create MPL Source Headed Branch and Apply Headers
Source: https://github.com/verapdf/verapdf-library/blob/integration/LICENSE-HEADERS.md
Create a new branch for MPL licensed source files and apply the MPL headers using Maven. This is similar to the GPL process but uses the MPL profile.
```bash
git checkout -b release-0.8-mpl origin/release-0.8
mvn license:format -P apply-mpl-header
mvn clean install
git add .
git commit -m "Added MPL source headers."
```
--------------------------------
### Create PDF/A Validators with VeraPDFFoundry
Source: https://context7.com/verapdf/verapdf-library/llms.txt
Demonstrates creating different types of PDFAValidator instances using VeraPDFFoundry. Includes simple, configuration-based, multi-flavour, and fail-fast validators. Ensure the VeraGreenfieldFoundryProvider is registered before use.
```java
import org.verapdf.gf.foundry.VeraGreenfieldFoundryProvider;
import org.verapdf.pdfa.*;
import org.verapdf.pdfa.flavours.PDFAFlavour;
import org.verapdf.pdfa.results.ValidationResult;
import org.verapdf.pdfa.validation.validators.ValidatorConfig;
import org.verapdf.pdfa.validation.validators.ValidatorConfigBuilder;
import java.io.File;
import java.util.Arrays;
public class ValidatorDemo {
public static void main(String[] args) throws Exception {
Foundries.registerDefaultProvider(new VeraGreenfieldFoundryProvider());
VeraPDFFoundry foundry = Foundries.defaultInstance();
// --- Simple validator (flavour + logSuccess flag) ---
PDFAValidator simple = foundry.createValidator(PDFAFlavour.PDFA_1_B, false);
// --- Config-based validator ---
ValidatorConfig config = ValidatorConfigBuilder.defaultBuilder()
.flavour(PDFAFlavour.PDFA_2_B)
.maxFails(-1) // full validation
.recordPasses(false)
.build();
PDFAValidator configured = foundry.createValidator(config);
// --- Multi-flavour validator ---
PDFAValidator multi = foundry.createValidator(
Arrays.asList(PDFAFlavour.PDFA_1_B, PDFAFlavour.PDFA_2_B));
// --- Fail-fast validator (stops after 10 failures) ---
PDFAValidator failFast = foundry.createFailFastValidator(
PDFAFlavour.PDFA_3_B, /*maxFailures*/10,
/*maxDisplayed*/20, /*logSuccess*/false,
/*showErrors*/true, /*showProgress*/false);
// --- Run validation ---
File pdfFile = new File("document.pdf");
try (PDFAParser parser = foundry.createParser(pdfFile, PDFAFlavour.PDFA_1_B)) {
ValidationResult result = simple.validate(parser);
System.out.println("Compliant : " + result.isCompliant());
System.out.println("Flavour : " + result.getPDFAFlavour());
System.out.println("Assertions : " + result.getTotalAssertions());
System.out.println("Failures : " + result.getFailedChecks().size());
}
}
}
```
--------------------------------
### Accessing veraPDF Library Release Details
Source: https://context7.com/verapdf/verapdf-library/llms.txt
Demonstrates how to retrieve and print the main library release details, iterate through all registered component details, and access the rights statement. It also shows how to register release details from an external properties resource.
```java
import org.verapdf.ReleaseDetails;
import java.util.Collection;
public class ReleaseDemo {
public static void main(String[] args) {
// Get the primary library release details
ReleaseDetails details = ReleaseDetails.getInstance();
System.out.println("ID : " + details.getId()); // e.g. "library"
System.out.println("Version : " + details.getVersion()); // e.g. "1.30.1"
System.out.println("Built : " + details.getBuildDate());
// Iterate all registered components (core + any additional registered modules)
Collection all = ReleaseDetails.getDetails();
for (ReleaseDetails rd : all) {
System.out.printf(" [%s] v%s%n", rd.getId(), rd.getVersion());
}
// Rights statement
System.out.println(ReleaseDetails.rightsStatement());
// "Developed and released by the veraPDF Consortium.\n"
// "Funded by the PREFORMA project.\n..."
// Register an additional module's release details from a properties resource
ReleaseDetails.addDetailsFromResource(
"org/verapdf/release/myplugin.properties");
}
}
```
--------------------------------
### Create GPL Source Archive (Tar.gz)
Source: https://github.com/verapdf/verapdf-library/blob/integration/LICENSE-HEADERS.md
Generate a compressed tarball of the GPL headed source code using Git archive. This command creates a .tar.gz file from the specified branch.
```bash
git archive --format=tar release-0.8-gpl | gzip > veraPDF-0.8-gpl.tar.gz
```
```bash
git archive --format=tar.gz release-0.8-gpl > veraPDF-0.8-gpl.tar.gz
```
```bash
git archive --format=tar -o veraPDF-0.8-gpl.tar.gz release-0.8-gpl
```
--------------------------------
### Create PDF/A Parser with VeraPDFFoundry
Source: https://context7.com/verapdf/verapdf-library/llms.txt
Opens a PDFAParser from a File or InputStream. Supports explicit PDFAFlavour, fallback flavour, and password for encrypted files. The parser is AutoCloseable and must be closed after use.
```java
import org.verapdf.gf.foundry.VeraGreenfieldFoundryProvider;
import org.verapdf.pdfa.Foundries;
import org.verapdf.pdfa.PDFAParser;
import org.verapdf.pdfa.VeraPDFFoundry;
import org.verapdf.pdfa.flavours.PDFAFlavour;
import java.io.File;
public class ParserDemo {
public static void main(String[] args) throws Exception {
Foundries.registerDefaultProvider(new VeraGreenfieldFoundryProvider());
VeraPDFFoundry foundry = Foundries.defaultInstance();
File pdfFile = new File("document.pdf");
// Auto-detect flavour from XMP metadata
try (PDFAParser autoParser = foundry.createParser(pdfFile)) {
System.out.println("Detected flavour: " + autoParser.getFlavour());
// e.g. "1b" if the document declares PDF/A-1B
}
// Explicit flavour (skip XMP detection)
try (PDFAParser explicitParser = foundry.createParser(pdfFile, PDFAFlavour.PDFA_2_B)) {
System.out.println("Forced flavour: " + explicitParser.getFlavour()); // "2b"
}
// Encrypted PDF with password
try (PDFAParser encParser = foundry.createParser(
pdfFile, PDFAFlavour.PDFA_3_U, "secret")) {
System.out.println("Encrypted PDF flavour: " + encParser.getFlavour());
}
}
}
```
--------------------------------
### VeraPDFFoundry.createParser
Source: https://context7.com/verapdf/verapdf-library/llms.txt
`createParser` opens a `PDFAParser` from a `File` or `InputStream`. It supports auto-detection of PDFA flavour, explicit flavour setting, and handling encrypted files with a password. The returned `PDFAParser` is `AutoCloseable` and should be closed after use.
```APIDOC
## `VeraPDFFoundry.createParser` — Parsing a PDF document
`createParser` opens a `PDFAParser` from a `File` or `InputStream`. The overloads accept an explicit `PDFAFlavour` (skip auto-detection), a default fallback flavour, and an optional password for encrypted files. The returned `PDFAParser` is `AutoCloseable` and should be closed after use.
### Usage Examples:
**Auto-detect flavour from XMP metadata:**
```java
try (PDFAParser autoParser = foundry.createParser(pdfFile)) {
System.out.println("Detected flavour: " + autoParser.getFlavour());
}
```
**Explicit flavour (skip XMP detection):**
```java
try (PDFAParser explicitParser = foundry.createParser(pdfFile, PDFAFlavour.PDFA_2_B)) {
System.out.println("Forced flavour: " + explicitParser.getFlavour());
}
```
**Encrypted PDF with password:**
```java
try (PDFAParser encParser = foundry.createParser(pdfFile, PDFAFlavour.PDFA_3_U, "secret")) {
System.out.println("Encrypted PDF flavour: " + encParser.getFlavour());
}
```
```
--------------------------------
### Manage PDF/A Validation Profiles with VeraPDF
Source: https://context7.com/verapdf/verapdf-library/llms.txt
Demonstrates accessing built-in profiles, loading custom profiles from XML, programmatically building a new profile, serializing it back to XML, and filtering rules by tags. Use `getVeraProfileDirectory()` for bundled profiles or `profileFromXml` for custom ones.
```java
import org.verapdf.pdfa.flavours.PDFAFlavour;
import org.verapdf.pdfa.validation.profiles.*;
import javax.xml.bind.JAXBException;
import java.io.InputStream;
import java.util.*;
public class ProfilesDemo {
public static void main(String[] args) throws JAXBException {
// Access built-in profile directory
ProfileDirectory dir = Profiles.getVeraProfileDirectory();
System.out.println("Available flavours: " + dir.getPDFAFlavours());
ValidationProfile pdfa1b = dir.getValidationProfileByFlavour(PDFAFlavour.PDFA_1_B);
System.out.println("Profile name : " + pdfa1b.getDetails().getName());
System.out.println("Rule count : " + pdfa1b.getRules().size());
// Load a custom profile from XML
try (InputStream is = ProfilesDemo.class.getResourceAsStream("/custom-profile.xml")) {
ValidationProfile custom = Profiles.profileFromXml(is);
System.out.println("Custom profile: " + custom.getPDFAFlavour());
} catch (Exception e) {
System.err.println("Custom profile not found: " + e.getMessage());
}
// Build a profile programmatically
ProfileDetails details = Profiles.profileDetailsFromValues(
"My PDF/A-1B Profile", "Custom rules", "MyOrg", new Date());
Reference ref = Profiles.referenceFromValues("ISO 19005-1:2005", "6.1.3");
ErrorDetails err = Profiles.errorFromValues(
"Font not embedded", Collections.emptyList());
RuleId ruleId = Profiles.ruleIdFromValues(
PDFAFlavour.Specification.ISO_19005_1, "6.1.3", 1);
Rule rule = Profiles.ruleFromValues(
ruleId, "CosDocument", "Font must be embedded",
"fontSize > 0", err, Collections.singletonList(ref));
ValidationProfile myProfile = Profiles.profileFromValues(
PDFAFlavour.PDFA_1_B, details, "abc123",
new HashSet<>(Collections.singletonList(rule)), Collections.emptySet());
// Serialise to XML string
String xml = Profiles.profileToXml(myProfile, true, false);
System.out.println(xml.substring(0, 80) + "...");
// Filter rules by tag
Set include = new HashSet<>(Arrays.asList("fonts"));
Set exclude = Collections.emptySet();
ValidationProfile filtered = Profiles.getProfileWithTags(pdfa1b, include, exclude);
System.out.println("Filtered rules: " + filtered.getRules().size());
}
}
```
--------------------------------
### Clone and Checkout Integration Branch
Source: https://github.com/verapdf/verapdf-library/blob/integration/README.md
Use Git to clone the veraPDF-library repository and checkout the integration branch for the latest development source.
```bash
git clone https://github.com/veraPDF/veraPDF-library
cd veraPDF-library
git checkout integration
```
--------------------------------
### Clone veraPDF Library Repository
Source: https://github.com/verapdf/verapdf-library/blob/integration/LICENSE-HEADERS.md
Clone the veraPDF library repository and navigate into the directory. This is the initial step before applying license headers.
```bash
git clone git@github.com:veraPDF/veraPDF-library.git
cd veraPDF-library
```
--------------------------------
### Registering Default Provider and Accessing Foundry
Source: https://context7.com/verapdf/verapdf-library/llms.txt
Register the greenfield parser as the default provider once at application startup using Foundries.registerDefaultProvider. Obtain the foundry instance via Foundries.defaultInstance() for subsequent parser and validator creation.
```java
import org.verapdf.gf.foundry.VeraGreenfieldFoundryProvider;
import org.verapdf.pdfa.Foundries;
import org.verapdf.pdfa.VeraPDFFoundry;
public class VeraPDFSetup {
public static void main(String[] args) {
// Register the greenfield parser as the default provider (call once)
Foundries.registerDefaultProvider(new VeraGreenfieldFoundryProvider());
// Obtain the foundry – same instance returned on every call
VeraPDFFoundry foundry = Foundries.defaultInstance();
System.out.println("Foundry parser ID: " + foundry.getParserId());
System.out.println("Default flavour : " + foundry.defaultFlavour());
// Output:
// Foundry parser ID: org.verapdf.gf.foundry
// Default flavour : 1b
}
```
--------------------------------
### Fetch Latest Changes and Checkout Release Branch
Source: https://github.com/verapdf/verapdf-library/blob/integration/LICENSE-HEADERS.md
Fetch the latest changes from the origin and checkout the specific release branch. Ensures you are working with the correct version of the code.
```bash
git fetch origin
git checkout -b release-0.8 origin/release-0.8
git pull origin release-0.8
```
--------------------------------
### Create PDFAValidator with ValidatorFactory
Source: https://context7.com/verapdf/verapdf-library/llms.txt
Demonstrates creating PDFAValidator instances directly using ValidatorFactory without a VeraPDFFoundry. Supports specifying flavour, logging, and maximum failures.
```java
import org.verapdf.pdfa.PDFAValidator;
import org.verapdf.pdfa.flavours.PDFAFlavour;
import org.verapdf.pdfa.validation.validators.*;
import java.io.*;
import java.util.logging.Level;
public class ValidatorFactoryDemo {
public static void main(String[] args) throws Exception {
// Create validator directly (no foundry needed)
PDFAValidator v1 = ValidatorFactory.createValidator(PDFAFlavour.PDFA_2_B, false);
PDFAValidator v2 = ValidatorFactory.createValidator(
PDFAFlavour.PDFA_1_B, /*logPassed*/false, /*maxFails*/50);
// Build and serialise a ValidatorConfig to XML
ValidatorConfig config = ValidatorFactory.createConfig(
PDFAFlavour.PDFA_3_U, // target flavour
PDFAFlavour.PDFA_3_U, // default fallback
/*recordPasses*/false,
/*maxFails*/-1,
/*debug*/false,
/*logsEnabled*/true,
Level.WARNING,
/*maxDisplayed*/100,
/*showErrors*/true,
/*password*/"",
/*showProgress*/false,
/*nonPDFExtension*/false);
// Serialise to XML string
String xml = ValidatorFactory.configToXml(config);
System.out.println(xml.substring(0, 120) + "...");
// Round-trip: serialise to OutputStream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ValidatorFactory.configToXml(config, baos);
// Deserialise from InputStream
ValidatorConfig loaded = ValidatorFactory.createConfig(
new ByteArrayInputStream(baos.toByteArray()));
System.out.println("Loaded flavour: " + loaded.getFlavour()); // 3u
}
}
```
--------------------------------
### Clone and Checkout Master Branch
Source: https://github.com/verapdf/verapdf-library/blob/integration/README.md
Use Git to clone the veraPDF-library repository and checkout the master branch for the latest release source.
```bash
git clone https://github.com/veraPDF/veraPDF-library
cd veraPDF-library
git checkout master
```
--------------------------------
### Verify Clean Working Directory
Source: https://github.com/verapdf/verapdf-library/blob/integration/LICENSE-HEADERS.md
Check the Git status to ensure there are no uncommitted local changes before proceeding. A clean working directory is essential for predictable builds.
```bash
git status
```
--------------------------------
### Create MPL Source Archive (Zip)
Source: https://github.com/verapdf/verapdf-library/blob/integration/LICENSE-HEADERS.md
Generate a zip archive of the MPL headed source code using Git archive. This command creates a .zip file from the specified branch.
```bash
git archive --format=zip release-0.8-mpl > veraPDF-0.8-mpl.zip
```
--------------------------------
### Repair PDF/A Metadata with MetadataFixer
Source: https://context7.com/verapdf/verapdf-library/llms.txt
Use `MetadataFixer` to repair XMP metadata discrepancies. This involves validating the PDF first to obtain a `ValidationResult`, then using the fixer with input and output streams.
```java
import org.verapdf.gf.foundry.VeraGreenfieldFoundryProvider;
import org.verapdf.pdfa.*;
import org.verapdf.pdfa.flavours.PDFAFlavour;
import org.verapdf.pdfa.results.*;
import java.io.*;
import java.nio.file.*;
public class MetadataFixerDemo {
public static void main(String[] args) throws Exception {
Foundries.registerDefaultProvider(new VeraGreenfieldFoundryProvider());
VeraPDFFoundry foundry = Foundries.defaultInstance();
File input = new File("document.pdf");
File output = new File("document_fixed.pdf");
// First validate to obtain the ValidationResult needed by the fixer
ValidationResult validationResult;
try (PDFAParser parser = foundry.createParser(input, PDFAFlavour.PDFA_1_B)) {
PDFAValidator validator = foundry.createValidator(PDFAFlavour.PDFA_1_B, false);
validationResult = validator.validate(parser);
}
// Then fix metadata using the same input stream
MetadataFixer fixer = foundry.createMetadataFixer();
try (InputStream in = new FileInputStream(input);
OutputStream out = new FileOutputStream(output)) {
MetadataFixerResult fixResult = fixer.fixMetadata(in, out, validationResult);
System.out.println("Repair status: " + fixResult.getRepairStatus());
// e.g. "Repair successful" or "No Action"
fixResult.getAppliedFixes().forEach(fix ->
System.out.println(" Applied fix: " + fix));
}
// RepairStatus values:
// SUCCESS – metadata repaired and written to output
// NO_ACTION – document was already valid; no changes needed
// WONT_FIX – fixer could not determine a repair strategy
// FIX_ERROR – repair was attempted but an error occurred
// ID_REMOVED – document ID was removed during repair
}
}
```
--------------------------------
### Configure VeraPDF Validator Behavior
Source: https://context7.com/verapdf/verapdf-library/llms.txt
Uses a fluent builder to control validator settings like flavour, recording of passed checks, failure thresholds, logging level, and display limits for failures. Ensure necessary imports are present.
```java
import org.verapdf.pdfa.flavours.PDFAFlavour;
import org.verapdf.pdfa.validation.validators.ValidatorConfig;
import org.verapdf.pdfa.validation.validators.ValidatorConfigBuilder;
import java.util.logging.Level;
public class ConfigDemo {
public static void main(String[] args) {
// Full configuration example
ValidatorConfig config = ValidatorConfigBuilder.defaultBuilder()
.flavour(PDFAFlavour.PDFA_1_B) // target standard
.defaultFlavour(PDFAFlavour.PDFA_1_B) // fallback if no XMP declaration
.recordPasses(false) // only record failed checks
.maxFails(100) // stop after 100 failures (-1 = unlimited)
.maxNumberOfDisplayedFailedChecks(50) // limit displayed failures in report
.showErrorMessages(true) // include human-readable error text
.showProgress(false) // suppress progress output
.isLogsEnabled(true)
.loggingLevel(Level.WARNING)
.debug(false)
.nonPDFExtension(false)
.build();
System.out.println("Flavour : " + config.getFlavour()); // 1b
System.out.println("Max fails : " + config.getMaxFails()); // 100
System.out.println("Log passes: " + config.isRecordPasses()); // false
}
}
```
--------------------------------
### Build and Manipulate Validation Results with Java
Source: https://context7.com/verapdf/verapdf-library/llms.txt
This Java code demonstrates building a ValidationResult and TestAssertion manually, stripping passed tests, and performing an XML round-trip. Ensure necessary VeraPDF library imports are present.
```java
import org.verapdf.pdfa.results.*;
import org.verapdf.pdfa.validation.profiles.*;
import org.verapdf.pdfa.flavours.PDFAFlavour;
import org.verapdf.processor.reports.enums.JobEndStatus;
import javax.xml.bind.JAXBException;
import java.util.*;
public class ResultsDemo {
public static void main(String[] args) throws JAXBException {
// Build a profile and assertion manually
ValidationProfile profile = Profiles.getVeraProfileDirectory()
.getValidationProfileByFlavour(PDFAFlavour.PDFA_1_B);
RuleId ruleId = Profiles.ruleIdFromValues(
PDFAFlavour.Specification.ISO_19005_1, "6.1.3", 1);
Location loc = ValidationResults.locationFromValues("CosDocument", "root");
TestAssertion failedAssertion = ValidationResults.assertionFromValues(
/*ordinal*/1, ruleId, TestAssertion.Status.FAILED,
"Test failed", loc, "CosDocument", "Font not embedded", Collections.emptyList());
List assertions = Collections.singletonList(failedAssertion);
ValidationResult result = ValidationResults.resultFromValues(
profile, assertions, /*isCompliant*/false, JobEndStatus.NORMAL);
System.out.println("Compliant: " + result.isCompliant()); // false
System.out.println("Assertions: " + result.getTotalAssertions()); // 1
// Strip passed assertions (returns clean copy)
ValidationResult stripped = ValidationResults.stripPassedTests(result);
System.out.println("Stripped assertions: " + stripped.getTotalAssertions()); // still 1
// Round-trip through XML
String xml = org.verapdf.core.XmlSerialiser.toXml(result, true, false);
ValidationResult fromXml = ValidationResults.resultFromXmlString(xml);
System.out.println("Round-trip compliant: " + fromXml.isCompliant()); // false
}
}
```
--------------------------------
### VeraPDFFoundry.createValidator
Source: https://context7.com/verapdf/verapdf-library/llms.txt
Creates a PDFAValidator instance. It can be configured with a specific PDFAFlavour, a ValidatorConfig object, a custom ValidationProfile, or a list of flavours for multi-standard validation. The `createFailFastValidator` variant allows for performance-sensitive scenarios by aborting validation after a configured number of failures.
```APIDOC
## `VeraPDFFoundry.createValidator` — Creating a PDF/A validator
`createValidator` produces a `PDFAValidator` from a `ValidatorConfig`, a `PDFAFlavour`, a custom `ValidationProfile`, or a list of flavours for multi-standard validation. `createFailFastValidator` aborts validation after a configured number of failures for performance-sensitive scenarios.
### Method Signatures
- `PDFAValidator createValidator(PDFAFlavour flavour, boolean logSuccess)`
- `PDFAValidator createValidator(ValidatorConfig config)`
- `PDFAValidator createValidator(List flavours)`
- `PDFAValidator createFailFastValidator(PDFAFlavour flavour, int maxFailures, int maxDisplayed, boolean logSuccess, boolean showErrors, boolean showProgress)`
### Description
These methods are used to instantiate a `PDFAValidator` object, which is responsible for performing PDF/A compliance checks. You can create a simple validator with a flavour and a flag to log success, a more complex validator using a `ValidatorConfig` object, or a validator capable of checking against multiple PDF/A standards simultaneously. The `createFailFastValidator` is optimized for speed by stopping validation early if a certain number of errors are encountered.
```
--------------------------------
### Run PDF/A Validation and Process Results
Source: https://context7.com/verapdf/verapdf-library/llms.txt
Executes validation on a PDF document using a PDFAValidator and processes the ValidationResult. Handles potential ValidationExceptions and iterates through assertions to report failures. Assumes the foundry is already registered.
```java
import org.verapdf.core.ValidationException;
import org.verapdf.pdfa.*;
import org.verapdf.pdfa.flavours.PDFAFlavour;
import org.verapdf.pdfa.results.*;
import java.io.File;
import java.util.List;
public class ValidationDemo {
public static void main(String[] args) throws Exception {
// Assumes foundry already registered
VeraPDFFoundry foundry = Foundries.defaultInstance();
File pdfFile = new File("document.pdf");
try (PDFAParser parser = foundry.createParser(pdfFile, PDFAFlavour.PDFA_1_B)) {
PDFAValidator validator = foundry.createValidator(PDFAFlavour.PDFA_1_B, false);
try {
ValidationResult result = validator.validate(parser);
System.out.println("Compliant: " + result.isCompliant());
System.out.println("Profile : " + result.getProfileDetails().getName());
for (TestAssertion assertion : result.getTestAssertions()) {
if (assertion.getStatus() == TestAssertion.Status.FAILED) {
System.out.printf(" FAIL rule=%s clause=%s msg=%s%n",
assertion.getRuleId().getSpecification(),
assertion.getRuleId().getClause(),
assertion.getErrorMessage());
// e.g. FAIL rule=ISO 19005-1:2005 clause=6.1.3 msg=...
}
}
// Failed rule counts per rule ID
result.getFailedChecks().forEach((ruleId, count) ->
System.out.printf(" Rule %s: %d failures%n", ruleId.getClause(), count));
} catch (ValidationException e) {
System.err.println("Validation error: " + e.getMessage());
}
}
}
}
```
--------------------------------
### ValidatorConfigBuilder
Source: https://context7.com/verapdf/verapdf-library/llms.txt
`ValidatorConfigBuilder` is a fluent builder for `ValidatorConfig`, allowing control over validator behavior such as target flavour, recording passed checks, maximum failure thresholds, logging level, password, and display limits for failures.
```APIDOC
## `ValidatorConfigBuilder` — Configuring validator behaviour
`ValidatorConfigBuilder` is a fluent builder for `ValidatorConfig`, controlling which flavour is validated, whether passed checks are recorded, maximum failure thresholds, logging level, password, and display limits for failures.
### Configuration Options:
- **`flavour(PDFAFlavour targetFlavour)`**: Sets the target PDF/A standard for validation.
- **`defaultFlavour(PDFAFlavour fallbackFlavour)`**: Sets a fallback flavour if no XMP declaration is found.
- **`recordPasses(boolean record)`**: Determines whether to record checks that pass validation.
- **`maxFails(int maxFailures)`**: Sets the maximum number of failures before validation stops (-1 for unlimited).
- **`maxNumberOfDisplayedFailedChecks(int limit)`**: Limits the number of failed checks displayed in the report.
- **`showErrorMessages(boolean show)`**: Includes human-readable error text in the report.
- **`showProgress(boolean show)`**: Controls the display of progress output during validation.
- **`isLogsEnabled(boolean enabled)`**: Enables or disables logging.
- **`loggingLevel(Level level)`**: Sets the logging level.
- **`debug(boolean debug)`**: Enables debug mode.
- **`nonPDFExtension(boolean handle)`**: Configures handling of non-PDF extensions.
### Example Usage:
```java
ValidatorConfig config = ValidatorConfigBuilder.defaultBuilder()
.flavour(PDFAFlavour.PDFA_1_B)
.defaultFlavour(PDFAFlavour.PDFA_1_B)
.recordPasses(false)
.maxFails(100)
.maxNumberOfDisplayedFailedChecks(50)
.showErrorMessages(true)
.showProgress(false)
.isLogsEnabled(true)
.loggingLevel(Level.WARNING)
.debug(false)
.nonPDFExtension(false)
.build();
```
```
--------------------------------
### Implement Custom Font Feature Extraction Plugin
Source: https://context7.com/verapdf/verapdf-library/llms.txt
Extend `AbstractFontFeaturesExtractor` to create a custom plugin for extracting font names and subtypes. Initialize the plugin with metadata and pass it to `PDFAParser.getFeatures`.
```java
import org.verapdf.features.*;
import org.verapdf.features.tools.FeatureTreeNode;
import org.verapdf.gf.foundry.VeraGreenfieldFoundryProvider;
import org.verapdf.pdfa.*;
import org.verapdf.pdfa.flavours.PDFAFlavour;
import java.io.File;
import java.util.*;
// Custom plugin that extracts font name and type
class MyFontExtractor extends AbstractFontFeaturesExtractor {
@Override
public List getFontFeatures(FontFeaturesData data) {
List result = new ArrayList<>();
FeatureTreeNode root = FeatureTreeNode.createRootNode("myFont");
root.setAttribute("name", String.valueOf(data.getFontName()));
root.setAttribute("subtype", String.valueOf(data.getFontSubtype()));
result.add(root);
return result;
}
}
public class PluginDemo {
public static void main(String[] args) throws Exception {
Foundries.registerDefaultProvider(new VeraGreenfieldFoundryProvider());
VeraPDFFoundry foundry = Foundries.defaultInstance();
// Initialise the plugin with metadata
MyFontExtractor plugin = new MyFontExtractor();
plugin.initialize(new AbstractFeaturesExtractor.ExtractorDetails(
"MyFontPlugin", "1.0", "Extracts font name and subtype"));
FeatureExtractorConfig config = FeatureFactory.configFromValues(
EnumSet.of(FeatureObjectType.FONT));
File pdfFile = new File("document.pdf");
try (PDFAParser parser = foundry.createParser(pdfFile, PDFAFlavour.PDFA_1_B)) {
FeatureExtractionResult result = parser.getFeatures(
config, Collections.singletonList(plugin));
result.getFeatureTreesForType(FeatureObjectType.FONT).forEach(node ->
System.out.println("Custom font data: " + node));
}
}
}
```
--------------------------------
### PDFAValidator.validate / validateAll
Source: https://context7.com/verapdf/verapdf-library/llms.txt
Executes the PDF/A validation process on a given PDF document. The `validate` method processes the document against a single profile, returning a `ValidationResult`. If the validator was configured for multiple flavours, `validateAll` returns a list of `ValidationResult` objects. Validation can be interrupted using `cancelValidation` from another thread.
```APIDOC
## `PDFAValidator.validate` / `validateAll` — Running validation
`validate` runs a PDF document through one profile and returns a single `ValidationResult`. `validateAll` returns a `List` when the validator was built with multiple flavours. `cancelValidation` can interrupt long-running validation from another thread.
### Method Signatures
- `ValidationResult validate(PDFAParser parser)`
- `List validateAll(PDFAParser parser)`
- `void cancelValidation()`
### Description
These methods initiate the PDF/A validation process. The `validate` method is used for single-profile checks, returning a detailed `ValidationResult`. For validators set up to check against multiple PDF/A standards, `validateAll` should be used to obtain results for each standard. The `cancelValidation` method provides a mechanism to halt an ongoing validation process, which is useful for long-running checks or in scenarios where early termination is required.
```
--------------------------------
### Serialize and Deserialize with XmlSerialiser
Source: https://context7.com/verapdf/verapdf-library/llms.txt
Utilizes XmlSerialiser for generic JAXB XML marshalling of JAXB-annotated objects. Supports various I/O streams and file operations, including schema generation.
```java
import org.verapdf.core.XmlSerialiser;
import org.verapdf.pdfa.flavours.PDFAFlavour;
import org.verapdf.pdfa.results.*;
import org.verapdf.pdfa.validation.profiles.*;
import javax.xml.bind.JAXBException;
import java.io.*;
public class XmlSerialiserDemo {
public static void main(String[] args) throws JAXBException, IOException {
// Serialise a ValidationProfile to a formatted XML string
ValidationProfile profile = Profiles.getVeraProfileDirectory()
.getValidationProfileByFlavour(PDFAFlavour.PDFA_1_B);
String xml = XmlSerialiser.toXml(profile, /*format*/true, /*fragment*/false);
System.out.println("XML length: " + xml.length());
// Write to file
XmlSerialiser.toXml(profile, new File("profile-1b.xml"), true, false);
// De-serialise from file
ValidationProfile loaded = XmlSerialiser.typeFromXml(
ValidationProfileImpl.class, new File("profile-1b.xml"));
System.out.println("Loaded profile flavour: " + loaded.getPDFAFlavour()); // 1b
// De-serialise from String
ValidationProfile fromStr = XmlSerialiser.typeFromXml(
ValidationProfileImpl.class, xml);
System.out.println("From string: " + fromStr.getPDFAFlavour());
// Generate XML Schema for a type
String schema = XmlSerialiser.schema(Profiles.defaultProfile());
System.out.println("Schema starts with: " + schema.substring(0, 60) + "...");
}
}
```