/* The contents of this file are subject to the license and copyright terms * detailed in the license directory at the root of the source tree (also * available online at http://fedora-commons.org/license/). */ package fedora.utilities.install; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Writer; import java.util.Map; import java.util.Properties; import org.apache.log4j.PropertyConfigurator; import fedora.utilities.FileUtils; import fedora.utilities.Zip; import fedora.utilities.install.container.Container; import fedora.utilities.install.container.ContainerFactory; import fedora.utilities.install.container.FedoraWebXML; public class Installer { static { //send all log4j (WARN only) output to STDOUT Properties props = new Properties(); props.setProperty("log4j.appender.STDOUT", "org.apache.log4j.ConsoleAppender"); props.setProperty("log4j.appender.STDOUT.layout", "org.apache.log4j.PatternLayout"); props.setProperty("log4j.appender.STDOUT.layout.ConversionPattern", "%p (%c{1}) %m%n"); props.setProperty("log4j.rootLogger", "WARN, STDOUT"); PropertyConfigurator.configure(props); //tell commons-logging to use log4j final String pfx = "org.apache.commons.logging."; if (System.getProperty(pfx + "LogFactory") == null) { System.setProperty(pfx + "LogFactory", pfx + "impl.Log4jFactory"); System.setProperty(pfx + "Log", pfx + "impl.Log4JLogger"); } } private final Distribution _dist; private final InstallOptions _opts; private final File fedoraHome; private final File installDir; public Installer(Distribution dist, InstallOptions opts) { _dist = dist; _opts = opts; fedoraHome = new File(_opts.getValue(InstallOptions.FEDORA_HOME)); installDir = new File(fedoraHome, "install" + File.separator); } /** * Install the distribution based on the options. */ public void install() throws InstallationFailedException { installDir.mkdirs(); // Write out the install options used to a properties file in the install directory try { OutputStream out = new FileOutputStream(new File(installDir, "install.properties")); _opts.dump(out); out.close(); } catch (Exception e) { throw new InstallationFailedException(e.getMessage(), e); } new FedoraHome(_dist, _opts).install(); if (!_opts.getValue(InstallOptions.INSTALL_TYPE) .equals(InstallOptions.INSTALL_CLIENT)) { Container container = ContainerFactory.getContainer(_dist, _opts); container.install(); container.deploy(buildWAR()); if (_opts.getBooleanValue(InstallOptions.DEPLOY_LOCAL_SERVICES, true)) { deployLocalService(container, Distribution.FOP_WAR); deployLocalService(container, Distribution.IMAGEMANIP_WAR); deployLocalService(container, Distribution.SAXON_WAR); deployLocalService(container, Distribution.DEMO_WAR); } Database database = new Database(_dist, _opts); database.install(); } System.out.println("Installation complete."); if (!_opts.getValue(InstallOptions.INSTALL_TYPE) .equals(InstallOptions.INSTALL_CLIENT) && _opts.getValue(InstallOptions.SERVLET_ENGINE) .equals(InstallOptions.OTHER)) { System.out .println("\n" + "----------------------------------------------------------------------\n" + "The Fedora Installer cannot automatically deploy the Web ARchives to \n" + "the selected servlet container. You must deploy the WAR files \n" + "manually. You can find fedora.war plus several sample back-end \n" + "services and a demonstration object package in: \n" + "\t" + fedoraHome.getAbsolutePath() + File.separator + "install"); } System.out .println("\n" + "----------------------------------------------------------------------\n" + "Before starting Fedora, please ensure that any required environment\n" + "variables are correctly defined\n" + "\t(e.g. FEDORA_HOME, JAVA_HOME, JAVA_OPTS, CATALINA_HOME).\n" + "For more information, please consult the Installation & Configuration\n" + "Guide in the online documentation.\n" + "----------------------------------------------------------------------\n"); } private File buildWAR() throws InstallationFailedException { String fedoraWarName = _opts.getValue(InstallOptions.FEDORA_APP_SERVER_CONTEXT) ; System.out.println("Preparing " + fedoraWarName + ".war..."); // build a staging area in FEDORA_HOME try { File warStage = new File(installDir, "fedorawar" + File.separator); warStage.mkdirs(); Zip.unzip(_dist.get(Distribution.FEDORA_WAR), warStage); // modify web.xml System.out.println("Processing web.xml"); File distWebXML = new File(warStage, "WEB-INF/web.xml"); FedoraWebXML webXML = new FedoraWebXML(distWebXML.getAbsolutePath(), _opts); Writer outputWriter = new BufferedWriter(new FileWriter(distWebXML)); webXML.write(outputWriter); outputWriter.close(); // Remove commons-collections, commons-dbcp, and commons-pool // from fedora.war if using Tomcat 5.0 String container = _opts.getValue(InstallOptions.SERVLET_ENGINE); File webinfLib = new File(warStage, "WEB-INF/lib/"); if (container.equals(InstallOptions.INCLUDED) || container.equals(InstallOptions.EXISTING_TOMCAT)) { File tomcatHome = new File(_opts.getValue(InstallOptions.TOMCAT_HOME)); File dbcp55 = new File(tomcatHome, "common/lib/naming-factory-dbcp.jar"); File dbcp6 = new File(tomcatHome, "lib/tomcat-dbcp.jar"); if (!dbcp55.exists() && !dbcp6.exists()) { new File(webinfLib, Distribution.COMMONS_COLLECTIONS) .delete(); new File(webinfLib, Distribution.COMMONS_DBCP).delete(); new File(webinfLib, Distribution.COMMONS_POOL).delete(); // JDBC driver installation into common/lib for Tomcat 5.0 is // handled by ExistingTomcat50 } else { installJDBCDriver(_dist, _opts, webinfLib); } } else { installJDBCDriver(_dist, _opts, webinfLib); } // Remove log4j if using JBoss Application Server if (container.equals(InstallOptions.OTHER) && _opts.getValue(InstallOptions.USING_JBOSS) .equals("true")) { new File(webinfLib, Distribution.LOG4J).delete(); } // FeSL configuration if (_opts.getBooleanValue(InstallOptions.FESL_ENABLED, false)) { File originalWsdd = new File(warStage, "WEB-INF/server-config.wsdd"); originalWsdd.renameTo(new File(warStage, "WEB-INF/server-config.wsdd.backup.original")); File feslWsdd = new File(warStage, "WEB-INF/melcoe-pep-server-config.wsdd"); feslWsdd.renameTo(new File(warStage, "WEB-INF/server-config.wsdd")); } File fedoraWar = new File(installDir, fedoraWarName + ".war"); Zip.zip(fedoraWar, warStage.listFiles()); return fedoraWar; } catch (FileNotFoundException e) { throw new InstallationFailedException(e.getMessage(), e); } catch (IOException e) { throw new InstallationFailedException(e.getMessage(), e); } } public static void installJDBCDriver(Distribution dist, InstallOptions opts, File destDir) throws InstallationFailedException { String databaseDriver = opts.getValue(InstallOptions.DATABASE_DRIVER); String database = opts.getValue(InstallOptions.DATABASE); InputStream is; File driver = null; boolean success = true; try { if (databaseDriver.equals(InstallOptions.INCLUDED)) { if (database.equals(InstallOptions.INCLUDED)) { is = dist.get(Distribution.JDBC_DERBY); driver = new File(destDir, Distribution.JDBC_DERBY); success = FileUtils.copy(is, new FileOutputStream(driver)); } else if (database.equals(InstallOptions.DERBY)) { is = dist.get(Distribution.JDBC_DERBY_NETWORK); driver = new File(destDir, Distribution.JDBC_DERBY_NETWORK); success = FileUtils.copy(is, new FileOutputStream(driver)); } else if (database.equals(InstallOptions.MCKOI)) { is = dist.get(Distribution.JDBC_MCKOI); driver = new File(destDir, Distribution.JDBC_MCKOI); success = FileUtils.copy(is, new FileOutputStream(driver)); } else if (database.equals(InstallOptions.MYSQL)) { is = dist.get(Distribution.JDBC_MYSQL); driver = new File(destDir, Distribution.JDBC_MYSQL); success = FileUtils.copy(is, new FileOutputStream(driver)); } else if (database.equals(InstallOptions.POSTGRESQL)) { is = dist.get(Distribution.JDBC_POSTGRESQL); driver = new File(destDir, Distribution.JDBC_POSTGRESQL); success = FileUtils.copy(is, new FileOutputStream(driver)); } } else { File f = new File(opts.getValue(InstallOptions.DATABASE_DRIVER)); driver = new File(destDir, f.getName()); success = FileUtils.copy(f, driver); } if (!success) { throw new InstallationFailedException("Copy to " + driver.getAbsolutePath() + " failed."); } } catch (IOException e) { throw new InstallationFailedException(e.getMessage(), e); } } private void deployLocalService(Container container, String filename) throws InstallationFailedException { try { File war = new File(installDir, filename); if (!FileUtils.copy(_dist.get(filename), new FileOutputStream(war))) { throw new InstallationFailedException("Copy to " + war.getAbsolutePath() + " failed."); } container.deploy(war); } catch (IOException e) { throw new InstallationFailedException(e.getMessage(), e); } } /** * Command-line entry point. */ public static void main(String[] args) { try { Distribution dist = new ClassLoaderDistribution(); InstallOptions opts = null; if (args.length == 0) { opts = new InstallOptions(dist); } else if (args.length == 1) { Map<String, String> props = FileUtils.loadMap(new File(args[0])); opts = new InstallOptions(dist, props); } else { System.err.println("ERROR: Too many arguments."); System.err .println("Usage: java -jar fedora-install.jar [options-file]"); System.exit(1); } // set fedora.home System.setProperty("fedora.home", opts .getValue(InstallOptions.FEDORA_HOME)); new Installer(dist, opts).install(); } catch (Exception e) { printException(e); System.exit(1); } } /** * Print a message appropriate for the given exception in as human-readable * way as possible. */ private static void printException(Exception e) { if (e instanceof InstallationCancelledException) { System.out.println("Installation cancelled."); return; } boolean recognized = false; String msg = "ERROR: "; if (e instanceof InstallationFailedException) { msg += "Installation failed: " + e.getMessage(); recognized = true; } else if (e instanceof OptionValidationException) { OptionValidationException ove = (OptionValidationException) e; msg += "Bad value for '" + ove.getOptionId() + "': " + e.getMessage(); recognized = true; } if (recognized) { System.err.println(msg); if (e.getCause() != null) { System.err.println("Caused by: "); e.getCause().printStackTrace(System.err); } } else { System.err.println(msg + "Unexpected error; installation aborted."); e.printStackTrace(); } } }