protected void extractFile()

in src/main/org/apache/tools/ant/taskdefs/Expand.java [254:376]


    protected void extractFile(FileUtils fileUtils, File srcF, File dir,
                               InputStream compressedInputStream,
                               String entryName, Date entryDate,
                               boolean isDirectory, FileNameMapper mapper)
                               throws IOException {

        final boolean entryNameStartsWithPathSpec = !entryName.isEmpty()
            && (entryName.charAt(0) == File.separatorChar
                || entryName.charAt(0) == '/'
                || entryName.charAt(0) == '\\');
        if (stripAbsolutePathSpec && entryNameStartsWithPathSpec) {
            log("stripped absolute path spec from " + entryName,
                Project.MSG_VERBOSE);
            entryName = entryName.substring(1);
        }
        boolean allowedOutsideOfDest = Boolean.TRUE == getAllowFilesToEscapeDest()
            || null == getAllowFilesToEscapeDest() && !stripAbsolutePathSpec && entryNameStartsWithPathSpec;

        if (patternsets != null && !patternsets.isEmpty()) {
            String name = entryName.replace('/', File.separatorChar)
                .replace('\\', File.separatorChar);

            Set<String> includePatterns = new HashSet<>();
            Set<String> excludePatterns = new HashSet<>();
            for (PatternSet p : patternsets) {
                String[] incls = p.getIncludePatterns(getProject());
                if (incls == null || incls.length == 0) {
                    // no include pattern implicitly means includes="**"
                    incls = new String[]{"**"};
                }

                for (String incl : incls) {
                    String pattern = incl.replace('/', File.separatorChar)
                            .replace('\\', File.separatorChar);
                    if (pattern.endsWith(File.separator)) {
                        pattern += "**";
                    }
                    includePatterns.add(pattern);
                }

                String[] excls = p.getExcludePatterns(getProject());
                if (excls != null) {
                    for (String excl : excls) {
                        String pattern = excl.replace('/', File.separatorChar)
                                .replace('\\', File.separatorChar);
                        if (pattern.endsWith(File.separator)) {
                            pattern += "**";
                        }
                        excludePatterns.add(pattern);
                    }
                }
            }

            boolean included = false;
            for (String pattern : includePatterns) {
                if (SelectorUtils.matchPath(pattern, name)) {
                    included = true;
                    break;
                }
            }

            for (String pattern : excludePatterns) {
                if (SelectorUtils.matchPath(pattern, name)) {
                    included = false;
                    break;
                }
            }

            if (!included) {
                // Do not process this file
                log("skipping " + entryName
                    + " as it is excluded or not included.",
                    Project.MSG_VERBOSE);
                return;
            }
        }
        String[] mappedNames = mapper.mapFileName(entryName);
        if (mappedNames == null || mappedNames.length == 0) {
            mappedNames = new String[] {entryName};
        }
        File f = fileUtils.resolveFile(dir, mappedNames[0]);
        if (!allowedOutsideOfDest && !fileUtils.isLeadingPath(dir, f, true)) {
            log("skipping " + entryName + " as its target " + f.getCanonicalPath()
                + " is outside of " + dir.getCanonicalPath() + ".", Project.MSG_VERBOSE);
                return;
        }

        try {
            if (!overwrite && f.exists()
                && f.lastModified() >= entryDate.getTime()) {
                log("Skipping " + f + " as it is up-to-date",
                    Project.MSG_DEBUG);
                return;
            }

            log("expanding " + entryName + " to " + f,
                Project.MSG_VERBOSE);
            // create intermediary directories - sometimes zip don't add them
            File dirF = f.getParentFile();
            if (dirF != null) {
                dirF.mkdirs();
            }

            if (isDirectory) {
                f.mkdirs();
            } else {
                byte[] buffer = new byte[BUFFER_SIZE];
                try (OutputStream fos = Files.newOutputStream(f.toPath())) {
                    int length;
                    while ((length = compressedInputStream.read(buffer)) >= 0) {
                        fos.write(buffer, 0, length);
                    }
                }
            }

            fileUtils.setFileLastModified(f, entryDate.getTime());
        } catch (FileNotFoundException ex) {
            log("Unable to expand to file " + f.getPath(),
                    ex,
                    Project.MSG_WARN);
        }

    }