private void extractPDEmbeddedFile(String displayName, String annotationType,
                                       PDComplexFileSpecification spec, String fileName,
                                       PDEmbeddedFile pdEmbeddedFile, AttributesImpl attributes)
            throws SAXException, IOException {

        if (pdEmbeddedFile == null) {
            //skip silently
            return;
        }

        fileName =
                (fileName == null || "".equals(fileName.trim())) ? spec.getFileUnicode() : fileName;
        fileName = (fileName == null || "".equals(fileName.trim())) ? displayName : fileName;

        // TODO: other metadata?
        Metadata embeddedMetadata = new Metadata();
        embeddedMetadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, fileName);
        //if the stream is missing a size, -1 is returned
        long sz = pdEmbeddedFile.getSize();
        if (sz > -1) {
            embeddedMetadata.set(Metadata.CONTENT_LENGTH, Long.toString(sz));
        }
        embeddedMetadata.set(TikaCoreProperties.EMBEDDED_RESOURCE_TYPE,
                TikaCoreProperties.EmbeddedResourceType.ATTACHMENT.toString());
        embeddedMetadata.set(TikaCoreProperties.ORIGINAL_RESOURCE_NAME, fileName);
        if (!StringUtils.isBlank(annotationType)) {
            embeddedMetadata.set(PDF.EMBEDDED_FILE_ANNOTATION_TYPE, annotationType);
        }
        if (!StringUtils.isBlank(pdEmbeddedFile.getSubtype())) {
            embeddedMetadata.set(PDF.EMBEDDED_FILE_SUBTYPE, pdEmbeddedFile.getSubtype());
        }
        if (!StringUtils.isBlank(spec.getFileDescription())) {
            embeddedMetadata.set(PDF.EMBEDDED_FILE_DESCRIPTION, spec.getFileDescription());
        }
        String afRelationship = spec.getCOSObject().getNameAsString(PDFParser.AF_RELATIONSHIP);
        if (StringUtils.isBlank(afRelationship)) {
            afRelationship = spec.getCOSObject().getString(PDFParser.AF_RELATIONSHIP);
        }
        if (!StringUtils.isBlank(afRelationship)) {
            embeddedMetadata.set(PDF.ASSOCIATED_FILE_RELATIONSHIP, afRelationship);
        }
        if (!embeddedDocumentExtractor.shouldParseEmbedded(embeddedMetadata)) {
            return;
        }
        TikaInputStream stream = null;
        try {
            stream = TikaInputStream.get(pdEmbeddedFile.createInputStream());
        } catch (IOException e) {
            //store this exception in the parent's metadata
            EmbeddedDocumentUtil.recordEmbeddedStreamException(e, metadata);
            return;
        }

        attributes.addAttribute("", "class", "class", "CDATA", "embedded");
        attributes.addAttribute("", "id", "id", "CDATA", fileName);
        xhtml.startElement("div", attributes);
        xhtml.endElement("div");

        try {
            embeddedDocumentExtractor.parseEmbedded(stream, new EmbeddedContentHandler(xhtml),
                    embeddedMetadata, false);
        } finally {
            IOUtils.closeQuietly(stream);
        }

    }
Format used for signature dates
TODO Make this thread-safe
tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/AbstractPDF2XHTML.java