private void parseEntry(ArchiveInputStream archive, ArchiveEntry entry,
                            EmbeddedDocumentExtractor extractor, Metadata parentMetadata,
                            XHTMLContentHandler xhtml)
            throws SAXException, IOException, TikaException {
        String name = entry.getName();
        
        //Try to detect charset of archive entry in case of non-unicode filename is used
        if (detectCharsetsInEntryNames && entry instanceof ZipArchiveEntry) {
            // Extend short entry name to improve accuracy of charset detection
            byte[] entryName = ((ZipArchiveEntry) entry).getRawName();
            byte[] extendedEntryName = entryName;
            if (0 < entryName.length && entryName.length < MIN_BYTES_FOR_DETECTING_CHARSET) {
                int len = entryName.length * (MIN_BYTES_FOR_DETECTING_CHARSET / entryName.length);
                extendedEntryName = new byte[len];
                for (int i = 0; i < len; i++) {
                    extendedEntryName[i] = entryName[i % entryName.length];
                }
            }

            Charset candidate =
                    getEncodingDetector().detect(
                            UnsynchronizedByteArrayInputStream.builder().setByteArray(extendedEntryName).get(),
                            parentMetadata);
            if (candidate != null) {
                name = new String(((ZipArchiveEntry) entry).getRawName(), candidate);
            }
        }
        
        if (archive.canReadEntryData(entry)) {
            // Fetch the metadata on the entry contained in the archive
            Metadata entrydata =
                    handleEntryMetadata(name, null, entry.getLastModifiedDate(), entry.getSize(),
                            xhtml);

            // Recurse into the entry if desired
            if (extractor.shouldParseEmbedded(entrydata)) {
                // For detectors to work, we need a mark/reset supporting
                // InputStream, which ArchiveInputStream isn't, so wrap
                TemporaryResources tmp = new TemporaryResources();
                try {
                    TikaInputStream tis = TikaInputStream.get(archive, tmp, entrydata);
                    extractor.parseEmbedded(tis, xhtml, entrydata, true);
                } finally {
                    tmp.dispose();
                }
            }
        } else {
            name = (name == null) ? "" : name;
            if (entry instanceof ZipArchiveEntry) {
                ZipArchiveEntry zipArchiveEntry = (ZipArchiveEntry) entry;
                boolean usesEncryption = zipArchiveEntry.getGeneralPurposeBit().usesEncryption();
                if (usesEncryption) {
                    EmbeddedDocumentUtil.recordEmbeddedStreamException(
                            new EncryptedDocumentException("stream (" + name + ") is encrypted"),
                            parentMetadata);
                }

                // do not write to the handler if
                // UnsupportedZipFeatureException.Feature.DATA_DESCRIPTOR
                // is met, we will catch this exception and read the zip archive once again
                boolean usesDataDescriptor =
                        zipArchiveEntry.getGeneralPurposeBit().usesDataDescriptor();
                if (usesDataDescriptor && zipArchiveEntry.getMethod() == ZipEntry.STORED) {
                    throw new UnsupportedZipFeatureException(
                            UnsupportedZipFeatureException.Feature.DATA_DESCRIPTOR,
                            zipArchiveEntry);
                }
            } else {
                EmbeddedDocumentUtil.recordEmbeddedStreamException(
                        new TikaException("Can't read archive stream (" + name + ")"),
                        parentMetadata);
            }
            if (name.length() > 0) {
                xhtml.element("p", name);
            }
        }
    }
Parse the entries of the zip archive

@param ais                     archive input stream
@param metadata                document metadata (input and output)
@param extractor               the delegate parser
@param xhtml                   the xhtml handler
@param shouldUseDataDescriptor indicates if a data descriptor is required or not
@param entryCnt                index of the entry
@throws TikaException if the document could not be parsed
@throws IOException   if a UnsupportedZipFeatureException is met
@throws SAXException  if the SAX events could not be processed
tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/PackageParser.java