Skip to content

Commit 44050f2

Browse files
ar3emiText-CI
authored andcommitted
Add check that PdfAPage can be flushed
Add PdfAPage class. Use page factories to create pages. Add check that PdfAPage object is ready to be flushed and if no don't call flushing. DEVSIX-2645
1 parent 9e5f823 commit 44050f2

File tree

15 files changed

+653
-67
lines changed

15 files changed

+653
-67
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2020 iText Group NV
4+
Authors: iText Software.
5+
6+
This program is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU Affero General Public License version 3
8+
as published by the Free Software Foundation with the addition of the
9+
following permission added to Section 15 as permitted in Section 7(a):
10+
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
11+
ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
12+
OF THIRD PARTY RIGHTS
13+
14+
This program is distributed in the hope that it will be useful, but
15+
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16+
or FITNESS FOR A PARTICULAR PURPOSE.
17+
See the GNU Affero General Public License for more details.
18+
You should have received a copy of the GNU Affero General Public License
19+
along with this program; if not, see http://www.gnu.org/licenses or write to
20+
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
Boston, MA, 02110-1301 USA, or download the license from the following URL:
22+
http://itextpdf.com/terms-of-use/
23+
24+
The interactive user interfaces in modified source and object code versions
25+
of this program must display Appropriate Legal Notices, as required under
26+
Section 5 of the GNU Affero General Public License.
27+
28+
In accordance with Section 7(b) of the GNU Affero General Public License,
29+
a covered work must retain the producer line in every PDF that is created
30+
or manipulated using iText.
31+
32+
You can be released from the requirements of the license by purchasing
33+
a commercial license. Buying such a license is mandatory as soon as you
34+
develop commercial activities involving the iText software without
35+
disclosing the source code of your own applications.
36+
These activities include: offering paid services to customers as an ASP,
37+
serving PDFs on the fly in a web application, shipping iText with a closed
38+
source product.
39+
40+
For more information, please contact iText Software Corp. at this
41+
42+
*/
43+
package com.itextpdf.kernel.pdf;
44+
45+
import com.itextpdf.kernel.geom.PageSize;
46+
47+
/**
48+
* Interface used to create instances of {@link PdfPage}.
49+
*/
50+
public interface IPdfPageFactory {
51+
52+
/**
53+
* Create {@link PdfPage} on the base of the page {@link PdfDictionary}.
54+
* @param pdfObject the {@link PdfDictionary} object on which the {@link PdfPage} will be based
55+
* @return created {@link PdfPage}
56+
*/
57+
PdfPage createPdfPage(PdfDictionary pdfObject);
58+
59+
/**
60+
* Create {@link PdfPage} with given page size and add it to the {@link PdfDocument}.
61+
* @param pdfDocument {@link PdfDocument} to add page
62+
* @param pageSize {@link PageSize} of the created page
63+
* @return created {@link PdfPage}
64+
*/
65+
PdfPage createPdfPage(PdfDocument pdfDocument, PageSize pageSize);
66+
}

kernel/src/main/java/com/itextpdf/kernel/pdf/PdfDocument.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ public class PdfDocument implements IEventDispatcher, Closeable, Serializable {
110110

111111
private static final long serialVersionUID = -7041578979319799646L;
112112

113+
private static IPdfPageFactory pdfPageFactory = new PdfPageFactory();
114+
113115
/**
114116
* Currently active page.
115117
* @deprecated Will be removed in iText 7.2
@@ -191,7 +193,6 @@ public class PdfDocument implements IEventDispatcher, Closeable, Serializable {
191193

192194
protected boolean closed = false;
193195

194-
195196
/**
196197
* flag determines whether to write unused objects to result document
197198
*/
@@ -454,7 +455,7 @@ public PdfPage addNewPage() {
454455
*/
455456
public PdfPage addNewPage(PageSize pageSize) {
456457
checkClosingStatus();
457-
PdfPage page = new PdfPage(this, pageSize);
458+
PdfPage page = getPageFactory().createPdfPage(this, pageSize);
458459
checkAndAddPage(page);
459460
dispatchEvent(new PdfDocumentEvent(PdfDocumentEvent.START_PAGE, page));
460461
dispatchEvent(new PdfDocumentEvent(PdfDocumentEvent.INSERT_PAGE, page));
@@ -482,7 +483,7 @@ public PdfPage addNewPage(int index) {
482483
*/
483484
public PdfPage addNewPage(int index, PageSize pageSize) {
484485
checkClosingStatus();
485-
PdfPage page = new PdfPage(this, pageSize);
486+
PdfPage page = getPageFactory().createPdfPage(this, pageSize);
486487
checkAndAddPage(index, page);
487488
currentPage = page;
488489
dispatchEvent(new PdfDocumentEvent(PdfDocumentEvent.START_PAGE, page));
@@ -2098,6 +2099,15 @@ protected List<ICounter> getCounters() {
20982099
return CounterManager.getInstance().getCounters(PdfDocument.class);
20992100
}
21002101

2102+
/**
2103+
* Returns the factory for creating page instances.
2104+
*
2105+
* @return implementation of {@link IPdfPageFactory} for current document
2106+
*/
2107+
protected IPdfPageFactory getPageFactory() {
2108+
return pdfPageFactory;
2109+
}
2110+
21012111
/**
21022112
* Gets iText version info.
21032113
*

kernel/src/main/java/com/itextpdf/kernel/pdf/PdfPage.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ public PdfPage copyTo(PdfDocument toDocument) {
399399
*/
400400
public PdfPage copyTo(PdfDocument toDocument, IPdfPageExtraCopier copier) {
401401
PdfDictionary dictionary = getPdfObject().copyTo(toDocument, PAGE_EXCLUDED_KEYS, true);
402-
PdfPage page = new PdfPage(dictionary);
402+
PdfPage page = getDocument().getPageFactory().createPdfPage(dictionary);
403403
copyInheritedProperties(page, toDocument);
404404
for (PdfAnnotation annot : getAnnotations()) {
405405
if (annot.getSubtype().equals(PdfName.Link)) {
@@ -506,7 +506,6 @@ public void flush() {
506506
* will be flushed.
507507
*/
508508
public void flush(boolean flushResourcesContentStreams) {
509-
// TODO log warning in case of failed flush in pdfa document case
510509
if (isFlushed()) {
511510
return;
512511
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2020 iText Group NV
4+
Authors: iText Software.
5+
6+
This program is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU Affero General Public License version 3
8+
as published by the Free Software Foundation with the addition of the
9+
following permission added to Section 15 as permitted in Section 7(a):
10+
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
11+
ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
12+
OF THIRD PARTY RIGHTS
13+
14+
This program is distributed in the hope that it will be useful, but
15+
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16+
or FITNESS FOR A PARTICULAR PURPOSE.
17+
See the GNU Affero General Public License for more details.
18+
You should have received a copy of the GNU Affero General Public License
19+
along with this program; if not, see http://www.gnu.org/licenses or write to
20+
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
Boston, MA, 02110-1301 USA, or download the license from the following URL:
22+
http://itextpdf.com/terms-of-use/
23+
24+
The interactive user interfaces in modified source and object code versions
25+
of this program must display Appropriate Legal Notices, as required under
26+
Section 5 of the GNU Affero General Public License.
27+
28+
In accordance with Section 7(b) of the GNU Affero General Public License,
29+
a covered work must retain the producer line in every PDF that is created
30+
or manipulated using iText.
31+
32+
You can be released from the requirements of the license by purchasing
33+
a commercial license. Buying such a license is mandatory as soon as you
34+
develop commercial activities involving the iText software without
35+
disclosing the source code of your own applications.
36+
These activities include: offering paid services to customers as an ASP,
37+
serving PDFs on the fly in a web application, shipping iText with a closed
38+
source product.
39+
40+
For more information, please contact iText Software Corp. at this
41+
42+
*/
43+
package com.itextpdf.kernel.pdf;
44+
45+
import com.itextpdf.kernel.geom.PageSize;
46+
47+
class PdfPageFactory implements IPdfPageFactory {
48+
49+
@Override
50+
public PdfPage createPdfPage(PdfDictionary pdfObject) {
51+
return new PdfPage(pdfObject);
52+
}
53+
54+
@Override
55+
public PdfPage createPdfPage(PdfDocument pdfDocument, PageSize pageSize) {
56+
return new PdfPage(pdfDocument, pageSize);
57+
}
58+
}

kernel/src/main/java/com/itextpdf/kernel/pdf/PdfPagesTree.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public PdfPage getPage(int pageNum) {
117117
int parentIndex = findPageParent(pageNum);
118118
PdfObject pageObject = pageRefs.get(pageNum).getRefersTo();
119119
if (pageObject instanceof PdfDictionary) {
120-
pdfPage = new PdfPage((PdfDictionary) pageObject);
120+
pdfPage = document.getPageFactory().createPdfPage((PdfDictionary) pageObject);
121121
pdfPage.parentPages = parents.get(parentIndex);
122122
} else {
123123
LOGGER.error(MessageFormatUtil.format(LogMessageConstant.PAGE_TREE_IS_BROKEN_FAILED_TO_RETRIEVE_PAGE, pageNum + 1));

pdfa/src/main/java/com/itextpdf/pdfa/PdfADocument.java

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ This file is part of the iText (R) project.
4343
*/
4444
package com.itextpdf.pdfa;
4545

46-
import com.itextpdf.io.LogMessageConstant;
4746
import com.itextpdf.kernel.font.PdfFont;
4847
import com.itextpdf.kernel.log.CounterManager;
4948
import com.itextpdf.kernel.log.ICounter;
5049
import com.itextpdf.kernel.pdf.DocumentProperties;
50+
import com.itextpdf.kernel.pdf.IPdfPageFactory;
5151
import com.itextpdf.kernel.pdf.IsoKey;
5252
import com.itextpdf.kernel.pdf.PdfAConformanceLevel;
5353
import com.itextpdf.kernel.pdf.PdfDictionary;
@@ -94,8 +94,15 @@ This file is part of the iText (R) project.
9494
public class PdfADocument extends PdfDocument {
9595

9696
private static final long serialVersionUID = -5908390625367471894L;
97+
98+
private static IPdfPageFactory pdfAPageFactory = new PdfAPageFactory();
99+
97100
protected PdfAChecker checker;
98101

102+
private boolean alreadyLoggedThatObjectFlushingWasNotPerformed = false;
103+
104+
private boolean alreadyLoggedThatPageFlushingWasNotPerformed = false;
105+
99106
/**
100107
* Constructs a new PdfADocument for writing purposes, i.e. from scratch. A
101108
* PDF/A file has a conformance level, and must have an explicit output
@@ -228,6 +235,14 @@ public PdfAConformanceLevel getConformanceLevel() {
228235
return checker.getConformanceLevel();
229236
}
230237

238+
void logThatPdfAPageFlushingWasNotPerformed() {
239+
if (!alreadyLoggedThatPageFlushingWasNotPerformed) {
240+
alreadyLoggedThatPageFlushingWasNotPerformed = true;
241+
// This log message will be printed once for one instance of the document.
242+
LoggerFactory.getLogger(PdfADocument.class).warn(PdfALogMessageConstant.PDFA_PAGE_FLUSHING_WAS_NOT_PERFORMED);
243+
}
244+
}
245+
231246
@Override
232247
protected void addCustomMetadataExtensions(XMPMeta xmpMeta) {
233248
if (this.isTagged()) {
@@ -238,7 +253,7 @@ protected void addCustomMetadataExtensions(XMPMeta xmpMeta) {
238253
}
239254
} catch (XMPException exc) {
240255
Logger logger = LoggerFactory.getLogger(PdfADocument.class);
241-
logger.error(LogMessageConstant.EXCEPTION_WHILE_UPDATING_XMPMETADATA, exc);
256+
logger.error(com.itextpdf.io.LogMessageConstant.EXCEPTION_WHILE_UPDATING_XMPMETADATA, exc);
242257
}
243258
}
244259
}
@@ -253,7 +268,7 @@ protected void updateXmpMetadata() {
253268
setXmpMetadata(xmpMeta);
254269
} catch (XMPException e) {
255270
Logger logger = LoggerFactory.getLogger(PdfADocument.class);
256-
logger.error(LogMessageConstant.EXCEPTION_WHILE_UPDATING_XMPMETADATA, e);
271+
logger.error(com.itextpdf.io.LogMessageConstant.EXCEPTION_WHILE_UPDATING_XMPMETADATA, e);
257272
}
258273
}
259274

@@ -267,9 +282,10 @@ protected void flushObject(PdfObject pdfObject, boolean canBeInObjStm) throws IO
267282
markObjectAsMustBeFlushed(pdfObject);
268283
if (isClosing || checker.objectIsChecked(pdfObject)) {
269284
super.flushObject(pdfObject, canBeInObjStm);
270-
} else {
271-
//suppress the call
272-
//TODO log unsuccessful call
285+
} else if (!alreadyLoggedThatObjectFlushingWasNotPerformed) {
286+
alreadyLoggedThatObjectFlushingWasNotPerformed = true;
287+
// This log message will be printed once for one instance of the document.
288+
LoggerFactory.getLogger(PdfADocument.class).warn(PdfALogMessageConstant.PDFA_OBJECT_FLUSHING_WAS_NOT_PERFORMED);
273289
}
274290
}
275291

@@ -305,6 +321,15 @@ protected List<ICounter> getCounters() {
305321
return CounterManager.getInstance().getCounters(PdfADocument.class);
306322
}
307323

324+
@Override
325+
protected IPdfPageFactory getPageFactory() {
326+
return pdfAPageFactory;
327+
}
328+
329+
boolean isClosing() {
330+
return isClosing;
331+
}
332+
308333
private static PdfVersion getPdfVersionForPdfA(PdfAConformanceLevel conformanceLevel) {
309334
PdfVersion version;
310335
switch (conformanceLevel.getPart()) {
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2020 iText Group NV
4+
Authors: iText Software.
5+
6+
This program is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU Affero General Public License version 3
8+
as published by the Free Software Foundation with the addition of the
9+
following permission added to Section 15 as permitted in Section 7(a):
10+
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
11+
ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
12+
OF THIRD PARTY RIGHTS
13+
14+
This program is distributed in the hope that it will be useful, but
15+
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16+
or FITNESS FOR A PARTICULAR PURPOSE.
17+
See the GNU Affero General Public License for more details.
18+
You should have received a copy of the GNU Affero General Public License
19+
along with this program; if not, see http://www.gnu.org/licenses or write to
20+
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
Boston, MA, 02110-1301 USA, or download the license from the following URL:
22+
http://itextpdf.com/terms-of-use/
23+
24+
The interactive user interfaces in modified source and object code versions
25+
of this program must display Appropriate Legal Notices, as required under
26+
Section 5 of the GNU Affero General Public License.
27+
28+
In accordance with Section 7(b) of the GNU Affero General Public License,
29+
a covered work must retain the producer line in every PDF that is created
30+
or manipulated using iText.
31+
32+
You can be released from the requirements of the license by purchasing
33+
a commercial license. Buying such a license is mandatory as soon as you
34+
develop commercial activities involving the iText software without
35+
disclosing the source code of your own applications.
36+
These activities include: offering paid services to customers as an ASP,
37+
serving PDFs on the fly in a web application, shipping iText with a closed
38+
source product.
39+
40+
For more information, please contact iText Software Corp. at this
41+
42+
*/
43+
package com.itextpdf.pdfa;
44+
45+
/**
46+
* Class containing constants to be used in logging.
47+
*/
48+
public class PdfALogMessageConstant {
49+
public static final String PDFA_PAGE_FLUSHING_WAS_NOT_PERFORMED = "Page flushing was not performed. Pages flushing in PDF/A mode works only with explicit calls to PdfPage#flush(boolean) with flushResourcesContentStreams argument set to true";
50+
51+
public static final String PDFA_OBJECT_FLUSHING_WAS_NOT_PERFORMED = "Object flushing was not performed. Object in PDF/A mode can only be flushed if the document is closed or if this object has already been checked for compliance with PDF/A rules.";
52+
}

0 commit comments

Comments
 (0)