2626import java .io .Writer ;
2727import java .nio .charset .StandardCharsets ;
2828
29+ import org .apache .logging .log4j .LogManager ;
30+ import org .apache .logging .log4j .Logger ;
31+
2932import org .apache .pdfbox .cos .COSDictionary ;
3033import org .apache .pdfbox .cos .COSDocument ;
3134import org .apache .pdfbox .cos .COSName ;
35+ import org .apache .pdfbox .io .IOUtils ;
36+ import org .apache .pdfbox .io .RandomAccessRead ;
3237import org .apache .pdfbox .pdfwriter .COSWriter ;
38+
3339import org .w3c .dom .Document ;
3440import org .w3c .dom .Element ;
3541
4147 */
4248public class FDFDocument implements Closeable
4349{
50+ private static final Logger LOG = LogManager .getLogger (FDFDocument .class );
51+
4452 private final COSDocument document ;
4553
54+ private final RandomAccessRead fdfSource ;
55+
4656 /**
4757 * Constructor, creates a new FDF document.
4858 *
4959 */
5060 public FDFDocument ()
5161 {
62+ fdfSource = null ;
5263 document = new COSDocument ();
5364 document .getDocumentState ().setParsing (false );
5465 document .setVersion (1.2f );
@@ -65,11 +76,25 @@ public FDFDocument()
6576 * Constructor that uses an existing document. The COSDocument that is passed in must be valid.
6677 *
6778 * @param doc The COSDocument that this document wraps.
79+ * @deprecated Use {@link #FDFDocument(COSDocument, RandomAccessRead) }
6880 */
81+ @ Deprecated
6982 public FDFDocument (COSDocument doc )
83+ {
84+ this (doc , null );
85+ }
86+
87+ /**
88+ * Constructor that uses an existing document. The COSDocument that is passed in must be valid.
89+ *
90+ * @param doc The COSDocument that this document wraps.
91+ * @param source The source that will be closed when this document gets closed, can be null.
92+ */
93+ public FDFDocument (COSDocument doc , RandomAccessRead source )
7094 {
7195 document = doc ;
7296 document .getDocumentState ().setParsing (false );
97+ fdfSource = source ;
7398 }
7499
75100 /**
@@ -249,6 +274,24 @@ public void saveXFDF(Writer output) throws IOException
249274 @ Override
250275 public void close () throws IOException
251276 {
252- document .close ();
277+ if (!document .isClosed ())
278+ {
279+ IOException firstException = null ;
280+
281+ // close all intermediate I/O streams
282+ firstException = IOUtils .closeAndLogException (document , LOG , "COSDocument" , firstException );
283+
284+ // close the source PDF stream, if we read from one
285+ if (fdfSource != null )
286+ {
287+ firstException = IOUtils .closeAndLogException (fdfSource , LOG , "RandomAccessRead pdfSource" , firstException );
288+ }
289+
290+ // rethrow first exception to keep method contract
291+ if (firstException != null )
292+ {
293+ throw firstException ;
294+ }
295+ }
253296 }
254297}
0 commit comments