Class COSObjectImporter


  • public final class COSObjectImporter
    extends java.lang.Object
    Deep-clones a value (and everything it transitively references) from a source COSDocument into a target one, allocating fresh indirect object numbers. Used both to combine two documents' object-numbering spaces without collision (com.pd4ml.pdf.merge) and to walk/copy only the objects reachable from a single document's own /Root (and /Info), which is what discards unreferenced objects and compacts the numbering (com.pd4ml.pdf.optimizer) -- in both cases the operation is "clone whatever this reference reaches into a fresh document," just seeded differently.

    Object identity/sharing is preserved: the same source object reached via two different paths (e.g. a font shared by two pages, or a StructElem's parent reached from two different children) is cloned exactly once and every reference to it in the target graph points at that single clone. A per-source-document cache, keyed by the source object's COSObjectKey, is what makes this work; cycles are broken by registering a not-yet-populated placeholder in that cache before recursing into the object's own content.

    One instance is meant to be reused across an entire operation (all sources cloned into one target, e.g. every merge source's selected pages, or the whole reachable graph of a single document being optimized), so sharing is preserved consistently across everything imported into the same target document.

    Thread-safety: safe to call from multiple threads concurrently (the cache and the object-number counter are built on ConcurrentHashMap/AtomicLong, and the "clone exactly once" guarantee is preserved -- two threads racing to import the same source key never produce two clones; the loser simply receives the winner's in-progress placeholder). The one caveat: don't resolve() a placeholder returned by one thread's still-in-flight importIndirect(com.pd4ml.pdf.cos.COSDocument, com.pd4ml.pdf.cos.COSObject) call from a different thread before that call has returned -- every current caller in this codebase only resolves a returned reference after the whole import (or batch of imports) it's part of has completed, which is the supported usage.

    • Constructor Detail

      • COSObjectImporter

        public COSObjectImporter​(COSDocument target)
    • Method Detail

      • importValue

        public COSBase importValue​(COSDocument sourceDoc,
                                   COSBase value)
        Imports value (which may be a direct value or an indirect COSObject reference) from sourceDoc, returning the equivalent value already registered in the target document.
      • allocate

        public COSObject allocate​(COSBase value)
        Allocates a brand-new indirect object in the target document for a value that has no source-document counterpart (e.g. a freshly built Catalog, Pages node, or StructTreeRoot). Routes through the same counter as importIndirect(com.pd4ml.pdf.cos.COSDocument, com.pd4ml.pdf.cos.COSObject), the sole numbering authority for the target document, so mixing freshly-built objects with imported ones can never collide.
      • preRegister

        public void preRegister​(COSDocument sourceDoc,
                                COSObjectKey sourceKey,
                                COSObject targetRef)
        Seeds the import cache so any future reference to sourceKey in sourceDoc resolves directly to targetRef instead of being cloned. Used by the merge structure-tree reconciliation to stop a StructElem's /P chain at the source document's StructTreeRoot without pulling that source's entire structure tree (every page, not just the selected ones) in behind it.
      • isImported

        public boolean isImported​(COSDocument sourceDoc,
                                  COSObjectKey sourceKey)
        True if sourceKey in sourceDoc has already been imported into the target document.
      • getImported

        public COSObject getImported​(COSDocument sourceDoc,
                                     COSObjectKey sourceKey)
        The already-imported target-document reference for sourceKey, or null if not imported yet.