Skip to content

Commit 1508418

Browse files
committed
PDFBOX-5950: use clone instead of setItem of source; improve logging; remove dead code
git-svn-id: https://svn.apache.org/repos/asf/pdfbox/trunk@1923746 13f79535-47bb-0310-9956-ffa450edef68
1 parent 9ea5905 commit 1508418

File tree

1 file changed

+19
-22
lines changed

1 file changed

+19
-22
lines changed

pdfbox/src/main/java/org/apache/pdfbox/multipdf/PDFMergerUtility.java

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@ private void legacyMergeDocuments(StreamCacheCreateFunction streamCacheCreateFun
512512
*/
513513
public void appendDocument(PDDocument destination, PDDocument source) throws IOException
514514
{
515+
PDFCloneUtility cloner = new PDFCloneUtility(destination);
515516
if (source.getDocument().isClosed())
516517
{
517518
throw new IOException("Error: source PDF is closed.");
@@ -529,7 +530,7 @@ public void appendDocument(PDDocument destination, PDDocument source) throws IOE
529530

530531
PDDocumentInformation destInfo = destination.getDocumentInformation();
531532
PDDocumentInformation srcInfo = source.getDocumentInformation();
532-
mergeInto(srcInfo.getCOSObject(), destInfo.getCOSObject(), Collections.emptySet());
533+
mergeInto(srcInfo.getCOSObject(), destInfo.getCOSObject(), cloner, Collections.emptySet());
533534

534535
// use the highest version number for the resulting pdf
535536
float destVersion = destination.getVersion();
@@ -541,8 +542,6 @@ public void appendDocument(PDDocument destination, PDDocument source) throws IOE
541542
}
542543

543544
PDDocumentCatalog destCatalog = destination.getDocumentCatalog();
544-
PDFCloneUtility cloner = new PDFCloneUtility(destination);
545-
546545
mergeAcroForm(cloner, destCatalog, srcCatalog);
547546

548547
COSArray destThreads = destCatalog.getCOSObject().getCOSArray(COSName.THREADS);
@@ -688,7 +687,7 @@ public void appendDocument(PDDocument destination, PDDocument source) throws IOE
688687
try
689688
{
690689
PDStream newStream = new PDStream(destination, srcMetadata.createInputStream(), (COSName) null);
691-
mergeInto(srcMetadata, newStream.getCOSObject(),
690+
mergeInto(srcMetadata, newStream.getCOSObject(), cloner,
692691
new HashSet<>(Arrays.asList(COSName.FILTER, COSName.LENGTH)));
693692
destCatalog.getCOSObject().setItem(COSName.METADATA, newStream);
694693
}
@@ -710,7 +709,7 @@ else if (destOCP != null && srcOCP != null)
710709
cloner.cloneMerge(srcOCP, destOCP);
711710
}
712711

713-
mergeOutputIntents(cloner, srcCatalog, destCatalog);
712+
mergeOutputIntents(srcCatalog, destCatalog, cloner);
714713

715714
// merge logical structure hierarchy
716715
boolean mergeStructTree = false;
@@ -770,7 +769,6 @@ else if (destOCP != null && srcOCP != null)
770769
}
771770

772771
Map<COSDictionary, COSDictionary> objMapping = new HashMap<>();
773-
int pageIndex = 0;
774772
PDPageTree destinationPageTree = destination.getPages(); // cache PageTree
775773
for (PDPage page : srcCatalog.getPages())
776774
{
@@ -813,7 +811,6 @@ else if (destOCP != null && srcOCP != null)
813811
// TODO update mapping for XObjects
814812
}
815813
destinationPageTree.add(newPage);
816-
++pageIndex;
817814
}
818815
mergeOpenAction(srcCatalog, destCatalog, cloner);
819816
if (mergeStructTree)
@@ -832,19 +829,19 @@ else if (destOCP != null && srcOCP != null)
832829

833830
// Note that all elements are stored flatly. This could become a problem for large files
834831
// when these are opened in a viewer that uses the tagging information.
835-
// If this happens, then PDNumberTreeNode should be improved with a convenience method that
832+
// If this happens, then PDNumberTreeNode should be improved with a convenience method that
836833
// stores the map into a B+Tree, see https://en.wikipedia.org/wiki/B+_tree
837834
newParentTreeNode.setNumbers(destNumberTreeAsMap);
838835

839836
destStructTree.setParentTree(newParentTreeNode);
840837
destStructTree.setParentTreeNextKey(destParentTreeNextKey);
841838

842839
mergeKEntries(cloner, srcStructTree, destStructTree);
843-
mergeRoleMap(srcStructTree, destStructTree);
840+
mergeRoleMap(srcStructTree, destStructTree, cloner);
844841
mergeIDTree(cloner, srcStructTree, destStructTree);
845842
mergeMarkInfo(destCatalog, srcCatalog);
846843
mergeLanguage(destCatalog, srcCatalog);
847-
mergeViewerPreferences(destCatalog, srcCatalog);
844+
mergeViewerPreferences(destCatalog, srcCatalog, cloner);
848845
}
849846
}
850847

@@ -893,7 +890,8 @@ else if (clonedOpenActionBase instanceof COSArray)
893890
}
894891
}
895892

896-
private void mergeViewerPreferences(PDDocumentCatalog destCatalog, PDDocumentCatalog srcCatalog)
893+
private void mergeViewerPreferences(PDDocumentCatalog destCatalog, PDDocumentCatalog srcCatalog,
894+
PDFCloneUtility cloner) throws IOException
897895
{
898896
PDViewerPreferences srcViewerPreferences = srcCatalog.getViewerPreferences();
899897
if (srcViewerPreferences == null)
@@ -906,7 +904,7 @@ private void mergeViewerPreferences(PDDocumentCatalog destCatalog, PDDocumentCat
906904
destViewerPreferences = new PDViewerPreferences();
907905
destCatalog.setViewerPreferences(destViewerPreferences);
908906
}
909-
mergeInto(srcViewerPreferences.getCOSObject(), destViewerPreferences.getCOSObject(),
907+
mergeInto(srcViewerPreferences.getCOSObject(), destViewerPreferences.getCOSObject(), cloner,
910908
Collections.emptySet());
911909

912910
// check the booleans - set to true if one is set and true
@@ -1106,7 +1104,7 @@ private void mergeIDTree(PDFCloneUtility cloner,
11061104
{
11071105
if (destNames.containsKey(entry.getKey()))
11081106
{
1109-
LOG.warn("key {} already exists in destination IDTree", entry.getKey());
1107+
LOG.warn("key '{}' already exists in destination IDTree", entry.getKey());
11101108
}
11111109
else
11121110
{
@@ -1183,7 +1181,8 @@ static Map<Integer, COSObjectable> getNumberTreeAsMap(PDNumberTreeNode tree)
11831181
return numbers;
11841182
}
11851183

1186-
private void mergeRoleMap(PDStructureTreeRoot srcStructTree, PDStructureTreeRoot destStructTree)
1184+
private void mergeRoleMap(PDStructureTreeRoot srcStructTree, PDStructureTreeRoot destStructTree,
1185+
PDFCloneUtility cloner) throws IOException
11871186
{
11881187
COSDictionary srcDict = srcStructTree.getCOSObject().getCOSDictionary(COSName.ROLE_MAP);
11891188
if (srcDict == null)
@@ -1193,7 +1192,7 @@ private void mergeRoleMap(PDStructureTreeRoot srcStructTree, PDStructureTreeRoot
11931192
COSDictionary destDict = destStructTree.getCOSObject().getCOSDictionary(COSName.ROLE_MAP);
11941193
if (destDict == null)
11951194
{
1196-
destStructTree.getCOSObject().setItem(COSName.ROLE_MAP, srcDict); // clone not needed
1195+
destStructTree.getCOSObject().setItem(COSName.ROLE_MAP, cloner.cloneForNewDocument(srcDict));
11971196
return;
11981197
}
11991198
for (Map.Entry<COSName, COSBase> entry : srcDict.entrySet())
@@ -1206,11 +1205,11 @@ private void mergeRoleMap(PDStructureTreeRoot srcStructTree, PDStructureTreeRoot
12061205
}
12071206
if (destDict.containsKey(entry.getKey()))
12081207
{
1209-
LOG.warn("key {} already exists in destination RoleMap", entry.getKey());
1208+
LOG.warn("key '{}' already exists in destination RoleMap", entry.getKey().getName());
12101209
}
12111210
else
12121211
{
1213-
destDict.setItem(entry.getKey(), entry.getValue());
1212+
destDict.setItem(entry.getKey(), cloner.cloneForNewDocument(entry.getValue()));
12141213
}
12151214
}
12161215
}
@@ -1332,11 +1331,9 @@ private void acroFormLegacyMode(PDFCloneUtility cloner, PDAcroForm destAcroForm,
13321331
}
13331332
}
13341333

1335-
13361334
// copy outputIntents to destination, but avoid duplicate OutputConditionIdentifier,
13371335
// except when it is missing or is named "Custom".
1338-
private void mergeOutputIntents(PDFCloneUtility cloner,
1339-
PDDocumentCatalog srcCatalog, PDDocumentCatalog destCatalog) throws IOException
1336+
private void mergeOutputIntents(PDDocumentCatalog srcCatalog, PDDocumentCatalog destCatalog, PDFCloneUtility cloner) throws IOException
13401337
{
13411338
List<PDOutputIntent> srcOutputIntents = srcCatalog.getOutputIntents();
13421339
List<PDOutputIntent> dstOutputIntents = destCatalog.getOutputIntents();
@@ -1541,13 +1538,13 @@ private boolean isDynamicXfa(PDAcroForm acroForm)
15411538
* @param dst The destination dictionary to merge the keys/values into.
15421539
* @param exclude Names of keys that shall be skipped.
15431540
*/
1544-
private void mergeInto(COSDictionary src, COSDictionary dst, Set<COSName> exclude)
1541+
private void mergeInto(COSDictionary src, COSDictionary dst, PDFCloneUtility cloner, Set<COSName> exclude) throws IOException
15451542
{
15461543
for (Map.Entry<COSName, COSBase> entry : src.entrySet())
15471544
{
15481545
if (!exclude.contains(entry.getKey()) && !dst.containsKey(entry.getKey()))
15491546
{
1550-
dst.setItem(entry.getKey(), entry.getValue());
1547+
dst.setItem(entry.getKey(), cloner.cloneForNewDocument(entry.getValue()));
15511548
}
15521549
}
15531550
}

0 commit comments

Comments
 (0)