diff --git a/pom.xml b/pom.xml index 3ac0b6297..428b32d1f 100644 --- a/pom.xml +++ b/pom.xml @@ -363,7 +363,7 @@ 2.9.1 4.2.0.Final 1.3 - 2.2.13 + 2.2.15 2.1.3 1.66 3.4.2 diff --git a/sejda-core/src/test/java/org/sejda/core/service/SetMetadataTaskTest.java b/sejda-core/src/test/java/org/sejda/core/service/SetMetadataTaskTest.java index f354edbed..f324c9056 100644 --- a/sejda-core/src/test/java/org/sejda/core/service/SetMetadataTaskTest.java +++ b/sejda-core/src/test/java/org/sejda/core/service/SetMetadataTaskTest.java @@ -114,6 +114,30 @@ public void accept(PDDocument document) { } }); } + + @Test + public void doesNotChangeProducerAndModificationDate() throws IOException { + SetMetadataParameters parameters = new SetMetadataParameters(); + parameters.put(PdfMetadataFields.AUTHOR, "test_author"); + parameters.addSource(mediumInput()); + + parameters.setUpdateCreatorProducerModifiedDate(false); + + parameters.setExistingOutputPolicy(ExistingOutputPolicy.OVERWRITE); + testContext.directoryOutputTo(parameters); + execute(parameters); + + testContext.assertTaskCompleted(); + testContext.forEachPdfOutput(new Consumer() { + @Override + public void accept(PDDocument document) { + PDDocumentInformation info = document.getDocumentInformation(); + assertEquals("iText 2.1.7 by 1T3XT", info.getProducer()); + assertNull(info.getCreator()); + assertEquals(DateConverter.toCalendar("D:20111010235709+02'00'"), info.getModificationDate()); + } + }); + } private void doExecute() throws IOException { testContext.directoryOutputTo(parameters); diff --git a/sejda-model/src/main/java/org/sejda/model/parameter/SetMetadataParameters.java b/sejda-model/src/main/java/org/sejda/model/parameter/SetMetadataParameters.java index 7b67d0d4d..1f2cd2e65 100644 --- a/sejda-model/src/main/java/org/sejda/model/parameter/SetMetadataParameters.java +++ b/sejda-model/src/main/java/org/sejda/model/parameter/SetMetadataParameters.java @@ -24,9 +24,7 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; import org.sejda.commons.collection.NullSafeSet; import org.sejda.model.parameter.base.MultiplePdfSourceMultipleOutputParameters; -import org.sejda.model.parameter.base.SinglePdfSourceSingleOutputParameters; import org.sejda.model.validation.constraint.NotEmpty; -import org.sejda.model.validation.constraint.SingleOutputAllowedExtensions; import java.util.*; @@ -41,6 +39,7 @@ public final class SetMetadataParameters extends MultiplePdfSourceMultipleOutput @NotEmpty private final Map metadata = new HashMap(); private final Set toRemove = new NullSafeSet<>(); + private Boolean updateCreatorProducerModifiedDate = true; public Map getMetadata() { return metadata; @@ -66,9 +65,18 @@ public Set getToRemove() { return toRemove; } + public Boolean isUpdateProducerModifiedDate() { + return updateCreatorProducerModifiedDate; + } + + public void setUpdateCreatorProducerModifiedDate(Boolean updateCreatorProducerModifiedDate) { + this.updateCreatorProducerModifiedDate = updateCreatorProducerModifiedDate; + } + @Override public int hashCode() { - return new HashCodeBuilder().appendSuper(super.hashCode()).append(metadata).append(toRemove).toHashCode(); + return new HashCodeBuilder().appendSuper(super.hashCode()).append(metadata).append(toRemove) + .append(updateCreatorProducerModifiedDate).toHashCode(); } @Override @@ -82,6 +90,7 @@ public boolean equals(Object other) { SetMetadataParameters parameter = (SetMetadataParameters) other; return new EqualsBuilder().appendSuper(super.equals(other)).append(metadata, parameter.metadata) .append(toRemove, parameter.toRemove) + .append(updateCreatorProducerModifiedDate, parameter.updateCreatorProducerModifiedDate) .isEquals(); } } diff --git a/sejda-sambox/src/main/java/org/sejda/impl/sambox/SetMetadataTask.java b/sejda-sambox/src/main/java/org/sejda/impl/sambox/SetMetadataTask.java index 889f20676..ab4067c43 100644 --- a/sejda-sambox/src/main/java/org/sejda/impl/sambox/SetMetadataTask.java +++ b/sejda-sambox/src/main/java/org/sejda/impl/sambox/SetMetadataTask.java @@ -32,7 +32,6 @@ import org.sejda.core.support.io.MultipleOutputWriter; import org.sejda.core.support.io.OutputWriters; -import org.sejda.core.support.io.SingleOutputWriter; import org.sejda.impl.sambox.component.DefaultPdfSourceOpener; import org.sejda.impl.sambox.component.PDDocumentHandler; import org.sejda.model.exception.TaskException; @@ -79,7 +78,10 @@ public void execute(SetMetadataParameters parameters) throws TaskException { LOG.debug("Opening {}", source); documentHandler = source.open(documentLoader); - documentHandler.setCreatorOnPDDocument(); + documentHandler.setUpdateProducerModifiedDate(parameters.isUpdateProducerModifiedDate()); + if(parameters.isUpdateProducerModifiedDate()) { + documentHandler.setCreatorOnPDDocument(); + } File tmpFile = createTemporaryBuffer(parameters.getOutput()); diff --git a/sejda-sambox/src/main/java/org/sejda/impl/sambox/component/PDDocumentHandler.java b/sejda-sambox/src/main/java/org/sejda/impl/sambox/component/PDDocumentHandler.java index f303ce4d6..2dbd30073 100644 --- a/sejda-sambox/src/main/java/org/sejda/impl/sambox/component/PDDocumentHandler.java +++ b/sejda-sambox/src/main/java/org/sejda/impl/sambox/component/PDDocumentHandler.java @@ -80,6 +80,7 @@ public class PDDocumentHandler implements Closeable { private PDDocument document; private PDDocumentAccessPermission permissions; private Set writeOptions = new HashSet<>(); + private boolean updateProducerModifiedDate = true; /** * Creates a new handler using the given document as underlying {@link PDDocument}. @@ -262,6 +263,10 @@ public void savePDDocument(File file, StandardSecurity security, EncryptionAtRes if (Boolean.getBoolean(SAMBOX_USE_ASYNC_WRITER)) { this.addWriteOption(WriteOption.ASYNC_BODY_WRITE); } + if(!updateProducerModifiedDate) { + this.addWriteOption(WriteOption.NO_METADATA_PRODUCER_MODIFIED_DATE_UPDATE); + } + if (encryptionAtRestSecurity instanceof NoEncryptionAtRest) { LOG.trace("Saving document to {} using options {}", file, writeOptions); document.writeTo(file, security, writeOptions.stream().toArray(WriteOption[]::new)); @@ -436,4 +441,12 @@ public PDPage addBlankPageBefore(int pageNumber) { document.getPages().insertBefore(result, target); return result; } + + public boolean isUpdateProducerModifiedDate() { + return updateProducerModifiedDate; + } + + public void setUpdateProducerModifiedDate(boolean updateProducerModifiedDate) { + this.updateProducerModifiedDate = updateProducerModifiedDate; + } }