Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PDF/A-3A validation fix #282

Merged
merged 11 commits into from
Sep 12, 2024
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ SHELL ?= /bin/bash
endif

#JAR_VERSION := $(shell mvn -q -Dexec.executable="echo" -Dexec.args='$${project.version}' --non-recursive exec:exec -DforceStdout)
JAR_VERSION := 1.99
JAR_VERSION := 2.00
JAR_FILE := mn2pdf-$(JAR_VERSION).jar

all: target/$(JAR_FILE)
Expand Down
10 changes: 5 additions & 5 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ You will need the Java Development Kit (JDK) version 8, Update 241 (8u241) or hi

[source,sh]
----
java -Xss5m -Xmx2048m -jar target/mn2pdf-1.99.jar --xml-file <XML-FileName> --xsl-file <XSLT-FileName> --pdf-file <Output-PDF-FileName> [--syntax-highlight]
java -Xss5m -Xmx2048m -jar target/mn2pdf-2.00.jar --xml-file <XML-FileName> --xsl-file <XSLT-FileName> --pdf-file <Output-PDF-FileName> [--syntax-highlight]
----

e.g.

[source,sh]
----
java -Xss5m -Xmx2048m -jar target/mn2pdf-1.99.jar --xml-file tests/G.191.xml --xsl-file tests/itu.recommendation.xsl --pdf-file tests/G.191.pdf
java -Xss5m -Xmx2048m -jar target/mn2pdf-2.00.jar --xml-file tests/G.191.xml --xsl-file tests/itu.recommendation.xsl --pdf-file tests/G.191.pdf
----

=== PDF encryption features
Expand Down Expand Up @@ -100,7 +100,7 @@ Update version in `pom.xml`, e.g.:
----
<groupId>org.metanorma.fop</groupId>
<artifactId>mn2pdf</artifactId>
<version>1.99</version>
<version>2.00</version>
<name>Metanorma XML to PDF converter</name>
----

Expand All @@ -111,8 +111,8 @@ Tag the same version in Git:

[source,xml]
----
git tag v1.99
git push origin v1.99
git tag v2.00
git push origin v2.00
----

Then the corresponding GitHub release will be automatically created at:
Expand Down
56 changes: 38 additions & 18 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.metanorma.fop</groupId>
<artifactId>mn2pdf</artifactId>
<version>1.99</version>
<version>2.00</version>
<name>Metanorma XML to PDF converter</name>
<packaging>jar</packaging>
<url>https://www.metanorma.org</url>
Expand Down Expand Up @@ -96,25 +96,35 @@
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/org.apache.xmlgraphics.image.loader.spi.ImagePreloader</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>org.metanorma.fop.mn2pdf</Main-Class>
<Implementation-Version>${project.version}</Implementation-Version>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/org.apache.xmlgraphics.image.loader.spi.ImagePreloader</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>org.metanorma.fop.mn2pdf</Main-Class>
<Implementation-Version>${project.version}</Implementation-Version>
</manifestEntries>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
Expand Down Expand Up @@ -282,5 +292,15 @@
<artifactId>webp-imageio</artifactId>
<version>0.1.6</version>
</dependency>
<dependency>
<groupId>org.verapdf</groupId>
<artifactId>validation-model</artifactId>
<version>1.26.1</version>
</dependency>
<dependency>
<groupId>org.verapdf</groupId>
<artifactId>validation-model-jakarta</artifactId>
<version>1.26.1</version>
</dependency>
</dependencies>
</project>
13 changes: 13 additions & 0 deletions src/main/java/org/metanorma/fop/PDFConformanceChecker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.metanorma.fop;

import static org.metanorma.Constants.PDF_A_MODE;

public class PDFConformanceChecker {

public static boolean hasException(String msg) {
if (msg != null) {
return msg.contains("PDFConformanceException") && (msg.contains("PDF/UA-1") || msg.contains(PDF_A_MODE));
}
return false;
}
}
18 changes: 14 additions & 4 deletions src/main/java/org/metanorma/fop/PDFGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,11 @@ private void convertmn2pdf(fontConfig fontcfg, XSLTconverter xsltConverter, File
logger.info(WARNING_NONPDFUA);
}

// validate PDF by veraPDF
VeraPDFValidator veraPDFValidator = new VeraPDFValidator();
veraPDFValidator.validate(pdf);


fontcfg.printMessages();

} catch (Exception e) {
Expand Down Expand Up @@ -580,6 +585,13 @@ private void runFOP (fontConfig fontcfg, Source src, File pdf) throws IOExceptio
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
// configure foUserAgent
foUserAgent.setProducer("Ribose Metanorma mn2pdf version " + Util.getAppVersion());

if (encryptionParams.isEmpty()) {
foUserAgent.getRendererOptions().put("pdf-a-mode", PDF_A_MODE);
} else {
logger.severe("PDF/A doesn't allow encrypted PDFs. PDF will be generated in non-PDF/A mode.");
}

setEncryptionParams(foUserAgent);

//Adding a simple logging listener that writes to stdout and stderr
Expand Down Expand Up @@ -641,8 +653,7 @@ private void runFOP (fontConfig fontcfg, Source src, File pdf) throws IOExceptio
}

} catch (Exception e) {
String excstr=e.toString();
if (excstr.contains("PDFConformanceException") && excstr.contains("PDF/UA-1") && !PDFUA_error) { // excstr.contains("all fonts, even the base 14 fonts, have to be embedded")
if (PDFConformanceChecker.hasException(e.toString()) && !PDFUA_error) { // excstr.contains("all fonts, even the base 14 fonts, have to be embedded")
//System.err.println(e.toString());
logger.severe(e.toString());
PDFUA_error = true;
Expand Down Expand Up @@ -1053,8 +1064,7 @@ public void error(TransformerException exc)

public void fatalError(TransformerException exc)
throws TransformerException {
String excstr=exc.toString();
if (excstr.contains("PDFConformanceException") && excstr.contains("PDF/UA-1") && !PDFUA_error) { // excstr.contains("all fonts, even the base 14 fonts, have to be embedded")
if (PDFConformanceChecker.hasException(exc.toString()) && !PDFUA_error) { // excstr.contains("all fonts, even the base 14 fonts, have to be embedded")
//System.err.println(exc.toString());
logger.severe(exc.toString());
PDFUA_error = true;
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/org/metanorma/fop/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,13 @@ public static int getStringWidth(String text, String fontName) {
return stringWidth;
}

public static float getStringWidthByFontSize(String text, String fontName, int fontSize) {
float stringWidth = 0.0f;
Font font = new Font(fontName, Font.PLAIN, fontSize);
stringWidth = SVGUtilities.getStringWidth(text, font);
return stringWidth;
}

public static String saveFileToDisk(String filename, String content) {
try {
Files.createDirectories(tmpfilepath);
Expand Down
55 changes: 55 additions & 0 deletions src/main/java/org/metanorma/fop/VeraPDFValidator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.metanorma.fop;

import org.metanorma.utils.LoggerHelper;
import org.verapdf.core.EncryptedPdfException;
import org.verapdf.core.ModelParsingException;
import org.verapdf.core.ValidationException;
import org.verapdf.gf.foundry.VeraGreenfieldFoundryProvider;
import org.verapdf.pdfa.Foundries;
import org.verapdf.pdfa.PDFAParser;
import org.verapdf.pdfa.results.ValidationResult;
import org.verapdf.pdfa.PDFAValidator;
import org.verapdf.pdfa.flavours.PDFAFlavour;
import org.verapdf.report.HTMLReport;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.logging.Logger;

import static org.metanorma.Constants.PDF_A_MODE;

public class VeraPDFValidator {

protected static final Logger logger = Logger.getLogger(LoggerHelper.LOGGER_NAME);

// see https://docs.verapdf.org/develop/
public void validate(File filePDF) {
VeraGreenfieldFoundryProvider.initialise();
String sPDFAmode = PDF_A_MODE.substring(PDF_A_MODE.indexOf("-"));
PDFAFlavour flavour = PDFAFlavour.fromString(sPDFAmode);
try (PDFAParser parser = Foundries.defaultInstance().createParser(new FileInputStream(filePDF), flavour)) {
PDFAValidator validator = Foundries.defaultInstance().createValidator(flavour, false);
ValidationResult result = validator.validate(parser);

if (result.isCompliant()) {
// File is a valid PDF/A PDF_A_MODE
return;
} else {
// it isn't
logger.severe("PDF isn't valid " + PDF_A_MODE + ":");
String veraPDFresult = result.toString();
veraPDFresult = veraPDFresult.replaceAll("(TestAssertion )","\n$1")
.replaceAll("\\s(message=)","\n$1")
.replaceAll("\\s(location=)","\n$1");
logger.severe(veraPDFresult);
//HTMLReport.writeHTMLReport()
}
} catch (IOException | ValidationException | ModelParsingException | EncryptedPdfException exception) {
// Exception during validation
logger.severe(exception.toString());
}
return;
}

}
2 changes: 2 additions & 0 deletions src/main/java/org/metanorma/fop/annotations/Annotation.java
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ public void process(File pdf, String xmlReview) throws IOException {

PDAnnotation pdfannot = PDAnnotation.createAnnotation(fdfannot.getCOSObject());

pdfannot.constructAppearances(); // requires for PDF/A

if (map_pdfannots.get(page) == null) {
map_pdfannots.put(page, new ArrayList<PDAnnotation>());
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/xfdf_simple.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
<text>
<xsl:attribute name="color"><xsl:value-of select="$color_annotation"/></xsl:attribute>
<xsl:attribute name="opacity"><xsl:value-of select="$opacity_popup"/></xsl:attribute>
<xsl:attribute name="flags">nozoom,norotate</xsl:attribute>
<xsl:attribute name="flags">print,nozoom,norotate</xsl:attribute>
<xsl:attribute name="date"><xsl:value-of select="$date"/></xsl:attribute>
<xsl:attribute name="page"><xsl:value-of select="$page - 1"/></xsl:attribute>
<xsl:attribute name="rect"><xsl:value-of select="concat($element_from/@x,',',$element_from/@y)"/></xsl:attribute>
Expand Down
Loading