Skip to content

Commit

Permalink
new release 1.8.0
Browse files Browse the repository at this point in the history
  • Loading branch information
HealthPDU committed Nov 1, 2019
1 parent 7f8223b commit 1294f0b
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 87 deletions.
10 changes: 10 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
include:
- project: 'health-pdu/htds/pipeline/ci-scripts'
file: 'maven-base.yml'
- project: 'health-pdu/htds/pipeline/ci-scripts'
file: 'containerise.yml'

variables:
LOCAL_PROJECT_NAME: "integn"
LOCAL_COMPONENT_NAME: "ms-html-to-pdfa"
ECS_SERVICE_NAME: "htmlpdfa"
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pipeline {
steps {
script {
jenkinsAgentDockerBuild {
projectName = "shared"
projectName = "integn"
componentName = "ms-html-to-pdfa"
slackChannel = 'health-pdu-fhajenkins'
}
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>uk.gov.dwp.pdfa</groupId>
<artifactId>ms-html-to-pdfa</artifactId>
<version>1.7.3</version>
<version>1.8.0</version>

<name>${project.groupId}:${project.artifactId}</name>
<description>Take an XHTML document and produce and pdf document at various conformance levels</description>
Expand Down Expand Up @@ -48,7 +48,7 @@
<jackson.version>2.10.0</jackson.version>
<mockito.version>2.24.5</mockito.version>
<jacoco.version>0.8.2</jacoco.version>
<owasp.version>4.0.2</owasp.version>
<owasp.version>5.2.1</owasp.version>
<junit.version>4.11</junit.version>
<jaxb.version>2.3.0</jaxb.version>

Expand Down
91 changes: 45 additions & 46 deletions src/main/java/uk/gov/dwp/pdfa/HtmlToPdfResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpStatus;
import org.slf4j.Logger;
Expand All @@ -11,38 +19,34 @@
import uk.gov.dwp.pdfa.items.PdfExtendedConstants;
import uk.gov.dwp.pdfa.transform.HtmlToPdfGenerator;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

@Path("/")
public class HtmlToPdfResource {

private static final Logger LOGGER = LoggerFactory.getLogger(HtmlToPdfResource.class.getName());
private final Map<String, String> defaultArialFont = new HashMap<>();
private final HtmlToPdfGenerator pdfGenerator;
private final String defaultColourProfile;

public HtmlToPdfResource(HtmlToPdfGenerator pdfGenerator) throws IOException {
this.getDefaultArialFont()
.put(
"courier",
Base64.getEncoder()
.encodeToString(
IOUtils.toByteArray(getClass().getResourceAsStream("/fonts/courier.ttf"))));
.put(
"courier",
Base64.getEncoder()
.encodeToString(
IOUtils.toByteArray(getClass().getResourceAsStream(
"/fonts/courier.ttf"))));
this.getDefaultArialFont()
.put(
"arial",
Base64.getEncoder()
.encodeToString(
IOUtils.toByteArray(getClass().getResourceAsStream("/fonts/arial.ttf"))));
this.defaultColourProfile =
Base64.getEncoder()
.encodeToString(
IOUtils.toByteArray(getClass().getResourceAsStream("/colours/sRGB.icm")));
.put(
"arial",
Base64.getEncoder()
.encodeToString(
IOUtils.toByteArray(getClass().getResourceAsStream(
"/fonts/arial.ttf"))));
this.defaultColourProfile
= Base64.getEncoder()
.encodeToString(
IOUtils.toByteArray(getClass().getResourceAsStream("/colours/sRGB.icm"))
);
this.pdfGenerator = pdfGenerator;
}

Expand All @@ -56,43 +60,38 @@ public Response generatePdfDocument(String json) {
JsonPdfInputItem pdfInputItem = new ObjectMapper().readValue(json, JsonPdfInputItem.class);
LOGGER.info("successfully serialised input json");

String base64Pdf =
pdfGenerator.createPdfaDocument(
pdfInputItem.getHtmlDocument(),
pdfInputItem.getColourProfile() != null
? pdfInputItem.getColourProfile()
: getDefaultColourProfile(),
(pdfInputItem.getFontMap() != null && pdfInputItem.getFontMap().size() > 0)
? pdfInputItem.getFontMap()
: getDefaultArialFont(),
pdfInputItem.getConformanceLevel() != null
? pdfInputItem.getConformanceLevel()
: PdfExtendedConstants.PDF_UA_CONFORMANCE);
String base64Pdf = pdfGenerator.createPdfaDocument(
pdfInputItem.getHtmlDocument(),
Optional.ofNullable(pdfInputItem.getColourProfile())
.orElseGet(this::getDefaultColourProfile),
Optional.ofNullable(pdfInputItem.getFontMap())
.filter(fontMap -> fontMap.size() > 0)
.orElseGet(this::getDefaultArialFont),
Optional.ofNullable(pdfInputItem.getConformanceLevel())
.orElse(PdfExtendedConstants.PDF_UA_CONFORMANCE)
);

response = Response.status(HttpStatus.SC_OK).entity(base64Pdf).build();
LOGGER.info("successfully written encoded pdf to response");

} catch (JsonParseException | JsonMappingException e) {
response =
Response.status(HttpStatus.SC_BAD_REQUEST)
.entity(String.format("Json formatting exception :: %s", e.getMessage()))
.build();
response = Response.status(HttpStatus.SC_BAD_REQUEST)
.entity(String.format("Json formatting exception :: %s", e.getMessage()))
.build();
LOGGER.debug(e.getClass().getName(), e);
LOGGER.error(e.getMessage());

} catch (IOException e) {
response =
Response.status(HttpStatus.SC_BAD_REQUEST)
.entity(String.format("IOException :: %s", e.getMessage()))
.build();
response = Response.status(HttpStatus.SC_BAD_REQUEST)
.entity(String.format("IOException :: %s", e.getMessage()))
.build();
LOGGER.debug(e.getClass().getName(), e);
LOGGER.error(e.getMessage());

} catch (Exception e) {
response =
Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
.entity(String.format("%s :: %s", e.getClass().getName(), e.getMessage()))
.build();
response = Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
.entity(String.format("%s :: %s", e.getClass().getName(), e.getMessage()))
.build();
LOGGER.debug(e.getClass().getName(), e);
LOGGER.error(e.getMessage());
}
Expand Down
13 changes: 7 additions & 6 deletions src/main/java/uk/gov/dwp/pdfa/VersionInformationResource.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package uk.gov.dwp.pdfa;

import java.io.IOException;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import java.io.IOException;

@Path("/version-info")
public class VersionInformationResource {
private static final Logger LOGGER = LoggerFactory.getLogger(VersionInformationResource.class.getName());
private static final Logger LOGGER = LoggerFactory.getLogger(
VersionInformationResource.class.getName()
);

@GET
public Response getVersionInformation() {
Expand Down
68 changes: 36 additions & 32 deletions src/main/java/uk/gov/dwp/pdfa/transform/HtmlToPdfGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,40 @@
import com.openhtmltopdf.pdfboxout.PdfBoxFontResolver;
import com.openhtmltopdf.pdfboxout.PdfBoxRenderer;
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.gov.dwp.pdfa.exception.PdfaGeneratorException;
import uk.gov.dwp.pdfa.items.PdfExtendedConstants;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Base64;
import java.util.Map;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.gov.dwp.pdfa.exception.PdfaGeneratorException;
import uk.gov.dwp.pdfa.items.PdfExtendedConstants;

public class HtmlToPdfGenerator {

private static final Logger LOGGER = LoggerFactory.getLogger(HtmlToPdfGenerator.class.getName());

public String createPdfaDocument(
String html, String colourProfile, Map<String, String> fontMap, String conformanceLevel)
throws PdfaGeneratorException {
String html, String colourProfile, Map<String, String> fontMap, String conformanceLevel)
throws PdfaGeneratorException {
try {
String base64pdf;

try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {

PdfRendererBuilder pdfBuilder =
new PdfRendererBuilder()
.defaultTextDirection(TextDirection.LTR)
.useColorProfile(getColourProfile(colourProfile))
.withHtmlContent(getHtml(html), null)
.useFastMode()
.toStream(outputStream);
PdfRendererBuilder pdfBuilder
= new PdfRendererBuilder()
.defaultTextDirection(TextDirection.LTR)
.useColorProfile(getColourProfile(colourProfile))
.withHtmlContent(getHtml(html), null)
.useFastMode()
.toStream(outputStream);

if (useConformanceLevelParameter(conformanceLevel)) {
LOGGER.info("building pdf to comply with conformance level {}", conformanceLevel);
pdfBuilder.usePdfAConformance(
PdfRendererBuilder.PdfAConformance.valueOf(conformanceLevel));
PdfRendererBuilder.PdfAConformance.valueOf(conformanceLevel));

} else {
LOGGER.info("building a PDF/UA accessible pdf");
Expand All @@ -64,34 +64,35 @@ public String createPdfaDocument(
}

private boolean useConformanceLevelParameter(String conformanceLevel)
throws PdfaGeneratorException {
throws PdfaGeneratorException {
boolean useConformanceLevel = false;

try {
PdfRendererBuilder.PdfAConformance.valueOf(conformanceLevel);
useConformanceLevel = true;

} catch (Exception e) {
if ((conformanceLevel == null)
|| (!conformanceLevel.equalsIgnoreCase(PdfExtendedConstants.PDF_UA_CONFORMANCE))) {
if (conformanceLevel == null
|| !conformanceLevel.equalsIgnoreCase(PdfExtendedConstants.PDF_UA_CONFORMANCE)) {
throw new PdfaGeneratorException(
String.format("'%s' is not a valid conformance level, aborting", conformanceLevel));
String.format("'%s' is not a valid conformance level, aborting", conformanceLevel));
}
}

return useConformanceLevel;
}

private void verifyFontApplication(
Map<String, String> fontMap, String html, String conformanceLevel)
throws PdfaGeneratorException {
if ((html != null)
&& (!conformanceLevel.equalsIgnoreCase(
PdfRendererBuilder.PdfAConformance.NONE.toString()))) {
Map<String, String> fontMap, String html, String conformanceLevel)
throws PdfaGeneratorException {
if (html != null
&& !conformanceLevel.equalsIgnoreCase(
PdfRendererBuilder.PdfAConformance.NONE.toString()
)) {
LOGGER.debug("validate that all fonts in the document are contained in the font map");

for (String fontHtml :
html.lines().filter(p -> p.contains("font-family")).collect(Collectors.toList())) {
for (String fontHtml
: html.lines().filter(p -> p.contains("font-family")).collect(Collectors.toList())) {
boolean fontMissing = true;
fontHtml = fontHtml.trim();

Expand All @@ -105,9 +106,11 @@ private void verifyFontApplication(

if (fontMissing) {
throw new PdfaGeneratorException(
String.format(
"html element requests %s. It is not passed in the font map, cannot encode.",
fontHtml.replace(";", "").trim()));
String.format(
"html element requests %s. It is not passed in the font map, cannot encode.",
fontHtml.replace(";", "").trim()
)
);
}
}
}
Expand All @@ -119,8 +122,8 @@ private String getHtml(String html) {

private byte[] getColourProfile(String base64ColourProfile) {
return base64ColourProfile != null
? Base64.getDecoder().decode(base64ColourProfile.getBytes())
: null;
? Base64.getDecoder().decode(base64ColourProfile.getBytes())
: null;
}

private void populateFontResolver(PdfBoxFontResolver fontResolver, Map<String, String> fontMap) {
Expand All @@ -130,7 +133,8 @@ private void populateFontResolver(PdfBoxFontResolver fontResolver, Map<String, S
entry.getKey(),
null,
null,
false);
false
);
LOGGER.debug("adding font '{}' to font map", entry.getKey());
}
}
Expand Down

0 comments on commit 1294f0b

Please sign in to comment.