/*
* 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();
}
}
}
}