/* * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. * * 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. * * Contributors: * bstefanescu, jcarsique */ package org.nuxeo.runtime.deployment.preprocessor; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuxeo.common.utils.ZipUtils; import org.nuxeo.launcher.config.ConfigurationException; import org.nuxeo.launcher.config.ConfigurationGenerator; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> */ public class PackZip { private static Log log = LogFactory.getLog(PackZip.class); public static final String ORDER_PREPROCESSING = "preprocessing"; public static final String ORDER_PACKAGING = "packaging"; protected File nuxeoEar; protected File deployerJar; protected File deployDir; protected File jbossLib; protected File dsFile; protected File target; public PackZip(File nuxeoEar, File target) { if (!nuxeoEar.isDirectory()) { throw new IllegalArgumentException("Invalid build - no exploded nuxeo.ear found at " + nuxeoEar.getAbsolutePath()); } if (!target.isDirectory()) { throw new IllegalArgumentException("Invalid configuration - no target directory found at " + nuxeoEar.getAbsolutePath()); } this.nuxeoEar = nuxeoEar; this.target = target; this.deployDir = nuxeoEar.getParentFile(); this.jbossLib = new File(deployDir.getParentFile(), "lib"); this.dsFile = new File(deployDir, "nuxeo-ds.xml"); File deployers = new File(deployDir.getParentFile(), "deployers"); String[] names = deployers.list(); if (names == null) { throw new IllegalArgumentException( "Invalid nuxeo.ear location - no nuxeo jboss deployer JAR found in deployers directory"); } for (String name : names) { if (name.startsWith("nuxeo-jboss-deployer") && name.endsWith(".jar")) { deployerJar = new File(deployers, name); } } if (deployerJar == null) { throw new IllegalArgumentException( "Invalid build - no nuxeo jboss deployer JAR found in deployers directory"); } } protected void executePreprocessing() throws ConfigurationException, IOException { // configure from templates new ConfigurationGenerator().run(); // run preprocessor runPreprocessor(); } protected void executePackaging() throws IOException, SAXException, ParserConfigurationException { // move non ejb jars to nuxeo.ear/lib moveNonEjbsToLib(nuxeoEar); // replace nuxeo-structure.xml with nuxeo-structure-zip.xml replaceStructureFile(); // move libs in jboss/lib to nuxeo.ear/lib moveJarsFromJbossLib(); // move nuxeo jboss deployer to nuxeo.ear/lib FileUtils.moveFile(deployerJar, new File(nuxeoEar, "lib" + File.separator + deployerJar.getName())); // zip the ear into target directory ZipUtils.zip(nuxeoEar.listFiles(), new File(target, "nuxeo.ear")); // copy nuxeo-ds.xml to target dir FileUtils.copyFileToDirectory(dsFile, target); } public void execute(String order) throws ConfigurationException, IOException, ParserConfigurationException, SAXException { if (ORDER_PREPROCESSING.equals(order) || StringUtils.isBlank(order)) { executePreprocessing(); } if (ORDER_PACKAGING.equals(order) || StringUtils.isBlank(order)) { executePackaging(); } if (!(ORDER_PREPROCESSING.equals(order) || StringUtils.isBlank(order) || ORDER_PACKAGING.equals(order))) { fail("Order param should be " + ORDER_PREPROCESSING + " or " + ORDER_PACKAGING); } } protected void runPreprocessor() throws IOException { DeploymentPreprocessor.main(new String[] { nuxeoEar.getAbsolutePath() }); } protected void replaceStructureFile() throws IOException { File oldf = new File(nuxeoEar, "META-INF" + File.separator + "nuxeo-structure.xml"); File newf = new File(nuxeoEar, "META-INF" + File.separator + "nuxeo-structure-zip.xml"); if (oldf.exists() && !FileUtils.deleteQuietly(oldf)) { log.warn("Cannot delete " + oldf.getName() + ", it may not replace it with the new file."); } FileUtils.moveFile(newf, oldf); } protected void moveJarsFromJbossLib() { } protected void moveNonEjbsToLib(File wd) throws ParserConfigurationException, SAXException, IOException { File file = new File(wd, "META-INF" + File.separator + "application.xml"); if (!file.isFile()) { log.error("You should run this tool from a preprocessed nuxeo.ear folder"); } DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); FileInputStream in = new FileInputStream(file); Document doc = docBuilder.parse(in); Element root = doc.getDocumentElement(); NodeList list = root.getElementsByTagName("module"); Collection<String> paths = new ArrayList<String>(); for (int i = 0; i < list.getLength(); i++) { Element el = (Element) list.item(i); Node n = el.getFirstChild(); while (n != null) { if (n.getNodeType() == Node.ELEMENT_NODE) { Element mtype = ((Element) n); String type = n.getNodeName().toLowerCase(); if (!"web".equals(type)) { String path = mtype.getTextContent().trim(); paths.add(path); } } n = n.getNextSibling(); } } File ejbs = new File(wd, "tmp-ejbs"); ejbs.mkdirs(); for (String path : paths) { log.info("Move EAR module " + path + " to " + ejbs.getName()); File f = new File(wd, path); if (f.getName().endsWith(".txt")) { continue; } FileUtils.moveToDirectory(f, ejbs, false); } File lib = new File(wd, "lib"); File[] files = new File(wd, "bundles").listFiles(); if (files != null) { for (File f : files) { if (f.getName().endsWith(".txt")) { continue; } log.info("Move POJO bundle " + f.getName() + " to lib"); FileUtils.moveToDirectory(f, lib, false); } } File bundles = new File(wd, "bundles"); files = ejbs.listFiles(); if (files != null) { for (File f : files) { if (f.getName().endsWith(".txt")) { continue; } log.info("Move back EAR module " + f.getName() + " to bundles"); FileUtils.moveToDirectory(f, bundles, false); } } } protected static void fail(String message) { log.error(message); System.exit(1); } public static void main(String[] args) throws IOException, ConfigurationException, ParserConfigurationException, SAXException { if (args.length < 2) { fail("Usage: PackZip nuxeo_ear_directory target_directory [order]"); } String v = args[0]; File ear = new File(v); if (!ear.isDirectory()) { fail("Invalid build - no exploded nuxeo.ear found at " + ear.getAbsolutePath()); } v = args[1]; File target = new File(v); ear = ear.getCanonicalFile(); target = target.getCanonicalFile(); if (target.exists()) { FileUtils.deleteDirectory(target); } target.mkdirs(); if (!target.isDirectory()) { fail("Invalid target directory: " + v + ". Not a directory or directory could not be created"); } log.info("Packing nuxeo.ear at " + ear.getAbsolutePath() + " into " + target.getAbsolutePath()); PackZip pack = new PackZip(ear, target); if (args.length >= 3) { pack.execute(args[2]); } else { pack.execute(null); } } }