private COSBase createDictionaryClone()

in pdfbox/src/main/java/org/apache/pdfbox/multipdf/Splitter.java [403:498]


        private COSBase createDictionaryClone(COSBase src, COSBase dstParent, COSDictionary currentPageDict)
        {
            COSDictionary srcDict = (COSDictionary) src;
            COSDictionary dstDict = structDictMap.get(srcDict);
            if (dstDict != null)
            {
                return dstDict;
            }
            COSDictionary dstPageDict = null;
            if (srcDict.containsKey(COSName.PG))
            {
                COSDictionary srcPageDict = srcDict.getCOSDictionary(COSName.PG);
                if (srcPageDict == null)
                {
                    return null;
                }
                dstPageDict = pageDictMap.get(srcPageDict);
                if (dstPageDict == null)
                {
                    return null;
                }
                PDPage dstPage = new PDPage(dstPageDict);
                if (dstPageTree.indexOf(dstPage) == -1)
                {
                    return null;
                }
            }

            // Create and fill clone
            dstDict = new COSDictionary();
            structDictMap.put(srcDict, dstDict);
            for (Map.Entry<COSName,COSBase> entry : srcDict.entrySet())
            {
                COSName key = entry.getKey();
                if (!COSName.K.equals(key) &&
                    !COSName.PG.equals(key) &&
                    !COSName.P.equals(key))
                {
                    dstDict.setItem(key, entry.getValue());
                }
            }

            // special handling for OBJR items ("object reference dictionary")
            // see e.g. file 488300.pdf and Root/StructTreeRoot/K/K/[2]/K/[1]/K/[0]/Obj
            COSName type = srcDict.getCOSName(COSName.TYPE);
            if (COSName.OBJR.equals(type))
            {
                COSDictionary srcObj = srcDict.getCOSDictionary(COSName.OBJ);
                COSDictionary dstObj = annotDictMap.get(srcObj);
                if (dstObj != null)
                {
                    // replace annotation with clone
                    dstDict.setItem(COSName.OBJ, dstObj);
                }
                else
                {
                    removePossibleOrphanAnnotation(srcObj, srcDict, currentPageDict, dstDict);
                }
            }
            else
            {
                // /P not needed for OBJR items
                dstDict.setItem(COSName.P, dstParent);
            }

            dstDict.setItem(COSName.PG, dstPageDict);
            COSBase kid = srcDict.getDictionaryObject(COSName.K);
            
            // stack overflow here with 207658.pdf, too complex
            COSBase cloneKid = createClone(kid, dstDict, dstPageDict != null ? dstPageDict : currentPageDict);
            if (cloneKid == null && kid != null)
            {
                return null; // kids array wasn't empty, but is empty now => ignore
            }
            
            // removes orphan nodes, example:
            // Root/StructTreeRoot/K/[7]/K/[3]/K/[5]/K/[2] in 271459.pdf
            // decide about keeping source dictionaries with no /K and no /PG
            if (dstPageDict == null && cloneKid == null && currentPageDict == null)
            {
                // if no parent page and no page here and no kids, assume this is an orphan
                return null;
            }
            dstDict.setItem(COSName.K, cloneKid);
            String id = dstDict.getString(COSName.ID);
            if (id != null)
            {
                idSet.add(id);
            }
            COSName s = dstDict.getCOSName(COSName.S);
            if (s != null)
            {
                roleSet.add(s);
            }
            return dstDict;
        }