<commit_before>/*
 * Copyright 2015 Open Networking Laboratory
 *
 * 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.onosproject.maven;

import com.google.common.collect.ImmutableList;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static com.google.common.io.ByteStreams.toByteArray;
import static org.codehaus.plexus.util.FileUtils.*;

/**
 * Produces ONOS application archive using the app.xml file information.
 */
@Mojo(name = "app", defaultPhase = LifecyclePhase.PACKAGE)
public class OnosAppMojo extends AbstractMojo {

    private static final String APP = "app";
    private static final String NAME = "[@name]";
    private static final String VERSION = "[@version]";
    private static final String FEATURES_REPO = "[@featuresRepo]";
    private static final String ARTIFACT = "artifact";

    private static final String APP_XML = "app.xml";
    private static final String FEATURES_XML = "features.xml";

    private static final String MVN_URL = "mvn:";
    private static final String M2_PREFIX = "m2";

    private static final String ONOS_APP_NAME = "onos.app.name";
    private static final String ONOS_APP_ORIGIN = "onos.app.origin";
    private static final String ONOS_APP_REQUIRES = "onos.app.requires";

    private static final String JAR = "jar";
    private static final String XML = "xml";
    private static final String APP_ZIP = "oar";
    private static final String PACKAGE_DIR = "oar";

    private static final String DEFAULT_ORIGIN = "ON.Lab";
    private static final String DEFAULT_VERSION = "${project.version}";

    private static final String DEFAULT_FEATURES_REPO =
            "mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features";
    private static final String DEFAULT_ARTIFACT =
            "mvn:${project.groupId}/${project.artifactId}/${project.version}";

    private static final int BUFFER_SIZE = 8192;

    private String name;
    private String origin;
    private String requiredApps;
    private String version = DEFAULT_VERSION;
    private String featuresRepo = DEFAULT_FEATURES_REPO;
    private List<String> artifacts;

    /**
     * The project base directory.
     */
    @Parameter(defaultValue = "${basedir}")
    protected File baseDir;

    /**
     * The directory where the generated catalogue file will be put.
     */
    @Parameter(defaultValue = "${project.build.directory}")
    protected File dstDirectory;

    /**
     * The project group ID.
     */
    @Parameter(defaultValue = "${project.groupId}")
    protected String projectGroupId;

    /**
     * The project artifact ID.
     */
    @Parameter(defaultValue = "${project.artifactId}")
    protected String projectArtifactId;

    /**
     * The project version.
     */
    @Parameter(defaultValue = "${project.version}")
    protected String projectVersion;

    /**
     * The project version.
     */
    @Parameter(defaultValue = "${project.description}")
    protected String projectDescription;

    @Parameter(defaultValue = "${localRepository}")
    protected ArtifactRepository localRepository;

    /**
     * Maven project
     */
    @Parameter(defaultValue = "${project}")
    protected MavenProject project;

    /**
     * Maven project helper.
     */
    @Component
    protected MavenProjectHelper projectHelper;


    private File m2Directory;
    protected File stageDirectory;
    protected String projectPath;

    @Override
    public void execute() throws MojoExecutionException {
        File appFile = new File(baseDir, APP_XML);
        File featuresFile = new File(baseDir, FEATURES_XML);

        name = (String) project.getProperties().get(ONOS_APP_NAME);

        // If neither the app.xml file exists, nor the onos.app.name property
        // is defined, there is nothing for this Mojo to do, so bail.
        if (!appFile.exists() && name == null) {
            return;
        }

        m2Directory = new File(localRepository.getBasedir());
        stageDirectory = new File(dstDirectory, PACKAGE_DIR);
        projectPath = M2_PREFIX + "/" + artifactDir(projectGroupId, projectArtifactId, projectVersion);

        origin = (String) project.getProperties().get(ONOS_APP_ORIGIN);
        origin = origin != null ? origin : DEFAULT_ORIGIN;

        requiredApps = (String) project.getProperties().get(ONOS_APP_REQUIRES);
        requiredApps = requiredApps == null ? "" : requiredApps;

        if (appFile.exists()) {
            loadAppFile(appFile);
        } else {
            artifacts = ImmutableList.of(eval(DEFAULT_ARTIFACT));
        }

        // If there are any artifacts, stage the
        if (!artifacts.isEmpty()) {
            getLog().info("Building ONOS application package for " + name + " (v" + eval(version) + ")");
            artifacts.forEach(a -> getLog().debug("Including artifact: " + a));

            if (stageDirectory.exists() || stageDirectory.mkdirs()) {
                processAppXml(appFile);
                processFeaturesXml(featuresFile);
                processArtifacts();
                generateAppPackage();
            } else {
                throw new MojoExecutionException("Unable to create directory: " + stageDirectory);
            }
        }
    }

    // Loads the app.xml file.
    private void loadAppFile(File appFile) throws MojoExecutionException {
        XMLConfiguration xml = new XMLConfiguration();
        xml.setRootElementName(APP);

        try (FileInputStream stream = new FileInputStream(appFile)) {
            xml.load(stream);
            xml.setAttributeSplittingDisabled(true);<commit_msg>Allowing white spaces in onos.app.requires property.<commit_after>/*
 * Copyright 2015 Open Networking Laboratory
 *
 * 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.onosproject.maven;

import com.google.common.collect.ImmutableList;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static com.google.common.io.ByteStreams.toByteArray;
import static org.codehaus.plexus.util.FileUtils.*;

/**
 * Produces ONOS application archive using the app.xml file information.
 */
@Mojo(name = "app", defaultPhase = LifecyclePhase.PACKAGE)
public class OnosAppMojo extends AbstractMojo {

    private static final String APP = "app";
    private static final String NAME = "[@name]";
    private static final String VERSION = "[@version]";
    private static final String FEATURES_REPO = "[@featuresRepo]";
    private static final String ARTIFACT = "artifact";

    private static final String APP_XML = "app.xml";
    private static final String FEATURES_XML = "features.xml";

    private static final String MVN_URL = "mvn:";
    private static final String M2_PREFIX = "m2";

    private static final String ONOS_APP_NAME = "onos.app.name";
    private static final String ONOS_APP_ORIGIN = "onos.app.origin";
    private static final String ONOS_APP_REQUIRES = "onos.app.requires";

    private static final String JAR = "jar";
    private static final String XML = "xml";
    private static final String APP_ZIP = "oar";
    private static final String PACKAGE_DIR = "oar";

    private static final String DEFAULT_ORIGIN = "ON.Lab";
    private static final String DEFAULT_VERSION = "${project.version}";

    private static final String DEFAULT_FEATURES_REPO =
            "mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features";
    private static final String DEFAULT_ARTIFACT =
            "mvn:${project.groupId}/${project.artifactId}/${project.version}";

    private static final int BUFFER_SIZE = 8192;

    private String name;
    private String origin;
    private String requiredApps;
    private String version = DEFAULT_VERSION;
    private String featuresRepo = DEFAULT_FEATURES_REPO;
    private List<String> artifacts;

    /**
     * The project base directory.
     */
    @Parameter(defaultValue = "${basedir}")
    protected File baseDir;

    /**
     * The directory where the generated catalogue file will be put.
     */
    @Parameter(defaultValue = "${project.build.directory}")
    protected File dstDirectory;

    /**
     * The project group ID.
     */
    @Parameter(defaultValue = "${project.groupId}")
    protected String projectGroupId;

    /**
     * The project artifact ID.
     */
    @Parameter(defaultValue = "${project.artifactId}")
    protected String projectArtifactId;

    /**
     * The project version.
     */
    @Parameter(defaultValue = "${project.version}")
    protected String projectVersion;

    /**
     * The project version.
     */
    @Parameter(defaultValue = "${project.description}")
    protected String projectDescription;

    @Parameter(defaultValue = "${localRepository}")
    protected ArtifactRepository localRepository;

    /**
     * Maven project
     */
    @Parameter(defaultValue = "${project}")
    protected MavenProject project;

    /**
     * Maven project helper.
     */
    @Component
    protected MavenProjectHelper projectHelper;


    private File m2Directory;
    protected File stageDirectory;
    protected String projectPath;

    @Override
    public void execute() throws MojoExecutionException {
        File appFile = new File(baseDir, APP_XML);
        File featuresFile = new File(baseDir, FEATURES_XML);

        name = (String) project.getProperties().get(ONOS_APP_NAME);

        // If neither the app.xml file exists, nor the onos.app.name property
        // is defined, there is nothing for this Mojo to do, so bail.
        if (!appFile.exists() && name == null) {
            return;
        }

        m2Directory = new File(localRepository.getBasedir());
        stageDirectory = new File(dstDirectory, PACKAGE_DIR);
        projectPath = M2_PREFIX + "/" + artifactDir(projectGroupId, projectArtifactId, projectVersion);

        origin = (String) project.getProperties().get(ONOS_APP_ORIGIN);
        origin = origin != null ? origin : DEFAULT_ORIGIN;

        requiredApps = (String) project.getProperties().get(ONOS_APP_REQUIRES);
        requiredApps = requiredApps == null ? "" : requiredApps.replaceAll("[\\s]", "");

        if (appFile.exists()) {
            loadAppFile(appFile);
        } else {
            artifacts = ImmutableList.of(eval(DEFAULT_ARTIFACT));
        }

        // If there are any artifacts, stage the
        if (!artifacts.isEmpty()) {
            getLog().info("Building ONOS application package for " + name + " (v" + eval(version) + ")");
            artifacts.forEach(a -> getLog().debug("Including artifact: " + a));

            if (stageDirectory.exists() || stageDirectory.mkdirs()) {
                processAppXml(appFile);
                processFeaturesXml(featuresFile);
                processArtifacts();
                generateAppPackage();
            } else {
                throw new MojoExecutionException("Unable to create directory: " + stageDirectory);
            }
        }
    }

    // Loads the app.xml file.
    private void loadAppFile(File appFile) throws MojoExecutionException {
        XMLConfiguration xml = new XMLConfiguration();
        xml.setRootElementName(APP);

        try (FileInputStream stream = new FileInputStream(appFile)) {
            xml.load(stream);
            xml.setAttributeSplittingDisabled(true);
{'fraction_non_alphanumeric': 0.10150940696759425, 'fraction_numerical': 0.0024322197582087417, 'mean_word_length': 3.258300335059397, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 22}, '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': '379233', 'n_tokens_mistral': 3834, 'n_tokens_neox': 3690, 'n_words': 1050}