PDFBox field value cannot display after flatten - java

I have a PDF form which is created by LiberOffice Draw 4.1.0.4.
The form contains text field, check box and radio button
After I set value to the fields and flatten the form with PDFBox(2.0.21), the field value cannot be displayed
I think it may be the problem of the appearance of the field's annotation but I have no idea how to make it right
Test PDF
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDTextField;
import java.io.File;
public class PdfGenerationTest {
public static void main( String[] args ) throws Exception{
testFillValue();
}
public static void testFillValue() throws Exception{
PDDocument pdDocument = PDDocument.load(new File("C:\\temp\\test.pdf"));
PDAcroForm acroForm = pdDocument.getDocumentCatalog().getAcroForm();
String defaultAppearance = "/Helv 12 Tf 0 0 1 rg";
for(PDField field : acroForm.getFields()) {
if (field instanceof PDTextField) {
PDTextField textField = (PDTextField) field;
textField.setActions(null);
textField.setDefaultAppearance(defaultAppearance);
}
}
setFormValue(acroForm, "TextBox", "testvalue");
setFormValue(acroForm, "radioBtn", "Yes");
setFormValue(acroForm, "chkBox", "Yes");
acroForm.refreshAppearances();
acroForm.flatten();
pdDocument.save("C:\\temp\\test_filled.pdf");
pdDocument.close();
}
private static void setFormValue(PDAcroForm acroForm, String key, String value) throws Exception {
PDField f = acroForm.getField(key);
if (f != null) {
if (value != null && StringUtils.isNotEmpty(value.trim())) {
f.setValue(value);
}
}
}
}

PDAcroForm.flaten is work for me after using pdfbox 2.0.24
<dependencies>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.24</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>fontbox</artifactId>
<version>2.0.24</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-examples</artifactId>
<version>2.0.24</version>
</dependency>
</dependencies>

Related

Expose metrics with akka-http-metrics in java

I'm trying expose metrics to Prometheus with library https://github.com/RustedBones/akka-http-metrics in java project.
After adapted code to java, I dont receive http metrics after call method, only a empy response.
If add module for jvm I have only jvm metrics.
package test;
import akka.http.javadsl.model.StatusCodes;
import akka.http.javadsl.server.AllDirectives;
import akka.http.javadsl.server.Route;
import akka.http.javadsl.server.directives.RouteAdapter;
import fr.davit.akka.http.metrics.core.scaladsl.server.HttpMetricsDirectives$;
import fr.davit.akka.http.metrics.prometheus.PrometheusRegistry;
import fr.davit.akka.http.metrics.prometheus.PrometheusSettings;
import fr.davit.akka.http.metrics.prometheus.marshalling.PrometheusMarshallers$;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.hotspot.DefaultExports;
import static akka.http.javadsl.server.PathMatchers.segment;
public class TestHttpMetrics extends AllDirectives {
public Route createRoute() {
return pathPrefix(segment("v1").slash("metrics"),
() -> concat(
path(segment("prometheus"), () -> get(this::micrometer)),
complete(StatusCodes.NOT_FOUND, "Path not found")
)
);
}
public Route micrometer() {
return pathEnd(() -> {
try {
CollectorRegistry prometheus = new CollectorRegistry();
PrometheusSettings settings = new MyPrometheusSettings().getInstance();
PrometheusRegistry registry = new PrometheusRegistry(settings, prometheus);
//DefaultExports.register(prometheus); //for JVM metrics
return RouteAdapter.asJava(HttpMetricsDirectives$.MODULE$.metrics(registry, PrometheusMarshallers$.MODULE$.marshaller()));
} catch (Exception e) {
e.printStackTrace();
}
return complete(StatusCodes.INTERNAL_SERVER_ERROR, "ERROR");
});
}
}
class MyPrometheusSettings {
public PrometheusSettings getInstance() throws Exception {
PrometheusSettings ps = ((PrometheusSettings) PrometheusSettings.class.getDeclaredMethod("default").invoke(null)) //default is reserved in java!
.withNamespace("akka_http")
.withIncludePathDimension(true)
.withIncludeMethodDimension(true)
.withIncludeStatusDimension(true)
.withDurationConfig(PrometheusSettings.DurationBuckets())
.withReceivedBytesConfig(PrometheusSettings.DefaultQuantiles())
.withSentBytesConfig(PrometheusSettings.DefaultQuantiles())
.withDefineError(response -> response.status().isFailure());
return ps;
}
}
in pom
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-http_2.12</artifactId>
<version>10.2.4</version>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>2.12.13</version>
</dependency>
<dependency>
<groupId>fr.davit</groupId>
<artifactId>akka-http-metrics-prometheus_2.12</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_hotspot</artifactId>
<version>0.15.0</version>
</dependency>
Where is the problem? In debug mode there is only null values in registry.

How to verify digital signature of the pdf with itext?

I don't know why this code is wrong. I am using a code from itext, but is giving error evin with all dependencies imported. Below is the codes that I am using in the project. Plase help me, someone.
https://developers.itextpdf.com/examples/security/digital-signatures-white-paper/digital-signatures-chapter-5
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.Security;
import java.util.ArrayList;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.text.log.SysoLogger;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.security.PdfPKCS7;
public class PdfReaderExample {
public static final String EXAMPLE1 = "/opt/doc.pdf";
public PdfPKCS7 verifySignature(AcroFields fields, String name) throws GeneralSecurityException, IOException {
System.out.println("Signature covers whole document: " + fields.signatureCoversWholeDocument(name));
System.out.println("Document revision: " + fields.getRevision(name) + " of " + fields.getTotalRevisions());
PdfPKCS7 pkcs7 = fields.verifySignature(name);
System.out.println("Integrity check OK? " + pkcs7.verify());
return pkcs7;
}
public void verifySignatures(String path) throws IOException, GeneralSecurityException {
System.out.println(path);
PdfReader reader = new PdfReader(path);
AcroFields fields = reader.getAcroFields();
ArrayList<String> names = fields.getSignatureNames();
for (String name : names) {
System.out.println("===== " + name + " =====");
verifySignature(fields, name);
}
System.out.println();
}
public static void main(String[] args) throws IOException, GeneralSecurityException {
LoggerFactory.getInstance().setLogger(new SysoLogger());
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
PdfReaderExample app = new PdfReaderExample();
app.verifySignatures(EXAMPLE1);
}
}
===== Signature2 =====
Signature covers whole document: true
Document revision: 1 of 1
Exception in thread "main" java.lang.VerifyError: (class: org/bouncycastle/cms/CMSSignedHelper, method: <clinit> signature: ()V) Incompatible argument to function
at org.bouncycastle.cms.CMSSignedData.<clinit>(Unknown Source)
at org.bouncycastle.tsp.TimeStampToken.getSignedData(Unknown Source)
at org.bouncycastle.tsp.TimeStampToken.<init>(Unknown Source)
at com.itextpdf.text.pdf.security.PdfPKCS7.<init>(PdfPKCS7.java:402)
at com.itextpdf.text.pdf.AcroFields.verifySignature(AcroFields.java:2419)
at com.itextpdf.text.pdf.AcroFields.verifySignature(AcroFields.java:2372)
at PdfReaderExample.verifySignature(PdfReaderExample.java:20)
at PdfReaderExample.verifySignatures(PdfReaderExample.java:32)
at PdfReaderExample.main(PdfReaderExample.java:42)
Process finished with exit code 1
File POM is this.
<dependencies>
<dependency>
<groupId>com.sparkjava</groupId>
<artifactId>spark-core</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.12</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.58</version>
</dependency>
</dependencies>

Disable Printing Issue with PDF Box

I am using this sample PDFBox code to encrypt and disable printing of a pdf file. Encryption happens successfully, but printing is not disabled.
What could be the issue?
Here's the dependencies section of my pom.xml
<dependencies>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15</artifactId>
<version>1.46</version>
</dependency>
</dependencies>
and below is the source code
import java.io.File;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;
public class Test {
public static void main(String[] args) throws Exception {
PDDocument doc = PDDocument.load(new File("/tmp/Test.pdf"));
int keyLength = 128;
AccessPermission ap = new AccessPermission();
ap.setCanPrint(false);
StandardProtectionPolicy spp = new StandardProtectionPolicy("Admin", "Password", ap);
spp.setEncryptionKeyLength(keyLength);
spp.setPermissions(ap);
doc.protect(spp);
doc.save("/tmp/Test-Encrypted.pdf");
doc.close();
}
}

How to capture a screenshot after each step in tests with JAVA and Cucumber?

What would be the best way to capture screenshots after each step when running integration tests?
Tests are written in Java using Selenium(3.0.1) and Cucumber(1.2.4).
Code for taking a screenshot after a test is below, but I need a screenshot after each method annotated with #Given, #When, #Then.
#After
public void after(Scenario scenario){
final byte[] screenshot = driver.getScreenshotAs(OutputType.BYTES);
scenario.embed(screenshot, "image/png");
}
Thank you for any hints.
Solved this using Aspects. Was pretty tricky, note the annotation:
#After("call(public * cucumber.runtime.StepDefinitionMatch.runStep(..)) && within(cucumber.runtime.Runtime)")
Below is the full code, written by Viviana Cattenazzi.
pom.xml
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-core</artifactId>
<version>1.2.4</version>
</dependency>
</dependencies>
......
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.10</version>
<configuration>
<weaveDependencies>
<weaveDependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-core</artifactId>
</weaveDependency>
</weaveDependencies>
<showWeaveInfo>true</showWeaveInfo>
<source>1.8</source>
<target>1.8</target>
<complianceLevel>1.8</complianceLevel>
</configuration>
<executions>
<execution>
<phase>process-test-classes</phase>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
.......
StepsInterceptor.java
#Aspect
public class StepsInterceptor {
#After("call(public * cucumber.runtime.StepDefinitionMatch.runStep(..)) && within(cucumber.runtime.Runtime)")
public void beforeRunningStep(JoinPoint thisJoinPoint) throws Exception {
try {
StepDefinitionMatch stepDefinitionMatch = (StepDefinitionMatch) thisJoinPoint.getTarget();
Step step = (Step) retrievePrivateField(stepDefinitionMatch, "step");
String stepName = step.getKeyword().trim();
if ("Given".equals(stepName) || "When".equals(stepName)) {
Object theRealStepDef = extractJavaStepDefinition(stepDefinitionMatch);
// take screen shot here
}
} catch (ClassCastException exc) { ....
}
}
}
At this time, OP might have figured out alternative options. However this may help others. Latest version of io.cucumber has both #BeforeStep and #AfterStep, so you can embed screenshot capturing in to #AfterStep function at only one place which solves your problem.
https://stackoverflow.com/a/53135127/5885718
Can this post help you?
Embedding screenshots in Cucumber JVM
Here is the Answer to your Question:
Lets assume your methods are as follows:
#Given("^Open$")
public void Open() throws Throwable
{
//your code
}
#When("^I$")
public void I(String uname, String pass) throws Throwable
{
//your code
}
#Then("^User$")
public void User() throws Throwable
{
//your code
}
You can write a library to take screenshots like:
public static void screenshot(WebDriver driver, long ms)
{
try {
TakesScreenshot ts = (TakesScreenshot) driver;
File source = ts.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(source, new File("./ScreenShots/"+ms+"Facebook.png"));
System.out.println("ScreenShot Taken");
}
catch (Exception e)
{
System.out.println("Exception while taking ScreenShot "+e.getMessage());
}
}
Now you can easily call the library after every method to take the screenshot as follows:
#Given("^Open$")
public void Open() throws Throwable
{
//your code
Utility.screenshot(driver, System.currentTimeMillis());
}
#When("^I$")
public void I(String uname, String pass) throws Throwable
{
//your code
Utility.screenshot(driver, System.currentTimeMillis());
}
#Then("^User$")
public void User() throws Throwable
{
//your code
Utility.screenshot(driver, System.currentTimeMillis());
}
Let me know if this Answers your Question.
I don't think it would be possible until following merge request is accepted and merged. if you are really interested you can merge it locally and have your own custom Jar.
https://github.com/cucumber/cucumber-jvm/pull/838
This might not be what you asked but this can help others too! (I haven't used Cucumber though)
Here is my code to take a screen shot and add it to a PDF file (If you want to do something else with it that you can).
Just you have to call screenshotPDF(webDriver, testName) method whenever you want!
package com.helper;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.server.handler.WebDriverHandler;
import org.testng.annotations.Test;
public class ScreenshotPDF {
#SuppressWarnings("deprecation")
#Test
//public static void screenshotPDF() {
public static void screenshotPDF(WebDriver webDriver, String testName){
{
PDDocument doc = null;
boolean isNewFile = false;
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy h:mm:ss a");
String timeStemp = sdf.format(date);
try {
try {
doc = PDDocument.load(new File(
"C:/Users/Documents/sample.pdf"));
} catch (FileNotFoundException f) {
doc = new PDDocument();
PDPage p = new PDPage();
doc.addPage(p);
isNewFile = true;
}
File screenshot = ((TakesScreenshot) webDriver)
.getScreenshotAs(OutputType.FILE);
Integer numberP = doc.getNumberOfPages();
PDPage blankPage = new PDPage();
PDPage page;
if (!isNewFile) {
doc.addPage(blankPage);
page = doc.getPage(numberP);
} else {
page = doc.getPage(numberP - 1);
}
PDImageXObject pdImage = PDImageXObject
.createFromFileByContent(screenshot, doc);
PDPageContentStream contentStream = new PDPageContentStream(
doc, page, AppendMode.APPEND, true);
PDFont font = PDType1Font.HELVETICA_BOLD;
contentStream.beginText();
contentStream.setFont(font, 12);
contentStream.moveTextPositionByAmount(100, 600);
contentStream.drawString(testName+" "+timeStemp);
contentStream.endText();
float scale = 0.4f;
Capabilities cap = ((RemoteWebDriver) webDriver).getCapabilities();
String browserName = cap.getBrowserName().toLowerCase();
if (browserName.contains("explorer"))
scale = 0.4f;
contentStream.drawImage(pdImage, 50, 210, pdImage.getWidth() * scale, pdImage.getHeight() * scale);
contentStream.close();
contentStream.close();
doc.save("C:/Users/Documents/sample.pdf");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (doc != null) {
try {
doc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
There is no afterStep annotation in cucumber java. So you cann't do it in straight forward. You can do it in another way as mentioned in #DebanjanB answer.
But this can be achievable in cucumber-ruby with after step annotation.
Selenium exposed a interfaced called as WebDriverEventListener, which you can implement you own code generally this interface has methods like afterFindBy , beforeFindBy just need to implement that method to take screen shots.
After implementing this method then you need to inject this implemented class to driver object as shown below
EventFiringWebDriver eventFiringWebDriver = new EventFiringWebDriver(driver);
MyWebDriverListerner handler = new MyWebDriverListerner();
eventFiringWebDriver.register(handler);
Now whenever driver finds the element then it will invoke that respective injected method.
Let me know if it solves your problem

How to read tibetan content from pdf file?

I have a tibetan pdf file, and I want to extract its content. But I tried following three codes to read the file, I got code that isn't what I wanted.
code1:
import java.io.IOException;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.PdfTextExtractor;
public class iTextReadDemo {
public static void main(String[] args) {
try {
PdfReader reader = new PdfReader("");
String page = PdfTextExtractor.getTextFromPage(reader, 1);
System.out.println("Page Content:\n\n" + page + "\n\n");
} catch (IOException e) {
e.printStackTrace();
}
}
}// - See more at:
// http://www.quicklyjava.com/read-pdf-file-in-java-using-itext/#sthash.iAhF00Kj.dpuf
code2 :
import java.io.FileOutputStream;
import com.lowagie.text.Document;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import com.lowagie.text.pdf.PdfWriter;
public class MainClass {
public static void main(String[] args) throws Exception {
PdfReader reader = new PdfReader("");
byte[] bs = new byte[100];
byte[] streamBytes = reader.getPageContent(1);
for(byte b: streamBytes){
System.out.print((char)b);
}
}
}
code3:
package pdfBox;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.util.PDFTextStripper;
public class PDFTest {
public static void main(String[] args) throws Exception {
PDDocument pd;
File input = new File("C:\\Users\\Administrator\\Desktop\\tibetan Dictionary pdf/藏英英藏词典 - 副本.pdf");
pd = PDDocument.load(input);
PDFTextStripper reader = new PDFTextStripper("utf-8");
String pageText = reader.getText(pd);
System.out.println(pageText);
}
}
and this is the part of the maven pom dependency
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.3</version>
</dependency>
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>org.swinglabs</groupId>
<artifactId>pdf-renderer</artifactId>
<version>1.0.5</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>1.8.7</version>
</dependency>
what is wrong ?
is he said right?
https://answers.acrobatusers.com/Can-I-convert-PDF-Word-Doc-Tibetan-script-addition-English-language-q219757.aspx
The quality of exported content from a PDF is directly related to the quality of the PDF's "build" (what is under the hood, not what you "see"). Poor quality export indicates a poorly built PDF. Nothing you can do other that ask the originator of the PDF to do a better job.

Categories

Resources