All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.objectweb.petals.plugin.jbiplugin.JBIPackageMojo Maven / Gradle / Ivy

/**
 * PETALS - PETALS Services Platform.
 * Copyright (c) 2005 EBM Websourcing, http://www.ebmwebsourcing.com/
 *
 * This 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 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 library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * -------------------------------------------------------------------------
 * $Id: PackageAssemblyMojo.java 16:56:43 ddesjardins $
 * -------------------------------------------------------------------------
 */

package org.objectweb.petals.plugin.jbiplugin;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
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.io.StringWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipOutputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingException;
import org.codehaus.plexus.util.interpolation.ObjectBasedValueSource;
import org.codehaus.plexus.util.interpolation.RegexBasedInterpolator;
import org.objectweb.petals.jbi.descriptor.Identification;
import org.objectweb.petals.jbi.descriptor.JBIDescriptor;
import org.objectweb.petals.jbi.descriptor.JBIDescriptorBuilder;
import org.objectweb.petals.jbi.descriptor.JBIDescriptorException;
import org.objectweb.petals.jbi.descriptor.ServiceUnit;
import org.objectweb.petals.plugin.jbiplugin.util.PropertiesInterpolationValueSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * Make a JBI Archive of a project
 * 
 * @goal jbi-package
 * @description Make a JBI archive from a JBI component project
 * @requiresDependencyResolution runtime
 * 
 * @author ddesjardins - eBMWebsourcing
 * @author cdeneux - Capgemini Sud
 */
public class JBIPackageMojo extends JBIAbstractMojo {

    /**
     * Component Jar
     * 
     * @parameter expression="${project.build.directory}/${project.artifactId}-${project.version}.jar"
     * @editable true
     * @required
     * @description Name of the generated component Jar
     */
    protected File componentJar;

    /**
     * Update JBI XML file
     * 
     * @parameter expression="true"
     * @editable true
     * @required
     * @description Boolean to force the update of the JBI XML file to add all
     *              the dependencies of the archive
     */
    protected boolean updateJBIXml;

    /**
     * Sets the mapping pattern for all SU file names included in this service
     * assembly.
     * 
     * @parameter expression="$${artifactId}-$${version}.$${extension}"
     * @editable true
     * @required
     * @description Sets the mapping pattern for all SU file names included in
     *              this service assembly. Example of usage (caution to the
     *              usage of "$" and "$$"):
     *              ${artifactId}.${extension}
     */
    protected String serviceUnitFileNameMapping;

    /**
     * If the JBI update is activated, sets the mapping pattern for all SU and
     * SA names included in this service assembly.
     * 
     * @parameter expression="$${artifactId}-$${version}"
     * @editable true
     * @required
     * @description If the JBI update is activated, sets the mapping pattern for
     *              all SU and SA names included in this service assembly.
     *              Example of usage (caution to the usage of "$" and "$$"):
     *              $${artifactId}
     */
    protected String serviceUnitNameMapping;

    /**
     * If the JBI update is activated, sets the mapping pattern for all SU and
     * SA names included in this service assembly.
     * 
     * @parameter expression="$${artifactId}-$${version}"
     * @editable true
     * @required
     * @description If the JBI update is activated, sets the mapping pattern for
     *              artifact JBI name.
     *              Example of usage (caution to the usage of "$" and "$$"):
     *              $${artifactId}
     */
    protected String artifactNameMapping;

    /**
     * List of entry to exclude (comma separated values)
     * 
     * @parameter expression="foo"
     * @required
     * @editable true
     * @description List of entry to exclude (comma separated values)
     */
    protected String toExcludes;

    /**
     * Set of entries in the zip
     */
    private Set entries = new HashSet();

    /**
     * List of entries to exclude
     */
    private Set entriesToExclude = new HashSet();

    /**
     * Recurse a directory to add its content to a zip file. If updateJBIXml
     * file is true do not add the jbi.xml file to the archive (it will be
     * updated and added later).
     * 
     * @param zipOutputStream
     *            zip file
     * @param directory
     *            directory to recurse
     * @param entryDirectoryName
     *            directory to put the content in the zip
     * @throws Exception
     */
    private void recurseDirectory(ZipOutputStream zipOutputStream,
            File directory, String entryDirectoryName) throws IOException {
        for (File file : directory.listFiles()) {
            if (file.isFile()) {
                if (!updateJBIXml
                        || (updateJBIXml && !file.getName().equals("jbi.xml"))) {

                    this.info("     " + file.getName()
                            + " added to JBI archive");

                    // Use "/" instead of File.separator to have a directory
                    // level in the ZIP file.
                    this.addFile(zipOutputStream, new FileInputStream(file),
                            (entryDirectoryName.equals("") ? ""
                                    : entryDirectoryName + "/")
                                    + file.getName());

                }
            } else {
                this.debug("File entry: " + file.getName());
                // Avoid to add the .svn and CVS directories and add directory
                // to zip.
                if (!file.getName().startsWith(".")
                        && !file.getName().toUpperCase(Locale.getDefault())
                                .equals("CVS")) {
                    // Use "/" instead of File.separator to have a directory
                    // level in the ZIP file
                    recurseDirectory(zipOutputStream, file, (entryDirectoryName
                            .equals("") ? "" : entryDirectoryName + "/")
                            + file.getName());
                }
            }
        }
    }

    /**
     * Extract the list of jar to exclude from the archive
     * 
     */
    private void extractExcludeValues() {
        // We remove the space
        if (!"foo".equals(toExcludes)) {
            toExcludes = toExcludes.replace(" ", "");
            for (String jar : toExcludes.split(",")) {
                entriesToExclude.add(jar);
            }
        }
    }

    /**
     * Execute the plugin
     */
    @Override
    public void executeMojo() throws MojoExecutionException, MojoFailureException {
        project.getArtifact().setFile(
                new File(outputDirectory + File.separator + jbiName + ".zip"));

        // Extract the exclude values
        extractExcludeValues();

        if (outputDirectory.exists()) {
            if (project.getArtifact().getFile().exists()) {
                project.getArtifact().getFile().delete();
            }
        } else {
            outputDirectory.mkdirs();
        }

        if (jbiDirectory.exists()) {
            if (PACKAGING_COMPONENT.equals(project.getPackaging())) {
                packageComponent();
            } else if (PACKAGING_SU.equals(project.getPackaging())) {
                packageServiceUnit();
            } else if (PACKAGING_SA.equals(project.getPackaging())) {
                packageServiceAssembly();
            } else if (PACKAGING_SL.equals(project.getPackaging())) {
                packageSharedLibrary();
            }
        } else {
            this.error("JBI directory [" + jbiDirectory + "] does not exist.");
            throw new MojoFailureException("JBI directory [" + jbiDirectory
                    + "] does not exist.");
        }
    }

    /**
     * Create a service-unit package.
     */
    private void packageComponent() throws MojoExecutionException {
        try {
            this.info("Start building JBI component archive "
                    + project.getArtifact().getFile().getAbsolutePath());

            // Add the jbi files
            ZipOutputStream zipOutputStream = new ZipOutputStream(
                    new FileOutputStream(project.getArtifact().getFile()));
            recurseDirectory(zipOutputStream, jbiDirectory, "");
            zipOutputStream.flush();

            // Add the component jar
            addComponentResources(zipOutputStream);

            // Add the component dependencies
            addDependencies(zipOutputStream);

            if (updateJBIXml) {
                // Update the JBI XML file
                updateComponentJBIXmlFile(zipOutputStream);
            }

            zipOutputStream.flush();
            zipOutputStream.close();

            this.info("JBI component archive building done.");
        } catch (IOException e) {
            throw new MojoExecutionException(e.getLocalizedMessage(), e);
        }
    }

    /**
     * Create a service-unit package.
     */
    private void packageServiceUnit() throws MojoExecutionException {
        try {
            this.info("Start building JBI service-unit archive "
                    + project.getArtifact().getFile().getAbsolutePath());

            // JBI Archive creation
            ZipOutputStream zipOutputStream = new ZipOutputStream(
                    new FileOutputStream(project.getArtifact().getFile()));

            // Add the jbi files
            recurseDirectory(zipOutputStream, jbiDirectory, "");
            zipOutputStream.flush();

            // Add directly the jbi.xml descriptor
            addFile(zipOutputStream, new FileInputStream(jbiDirectory
                    + File.separator + "jbi.xml"), "META-INF/jbi.xml");

            // Add the service unit resources
            addComponentResources(zipOutputStream);

            // Add the service unit dependencies
            addDependencies(zipOutputStream);

            zipOutputStream.close();

            this.info("JBI Service unit archive building done.");

        } catch (IOException e) {
            throw new MojoExecutionException(e.getLocalizedMessage(), e);
        }
    }

    /**
     * Create a service-assembly package.
     */
    private void packageServiceAssembly() throws MojoExecutionException {

        this.info("Start building JBI service-assembly archive "
                + project.getArtifact().getFile().getAbsolutePath());

        try {

            // JBI Archive creation
            ZipOutputStream zipOutputStream = new ZipOutputStream(
                    new FileOutputStream(project.getArtifact().getFile()));

            try {

                // Load the JBI descriptor
                InputStream jbiDescriptorToUpdateInputStream = new FileInputStream(jbiDirectory
                        + File.separator + "jbi.xml");
                JBIDescriptor jbiDescriptor = JBIDescriptorBuilder.getInstance()
                        .buildDescriptor(jbiDescriptorToUpdateInputStream);
                
                if (jbiDescriptor == null) {
                    throw new MojoExecutionException("JBI Descriptor is null");
                }
                
                List serviceUnitList = new ArrayList();
                if (this.updateJBIXml) {
                    if (jbiDescriptor.getServiceAssembly() == null) {
                        throw new MojoExecutionException(
                                "No service-assembly in the JBI descriptor.");
                    }
                    if (jbiDescriptor.getServiceAssembly().getIdentification() == null) {
                        throw new MojoExecutionException(
                                "No identification in the JBI descriptor.");
                    }

                    String artifactName = evaluateFileNameMapping(
                            this.artifactNameMapping, this.project.getArtifact());
                    
                    jbiDescriptor.getServiceAssembly().getIdentification()
                            .setName(artifactName);
                    
                    jbiDescriptor.getServiceAssembly().getIdentification()
                            .setDescription(this.project.getDescription());
                    
                    jbiDescriptor.getServiceAssembly().setServiceUnits(serviceUnitList);
                }
                
                // Add the service unit dependencies files
                List dependencies = project.getDependencies();
                for (Dependency dependency : dependencies) {

                    if (PACKAGING_SU.equals(dependency.getType())) {
                        Artifact serviceUnitArtifact = this.artifactFactory
                            .createDependencyArtifact(dependency
                                    .getGroupId(), dependency
                                    .getArtifactId(), VersionRange
                                    .createFromVersionSpec(dependency
                                            .getVersion()), dependency
                                    .getType(), dependency.getClassifier(),
                                    dependency.getScope(), null, dependency
                                            .isOptional());
                        
                        this.artifactResolver.resolve(serviceUnitArtifact, this.project
                                .getRemoteArtifactRepositories(),
                                this.localRepository);
                        
                        MavenProject serviceUnitProject = this.mavenProjectBuilder
                            .buildFromRepository(serviceUnitArtifact,
                                    this.project
                                            .getRemoteArtifactRepositories(),
                                    this.localRepository);

                        String zipDependencyFileName = evaluateFileNameMapping(
                                this.serviceUnitFileNameMapping, serviceUnitArtifact);

                        if (this.updateJBIXml) {
                            
                            ServiceUnit serviceUnit = new ServiceUnit();
                            Identification identification = new Identification();
                            identification.setName(evaluateFileNameMapping(
                                    this.serviceUnitNameMapping, serviceUnitProject
                                            .getArtifact()));
                            
                            identification.setDescription(serviceUnitProject.getDescription());
                            serviceUnit.setIdentification(identification);
                            
                            // We find the target component name following dependencies
                            JBIDescriptor jbiComponentDescriptor = null;
                            boolean foundInServiceUnitDependencies = false;
                            List serviceUnitDependencies = serviceUnitProject.getDependencies();
                            for (Dependency serviceUnitDependency : serviceUnitDependencies) {
                                this.debug("SU dependency: " + serviceUnitDependency);
                                if (PACKAGING_COMPONENT.equals(serviceUnitDependency.getType())) {
                                    // We have found the component
                                    this.debug("Component dependency found: " + serviceUnitDependency);
                                    foundInServiceUnitDependencies = true;

                                    try {
                                        
                                        Artifact serviceUnitComponentArtifact = this.artifactFactory
                                                .createDependencyArtifact(serviceUnitDependency
                                                        .getGroupId(), serviceUnitDependency
                                                        .getArtifactId(), VersionRange
                                                        .createFromVersionSpec(serviceUnitDependency
                                                                .getVersion()), serviceUnitDependency
                                                        .getType(), serviceUnitDependency.getClassifier(),
                                                        serviceUnitDependency.getScope(), null, serviceUnitDependency
                                                                .isOptional());

                                        this.artifactResolver.resolve(serviceUnitComponentArtifact, this.project
                                                .getRemoteArtifactRepositories(),
                                                this.localRepository);

                                        jbiComponentDescriptor = this
                                            .readJbiDescriptor(serviceUnitComponentArtifact.getFile());
                                        
                                        this.debug("Component found: " + serviceUnitComponentArtifact);
                                        
                                    } catch (InvalidVersionSpecificationException e) {
                                        throw new MojoExecutionException(e
                                                .getLocalizedMessage(), e);
                                    } catch (ArtifactResolutionException e) {
                                        throw new MojoExecutionException(e
                                                .getLocalizedMessage(), e);
                                    } catch (ArtifactNotFoundException e) {
                                        throw new MojoExecutionException(e
                                                .getLocalizedMessage(), e);
                                    }
                                    
                                    break;
                                }
                            }
                            
                            if (!foundInServiceUnitDependencies) {
                                throw new MojoExecutionException("No component defined in SU as dependency.");
                            }
                            
                            this.debug("Component name: " + jbiComponentDescriptor
                                            .getComponent().getIdentification().getName());
                            serviceUnit
                                    .setTargetComponentName(jbiComponentDescriptor
                                            .getComponent().getIdentification().getName());
                            serviceUnit
                                    .setTargetArtifactsZip(zipDependencyFileName);
                            
                            serviceUnitList.add(serviceUnit);
                        }
                        
                        this.debug("SU artifact file: " + serviceUnitArtifact.getFile());
                        this.addFile(zipOutputStream, new FileInputStream(
                                serviceUnitArtifact.getFile()), zipDependencyFileName);

                        this.info("\t" + serviceUnitArtifact.getFile().getName()
                                + " added to JBI Service Assembly archive (as "
                                + zipDependencyFileName + ")");
                    }
                }
                
                InputStream jbiDescriptorInputStream;
                if (this.updateJBIXml) {
                    String jbiXml = jbiDescriptor.toXmlText();
                    this.debug("Generated JBI Descriptor:\n" + jbiXml);
                    jbiDescriptorInputStream = new ByteArrayInputStream(jbiXml
                            .getBytes());
                }
                else {
                    jbiDescriptorInputStream = new FileInputStream(jbiDirectory
                            + File.separator + "jbi.xml");
                }

                // Add the jbi.xml file
                addFile(zipOutputStream, jbiDescriptorInputStream,
                        "META-INF/jbi.xml");
                this.info("\tJBI descriptor added to JBI Service Assembly archive");

            } catch (IOException e) {
                throw new MojoExecutionException(e.getLocalizedMessage(), e);
            } catch (JBIDescriptorException e) {
                throw new MojoExecutionException(e.getLocalizedMessage(), e);
            } catch (ProjectBuildingException e) {
                throw new MojoExecutionException(e.getLocalizedMessage(), e);
            } catch (InvalidVersionSpecificationException e) {
                throw new MojoExecutionException(e.getLocalizedMessage(), e);
            } catch (Throwable e) {
                throw new MojoExecutionException(e.getLocalizedMessage(), e);
            } finally {
                try {
                    zipOutputStream.close();
                } catch (ZipException e) {
                    // This exception occurs on ZipOutputStream.close() when no
                    // entry has been added, so we ignore it
                } catch (IOException e) {
                    throw new MojoExecutionException(e.getLocalizedMessage(), e);
                }
            }

            this.info("JBI Service Assembly archive building done.");

        } catch (FileNotFoundException e) {
            throw new MojoExecutionException(e.getLocalizedMessage(), e);
        }
    }

    /**
     * Create a shared-library package.
     */
    private void packageSharedLibrary() throws MojoExecutionException {
        try {
            this.info("Start building JBI shared-library archive "
                    + project.getArtifact().getFile().getAbsolutePath());

            // JBI Archive creation
            ZipOutputStream zipOutputStream = new ZipOutputStream(
                    new FileOutputStream(project.getArtifact().getFile()));

            // Add the jbi files
            recurseDirectory(zipOutputStream, jbiDirectory, "");
            zipOutputStream.flush();

            // Add the shared-library component jar
            addComponentResources(zipOutputStream);

            // Add the shared library dependencies
            addDependencies(zipOutputStream);

            if (updateJBIXml) {
                // Update the JBI XML file
                updateSharedLibraryJBIXmlFile(zipOutputStream);
            }

            zipOutputStream.close();

            this.info("JBI Shared library archive building done.");

        } catch (IOException e) {
            throw new MojoExecutionException(e.getLocalizedMessage(), e);
        }
    }

    /**
     * Add the Java resources (classes and resources) in the JBI archive.
     * 
     * @param zipOutputStream
     *            The JBI archive
     */
    private void addComponentResources(ZipOutputStream zipOutputStream)
            throws IOException {
        if (componentJar.exists()) {
            zipFile(zipOutputStream, componentJar);
        }
    }

    /**
     * Add dependencies in the JBI archive.
     * 
     * @param zipOutputStream
     *            The JBI archive
     */
    private void addDependencies(ZipOutputStream zipOutputStream)
            throws IOException {

        Set artifacts = project.getArtifacts();
        for (Artifact artifact : artifacts) {

            String artifactName = artifact.getArtifactId() + "-"
                    + artifact.getVersion() + ".jar";

            boolean dependencyToInclude = false;

            if (artifact.getScope() == null
                    || (artifact.getScope() != null
                            && !artifact.getScope().equals("test") && !artifact
                            .getScope().equals("provided"))) {

                dependencyToInclude = true;

            }
            if (dependencyToInclude && !entriesToExclude.contains(artifactName)) {
                zipFile(zipOutputStream, artifact.getFile());
            }
        }
    }

    /**
     * Clone a set of String
     * 
     * @param setToClone
     * @return
     */
    private Set cloneSet(Set setToClone) {
        Set outSet = new HashSet();
        for (String string : setToClone) {
            outSet.add(string);
        }
        return outSet;
    }

    /**
     * Update the JBI xml file to added all the dependencies of a component JBI
     * archive.
     * 
     * @param zipOutputStream
     * @throws MojoExecutionException
     */
    private void updateComponentJBIXmlFile(ZipOutputStream zipOutputStream)
            throws MojoExecutionException {
        InputStream inputStream = null;
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory
                    .newInstance();
            factory.setNamespaceAware(true);

            DocumentBuilder builder = factory.newDocumentBuilder();

            Document document = builder.parse(new FileInputStream(new File(
                    jbiDirectory + File.separator + "jbi.xml")));

            NodeList list = document.getElementsByTagNameNS(
                    JBIDescriptorBuilder.NAMESPACE_JBI, "jbi");
            if (list.getLength() == 0) {
                throw new Exception("No jbi node found");
            } else if (list.getLength() != 1) {
                throw new Exception("Impossible to have several jbi node");
            }
            Element element = (Element) list.item(0);

            // Check the component-class-path
            Element compoClassPath = (Element) element.getElementsByTagNameNS(
                    JBIDescriptorBuilder.NAMESPACE_JBI, "component-class-path")
                    .item(0);
            this.updateClasspathBlock(compoClassPath, document);
            // add the main component-jar in the component-class-path
            Element mainElem = document.createElementNS(
                    JBIDescriptorBuilder.NAMESPACE_JBI, "path-element");
            mainElem.setPrefix(document
                    .lookupPrefix(JBIDescriptorBuilder.NAMESPACE_JBI));
            mainElem.setTextContent(componentJar.getName());
            compoClassPath.appendChild(mainElem);

            // Check the bootstrap-class-path
            Element bootClassPath = (Element) element.getElementsByTagNameNS(
                    JBIDescriptorBuilder.NAMESPACE_JBI, "bootstrap-class-path")
                    .item(0);
            this.updateClasspathBlock(bootClassPath, document);
            // add the main component-jar in the component-class-path
            bootClassPath.appendChild(mainElem);

            document.normalize();
            Source source = new DOMSource(document);
            StringWriter out = new StringWriter();
            Result resultStream = new StreamResult(out);
            TransformerFactory tFactory = TransformerFactory.newInstance();
            Transformer transformer;
            transformer = tFactory.newTransformer();
            transformer.transform(source, resultStream);

            inputStream = new ByteArrayInputStream(out.toString().getBytes());

            // Add the jbi.xml entry
            this.addFile(zipOutputStream, inputStream, "META-INF/jbi.xml");

        } catch (Exception e) {
            throw new MojoExecutionException(
                    "Problem while updating jbi.xml file. We add it like it is",
                    e);

        }
    }

    /**
     * Update the JBI xml file to added all the dependencies of a shared library
     * JBI archive.
     * 
     * @param zipOutputStream
     * @throws MojoExecutionException
     */
    private void updateSharedLibraryJBIXmlFile(ZipOutputStream zipOutputStream)
            throws MojoExecutionException {
        InputStream inputStream = null;
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory
                    .newInstance();
            factory.setNamespaceAware(true);

            DocumentBuilder builder = factory.newDocumentBuilder();

            Document document = builder.parse(new FileInputStream(new File(
                    jbiDirectory + File.separator + "jbi.xml")));

            NodeList list = document.getElementsByTagNameNS(
                    JBIDescriptorBuilder.NAMESPACE_JBI, "jbi");
            if (list.getLength() == 0) {
                throw new Exception("No jbi node found");
            } else if (list.getLength() != 1) {
                throw new Exception("Impossible to have several jbi node");
            }
            Element element = (Element) list.item(0);

            // Check the shared-library-class-path
            Element sharedLibraryClassPath = (Element) element
                    .getElementsByTagNameNS(JBIDescriptorBuilder.NAMESPACE_JBI,
                            "shared-library-class-path").item(0);
            this.updateClasspathBlock(sharedLibraryClassPath, document);
            // add the main shared-library jar in the shared-library-class-path
            Element mainElem = document.createElementNS(
                    JBIDescriptorBuilder.NAMESPACE_JBI, "path-element");
            mainElem.setPrefix(document
                    .lookupPrefix(JBIDescriptorBuilder.NAMESPACE_JBI));
            mainElem.setTextContent(componentJar.getName());
            sharedLibraryClassPath.appendChild(mainElem);

            document.normalize();
            Source source = new DOMSource(document);
            StringWriter out = new StringWriter();
            Result resultStream = new StreamResult(out);
            TransformerFactory tFactory = TransformerFactory.newInstance();
            Transformer transformer;
            transformer = tFactory.newTransformer();
            transformer.transform(source, resultStream);

            inputStream = new ByteArrayInputStream(out.toString().getBytes());

            // Add the jbi.xml entry
            this.addFile(zipOutputStream, inputStream, "META-INF/jbi.xml");

        } catch (Exception e) {
            throw new MojoExecutionException(
                    "Problem while updating jbi.xml file. We add it like it is",
                    e);
        }
    }

    private void updateClasspathBlock(Element classpathElement,
            Document document) {
        NodeList bootElems = classpathElement.getElementsByTagNameNS(
                JBIDescriptorBuilder.NAMESPACE_JBI, "path-element");
        Set elemsToAdd = cloneSet(entries);
        for (int i = 0; i < bootElems.getLength(); i++) {
            Element elem = (Element) bootElems.item(i);
            elem.setPrefix(document
                    .lookupPrefix(JBIDescriptorBuilder.NAMESPACE_JBI));
            if (elemsToAdd.contains(elem.getTextContent())) {
                elemsToAdd.remove(elem.getTextContent());
            }
        }
        if (elemsToAdd.size() > 0) {
            // We need to add the missing elements
            for (String jar : elemsToAdd) {
                Element elem = document.createElementNS(
                        JBIDescriptorBuilder.NAMESPACE_JBI, "path-element");
                elem.setPrefix(document
                        .lookupPrefix(JBIDescriptorBuilder.NAMESPACE_JBI));
                elem.setTextContent(jar);
                classpathElement.appendChild(elem);
            }
        }
    }

    /**
     * Add a file to a zip stream, if not alreadey zipped
     * 
     * @param zipOutputStream
     * @param file
     */
    private void zipFile(ZipOutputStream zipOutputStream, File file) {

        try {
            if (!entries.contains(file.getName())) {
                addFile(zipOutputStream, new FileInputStream(file), file
                        .getName());

                entries.add(file.getName());

                this.info("\t" + file.getName() + " added to JBI archive");
            }
        } catch (IOException e) {
            entriesToExclude.add(file.getName());
            this.error("Problem while adding " + file.getName()
                    + " to JBI archive");
        }
    }

    /**
     * Add a file to a zip stream, without checking if alreadey zipped.
     * 
     * @param zipOutputStream
     * @parma inputStream
     * @param zipEntryName
     */
    private void addFile(ZipOutputStream zipOutputStream,
            InputStream inputStream, final String zipEntryName)
            throws IOException {
        DataInputStream dis = new DataInputStream(inputStream);
        try {
            byte[] content = new byte[dis.available()];
            dis.readFully(content);

            ZipEntry zipEntry = new ZipEntry(zipEntryName);
            zipOutputStream.putNextEntry(zipEntry);
            zipOutputStream.write(content);
            zipOutputStream.closeEntry();
        } finally {
            dis.close();

        }
    }

    /**
     * Evaluates Filename Mapping (source code copied from
     * maven-assembly-plugin)
     * 
     * @param expression
     * @param artifact
     * @return expression
     * @throws AssemblyFormattingException
     * @throws org.apache.maven.plugin.MojoExecutionException
     */
    private String evaluateFileNameMapping(String expression, Artifact artifact) {
        String value = expression.replaceAll("\\$\\{dollarSign\\}", "\\$");

        // FIXME: This is BAD! Accessors SHOULD NOT change the behavior of the
        // object.
        artifact.isSnapshot();

        RegexBasedInterpolator interpolator = new RegexBasedInterpolator();

        interpolator.addValueSource(new ObjectBasedValueSource(artifact));
        interpolator.addValueSource(new ObjectBasedValueSource(artifact
                .getArtifactHandler()));

        Properties classifierMask = new Properties();
        classifierMask.setProperty("classifier", "");

        interpolator.addValueSource(new PropertiesInterpolationValueSource(
                classifierMask));

        value = interpolator.interpolate(value, "__artifact");

        return value;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy