/**
 * Copyright (c) 2009 Capgemini Sud, 2010-2012 EBM WebSourcing, 2012-2022 Linagora
 * 
 * This program/library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This program/library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program/library; If not, see http://www.gnu.org/licenses/
 * for the GNU Lesser General Public License version 2.1.
 */
package org.ow2.petals.plugin.jbiplugin;

import static org.junit.Assert.assertNotEquals;

import java.io.File;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.junit.Test;
import org.ow2.easywsdl.extensions.wsdl4complexwsdl.WSDL4ComplexWsdlFactory;
import org.ow2.easywsdl.extensions.wsdl4complexwsdl.api.Description;
import org.ow2.easywsdl.extensions.wsdl4complexwsdl.api.WSDL4ComplexWsdlReader;
import org.ow2.easywsdl.wsdl.api.Service;
import org.ow2.petals.jbi.descriptor.extension.JBIDescriptorExtensionBuilder;
import org.ow2.petals.jbi.descriptor.extension.exception.NotDeployableServiceUnitException;
import org.ow2.petals.jbi.descriptor.original.JBIDescriptorBuilder;
import org.ow2.petals.jbi.descriptor.original.generated.ClassPath;
import org.ow2.petals.jbi.descriptor.original.generated.Component;
import org.ow2.petals.jbi.descriptor.original.generated.Identification;
import org.ow2.petals.jbi.descriptor.original.generated.Jbi;
import org.ow2.petals.jbi.descriptor.original.generated.ServiceAssembly;
import org.ow2.petals.jbi.descriptor.original.generated.ServiceUnit;
import org.ow2.petals.plugin.jbiplugin.environement.ComponentWithUpdateOnAlreadyProvidedClasspathElt;
import org.ow2.petals.plugin.jbiplugin.environement.ComponentWithUpdateOnEmptyClasspathElt;
import org.ow2.petals.plugin.jbiplugin.environement.ComponentWithUpdateOnEmptyProvidedDescription;
import org.ow2.petals.plugin.jbiplugin.environement.ComponentWithUpdateOnExtraClasspathElt;
import org.ow2.petals.plugin.jbiplugin.environement.ComponentWithUpdateOnNotProvidedClasspathElt;
import org.ow2.petals.plugin.jbiplugin.environement.ComponentWithUpdateOnNotProvidedDescription;
import org.ow2.petals.plugin.jbiplugin.environement.ComponentWithUpdateOnProvidedDescription;
import org.ow2.petals.plugin.jbiplugin.environement.GlobalUnitTestEnvironnement;
import org.ow2.petals.plugin.jbiplugin.environement.ServiceAssemblyWithSimpleServiceUnitWithSeveralJBIComponentDependenciesWithComponentToUseDeclared;
import org.ow2.petals.plugin.jbiplugin.environement.ServiceAssemblyWithUpdateWithoutDescriptionInServiceUnitPomFile;
import org.ow2.petals.plugin.jbiplugin.environement.ServiceUnitWithUpdateDownloadingRemoteWsdlImports;
import org.ow2.petals.plugin.jbiplugin.environement.ServiceUnitWithUpdateFrenchCharacters;
import org.ow2.petals.plugin.jbiplugin.environement.ServiceUnitWithUpdateNotDownloadingRemoteWsdlImports;
import org.ow2.petals.plugin.jbiplugin.environement.SimpleServiceUnitWithSeveralJBIComponentDependenciesWithComponentToUseDeclaredJBIDescriptorUpdated;
import org.ow2.petals.plugin.jbiplugin.environement.SimpleServiceUnitWithUpdate;
import org.xml.sax.InputSource;

/**
 * Test the jbi maven plugin about the JBI descriptor updates of the goal 'jbi-package'.
 * @author Christophe DENEUX - Capgemini Sud
 */
public class JBIPackageWithUpdateMojoTest extends JBIAbstractTestMojo {

    /**
     * <p>
     * Test the goal 'jbi-package' about JBI descriptor updates against a
     * description provided in the POM file.
     * </p>
     */
    @Test
    public void testPackageComponentWithUpdateOnProvidedDescription() throws Exception {

        // First, we generate the component JBI archive to configure
        final File componentPomFile = new File(ComponentWithUpdateOnProvidedDescription.SRC_HOME,
                "pom.xml");
        final JBIPackageMojo packageMojo = this.getPackageMojo(componentPomFile);

        packageMojo.execute();

        // Second, we check the JBI descriptor against bootstrap and component
        // classpath
        final ZipFile packagedComponentFile = new ZipFile(new File(
                ComponentWithUpdateOnProvidedDescription.TARGET_HOME,
                ComponentWithUpdateOnProvidedDescription.FINAL_NAME));

        final ZipEntry jbiEntry = packagedComponentFile
                .getEntry(JBIDescriptorBuilder.JBI_DESCRIPTOR_RESOURCE_IN_ARCHIVE);
        assertNotNull("The JBI descriptor is missing in the packaged JBI component",
                jbiEntry);
        final Jbi jbiDescriptor = JBIDescriptorBuilder.getInstance().buildJavaJBIDescriptor(
                packagedComponentFile
                .getInputStream(jbiEntry));
        packagedComponentFile.close();
        final Component jbiComponent = jbiDescriptor.getComponent();
        assertNotNull("The section 'component' is missing in the JBI descriptor.",
                jbiComponent);
        final Identification jbiIdent = jbiComponent.getIdentification();
        assertNotNull(
                "The identification is missing in the section 'component' in the JBI descriptor.",
                jbiIdent);
        assertEquals("Incorrect description found in the JBI decsriptor",
                ComponentWithUpdateOnProvidedDescription.EXPECTED_DESCRIPTION, jbiIdent
                        .getDescription());
    }
    
    /**
     * <p>
     * Test the goal 'jbi-package' about JBI descriptor updates against an empty
     * description provided in the POM file.
     * </p>
     */
    @Test
    public void testPackageComponentWithUpdateOnEmptyProvidedDescription() throws Exception {

        // First, we generate the component JBI archive to configure
        final File componentPomFile = new File(
                ComponentWithUpdateOnEmptyProvidedDescription.SRC_HOME, "pom.xml");
        final JBIPackageMojo packageMojo = this.getPackageMojo(componentPomFile);

        packageMojo.execute();

        // Second, we check the JBI descriptor against bootstrap and component
        // classpath
        final ZipFile packagedComponentFile = new ZipFile(new File(
                ComponentWithUpdateOnEmptyProvidedDescription.TARGET_HOME,
                ComponentWithUpdateOnEmptyProvidedDescription.FINAL_NAME));

        final ZipEntry jbiEntry = packagedComponentFile
                .getEntry(JBIDescriptorBuilder.JBI_DESCRIPTOR_RESOURCE_IN_ARCHIVE);
        assertNotNull("The JBI descriptor is missing in the packaged JBI component",
                jbiEntry);
        final Jbi jbiDescriptor = JBIDescriptorBuilder.getInstance().buildJavaJBIDescriptor(
                packagedComponentFile
                .getInputStream(jbiEntry));
        packagedComponentFile.close();
        final Component jbiComponent = jbiDescriptor.getComponent();
        assertNotNull("The section 'component' is missing in the JBI descriptor.",
                jbiComponent);
        final Identification jbiIdent = jbiComponent.getIdentification();
        assertNotNull(
                "The identification is missing in the section 'component' in the JBI descriptor.",
                jbiIdent);
        assertEquals("Incorrect description found in the JBI decsriptor",
                ComponentWithUpdateOnEmptyProvidedDescription.EXPECTED_DESCRIPTION, jbiIdent
                        .getDescription());
    }

    /**
     * <p>
     * Test the goal 'jbi-package' about JBI descriptor updates against a
     * description not provided in the POM file.
     * </p>
     */
    @Test
    public void testPackageComponentWithUpdateOnNotProvidedDescription() throws Exception {

        // First, we generate the component JBI archive to configure
        final File componentPomFile = new File(
                ComponentWithUpdateOnNotProvidedDescription.SRC_HOME, "pom.xml");
        final JBIPackageMojo packageMojo = this.getPackageMojo(componentPomFile);

        packageMojo.execute();

        // Second, we check the JBI descriptor against bootstrap and component
        // classpath
        final ZipFile packagedComponentFile = new ZipFile(new File(
                ComponentWithUpdateOnNotProvidedDescription.TARGET_HOME,
                ComponentWithUpdateOnNotProvidedDescription.FINAL_NAME));

        final ZipEntry jbiEntry = packagedComponentFile
                .getEntry(JBIDescriptorBuilder.JBI_DESCRIPTOR_RESOURCE_IN_ARCHIVE);
        assertNotNull("The JBI descriptor is missing in the packaged JBI component",
                jbiEntry);
        final Jbi jbiDescriptor = JBIDescriptorBuilder.getInstance().buildJavaJBIDescriptor(
                packagedComponentFile
                .getInputStream(jbiEntry));
        packagedComponentFile.close();
        final Component jbiComponent = jbiDescriptor.getComponent();
        assertNotNull("The section 'component' is missing in the JBI descriptor.",
                jbiComponent);
        final Identification jbiIdent = jbiComponent.getIdentification();
        assertNotNull(
                "The identification is missing in the section 'component' in the JBI descriptor.",
                jbiIdent);
        assertEquals("Incorrect description found in the JBI decsriptor",
                ComponentWithUpdateOnNotProvidedDescription.EXPECTED_DESCRIPTION, jbiIdent
                        .getDescription());
    }

    /**
     * <p>
     * Test the goal 'jbi-package' about JBI descriptor updates against an
     * original JBI descriptor containing already a needed dependency.
     * </p>
     */
    @Test
    public void testPackageComponentWithUpdateOnAlreadyProvidedClasspathElt() throws Exception {

        // First, we generate the component JBI archive to configure
        final File componentPomFile = new File(
                ComponentWithUpdateOnAlreadyProvidedClasspathElt.SRC_HOME, "pom.xml");
        final JBIPackageMojo packageMojo = this.getPackageMojo(componentPomFile);

        packageMojo.execute();

        // Second, we check the JBI descriptor against bootstrap and component
        // classpath
        final ZipFile packagedComponentFile = new ZipFile(new File(
                ComponentWithUpdateOnAlreadyProvidedClasspathElt.TARGET_HOME,
                ComponentWithUpdateOnAlreadyProvidedClasspathElt.FINAL_NAME));

        final ZipEntry jbiEntry = packagedComponentFile
                .getEntry(JBIDescriptorBuilder.JBI_DESCRIPTOR_RESOURCE_IN_ARCHIVE);
        assertNotNull("The JBI descriptor is missing in the packaged JBI component",
                jbiEntry);
        final Jbi jbiDescriptor = JBIDescriptorBuilder.getInstance().buildJavaJBIDescriptor(
                packagedComponentFile
                .getInputStream(jbiEntry));
        packagedComponentFile.close();
        final Component jbiComponent = jbiDescriptor.getComponent();
        assertNotNull("The section 'component' is missing in the JBI descriptor.",
                jbiComponent);
        {
            final ClassPath jbiClassPath = jbiComponent.getBootstrapClassPath();
            assertNotNull(
                            "The boostrap classpath is missing in the section 'component' in the JBI descriptor.",
                            jbiComponent);
            final List<String> jbiClassPathElts = jbiClassPath.getPathElement();
            assertNotNull(
                            "The boostrap classpath is empty in the section 'component' in the JBI descriptor.",
                            jbiClassPathElts);
            assertNotEquals(
                            "The boostrap classpath is empty in the section 'component' in the JBI descriptor.",
                            0, jbiClassPathElts.size());
            assertTrue(
                            "The dependency is missing in bootstrap classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnAlreadyProvidedClasspathElt.DEPENDENCY_FINAL_NAME));
            assertTrue(
                            "The component JAR is missing in bootstrap classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnAlreadyProvidedClasspathElt.COMPONENT_JAR_FINAL_NAME));
        }

        {
            final ClassPath jbiClassPath = jbiComponent.getComponentClassPath();
            assertNotNull(
                            "The component classpath is missing in the section 'component' in the JBI descriptor.",
                            jbiComponent);
            final List<String> jbiClassPathElts = jbiClassPath.getPathElement();
            assertNotNull(
                            "The component classpath is empty in the section 'component' in the JBI descriptor.",
                            jbiClassPathElts);
            assertNotEquals(
                            "The component classpath is empty in the section 'component' in the JBI descriptor.",
                            0, jbiClassPathElts.size());
            assertTrue(
                            "The dependency is missing in component classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnAlreadyProvidedClasspathElt.DEPENDENCY_FINAL_NAME));
            assertTrue(
                            "The component JAR  is missing in component classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnAlreadyProvidedClasspathElt.COMPONENT_JAR_FINAL_NAME));
        }
    }

    /**
     * <p>
     * Test the goal 'jbi-package' about JBI descriptor updates against an
     * original JBI descriptor containing no classpath element.
     * </p>
     */
    @Test
    public void testPackageComponentWithUpdateOnNotProvidedClasspathElt() throws Exception {

        // First, we generate the component JBI archive to configure
        final File componentPomFile = new File(
                ComponentWithUpdateOnNotProvidedClasspathElt.SRC_HOME, "pom.xml");
        final JBIPackageMojo packageMojo = this.getPackageMojo(componentPomFile);

        packageMojo.execute();

        // Second, we check the JBI descriptor against bootstrap and component
        // classpath
        final ZipFile packagedComponentFile = new ZipFile(new File(
                ComponentWithUpdateOnNotProvidedClasspathElt.TARGET_HOME,
                ComponentWithUpdateOnNotProvidedClasspathElt.FINAL_NAME));

        final ZipEntry jbiEntry = packagedComponentFile
                .getEntry(JBIDescriptorBuilder.JBI_DESCRIPTOR_RESOURCE_IN_ARCHIVE);
        assertNotNull("The JBI descriptor is missing in the packaged JBI component",
                jbiEntry);
        final Jbi jbiDescriptor = JBIDescriptorBuilder.getInstance().buildJavaJBIDescriptor(
                packagedComponentFile
                .getInputStream(jbiEntry));
        packagedComponentFile.close();
        final Component jbiComponent = jbiDescriptor.getComponent();
        assertNotNull("The section 'component' is missing in the JBI descriptor.",
                jbiComponent);
        {
            final ClassPath jbiClassPath = jbiComponent.getBootstrapClassPath();
            assertNotNull(
                            "The boostrap classpath is missing in the section 'component' in the JBI descriptor.",
                            jbiComponent);
            final List<String> jbiClassPathElts = jbiClassPath.getPathElement();
            assertNotNull(
                            "The boostrap classpath is empty in the section 'component' in the JBI descriptor.",
                            jbiClassPathElts);
            assertNotEquals(
                            "The boostrap classpath is empty in the section 'component' in the JBI descriptor.",
                            0, jbiClassPathElts.size());
            assertTrue(
                            "The dependency is missing in bootstrap classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnNotProvidedClasspathElt.DEPENDENCY_FINAL_NAME));
            assertTrue(
"The transitive dependency is missing in bootstrap classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnNotProvidedClasspathElt.TRANSITIVE_DEPENDENCY_FINAL_NAME));
            assertTrue(
                            "The component JAR is missing in bootstrap classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnNotProvidedClasspathElt.COMPONENT_JAR_FINAL_NAME));
        }

        {
            final ClassPath jbiClassPath = jbiComponent.getComponentClassPath();
            assertNotNull(
                            "The component classpath is missing in the section 'component' in the JBI descriptor.",
                            jbiComponent);
            final List<String> jbiClassPathElts = jbiClassPath.getPathElement();
            assertNotNull(
                            "The component classpath is empty in the section 'component' in the JBI descriptor.",
                            jbiClassPathElts);
            assertNotEquals(
                            "The component classpath is empty in the section 'component' in the JBI descriptor.",
                            0, jbiClassPathElts.size());
            assertTrue(
                            "The dependency is missing in component classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnNotProvidedClasspathElt.DEPENDENCY_FINAL_NAME));
            assertTrue(
"The transitive dependency is missing in bootstrap classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnNotProvidedClasspathElt.TRANSITIVE_DEPENDENCY_FINAL_NAME));
            assertTrue(
                            "The component JAR  is missing in component classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnNotProvidedClasspathElt.COMPONENT_JAR_FINAL_NAME));
        }
    }

    /**
     * <p>
     * Test the goal 'jbi-package' about JBI descriptor updates against an
     * original JBI descriptor containing an extra classpath element (not
     * included in dependencies list).
     * </p>
     */
    @Test
    public void testPackageComponentWithUpdateOnExtraClasspathElt() throws Exception {

        // First, we generate the component JBI archive to configure
        final File componentPomFile = new File(
                ComponentWithUpdateOnExtraClasspathElt.SRC_HOME,
                "pom.xml");
        final JBIPackageMojo packageMojo = this.getPackageMojo(componentPomFile);

        packageMojo.execute();

        // Second, we check the JBI descriptor against bootstrap and component
        // classpath
        final ZipFile packagedComponentFile = new ZipFile(new File(
                ComponentWithUpdateOnExtraClasspathElt.TARGET_HOME,
                ComponentWithUpdateOnExtraClasspathElt.FINAL_NAME));

        final ZipEntry jbiEntry = packagedComponentFile
                .getEntry(JBIDescriptorBuilder.JBI_DESCRIPTOR_RESOURCE_IN_ARCHIVE);
        assertNotNull("The JBI descriptor is missing in the packaged JBI component",
                jbiEntry);
        final Jbi jbiDescriptor = JBIDescriptorBuilder.getInstance().buildJavaJBIDescriptor(
                packagedComponentFile
                .getInputStream(jbiEntry));
        packagedComponentFile.close();
        final Component jbiComponent = jbiDescriptor.getComponent();
        assertNotNull("The section 'component' is missing in the JBI descriptor.",
                jbiComponent);
        {
            final ClassPath jbiClassPath = jbiComponent.getBootstrapClassPath();
            assertNotNull(
                            "The boostrap classpath is missing in the section 'component' in the JBI descriptor.",
                            jbiComponent);
            final List<String> jbiClassPathElts = jbiClassPath.getPathElement();
            assertNotNull(
                            "The boostrap classpath is empty in the section 'component' in the JBI descriptor.",
                            jbiClassPathElts);
            assertNotEquals(
                            "The boostrap classpath is empty in the section 'component' in the JBI descriptor.",
                            0, jbiClassPathElts.size());
            assertTrue(
                            "The dependency is missing in bootstrap classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnExtraClasspathElt.DEPENDENCY_FINAL_NAME));
            assertTrue(
                            "The dependency is missing in bootstrap classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnExtraClasspathElt.TRANSITIVE_DEPENDENCY_FINAL_NAME));
            assertTrue(
                            "The component JAR is missing in bootstrap classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnExtraClasspathElt.COMPONENT_JAR_FINAL_NAME));
            assertTrue(
                            "The extra classpath element is missing in component classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnExtraClasspathElt.EXTRA_CLASSPATH_ELT));
        }

        {
            final ClassPath jbiClassPath = jbiComponent.getComponentClassPath();
            assertNotNull(
                            "The component classpath is missing in the section 'component' in the JBI descriptor.",
                            jbiComponent);
            final List<String> jbiClassPathElts = jbiClassPath.getPathElement();
            assertNotNull(
                            "The component classpath is empty in the section 'component' in the JBI descriptor.",
                            jbiClassPathElts);
            assertNotEquals(
                            "The component classpath is empty in the section 'component' in the JBI descriptor.",
                            0, jbiClassPathElts.size());
            assertTrue(
                            "The dependency is missing in component classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnExtraClasspathElt.DEPENDENCY_FINAL_NAME));
            assertTrue(
                            "The dependency is missing in bootstrap classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnExtraClasspathElt.TRANSITIVE_DEPENDENCY_FINAL_NAME));
            assertTrue(
                            "The component JAR  is missing in component classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnExtraClasspathElt.COMPONENT_JAR_FINAL_NAME));
            assertTrue(
                            "The extra classpath element is missing in component classpath in the JBI descriptor",
                            jbiClassPathElts
                                    .contains(ComponentWithUpdateOnExtraClasspathElt.EXTRA_CLASSPATH_ELT));
        }
    }

    /**
     * <p>
     * Test the goal 'jbi-package' about JBI descriptor updates against an
     * original JBI descriptor containing empty classpath elements.
     * </p>
     */
    @Test
    public void testPackageComponentWithUpdateOnEmptyClasspathElt() throws Exception {

        // First, we generate the component JBI archive to configure
        final File componentPomFile = new File(ComponentWithUpdateOnEmptyClasspathElt.SRC_HOME,
                "pom.xml");
        final JBIPackageMojo packageMojo = this.getPackageMojo(componentPomFile);

        packageMojo.execute();

        // Second, we check the JBI descriptor against bootstrap and component
        // classpath
        final ZipFile packagedComponentFile = new ZipFile(new File(
                ComponentWithUpdateOnEmptyClasspathElt.TARGET_HOME,
                ComponentWithUpdateOnEmptyClasspathElt.FINAL_NAME));

        final ZipEntry jbiEntry = packagedComponentFile
                .getEntry(JBIDescriptorBuilder.JBI_DESCRIPTOR_RESOURCE_IN_ARCHIVE);
        assertNotNull("The JBI descriptor is missing in the packaged JBI component",
                jbiEntry);
        final Jbi jbiDescriptor = JBIDescriptorBuilder.getInstance().buildJavaJBIDescriptor(
                packagedComponentFile
                .getInputStream(jbiEntry));
        packagedComponentFile.close();
        final Component jbiComponent = jbiDescriptor.getComponent();
        assertNotNull("The section 'component' is missing in the JBI descriptor.",
                jbiComponent);
        {
            final ClassPath jbiClassPath = jbiComponent.getBootstrapClassPath();
            assertNotNull(
                            "The boostrap classpath is missing in the section 'component' in the JBI descriptor.",
                            jbiComponent);
            final List<String> jbiClassPathElts = jbiClassPath.getPathElement();
            assertNotNull(
                            "The boostrap classpath is empty in the section 'component' in the JBI descriptor.",
                            jbiClassPathElts);
            assertNotEquals(
                            "The boostrap classpath is empty in the section 'component' in the JBI descriptor.",
                            0, jbiClassPathElts.size());

            for (String jbiClassPathElt : jbiClassPathElts) {
                assertFalse(
                                "An empty classpath element exists in the bootstrap classpath in the JBI descriptor",
                                jbiClassPathElt.trim().length() == 0);
            }
        }

        {
            final ClassPath jbiClassPath = jbiComponent.getComponentClassPath();
            assertNotNull(
                            "The component classpath is missing in the section 'component' in the JBI descriptor.",
                            jbiComponent);
            final List<String> jbiClassPathElts = jbiClassPath.getPathElement();
            assertNotNull(
                            "The component classpath is empty in the section 'component' in the JBI descriptor.",
                            jbiClassPathElts);
            assertNotEquals(
                            "The component classpath is empty in the section 'component' in the JBI descriptor.",
                            0, jbiClassPathElts.size());

            for (String jbiClassPathElt : jbiClassPathElts) {
                assertFalse(
                                "An empty classpath element exists in the component classpath in the JBI descriptor",
                                jbiClassPathElt.trim().length() == 0);
            }
        }
    }

    /**
     * <p>
     * Test the goal 'jbi-package' about download of remote WSDL imports.
     * </p>
     */
    @Test
    public void testPackageServiceUnitWithUpdateDownloadingRemoteWSDLImports() throws Exception {

        // First, we generate the service unit JBI archive to configure
        final File serviceUnitPomFile = new File(ServiceUnitWithUpdateDownloadingRemoteWsdlImports.SRC_HOME, "pom.xml");
        final JBIPackageMojo packageMojo = this.getPackageMojo(serviceUnitPomFile);

        packageMojo.execute();

        // Second, we check the content of the JBI archive
        final ZipFile packagedSuFile = new ZipFile(new File(
                ServiceUnitWithUpdateDownloadingRemoteWsdlImports.TARGET_HOME,
                ServiceUnitWithUpdateDownloadingRemoteWsdlImports.FINAL_NAME));

        // The WSDL is present
        final ZipEntry wsdlEntry = packagedSuFile.getEntry("echo.wsdl");
        assertNotNull("The WSDL is missing in the JBI archive", wsdlEntry);

        // ... with its import as file
        final ZipEntry importEntry = packagedSuFile.getEntry("2005/05/xmlmime");
        assertNotNull("The WSDL import is missing in the JBI archive", importEntry);

        // The JBI descriptor does not contain extensions of a deployable service unit because no component declared in
        // the POM
        final ZipEntry jbiEntry = packagedSuFile.getEntry(JBIDescriptorBuilder.JBI_DESCRIPTOR_RESOURCE_IN_ARCHIVE);
        assertNotNull(jbiEntry);
        final Jbi jbi = JBIDescriptorBuilder.getInstance().buildJavaJBIDescriptor(
                packagedSuFile.getInputStream(jbiEntry));
        packagedSuFile.close();
        try {
            JBIDescriptorExtensionBuilder.getInstance().getDeployableServiceUnitIndentification(jbi);
            fail("The identification part of a deployable service unit is present in the JBI descriptor.");
        } catch (final NotDeployableServiceUnitException e) {
            // Expected exception
        }
        try {
            JBIDescriptorExtensionBuilder.getInstance().getDeployableServiceUnitTargetComponent(jbi);
            fail("The target component part of a deployable service unit is present in the JBI descriptor.");
        } catch (final NotDeployableServiceUnitException e) {
            // Expected exception
        }
    }

    /**
     * <p>
     * Test the goal 'jbi-package' about remote WSDL imports that must be not downloaded.
     * </p>
     */
    @Test
    public void testPackageServiceUnitWithUpdateNotDownloadingRemoteWSDLImports() throws Exception {

        // First, we generate the service unit JBI archive to configure
        final File serviceUnitPomFile = new File(ServiceUnitWithUpdateNotDownloadingRemoteWsdlImports.SRC_HOME,
                "pom.xml");
        final JBIPackageMojo packageMojo = this.getPackageMojo(serviceUnitPomFile);

        packageMojo.execute();

        // Second, we check the content of the JBI archive
        final ZipFile packagedSuFile = new ZipFile(new File(
                ServiceUnitWithUpdateNotDownloadingRemoteWsdlImports.TARGET_HOME,
                ServiceUnitWithUpdateNotDownloadingRemoteWsdlImports.FINAL_NAME));

        // The WSDL is present
        final ZipEntry wsdlEntry = packagedSuFile.getEntry("echo.wsdl");
        assertNotNull("The WSDL is missing in the JBI archive", wsdlEntry);

        // ... without its import as file
        final ZipEntry importEntry = packagedSuFile.getEntry("2005/05/xmlmime");
        assertNull("The WSDL import is packaged in the JBI archive", importEntry);

        // The JBI descriptor does not contain extensions of a deployable service unit because no component declared in
        // the POM
        final ZipEntry jbiEntry = packagedSuFile.getEntry(JBIDescriptorBuilder.JBI_DESCRIPTOR_RESOURCE_IN_ARCHIVE);
        assertNotNull(jbiEntry);
        final Jbi jbi = JBIDescriptorBuilder.getInstance().buildJavaJBIDescriptor(
                packagedSuFile.getInputStream(jbiEntry));
        packagedSuFile.close();
        try {
            JBIDescriptorExtensionBuilder.getInstance().getDeployableServiceUnitIndentification(jbi);
            fail("The identification part of a deployable service unit is present in the JBI descriptor.");
        } catch (final NotDeployableServiceUnitException e) {
            // Expected exception
        }
        try {
            JBIDescriptorExtensionBuilder.getInstance().getDeployableServiceUnitTargetComponent(jbi);
            fail("The target component part of a deployable service unit is present in the JBI descriptor.");
        } catch (final NotDeployableServiceUnitException e) {
            // Expected exception
        }

    }

    /**
     * <p>
     * Test the goal 'jbi-package' about a service unit with a WSDL containing French characters.
     * </p>
     */
    @Test
    public void testPackageServiceUnitWithUpdateFrenchCharacters() throws Exception {

        // First, we generate the service unit JBI archive to configure
        final File serviceUnitPomFile = new File(ServiceUnitWithUpdateFrenchCharacters.SRC_HOME,
                "pom.xml");
        final JBIPackageMojo packageMojo = this.getPackageMojo(serviceUnitPomFile);

        packageMojo.execute();

        // Second, we check the content of the JBI archive
        final ZipFile packagedSuFile = new ZipFile(new File(
                ServiceUnitWithUpdateFrenchCharacters.TARGET_HOME,
                ServiceUnitWithUpdateFrenchCharacters.FINAL_NAME));

        // The WSDL is present
        final ZipEntry wsdlEntry = packagedSuFile.getEntry("echo.wsdl");
        assertNotNull("The WSDL is missing in the JBI archive", wsdlEntry);

        // and its is parsable
        final WSDL4ComplexWsdlReader wsdlReader = WSDL4ComplexWsdlFactory.newInstance().newWSDLReader();
        final Description description = wsdlReader.read(new InputSource(packagedSuFile.getInputStream(wsdlEntry)));
        final Service svc = description.getService(ServiceUnitWithUpdateFrenchCharacters.SERVICE_NAME);
        assertEquals("Unexpected documentation", ServiceUnitWithUpdateFrenchCharacters.SERVICE_DOCUMENTATION, svc
                .getDocumentation().getContent());
        
        // The JBI descriptor does not contain extensions of a deployable service unit because no component declared in
        // the POM
        final ZipEntry jbiEntry = packagedSuFile.getEntry(JBIDescriptorBuilder.JBI_DESCRIPTOR_RESOURCE_IN_ARCHIVE);
        assertNotNull(jbiEntry);
        final Jbi jbi = JBIDescriptorBuilder.getInstance().buildJavaJBIDescriptor(
                packagedSuFile.getInputStream(jbiEntry));
        packagedSuFile.close();
        try {
            JBIDescriptorExtensionBuilder.getInstance().getDeployableServiceUnitIndentification(jbi);
            fail("The identification part of a deployable service unit is present in the JBI descriptor.");
        } catch (final NotDeployableServiceUnitException e) {
            // Expected exception
        }
        try {
            JBIDescriptorExtensionBuilder.getInstance().getDeployableServiceUnitTargetComponent(jbi);
            fail("The target component part of a deployable service unit is present in the JBI descriptor.");
        } catch (final NotDeployableServiceUnitException e) {
            // Expected exception
        }
    }

    /**
     * <p>
     * Test the goal 'jbi-package' about a simple service unit.
     * </p>
     */
    @Test
    public void testPackageServiceUnitWithUpdateSimpleServiceUnit() throws Exception {

        // First, we generate the service unit JBI archive to configure
        final File serviceUnitPomFile = new File(new File(GlobalUnitTestEnvironnement.PACKAGE_UNIT_TESTS_SRC_HOME,
                SimpleServiceUnitWithUpdate.ARTIFACT_ID), "pom.xml");
        final JBIPackageMojo packageMojo = this.getPackageMojo(serviceUnitPomFile);

        packageMojo.execute();

        // Second, we check the content of the JBI archive
        try (final ZipFile packagedSuFile = new ZipFile(
                new File(SimpleServiceUnitWithUpdate.TARGET_HOME, SimpleServiceUnitWithUpdate.FINAL_NAME))) {

            // The JBI descriptor does not contains extensions of a deployable service unit
            final ZipEntry jbiEntry = packagedSuFile.getEntry(JBIDescriptorBuilder.JBI_DESCRIPTOR_RESOURCE_IN_ARCHIVE);
            assertNotNull(jbiEntry);
            final Jbi jbi = JBIDescriptorBuilder.getInstance()
                    .buildJavaJBIDescriptor(packagedSuFile.getInputStream(jbiEntry));

            JBIDescriptorExtensionBuilder.getInstance().getDeployableServiceUnitIndentification(jbi);
            fail("Exception NotDeployableServiceUnitException not fired");
        } catch (final NotDeployableServiceUnitException e) {
            // Expected exception
        }
    }

    /**
     * <p>
     * Test the goal 'jbi-package' about a simple service unit, updating JBI descriptor for a standard service unit.
     * </p>
     */
    @Test
    public void testPackageServiceUnitWithUpdateForStandardServiceUnit() throws Exception {

        // First, we generate the service unit JBI archive to configure
        final File serviceUnitPomFile = new File(new File(GlobalUnitTestEnvironnement.PACKAGE_UNIT_TESTS_SRC_HOME,
                SimpleServiceUnitWithUpdate.ARTIFACT_ID), "pom.xml");
        final JBIPackageMojo packageMojo = this.getPackageMojo(serviceUnitPomFile);

        // Extension for deployable service unit have not to be generated
        packageMojo.isDeployableServiceUnit = false;
        packageMojo.execute();

        // Second, we check the content of the JBI archive
        final ZipFile packagedSuFile = new ZipFile(new File(SimpleServiceUnitWithUpdate.TARGET_HOME,
                SimpleServiceUnitWithUpdate.FINAL_NAME));

        // The JBI descriptor does not contain extensions of a deployable service unit because of
        // "isDeployableServiceUnit=false"
        final ZipEntry jbiEntry = packagedSuFile.getEntry(JBIDescriptorBuilder.JBI_DESCRIPTOR_RESOURCE_IN_ARCHIVE);
        assertNotNull(jbiEntry);
        final Jbi jbi = JBIDescriptorBuilder.getInstance().buildJavaJBIDescriptor(
                packagedSuFile.getInputStream(jbiEntry));
        packagedSuFile.close();
        try {
            JBIDescriptorExtensionBuilder.getInstance().getDeployableServiceUnitIndentification(jbi);
            fail("The identification part of a deployable service unit is present in the JBI descriptor.");
        } catch (final NotDeployableServiceUnitException e) {
            // Expected exception
        }
        try {
            JBIDescriptorExtensionBuilder.getInstance().getDeployableServiceUnitTargetComponent(jbi);
            fail("The target component part of a deployable service unit is present in the JBI descriptor.");
        } catch (final NotDeployableServiceUnitException e) {
            // Expected exception
        }
    }

    /**
     * <p>
     * Test the goal 'jbi-package' about a simple service unit (not deployable service unit) defining several JBI
     * component dependencies with the component to use and updating the JBI descriptor.
     * </p>
     * <p>
     * Expected results:
     * </p>
     * <ul>
     * <li>no error occurs,</li>
     * <li>the target component to use is set as GAV in the service unit JBI descriptor</li>
     * </ul>
     */
    @Test
    public void testPackageSimpleServiceUnitWithSeveralJBIComponentDependenciesWithComponentToUseDeclaredJBIDescriptorUpdated()
            throws Exception {

        // First, we generate the service unit JBI archive to configure
        final File serviceUnitPomFile = new File(
                SimpleServiceUnitWithSeveralJBIComponentDependenciesWithComponentToUseDeclaredJBIDescriptorUpdated.SRC_HOME,
                "pom.xml");
        final JBIPackageMojo packageMojo = this.getPackageMojo(serviceUnitPomFile);
        packageMojo.artifactJar = new File("Does not exist");

        packageMojo.execute();

        // Second, we check the content of the JBI archive
        try (final ZipFile packagedSuFile = new ZipFile(new File(
                SimpleServiceUnitWithSeveralJBIComponentDependenciesWithComponentToUseDeclaredJBIDescriptorUpdated.TARGET_HOME,
                SimpleServiceUnitWithSeveralJBIComponentDependenciesWithComponentToUseDeclaredJBIDescriptorUpdated.FINAL_NAME))) {

            // The JBI descriptor must contain the extension about the target component to use as GAV
            final ZipEntry jbiEntry = packagedSuFile.getEntry(JBIDescriptorBuilder.JBI_DESCRIPTOR_RESOURCE_IN_ARCHIVE);
            assertNotNull(jbiEntry);
            final Jbi jbi = JBIDescriptorBuilder.getInstance()
                    .buildJavaJBIDescriptor(packagedSuFile.getInputStream(jbiEntry));
            assertEquals(
                    SimpleServiceUnitWithSeveralJBIComponentDependenciesWithComponentToUseDeclaredJBIDescriptorUpdated.COMPONENT_GROUP_ID
                            + ":"
                            + SimpleServiceUnitWithSeveralJBIComponentDependenciesWithComponentToUseDeclaredJBIDescriptorUpdated.COMPONENT_ARTIFACT_ID,
                    JBIDescriptorExtensionBuilder.getInstance().getServiceUnitTargetComponentAsGA(jbi));
        }
    }

    /**
     * <p>
     * Test the goal 'jbi-package' about a simple service unit (not deployable service unit) defining only one JBI
     * component dependency and updating the JBI descriptor.
     * </p>
     * <p>
     * Expected results:
     * </p>
     * <ul>
     * <li>no error occurs,</li>
     * <li>the target component to use is set as GAV in the service unit JBI descriptor</li>
     * </ul>
     */
    @Test
    public void testPackageSimpleServiceUnitWithOneJBIComponentDependenciesWithJBIDescriptorUpdated() throws Exception {

        // First, we generate the service unit JBI archive to configure
        final File serviceUnitPomFile = new File(SimpleServiceUnitWithUpdate.SRC_HOME, "pom.xml");
        final JBIPackageMojo packageMojo = this.getPackageMojo(serviceUnitPomFile);
        packageMojo.artifactJar = new File("Does not exist");

        packageMojo.execute();

        // Second, we check the content of the JBI archive
        try (final ZipFile packagedSuFile = new ZipFile(
                new File(SimpleServiceUnitWithUpdate.TARGET_HOME, SimpleServiceUnitWithUpdate.FINAL_NAME))) {

            // The JBI descriptor must contain the extension about the target component to use as GAV
            final ZipEntry jbiEntry = packagedSuFile.getEntry(JBIDescriptorBuilder.JBI_DESCRIPTOR_RESOURCE_IN_ARCHIVE);
            assertNotNull(jbiEntry);
            final Jbi jbi = JBIDescriptorBuilder.getInstance()
                    .buildJavaJBIDescriptor(packagedSuFile.getInputStream(jbiEntry));
            assertEquals(
                    SimpleServiceUnitWithUpdate.COMPONENT_GROUP_ID + ":"
                            + SimpleServiceUnitWithUpdate.COMPONENT_ARTIFACT_ID,
                    JBIDescriptorExtensionBuilder.getInstance().getServiceUnitTargetComponentAsGA(jbi));
        }
    }

    /**
     * <p>
     * Test the goal 'jbi-package' about a SA embedding a SU that does not set a description in its POM. The SA JBI
     * descriptor is updated during the packaging
     * </p>
     */
    @Test
    public void testPackageServiceAssemblyWithUpdateWithoutDescriptionInServiceUnitPomFile() throws Exception {

        // First, we generate the service assembly JBI archive to configure
        final File serviceAssemblyPomFile = new File(
                ServiceAssemblyWithUpdateWithoutDescriptionInServiceUnitPomFile.SRC_HOME, "pom.xml");
        final JBIPackageMojo packageMojo = this.getPackageMojo(serviceAssemblyPomFile);

        packageMojo.execute();

        // Second, we check the content of the JBI archive
        final ZipFile packagedSaFile = new ZipFile(new File(
                ServiceAssemblyWithUpdateWithoutDescriptionInServiceUnitPomFile.TARGET_HOME,
                ServiceAssemblyWithUpdateWithoutDescriptionInServiceUnitPomFile.FINAL_NAME));

        final ZipEntry jbiEntry = packagedSaFile.getEntry(JBIDescriptorBuilder.JBI_DESCRIPTOR_RESOURCE_IN_ARCHIVE);
        assertNotNull("The JBI descriptor is missing in the packaged JBI SA", jbiEntry);
        final Jbi jbiDescriptor = JBIDescriptorBuilder.getInstance().buildJavaJBIDescriptor(
                packagedSaFile.getInputStream(jbiEntry));
        packagedSaFile.close();
        assertNotNull("JBI descriptor is null", jbiDescriptor);

        final ServiceAssembly sa = jbiDescriptor.getServiceAssembly();
        assertNotNull("no service assembly section", sa);

        final List<ServiceUnit> sus = sa.getServiceUnit();
        assertNotNull("No service unit in SA", sus);
        assertEquals("UNexpected number of service unit", 1, sus.size());

        final ServiceUnit su = sus.get(0);
        final Identification identification = su.getIdentification();
        assertNotNull("Identification is missing", identification);

        final String description = identification.getDescription();
        assertNotNull("Description missing in identification", description);
        assertEquals("Unexpected default description", "", identification.getDescription());

    }

    /**
     * <p>
     * Test the goal 'jbi-package' about a simple SA embedding a simple service unit providing only one JBI component
     * dependency in its project (POM file). No component to use is specified in the JBI descriptor of the SU
     * </p>
     * <p>
     * Expected results:
     * </p>
     * <ul>
     * <li>no error occurs</li>
     * </ul>
     */
    @Test
    public void testPackageStandardServiceAssemblyWhereServiceUnitDefinesOnlyOneJBIComponentDependency()
            throws Exception {

        // First, we generate the service assembly JBI archive to configure
        final File serviceAssemblyPomFile = new File(
                ServiceAssemblyWithUpdateWithoutDescriptionInServiceUnitPomFile.SRC_HOME, "pom.xml");
        final JBIPackageMojo packageMojo = this.getPackageMojo(serviceAssemblyPomFile);
        packageMojo.artifactJar = new File("No artifact JAR");

        packageMojo.execute();

        // Second, we check the content of the JBI archive
        try (final ZipFile packagedSaFile = new ZipFile(
                new File(ServiceAssemblyWithUpdateWithoutDescriptionInServiceUnitPomFile.TARGET_HOME,
                        ServiceAssemblyWithUpdateWithoutDescriptionInServiceUnitPomFile.FINAL_NAME))) {

            // The JBI descriptor must contain the extension about the target component to use as GAV
            final ZipEntry jbiEntry = packagedSaFile.getEntry(JBIDescriptorBuilder.JBI_DESCRIPTOR_RESOURCE_IN_ARCHIVE);
            assertNotNull(jbiEntry);
            final Jbi jbi = JBIDescriptorBuilder.getInstance()
                    .buildJavaJBIDescriptor(packagedSaFile.getInputStream(jbiEntry));
            assertNotNull(jbi.getServiceAssembly());
            assertNotNull(jbi.getServiceAssembly().getServiceUnit());
            assertEquals(1, jbi.getServiceAssembly().getServiceUnit().size());
            final ServiceUnit serviceUnit = jbi.getServiceAssembly().getServiceUnit().get(0);
            assertNotNull(serviceUnit.getTarget());
            assertEquals(ServiceAssemblyWithUpdateWithoutDescriptionInServiceUnitPomFile.TARGET_COMPONENT_OF_SU,
                    serviceUnit.getTarget().getComponentName());
        }
    }

    /**
     * <p>
     * Test the goal 'jbi-package' about a simple SA embedding a simple service unit with several JBI component
     * dependencies provided in its project (POM file) and a component to use is declared.
     * </p>
     * <p>
     * Expected results:
     * </p>
     * <ul>
     * <li>no error occurs</li>
     * </ul>
     */
    @Test
    public void testPackageStandardServiceAssemblyWhereServiceUnitDefinesSeveralJBIComponentDependenciesWithComponentToUseDeclared()
            throws Exception {

        // First, we generate the service assembly JBI archive to configure
        final File serviceAssemblyPomFile = new File(
                ServiceAssemblyWithSimpleServiceUnitWithSeveralJBIComponentDependenciesWithComponentToUseDeclared.SRC_HOME,
                "pom.xml");
        final JBIPackageMojo packageMojo = this.getPackageMojo(serviceAssemblyPomFile);
        packageMojo.artifactJar = new File("No artifact JAR");

        packageMojo.execute();

        // Second, we check the content of the JBI archive
        try (final ZipFile packagedSaFile = new ZipFile(new File(
                ServiceAssemblyWithSimpleServiceUnitWithSeveralJBIComponentDependenciesWithComponentToUseDeclared.TARGET_HOME,
                ServiceAssemblyWithSimpleServiceUnitWithSeveralJBIComponentDependenciesWithComponentToUseDeclared.FINAL_NAME))) {

            // The JBI descriptor must contain the extension about the target component to use as GAV
            final ZipEntry jbiEntry = packagedSaFile.getEntry(JBIDescriptorBuilder.JBI_DESCRIPTOR_RESOURCE_IN_ARCHIVE);
            assertNotNull(jbiEntry);
            final Jbi jbi = JBIDescriptorBuilder.getInstance()
                    .buildJavaJBIDescriptor(packagedSaFile.getInputStream(jbiEntry));
            assertNotNull(jbi.getServiceAssembly());
            assertNotNull(jbi.getServiceAssembly().getServiceUnit());
            assertEquals(1, jbi.getServiceAssembly().getServiceUnit().size());
            final ServiceUnit serviceUnit = jbi.getServiceAssembly().getServiceUnit().get(0);
            assertNotNull(serviceUnit.getTarget());
            assertEquals(
                    ServiceAssemblyWithSimpleServiceUnitWithSeveralJBIComponentDependenciesWithComponentToUseDeclared.TARGET_COMPONENT_OF_SU,
                    serviceUnit.getTarget().getComponentName());
        }

    }
}
