<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.catalina.startup;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.JarURLConnection;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipException;

import org.apache.catalina.Host;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.res.StringManager;

/**
 * Expand out a WAR in a Host's appBase.
 *
 * @author <NAME>
 * @author <NAME>
 * @author <NAME>
 */
public class ExpandWar {

    private static final Log log = LogFactory.getLog(ExpandWar.class);

    /**
     * The string resources for this package.
     */
    protected static final StringManager sm =
        StringManager.getManager(Constants.Package);


    /**
     * Expand the WAR file found at the specified URL into an unpacked
     * directory structure.
     *
     * @param host Host war is being installed for
     * @param war URL of the web application archive to be expanded
     *  (must start with "jar:")
     * @param pathname Context path name for web application
     *
     * @exception IllegalArgumentException if this is not a "jar:" URL or if the
     *            WAR file is invalid
     * @exception IOException if an input/output error was encountered
     *  during expansion
     *
     * @return The absolute path to the expanded directory foe the given WAR
     */
    public static String expand(Host host, URL war, String pathname)
        throws IOException {

        // Open the connection to the WAR. There is no explicit close method.
        // You have to get the JarFile and close that.
        JarURLConnection juc = (JarURLConnection) war.openConnection();
        juc.setUseCaches(false);

        // Set up the variables used in the finally block of the following try
        boolean success = false;
        File docBase = new File(host.getAppBaseFile(), pathname);
        File warTracker = new File(host.getAppBaseFile(), pathname + Constants.WarTracker);

        try (JarFile jarFile = juc.getJarFile()) {

            // Get the last modified time for the WAR
            long warLastModified = juc.getLastModified();

            // Check to see of the WAR has been expanded previously
            if (docBase.exists()) {
                // A WAR was expanded. Tomcat will have set the last modified
                // time of the expanded directory to the last modified time of
                // the WAR so changes to the WAR while Tomcat is stopped can be
                // detected
                if (!warTracker.exists() || warTracker.lastModified() == warLastModified) {
                    // No (detectable) changes to the WAR
                    success = true;
                    return (docBase.getAbsolutePath());
                }

                // WAR must have been modified. Remove expanded directory.
                log.info(sm.getString("expandWar.deleteOld", docBase));
                if (!delete(docBase)) {
                    throw new IOException(sm.getString("expandWar.deleteFailed", docBase));
                }
            }

            // Create the new document base directory
            if(!docBase.mkdir() && !docBase.isDirectory()) {
                throw new IOException(sm.getString("expandWar.createFailed", docBase));
            }

            // Expand the WAR into the new document base directory
            String canonicalDocBasePrefix = docBase.getCanonicalPath();
            if (!canonicalDocBasePrefix.endsWith(File.separator)) {
                canonicalDocBasePrefix += File.separator;
            }

            Enumeration<JarEntry> jarEntries = jarFile.entries();<commit_msg>Create sometimes missing marker parent file (META-INF) that caused testsuite failures.<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.catalina.startup;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.JarURLConnection;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipException;

import org.apache.catalina.Host;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.res.StringManager;

/**
 * Expand out a WAR in a Host's appBase.
 *
 * @author <NAME>
 * @author <NAME>
 * @author <NAME>
 */
public class ExpandWar {

    private static final Log log = LogFactory.getLog(ExpandWar.class);

    /**
     * The string resources for this package.
     */
    protected static final StringManager sm =
        StringManager.getManager(Constants.Package);


    /**
     * Expand the WAR file found at the specified URL into an unpacked
     * directory structure.
     *
     * @param host Host war is being installed for
     * @param war URL of the web application archive to be expanded
     *  (must start with "jar:")
     * @param pathname Context path name for web application
     *
     * @exception IllegalArgumentException if this is not a "jar:" URL or if the
     *            WAR file is invalid
     * @exception IOException if an input/output error was encountered
     *  during expansion
     *
     * @return The absolute path to the expanded directory foe the given WAR
     */
    public static String expand(Host host, URL war, String pathname)
        throws IOException {

        // Open the connection to the WAR. There is no explicit close method.
        // You have to get the JarFile and close that.
        JarURLConnection juc = (JarURLConnection) war.openConnection();
        juc.setUseCaches(false);

        // Set up the variables used in the finally block of the following try
        boolean success = false;
        File docBase = new File(host.getAppBaseFile(), pathname);
        File warTracker = new File(host.getAppBaseFile(), pathname + Constants.WarTracker);

        try (JarFile jarFile = juc.getJarFile()) {

            // Get the last modified time for the WAR
            long warLastModified = juc.getLastModified();

            // Check to see of the WAR has been expanded previously
            if (docBase.exists()) {
                // A WAR was expanded. Tomcat will have set the last modified
                // time of the expanded directory to the last modified time of
                // the WAR so changes to the WAR while Tomcat is stopped can be
                // detected
                if (!warTracker.exists() || warTracker.lastModified() == warLastModified) {
                    // No (detectable) changes to the WAR
                    success = true;
                    return (docBase.getAbsolutePath());
                }

                // WAR must have been modified. Remove expanded directory.
                log.info(sm.getString("expandWar.deleteOld", docBase));
                if (!delete(docBase)) {
                    throw new IOException(sm.getString("expandWar.deleteFailed", docBase));
                }
            }

            // Create the new document base directory
            if(!docBase.mkdir() && !docBase.isDirectory()) {
                throw new IOException(sm.getString("expandWar.createFailed", docBase));
            }

            // Expand the WAR into the new document base directory
            String canonicalDocBasePrefix = docBase.getCanonicalPath();
            if (!canonicalDocBasePrefix.endsWith(File.separator)) {
                canonicalDocBasePrefix += File.separator;
            }

            // Creating war tracker parent (normally META-INF)
            File warTrackerParent = warTracker.getParentFile();
            if (!warTrackerParent.isDirectory() && !warTrackerParent.mkdirs()) {
                throw new IOException(sm.getString("expandWar.createFailed", warTrackerParent.getAbsolutePath()));
            }

            Enumeration<JarEntry> jarEntries = jarFile.entries();
{'fraction_non_alphanumeric': 0.08158081885603982, 'fraction_numerical': 0.00081276033729554, 'mean_word_length': 2.503202846975089, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3218203', 'n_tokens_mistral': 2496, 'n_tokens_neox': 2427, 'n_words': 935}