"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "pdfbox/src/main/java/org/apache/pdfbox/multipdf/PDFMergerUtility.java" between
pdfbox-2.0.23-src.zip and pdfbox-2.0.24-src.zip

About: Apache PDFBox is a Java PDF library tool that allows creation of new PDF documents, manipulation of existing documents and the ability to extract content from documents.

PDFMergerUtility.java  (pdfbox-2.0.23-src):PDFMergerUtility.java  (pdfbox-2.0.24-src)
skipping to change at line 428 skipping to change at line 428
* file. * file.
* *
* @param memUsageSetting defines how memory is used for buffering PDF strea ms; * @param memUsageSetting defines how memory is used for buffering PDF strea ms;
* in case of <code>null</code> unrestricted main mem ory is used * in case of <code>null</code> unrestricted main mem ory is used
* *
* @throws IOException If there is an error saving the document. * @throws IOException If there is an error saving the document.
*/ */
private void legacyMergeDocuments(MemoryUsageSetting memUsageSetting) throws IOException private void legacyMergeDocuments(MemoryUsageSetting memUsageSetting) throws IOException
{ {
PDDocument destination = null; PDDocument destination = null;
if (sources != null && sources.size() > 0) if (sources.size() > 0)
{ {
// Make sure that: // Make sure that:
// - first Exception is kept // - first Exception is kept
// - destination is closed // - destination is closed
// - all PDDocuments are closed // - all PDDocuments are closed
// - all FileInputStreams are closed // - all FileInputStreams are closed
// - there's a way to see which errors occurred // - there's a way to see which errors occurred
List<PDDocument> tobeclosed = new ArrayList<PDDocument>(sources.size ()); List<PDDocument> tobeclosed = new ArrayList<PDDocument>(sources.size ());
skipping to change at line 610 skipping to change at line 610
} }
} }
if (destNames != null && destNames.getCOSObject().containsKey(COSName.ID _TREE)) if (destNames != null && destNames.getCOSObject().containsKey(COSName.ID _TREE))
{ {
// found in 001031.pdf from PDFBOX-4417 and doesn't belong there // found in 001031.pdf from PDFBOX-4417 and doesn't belong there
destNames.getCOSObject().removeItem(COSName.ID_TREE); destNames.getCOSObject().removeItem(COSName.ID_TREE);
LOG.warn("Removed /IDTree from /Names dictionary, doesn't belong the re"); LOG.warn("Removed /IDTree from /Names dictionary, doesn't belong the re");
} }
PDDocumentNameDestinationDictionary destDests = destCatalog.getDests();
PDDocumentNameDestinationDictionary srcDests = srcCatalog.getDests(); PDDocumentNameDestinationDictionary srcDests = srcCatalog.getDests();
if (srcDests != null) if (srcDests != null)
{ {
PDDocumentNameDestinationDictionary destDests = destCatalog.getDests ();
if (destDests == null) if (destDests == null)
{ {
destCatalog.getCOSObject().setItem(COSName.DESTS, cloner.cloneFo rNewDocument(srcDests)); destCatalog.getCOSObject().setItem(COSName.DESTS, cloner.cloneFo rNewDocument(srcDests));
} }
else else
{ {
cloner.cloneMerge(srcDests, destDests); cloner.cloneMerge(srcDests, destDests);
} }
} }
PDDocumentOutline destOutline = destCatalog.getDocumentOutline();
PDDocumentOutline srcOutline = srcCatalog.getDocumentOutline(); PDDocumentOutline srcOutline = srcCatalog.getDocumentOutline();
if (srcOutline != null) if (srcOutline != null)
{ {
PDDocumentOutline destOutline = destCatalog.getDocumentOutline();
if (destOutline == null || destOutline.getFirstChild() == null) if (destOutline == null || destOutline.getFirstChild() == null)
{ {
PDDocumentOutline cloned = new PDDocumentOutline((COSDictionary) cloner.cloneForNewDocument(srcOutline)); PDDocumentOutline cloned = new PDDocumentOutline((COSDictionary) cloner.cloneForNewDocument(srcOutline));
destCatalog.setDocumentOutline(cloned); destCatalog.setDocumentOutline(cloned);
} }
else else
{ {
// search last sibling for dest, because /Last entry is sometime s wrong // search last sibling for dest, because /Last entry is sometime s wrong
PDOutlineItem destLastOutlineItem = destOutline.getFirstChild(); PDOutlineItem destLastOutlineItem = destOutline.getFirstChild();
while (destLastOutlineItem.getNextSibling() != null) while (destLastOutlineItem.getNextSibling() != null)
skipping to change at line 656 skipping to change at line 656
clonedDict.removeItem(COSName.PREV); clonedDict.removeItem(COSName.PREV);
clonedDict.removeItem(COSName.NEXT); clonedDict.removeItem(COSName.NEXT);
PDOutlineItem clonedItem = new PDOutlineItem(clonedDict); PDOutlineItem clonedItem = new PDOutlineItem(clonedDict);
destLastOutlineItem.insertSiblingAfter(clonedItem); destLastOutlineItem.insertSiblingAfter(clonedItem);
destLastOutlineItem = destLastOutlineItem.getNextSibling(); destLastOutlineItem = destLastOutlineItem.getNextSibling();
} }
} }
} }
PageMode destPageMode = destCatalog.getPageMode(); PageMode destPageMode = destCatalog.getPageMode();
PageMode srcPageMode = srcCatalog.getPageMode();
if (destPageMode == null) if (destPageMode == null)
{ {
PageMode srcPageMode = srcCatalog.getPageMode();
destCatalog.setPageMode(srcPageMode); destCatalog.setPageMode(srcPageMode);
} }
COSDictionary destLabels = destCatalog.getCOSObject().getCOSDictionary(C OSName.PAGE_LABELS); COSDictionary destLabels = destCatalog.getCOSObject().getCOSDictionary(C OSName.PAGE_LABELS);
COSDictionary srcLabels = srcCatalog.getCOSObject().getCOSDictionary(COS Name.PAGE_LABELS); COSDictionary srcLabels = srcCatalog.getCOSObject().getCOSDictionary(COS Name.PAGE_LABELS);
if (srcLabels != null) if (srcLabels != null)
{ {
int destPageCount = destination.getNumberOfPages(); int destPageCount = destination.getNumberOfPages();
COSArray destNums; COSArray destNums;
if (destLabels == null) if (destLabels == null)
skipping to change at line 929 skipping to change at line 929
destViewerPreferences.setCenterWindow(true); destViewerPreferences.setCenterWindow(true);
} }
if (srcViewerPreferences.displayDocTitle() || destViewerPreferences.disp layDocTitle()) if (srcViewerPreferences.displayDocTitle() || destViewerPreferences.disp layDocTitle())
{ {
destViewerPreferences.setDisplayDocTitle(true); destViewerPreferences.setDisplayDocTitle(true);
} }
} }
private void mergeLanguage(PDDocumentCatalog destCatalog, PDDocumentCatalog srcCatalog) private void mergeLanguage(PDDocumentCatalog destCatalog, PDDocumentCatalog srcCatalog)
{ {
if (destCatalog.getLanguage() == null && srcCatalog.getLanguage() != nul l) if (destCatalog.getLanguage() == null)
{ {
destCatalog.setLanguage(srcCatalog.getLanguage()); String srcLanguage = srcCatalog.getLanguage();
if (srcLanguage != null)
{
destCatalog.setLanguage(srcLanguage);
}
} }
} }
private void mergeMarkInfo(PDDocumentCatalog destCatalog, PDDocumentCatalog srcCatalog) private void mergeMarkInfo(PDDocumentCatalog destCatalog, PDDocumentCatalog srcCatalog)
{ {
PDMarkInfo destMark = destCatalog.getMarkInfo(); PDMarkInfo destMark = destCatalog.getMarkInfo();
PDMarkInfo srcMark = srcCatalog.getMarkInfo(); PDMarkInfo srcMark = srcCatalog.getMarkInfo();
if (destMark == null) if (destMark == null)
{ {
destMark = new PDMarkInfo(); destMark = new PDMarkInfo();
skipping to change at line 957 skipping to change at line 961
destMark.setMarked(true); destMark.setMarked(true);
destMark.setSuspect(srcMark.isSuspect() || destMark.isSuspect()); destMark.setSuspect(srcMark.isSuspect() || destMark.isSuspect());
destMark.setSuspect(srcMark.usesUserProperties() || destMark.usesUserPro perties()); destMark.setSuspect(srcMark.usesUserProperties() || destMark.usesUserPro perties());
destCatalog.setMarkInfo(destMark); destCatalog.setMarkInfo(destMark);
} }
private void mergeKEntries(PDFCloneUtility cloner, private void mergeKEntries(PDFCloneUtility cloner,
PDStructureTreeRoot srcStructTree, PDStructureTreeRoot srcStructTree,
PDStructureTreeRoot destStructTree) throws IOException PDStructureTreeRoot destStructTree) throws IOException
{ {
// make new /K with array that has the input /K entries COSArray dstKArray = new COSArray();
COSArray newKArray = new COSArray();
if (destStructTree.getK() != null) if (destStructTree.getK() != null)
{ {
COSBase base = destStructTree.getK(); COSBase base = destStructTree.getK();
if (base instanceof COSArray) if (base instanceof COSArray)
{ {
newKArray.addAll((COSArray) base); dstKArray.addAll((COSArray) base);
} }
else else if (base instanceof COSDictionary)
{ {
newKArray.add(base); dstKArray.add(base);
} }
} }
COSArray srcKArray = new COSArray();
if (srcStructTree.getK() != null) if (srcStructTree.getK() != null)
{ {
COSBase base = cloner.cloneForNewDocument(srcStructTree.getK()); COSBase base = cloner.cloneForNewDocument(srcStructTree.getK());
if (base instanceof COSArray) if (base instanceof COSArray)
{ {
newKArray.addAll((COSArray) base); srcKArray.addAll((COSArray) base);
} }
else else if (base instanceof COSDictionary)
{
srcKArray.add(base);
}
}
if (srcKArray.size() == 0)
{
return;
}
if (dstKArray.size() == 1 && dstKArray.getObject(0) instanceof COSDictio
nary)
{
// Only one element in the destination. If it is a /Document and its
children
// are /Document or /Part, then we can insert there
COSDictionary topKDict = (COSDictionary) dstKArray.getObject(0);
if (COSName.DOCUMENT.equals(topKDict.getCOSName(COSName.S)))
{ {
newKArray.add(base); COSArray kLevelOneArray = topKDict.getCOSArray(COSName.K);
if (kLevelOneArray != null)
{
boolean onlyDocuments = hasOnlyDocumentsOrParts(kLevelOneArr
ay);
if (onlyDocuments)
{
// insert src elements at level 1
kLevelOneArray.addAll(srcKArray);
updateParentEntry(kLevelOneArray, topKDict, COSName.PART
);
return;
}
}
} }
} }
if (newKArray.size() > 0)
if (dstKArray.size() == 0)
{
updateParentEntry(srcKArray, destStructTree.getCOSObject(), null);
destStructTree.setK(srcKArray);
return;
}
// whatever this is, merge this under a new /Document element
dstKArray.addAll(srcKArray);
COSDictionary kLevelZeroDict = new COSDictionary();
// If it is all Document, then make it all Part
COSName newStructureType = hasOnlyDocumentsOrParts(dstKArray) ? COSName.
PART : null;
updateParentEntry(dstKArray, kLevelZeroDict, newStructureType);
kLevelZeroDict.setItem(COSName.K, dstKArray);
kLevelZeroDict.setItem(COSName.P, destStructTree);
kLevelZeroDict.setItem(COSName.S, COSName.DOCUMENT);
destStructTree.setK(kLevelZeroDict);
}
private boolean hasOnlyDocumentsOrParts(COSArray kLevelOneArray)
{
for (int i = 0; i < kLevelOneArray.size(); ++i)
{
COSBase base = kLevelOneArray.getObject(i);
if (!(base instanceof COSDictionary))
{
return false;
}
COSDictionary dict = (COSDictionary) base;
if (!COSName.DOCUMENT.equals(dict.getCOSName(COSName.S)) &&
!COSName.PART.equals(dict.getCOSName(COSName.S)))
{
return false;
}
}
return true;
}
/**
* Update the P reference to the new parent dictionary.
*
* @param kArray the kids array
* @param newParent the new parent
* @param newStructureType the new structure type in /S or null so it doesn'
t get replaced
*/
private void updateParentEntry(COSArray kArray, COSDictionary newParent, COS
Name newStructureType)
{
for (int i = 0; i < kArray.size(); i++)
{ {
COSDictionary kDictLevel0 = new COSDictionary(); COSBase subEntry = kArray.getObject(i);
updateParentEntry(newKArray, kDictLevel0); if (subEntry instanceof COSDictionary)
kDictLevel0.setItem(COSName.K, newKArray); {
kDictLevel0.setItem(COSName.P, destStructTree); COSDictionary dictEntry = (COSDictionary) subEntry;
kDictLevel0.setItem(COSName.S, COSName.DOCUMENT); dictEntry.setItem(COSName.P, newParent);
destStructTree.setK(kDictLevel0); if (newStructureType != null)
{
dictEntry.setItem(COSName.S, newStructureType);
}
}
} }
} }
private void mergeIDTree(PDFCloneUtility cloner, private void mergeIDTree(PDFCloneUtility cloner,
PDStructureTreeRoot srcStructTree, PDStructureTreeRoot srcStructTree,
PDStructureTreeRoot destStructTree) throws IOException PDStructureTreeRoot destStructTree) throws IOException
{ {
PDNameTreeNode<PDStructureElement> srcIDTree = srcStructTree.getIDTree() ; PDNameTreeNode<PDStructureElement> srcIDTree = srcStructTree.getIDTree() ;
PDNameTreeNode<PDStructureElement> destIDTree = destStructTree.getIDTree ();
if (srcIDTree == null) if (srcIDTree == null)
{ {
return; return;
} }
PDNameTreeNode<PDStructureElement> destIDTree = destStructTree.getIDTree ();
if (destIDTree == null) if (destIDTree == null)
{ {
destIDTree = new PDStructureElementNameTreeNode(); destIDTree = new PDStructureElementNameTreeNode();
} }
Map<String, PDStructureElement> srcNames = getIDTreeAsMap(srcIDTree); Map<String, PDStructureElement> srcNames = getIDTreeAsMap(srcIDTree);
Map<String, PDStructureElement> destNames = getIDTreeAsMap(destIDTree); Map<String, PDStructureElement> destNames = getIDTreeAsMap(destIDTree);
for (Map.Entry<String, PDStructureElement> entry : srcNames.entrySet()) for (Map.Entry<String, PDStructureElement> entry : srcNames.entrySet())
{ {
if (destNames.containsKey(entry.getKey())) if (destNames.containsKey(entry.getKey()))
{ {
skipping to change at line 1367 skipping to change at line 1451
// fields starting with dummyFieldName may already exist. We need to determine the last unique // fields starting with dummyFieldName may already exist. We need to determine the last unique
// number used and increment that. // number used and increment that.
final String prefix = "dummyFieldName"; final String prefix = "dummyFieldName";
final int prefixLength = prefix.length(); final int prefixLength = prefix.length();
for (PDField destField : destAcroForm.getFieldTree()) for (PDField destField : destAcroForm.getFieldTree())
{ {
String fieldName = destField.getPartialName(); String fieldName = destField.getPartialName();
if (fieldName.startsWith(prefix)) if (fieldName.startsWith(prefix))
{ {
nextFieldNum = Math.max(nextFieldNum, Integer.parseInt(field Name.substring(prefixLength, fieldName.length())) + 1); nextFieldNum = Math.max(nextFieldNum, Integer.parseInt(field Name.substring(prefixLength)) + 1);
} }
} }
// get the destinations root fields. Could be that the entry doesn't exist // get the destinations root fields. Could be that the entry doesn't exist
// or is of wrong type // or is of wrong type
COSBase base = destAcroForm.getCOSObject().getItem(COSName.FIELDS); COSBase base = destAcroForm.getCOSObject().getItem(COSName.FIELDS);
if (base instanceof COSArray) if (base instanceof COSArray)
{ {
destFields = (COSArray) base; destFields = (COSArray) base;
} }
skipping to change at line 1523 skipping to change at line 1607
updatePageReferences(cloner, (COSArray) subEntry, objMapping); updatePageReferences(cloner, (COSArray) subEntry, objMapping);
} }
else if (subEntry instanceof COSDictionary) else if (subEntry instanceof COSDictionary)
{ {
updatePageReferences(cloner, (COSDictionary) subEntry, objMappin g); updatePageReferences(cloner, (COSDictionary) subEntry, objMappin g);
} }
} }
} }
/** /**
* Update the P reference to the new parent dictionary.
*
* @param kArray the kids array
* @param newParent the new parent
*/
private void updateParentEntry(COSArray kArray, COSDictionary newParent)
{
for (int i = 0; i < kArray.size(); i++)
{
COSBase subEntry = kArray.getObject(i);
if (subEntry instanceof COSDictionary)
{
COSDictionary dictEntry = (COSDictionary) subEntry;
if (dictEntry.getDictionaryObject(COSName.P) != null)
{
dictEntry.setItem(COSName.P, newParent);
}
}
}
}
/**
* Update the StructParents and StructParent values in a PDPage. * Update the StructParents and StructParent values in a PDPage.
* *
* @param page the new page * @param page the new page
* @param structParentOffset the offset which should be applied * @param structParentOffset the offset which should be applied
*/ */
private void updateStructParentEntries(PDPage page, int structParentOffset) throws IOException private void updateStructParentEntries(PDPage page, int structParentOffset) throws IOException
{ {
if (page.getStructParents() >= 0) if (page.getStructParents() >= 0)
{ {
page.setStructParents(page.getStructParents() + structParentOffset); page.setStructParents(page.getStructParents() + structParentOffset);
 End of changes. 23 change blocks. 
45 lines changed or deleted 114 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)