<commit_before>/*
 *  Copyright 2008 <NAME> <<EMAIL>>
 *
 *  Licensed 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.helma.tools;

import org.apache.log4j.Logger;
import org.helma.repository.*;
import org.helma.util.StringUtils;
import org.helma.tools.launcher.HelmaClassLoader;
import org.mozilla.javascript.ClassShutter;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * This class describes the configuration for a Helma NG application or shell session.
 * @author hannes
 */
public class HelmaConfiguration {

    private Repository home;
    private List<Repository> repositories;
    private Resource mainResource;
    private String[] arguments;
    private int optimizationLevel = 0;
    private int languageVersion = 180;
    private boolean parentProtoProperties = false;
    private Class<?>[] hostClasses = null;
    private HelmaClassLoader loader;
    private ClassShutter classShutter = null;
    private List<String> bootstrapScripts;
    private boolean sealed = false;
    private boolean policyEnabled = false;

    /**
     * Create a new Helma configuration and sets up its module search path.
     *
     * @param helmaHome the helma installation directory
     * @param modulePath the module search path as comma separated string
     * @param systemModules system module path to append to module path, or null
     * @throws FileNotFoundException if a moudule path item does not exist
     */
    public HelmaConfiguration(Repository helmaHome, String modulePath, String systemModules)
            throws IOException {
        repositories = new ArrayList<Repository>();
        home = helmaHome;

        String optLevel = System.getProperty("rhino.optlevel");
        if (optLevel != null) {
            optimizationLevel = Integer.parseInt(optLevel);
        }
        String langVersion = System.getProperty("rhino.langversion");
        if (langVersion != null) {
            languageVersion = Integer.parseInt(langVersion);
        }
        String parentProto = System.getProperty("rhino.parentproto");
        if (parentProto != null) {
            parentProtoProperties = Integer.parseInt(parentProto) != 0;
        }

        if (modulePath != null) {
            String[] paths = StringUtils.split(modulePath, File.pathSeparator);
            for (int i = 0; i < paths.length; i++) {
                String path = paths[i].trim();
                Repository repository = resolveRootRepository(path);
                if (repository != null && repository.exists()) {
                    repositories.add(repository);
                } else {
                    System.err.println("Cannot resolve module path entry: " + path);
                }
            }
        }

        // append system modules path relative to helma home
        if (systemModules != null) {
            Repository repository = resolveRootRepository(systemModules);
                if (repository != null && repository.exists()) {
                    repositories.add(repository);
                } else {
                    System.err.println("Cannot resolve system module root: " + systemModules);
                }
        }

        // now that repositories are set up try to set default log4j configuration file
        if (System.getProperty("log4j.configuration") == null) {
            Resource log4jConfig = getResource("config/log4j.properties");
            try {
                System.setProperty("log4j.configuration", log4jConfig.getUrl().toString());
            } catch (MalformedURLException x) {
                System.setProperty("log4j.configuration", "file:" + log4jConfig.getPath());
            }
        }
        getLogger().debug("Parsed repository list: " + repositories);
    }

    /**
     * Resolve a module repository path.
     * @param path the path
     * @return a repository
     * @throws FileNotFoundException if the path couldn't be resolved
     */
    public Repository resolveRootRepository(String path) throws IOException {
        Repository repository = home.getChildRepository(path);
        if (repository != null && repository.exists()) {
            repository.setRoot();
            return repository;
        }
        File file = new File(path);
        if (!file.isAbsolute()) {
            // if path is relative, try to resolve against current directory first,
            // then relative to helma installation directory.
            file = file.getAbsoluteFile();
            if (!file.exists()) {
                file = new File(home.getPath(), path);
            }
        }
        if (!file.exists()) {
            throw new FileNotFoundException("File '" + file + "' does not exist.");
        }
        if (path.toLowerCase().endsWith(".zip")) {
            return new ZipRepository(file);
        } else {
            return new FileRepository(file);
        }
    }

    /**
     * Set the main script for this configuration. If the scriptName argument is not null,
     * we check whether the script is already contained in the helma module path.
     *
     * If not, the script's parent repository is prepended to the module path. If scriptName is
     * null, we prepend the current working directory to the module path.
     * @param scriptName the name of the script, or null.
     * @throws FileNotFoundException if the script repository does not exist
     */
    public void setMainScript(String scriptName) throws IOException {
        if (scriptName != null) {
            // first check if the script exists as a standalone file
            int zip = scriptName.indexOf(".zip/");
            if (zip > -1) {
                String zipFile = scriptName.substring(0, zip + 4);
                String scriptPath = scriptName.substring(zip + 5);
                ZipRepository zipRepo = new ZipRepository(new File(zipFile));
                mainResource = zipRepo.getResource(scriptPath);
                if (mainResource.exists()) {
                    repositories.add(0, zipRepo);
                    return;
                }
            }
            Resource script = new FileResource(new File(scriptName));
            if (script.exists()) {
                // check if we are contained in one of the existing repositories
                String scriptPath = script.getPath();
                for (Repository repo : repositories) {
                    if (repo instanceof FileRepository && scriptPath.indexOf(repo.getPath()) == 0) {
                        // found a repository that contains main script - use it as base for module name
                        script = repo.getResource(scriptPath.substring(repo.getPath().length()));
                        mainResource = script;
                        return;
                    }
                }
                // not found in the existing repositories - add parent as first element of module path
                repositories.add(0, script.getParentRepository());
                mainResource = script;
            } else {
                // check if the script can be found in the module path
                script = getResource(scriptName);
                if (!script.exists()) {
                    // try converting module name to file path and lookup in module path<commit_msg>Add convenience feature to run zipped apps by just specifying the zip file (adds zip repository to module path and runs main.js)<commit_after>/*
 *  Copyright 2008 <NAME> <<EMAIL>>
 *
 *  Licensed 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.helma.tools;

import org.apache.log4j.Logger;
import org.helma.repository.*;
import org.helma.util.StringUtils;
import org.helma.tools.launcher.HelmaClassLoader;
import org.mozilla.javascript.ClassShutter;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * This class describes the configuration for a Helma NG application or shell session.
 * @author hannes
 */
public class HelmaConfiguration {

    private Repository home;
    private List<Repository> repositories;
    private Resource mainResource;
    private String[] arguments;
    private int optimizationLevel = 0;
    private int languageVersion = 180;
    private boolean parentProtoProperties = false;
    private Class<?>[] hostClasses = null;
    private HelmaClassLoader loader;
    private ClassShutter classShutter = null;
    private List<String> bootstrapScripts;
    private boolean sealed = false;
    private boolean policyEnabled = false;

    /**
     * Create a new Helma configuration and sets up its module search path.
     *
     * @param helmaHome the helma installation directory
     * @param modulePath the module search path as comma separated string
     * @param systemModules system module path to append to module path, or null
     * @throws FileNotFoundException if a moudule path item does not exist
     */
    public HelmaConfiguration(Repository helmaHome, String modulePath, String systemModules)
            throws IOException {
        repositories = new ArrayList<Repository>();
        home = helmaHome;

        String optLevel = System.getProperty("rhino.optlevel");
        if (optLevel != null) {
            optimizationLevel = Integer.parseInt(optLevel);
        }
        String langVersion = System.getProperty("rhino.langversion");
        if (langVersion != null) {
            languageVersion = Integer.parseInt(langVersion);
        }
        String parentProto = System.getProperty("rhino.parentproto");
        if (parentProto != null) {
            parentProtoProperties = Integer.parseInt(parentProto) != 0;
        }

        if (modulePath != null) {
            String[] paths = StringUtils.split(modulePath, File.pathSeparator);
            for (int i = 0; i < paths.length; i++) {
                String path = paths[i].trim();
                Repository repository = resolveRootRepository(path);
                if (repository != null && repository.exists()) {
                    repositories.add(repository);
                } else {
                    System.err.println("Cannot resolve module path entry: " + path);
                }
            }
        }

        // append system modules path relative to helma home
        if (systemModules != null) {
            Repository repository = resolveRootRepository(systemModules);
                if (repository != null && repository.exists()) {
                    repositories.add(repository);
                } else {
                    System.err.println("Cannot resolve system module root: " + systemModules);
                }
        }

        // now that repositories are set up try to set default log4j configuration file
        if (System.getProperty("log4j.configuration") == null) {
            Resource log4jConfig = getResource("config/log4j.properties");
            try {
                System.setProperty("log4j.configuration", log4jConfig.getUrl().toString());
            } catch (MalformedURLException x) {
                System.setProperty("log4j.configuration", "file:" + log4jConfig.getPath());
            }
        }
        getLogger().debug("Parsed repository list: " + repositories);
    }

    /**
     * Resolve a module repository path.
     * @param path the path
     * @return a repository
     * @throws FileNotFoundException if the path couldn't be resolved
     */
    public Repository resolveRootRepository(String path) throws IOException {
        Repository repository = home.getChildRepository(path);
        if (repository != null && repository.exists()) {
            repository.setRoot();
            return repository;
        }
        File file = new File(path);
        if (!file.isAbsolute()) {
            // if path is relative, try to resolve against current directory first,
            // then relative to helma installation directory.
            file = file.getAbsoluteFile();
            if (!file.exists()) {
                file = new File(home.getPath(), path);
            }
        }
        if (!file.exists()) {
            throw new FileNotFoundException("File '" + file + "' does not exist.");
        }
        if (path.toLowerCase().endsWith(".zip")) {
            return new ZipRepository(file);
        } else {
            return new FileRepository(file);
        }
    }

    /**
     * Set the main script for this configuration. If the scriptName argument is not null,
     * we check whether the script is already contained in the helma module path.
     *
     * If not, the script's parent repository is prepended to the module path. If scriptName is
     * null, we prepend the current working directory to the module path.
     * @param scriptName the name of the script, or null.
     * @throws FileNotFoundException if the script repository does not exist
     */
    public void setMainScript(String scriptName) throws IOException {
        if (scriptName != null) {
            // check if the script is a zip file
            if (scriptName.toLowerCase().endsWith(".zip")) {
                ZipRepository zipRepo = new ZipRepository(new File(scriptName));
                mainResource = zipRepo.getResource("main.js");
                if (mainResource.exists()) {
                    repositories.add(0, zipRepo);
                    return;
                }
            }
            // check if script is a path within a zip file
            int zip = scriptName.toLowerCase().indexOf(".zip/");
            if (zip > -1) {
                String zipFile = scriptName.substring(0, zip + 4);
                String scriptPath = scriptName.substring(zip + 5);
                ZipRepository zipRepo = new ZipRepository(new File(zipFile));
                mainResource = zipRepo.getResource(scriptPath);
                if (mainResource.exists()) {
                    repositories.add(0, zipRepo);
                    return;
                }
            }
            // check if the script exists as a standalone file
            Resource script = new FileResource(new File(scriptName));
            if (script.exists()) {
                // check if we are contained in one of the existing repositories
                String scriptPath = script.getPath();
                for (Repository repo : repositories) {
                    if (repo instanceof FileRepository && scriptPath.indexOf(repo.getPath()) == 0) {
                        // found a repository that contains main script - use it as base for module name
                        script = repo.getResource(scriptPath.substring(repo.getPath().length()));
                        mainResource = script;
                        return;
                    }
                }
                // not found in the existing repositories - add parent as first element of module path
                repositories.add(0, script.getParentRepository());
                mainResource = script;
            } else {
                // check if the script can be found in the module path
                script = getResource(scriptName);
                if (!script.exists()) {
                    // try converting module name to file path and lookup in module path
{'fraction_non_alphanumeric': 0.08707746265949085, 'fraction_numerical': 0.0036886980709923203, 'mean_word_length': 2.135760333712552, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, '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': '7381264', 'n_tokens_mistral': 4022, 'n_tokens_neox': 3875, 'n_words': 1359}