com.asual.summer.bundle.BundleDescriptorMojo.java Source code

Java tutorial

Introduction

Here is the source code for com.asual.summer.bundle.BundleDescriptorMojo.java

Source

/*
 * 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 com.asual.summer.bundle;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.jar.JarInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.commons.io.FileUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.Descriptor;
import org.eclipse.jetty.webapp.FragmentConfiguration;
import org.eclipse.jetty.webapp.FragmentDescriptor;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.webapp.WebXmlConfiguration;
import org.eclipse.jetty.xml.XmlParser.Node;

/**
 * @goal descriptor
 * @phase package
 * @requiresProject
 * @requiresDependencyResolution runtime
 * 
 * @author Rostislav Hristov
 * 
 */
public class BundleDescriptorMojo extends AbstractMojo {

    /**
     * @parameter default-value="${project.artifacts}"
     * @readonly
     */
    private Collection<Artifact> artifacts;

    /**
     * @parameter expression="${basedir}"
     * @readonly
     */
    private File basedir;

    /**
     * @parameter expression="${project.build.directory}"
     * @readonly
     */
    private File buildDirectory;

    /**
     * @parameter expression="${project.build.finalName}"
     * @readonly
     */
    private String finalName;

    public void execute() throws MojoExecutionException {

        try {

            String webXml = "WEB-INF/web.xml";
            File warDir = new File(buildDirectory, finalName);
            File warFile = new File(buildDirectory, finalName + ".war");
            File webXmlFile = new File(warDir, webXml);
            FileUtils.copyFile(new File(basedir, "src/main/webapp/" + webXml), webXmlFile);

            Configuration[] configurations = new Configuration[] { new WebXmlConfiguration(),
                    new FragmentConfiguration() };
            WebAppContext context = new WebAppContext();
            context.setDefaultsDescriptor(null);
            context.setDescriptor(webXmlFile.getAbsolutePath());
            context.setConfigurations(configurations);

            for (Artifact artifact : artifacts) {
                JarInputStream in = new JarInputStream(new FileInputStream(artifact.getFile()));
                while (true) {
                    ZipEntry entry = in.getNextEntry();
                    if (entry != null) {
                        if ("META-INF/web-fragment.xml".equals(entry.getName())) {
                            Resource fragment = Resource
                                    .newResource("file:" + artifact.getFile().getAbsolutePath());
                            context.getMetaData().addFragment(fragment, Resource
                                    .newResource("jar:" + fragment.getURL() + "!/META-INF/web-fragment.xml"));
                            context.getMetaData().addWebInfJar(fragment);
                        }
                    } else {
                        break;
                    }
                }
                in.close();
            }

            for (int i = 0; i < configurations.length; i++) {
                configurations[i].preConfigure(context);
            }

            for (int i = 0; i < configurations.length; i++) {
                configurations[i].configure(context);
            }

            for (int i = 0; i < configurations.length; i++) {
                configurations[i].postConfigure(context);
            }

            Descriptor descriptor = context.getMetaData().getWebXml();
            Node root = descriptor.getRoot();

            List<Object> nodes = new ArrayList<Object>();
            List<FragmentDescriptor> fragmentDescriptors = context.getMetaData().getOrderedFragments();
            for (FragmentDescriptor fd : fragmentDescriptors) {
                for (int i = 0; i < fd.getRoot().size(); i++) {
                    Object el = fd.getRoot().get(i);
                    if (el instanceof Node && ((Node) el).getTag().matches("^name|ordering$")) {
                        continue;
                    }
                    nodes.add(el);
                }
            }
            root.addAll(nodes);

            BufferedWriter writer = new BufferedWriter(new FileWriter(new File(warDir, webXml)));
            writer.write(root.toString());
            writer.close();

            ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(warFile));
            zip(warDir, warDir, zos);
            zos.close();

        } catch (Exception e) {
            getLog().error(e.getMessage(), e);
            throw new MojoExecutionException(e.getMessage(), e);
        }
    }

    private void zip(File directory, File base, ZipOutputStream zos) throws IOException {
        File[] files = directory.listFiles();
        byte[] buffer = new byte[8192];
        int read = 0;
        for (int i = 0, n = files.length; i < n; i++) {
            String name = files[i].getPath().replace(File.separatorChar, '/')
                    .substring(base.getPath().length() + 1);
            if (files[i].isDirectory()) {
                if (!name.endsWith("/")) {
                    name = name + "/";
                }
                ZipEntry entry = new ZipEntry(name);
                zos.putNextEntry(entry);
                zip(files[i], base, zos);
            } else {
                FileInputStream in = new FileInputStream(files[i]);
                ZipEntry entry = new ZipEntry(name);
                zos.putNextEntry(entry);
                while (-1 != (read = in.read(buffer))) {
                    zos.write(buffer, 0, read);
                }
                in.close();
            }
        }
    }

}