Class NestedJarHandler


  • public class NestedJarHandler
    extends java.lang.Object
    Open and read jarfiles, which may be nested within other jarfiles.
    • Field Detail

      • canonicalFileToPhysicalZipFileMap

        private SingletonMap<java.io.File,​PhysicalZipFile,​java.io.IOException> canonicalFileToPhysicalZipFileMap
        A singleton map from a zipfile's File to the PhysicalZipFile for that file, used to ensure that the RandomAccessFile and FileChannel for any given zipfile is opened only once.
      • fastZipEntryToZipFileSliceMap

        private SingletonMap<FastZipEntry,​ZipFileSlice,​java.io.IOException> fastZipEntryToZipFileSliceMap
        A singleton map from a FastZipEntry to the ZipFileSlice wrapping either the zip entry data, if the entry is stored, or a ByteBuffer, if the zip entry was inflated to memory, or a physical file on disk if the zip entry was inflated to a temporary file.
      • nestedPathToLogicalZipFileAndPackageRootMap

        public SingletonMap<java.lang.String,​java.util.Map.Entry<LogicalZipFile,​java.lang.String>,​java.io.IOException> nestedPathToLogicalZipFileAndPackageRootMap
        A singleton map from nested jarfile path to a tuple of the logical zipfile for the path, and the package root within the logical zipfile.
      • openSlices

        private java.util.Set<Slice> openSlices
        FileSlice instances that are currently open.
      • tempFiles

        private java.util.Set<java.io.File> tempFiles
        Any temporary files created while scanning.
      • TEMP_FILENAME_LEAF_SEPARATOR

        public static final java.lang.String TEMP_FILENAME_LEAF_SEPARATOR
        The separator between random temp filename part and leafname.
        See Also:
        Constant Field Values
      • closed

        private final java.util.concurrent.atomic.AtomicBoolean closed
        True if close(LogNode) has been called.
      • interruptionChecker

        public InterruptionChecker interruptionChecker
        The interruption checker.
      • DEFAULT_BUFFER_SIZE

        private static final int DEFAULT_BUFFER_SIZE
        The default size of a file buffer.
        See Also:
        Constant Field Values
      • MAX_INITIAL_BUFFER_SIZE

        private static final int MAX_INITIAL_BUFFER_SIZE
        The maximum initial buffer size.
        See Also:
        Constant Field Values
      • HTTP_TIMEOUT

        private static final int HTTP_TIMEOUT
        HTTP(S) timeout, ms.
        See Also:
        Constant Field Values
      • runFinalizationMethod

        private static java.lang.reflect.Method runFinalizationMethod
        System.runFinalization() -- deprecated in JDK 18, so accessed by reflection.
    • Constructor Detail

      • NestedJarHandler

        public NestedJarHandler​(ScanSpec scanSpec,
                                InterruptionChecker interruptionChecker,
                                ReflectionUtils reflectionUtils)
        A handler for nested jars.
        Parameters:
        scanSpec - The ScanSpec.
        interruptionChecker - the interruption checker
    • Method Detail

      • leafname

        private static java.lang.String leafname​(java.lang.String path)
        Get the leafname of a path.
        Parameters:
        path - the path
        Returns:
        the string
      • sanitizeFilename

        private java.lang.String sanitizeFilename​(java.lang.String filename)
        Sanitize filename.
        Parameters:
        filename - the filename
        Returns:
        the sanitized filename
      • makeTempFile

        public java.io.File makeTempFile​(java.lang.String filePathBase,
                                         boolean onlyUseLeafname)
                                  throws java.io.IOException
        Create a temporary file, and mark it for deletion on exit.
        Parameters:
        filePathBase - The path to derive the temporary filename from.
        onlyUseLeafname - If true, only use the leafname of filePath to derive the temporary filename.
        Returns:
        The temporary File.
        Throws:
        java.io.IOException - If the temporary file could not be created.
      • removeTempFile

        void removeTempFile​(java.io.File tempFile)
                     throws java.io.IOException,
                            java.lang.SecurityException
        Attempt to remove a temporary file.
        Parameters:
        tempFile - the temp file
        Throws:
        java.io.IOException - If the temporary file could not be removed.
        java.lang.SecurityException - If the temporary file is inaccessible.
      • markSliceAsOpen

        public void markSliceAsOpen​(Slice slice)
                             throws java.io.IOException
        Mark a Slice as open, so it can be closed when the ScanResult is closed.
        Parameters:
        slice - the Slice that was just opened.
        Throws:
        java.io.IOException - Signals that an I/O exception has occurred.
      • markSliceAsClosed

        public void markSliceAsClosed​(Slice slice)
        Mark a Slice as closed.
        Parameters:
        slice - the Slice to close.
      • downloadJarFromURL

        private PhysicalZipFile downloadJarFromURL​(java.lang.String jarURL,
                                                   LogNode log)
                                            throws java.io.IOException,
                                                   java.lang.InterruptedException
        Download a jar from a URL to a temporary file, or to a ByteBuffer if the temporary directory is not writeable or full. The downloaded jar is returned wrapped in a PhysicalZipFile instance.
        Parameters:
        jarURL - the jar URL
        log - the log
        Returns:
        the temporary file or ByteBuffer the jar was downloaded to, wrapped in a PhysicalZipFile instance.
        Throws:
        java.io.IOException - If the jar could not be downloaded, or the jar URL is malformed.
        java.lang.InterruptedException - if the thread was interrupted
        java.lang.IllegalArgumentException - If the temp dir is not writeable, or has insufficient space to download the jar. (This is thrown as a separate exception from IOException, so that the case of an unwriteable temp dir can be handled separately, by downloading the jar to a ByteBuffer in RAM.)
      • openInflaterInputStream

        public java.io.InputStream openInflaterInputStream​(java.io.InputStream rawInputStream)
                                                    throws java.io.IOException
        Wrap an InputStream with an InflaterInputStream, recycling the Inflater instance.
        Parameters:
        rawInputStream - the raw input stream
        Returns:
        the inflater input stream
        Throws:
        java.io.IOException - Signals that an I/O exception has occurred.
      • readAllBytesWithSpilloverToDisk

        public Slice readAllBytesWithSpilloverToDisk​(java.io.InputStream inputStream,
                                                     java.lang.String tempFileBaseName,
                                                     long inputStreamLengthHint,
                                                     LogNode log)
                                              throws java.io.IOException
        Read all the bytes in an InputStream, with spillover to a temporary file on disk if a maximum buffer size is exceeded.
        Parameters:
        inputStream - the InputStream to read from.
        tempFileBaseName - the source URL or zip entry that inputStream was opened from (used to name temporary file, if needed).
        inputStreamLengthHint - the length of inputStream if known, else -1L.
        log - the log.
        Returns:
        if the InputStream could be read into a byte array, an ArraySlice will be returned. If this fails and the InputStream is spilled over to disk, a FileSlice will be returned.
        Throws:
        java.io.IOException - If the contents could not be read.
      • spillToDisk

        private FileSlice spillToDisk​(java.io.InputStream inputStream,
                                      java.lang.String tempFileBaseName,
                                      byte[] buf,
                                      byte[] overflowBuf,
                                      LogNode log)
                               throws java.io.IOException
        Spill an InputStream to disk if the stream is too large to fit in RAM.
        Parameters:
        inputStream - The InputStream.
        tempFileBaseName - The stem to base the temporary filename on.
        buf - The first buffer to write to the beginning of the file, or null if none.
        overflowBuf - The second buffer to write to the beginning of the file, or null if none. (Should have same nullity as buf.)
        log - The log.
        Returns:
        the file slice
        Throws:
        java.io.IOException - If anything went wrong creating or writing to the temp file.
      • readAllBytesAsArray

        public static byte[] readAllBytesAsArray​(java.io.InputStream inputStream,
                                                 long uncompressedLengthHint)
                                          throws java.io.IOException
        Read all the bytes in an InputStream.
        Parameters:
        inputStream - The InputStream.
        uncompressedLengthHint - The length of the data once inflated from the InputStream, if known, otherwise -1L.
        Returns:
        The contents of the InputStream as a byte array.
        Throws:
        java.io.IOException - If the contents could not be read.
      • close

        public void close​(LogNode log)
        Close zipfiles, modules, and recyclers, and delete temporary files. Called by ScanResult.close().
        Parameters:
        log - The log.
      • runFinalizationMethod

        public void runFinalizationMethod()
      • closeDirectByteBuffer

        public void closeDirectByteBuffer​(java.nio.ByteBuffer backingByteBuffer)