/*
* Copyright 2000-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.jetspeed.tools.deploy;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.File;
import java.nio.channels.FileChannel;
import java.util.Enumeration;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import org.jdom.Document;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* Makes a web application Deploy-ready for Jetspeed.
*
* @author <a href="mailto:taylor@apache.org">Dain Sundstrom </a>
* @author <a href="mailto:dsundstrom@gluecode.com">David Sean Taylor </a>
* @version $Id: JetspeedDeploy.java,v 1.11 2005/03/23 22:24:36 ate Exp $
*/
public class JetspeedDeploy implements Deploy
{
public static void main(String[] args) throws Exception
{
if (args.length < 2 || args.length > 3 || args.length == 3 && !(args[0].equalsIgnoreCase("-s")))
{
System.out.println("Usage: java -jar jetspeed-deploy-tools-<version>.jar [-s] INPUT OUTPUT");
System.out.println("Options:");
System.out
.println(" -s: stripLoggers - remove commons-logging[version].jar and/or log4j[version].jar from war");
System.out.println(" (required when targetting application servers like JBoss)");
System.exit(1);
return;
}
new JetspeedDeploy(args[0], args[1], args.length == 3 ? true : false);
}
private final byte[] buffer = new byte[4096];
public JetspeedDeploy(String inputName, String outputName, boolean stripLoggers) throws Exception
{
File tempFile = null;
JarFile jin = null;
JarOutputStream jout = null;
FileChannel srcChannel = null;
FileChannel dstChannel = null;
try
{
String portletApplicationName = getPortletApplicationName(outputName);
tempFile = File.createTempFile(portletApplicationName, "");
tempFile.deleteOnExit();
jin = new JarFile(inputName);
jout = new JarOutputStream(new FileOutputStream(tempFile));
// copy over all of the files in the input war to the output
// war except for web.xml, portlet.xml, and context.xml which
// we parse for use later
Document webXml = null;
Document portletXml = null;
Document contextXml = null;
ZipEntry src;
InputStream source;
Enumeration zipEntries = jin.entries();
while (zipEntries.hasMoreElements())
{
src = (ZipEntry) zipEntries.nextElement();
source = jin.getInputStream(src);
try
{
String target = src.getName();
if ("WEB-INF/web.xml".equals(target))
{
System.out.println("Found web.xml");
webXml = parseXml(source);
}
else if ("WEB-INF/portlet.xml".equals(target))
{
System.out.println("Found WEB-INF/portlet.xml");
portletXml = parseXml(source);
}
else if ("META-INF/context.xml".equals(target))
{
System.out.println("Found META-INF/context.xml");
contextXml = parseXml(source);
}
else
{
if ( stripLoggers && target.endsWith(".jar") &&
(target.startsWith("WEB-INF/lib/commons-logging") || target.startsWith("WEB-INF/lib/log4j")))
{
System.out.println("Stripping logger "+target);
continue;
}
addFile(target, source, jout);
}
}
finally
{
source.close();
}
}
if (webXml == null)
{
throw new IllegalArgumentException("WEB-INF/web.xml");
}
if (portletXml == null)
{
throw new IllegalArgumentException("WEB-INF/portlet.xml");
}
JetspeedWebApplicationRewriter webRewriter = new JetspeedWebApplicationRewriter(webXml,
portletApplicationName);
webRewriter.processWebXML();
JetspeedContextRewriter contextRewriter = new JetspeedContextRewriter(contextXml, portletApplicationName);
contextRewriter.processContextXML();
// write the web.xml, portlet.xml, and context.xml files
addFile("WEB-INF/web.xml", webXml, jout);
addFile("WEB-INF/portlet.xml", portletXml, jout);
addFile("META-INF/context.xml", contextXml, jout);
if (webRewriter.isPortletTaglibAdded())
{
System.out.println("Attempting to add portlet.tld to war...");
InputStream is = this.getClass().getResourceAsStream("/org/apache/jetspeed/tools/deploy/portlet.tld");
if (is == null)
{
System.out.println("Failed to find portlet.tld in classpath");
}
else
{
System.out.println("Adding portlet.tld to war...");
try
{
addFile("WEB-INF/tld/portlet.tld", is, jout);
}
finally
{
is.close();
}
}
}
jout.close();
jin.close();
jin = null;
jout = null;
System.out.println("Creating war " + outputName + " ...");
System.out.flush();
// Now copy the new war to its destination
srcChannel = new FileInputStream(tempFile).getChannel();
dstChannel = new FileOutputStream(outputName).getChannel();
dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
srcChannel.close();
srcChannel = null;
dstChannel.close();
dstChannel = null;
tempFile.delete();
tempFile = null;
System.out.println("War " + outputName + " created");
System.out.flush();
}
finally
{
if (srcChannel != null && srcChannel.isOpen())
{
try
{
srcChannel.close();
}
catch (IOException e1)
{
// ignore
}
}
if (dstChannel != null && dstChannel.isOpen())
{
try
{
dstChannel.close();
}
catch (IOException e1)
{
// ignore
}
}
if (jin != null)
{
try
{
jin.close();
jin = null;
}
catch (IOException e1)
{
// ignore
}
}
if (jout != null)
{
try
{
jout.close();
jout = null;
}
catch (IOException e1)
{
// ignore
}
}
if (tempFile != null && tempFile.exists())
{
tempFile.delete();
}
}
}
protected Document parseXml(InputStream source) throws Exception
{
// Parse using the local dtds instead of remote dtds. This
// allows to deploy the application offline
SAXBuilder saxBuilder = new SAXBuilder();
saxBuilder.setEntityResolver(new EntityResolver()
{
public InputSource resolveEntity(java.lang.String publicId, java.lang.String systemId) throws SAXException,
java.io.IOException
{
if (systemId.equals("http://java.sun.com/dtd/web-app_2_3.dtd"))
{
return new InputSource(getClass().getResourceAsStream("web-app_2_3.dtd"));
}
return null;
}
});
Document document = saxBuilder.build(source);
return document;
}
protected void addFile(String path, InputStream source, JarOutputStream jos) throws IOException
{
jos.putNextEntry(new ZipEntry(path));
try
{
int count;
while ((count = source.read(buffer)) > 0)
{
jos.write(buffer, 0, count);
}
}
finally
{
jos.closeEntry();
}
}
protected void addFile(String path, Document source, JarOutputStream jos) throws IOException
{
if (source != null)
{
jos.putNextEntry(new ZipEntry(path));
XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
try
{
xmlOutputter.output(source, jos);
}
finally
{
jos.closeEntry();
}
}
}
protected String getPortletApplicationName(String path)
{
File file = new File(path);
String name = file.getName();
String portletApplicationName = name;
int index = name.lastIndexOf(".");
if (index > -1)
{
portletApplicationName = name.substring(0, index);
}
return portletApplicationName;
}
}