Java tutorial
/* * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved. * * http://izpack.org/ * http://izpack.codehaus.org/ * * Copyright 2007 Dennis Reil * * 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.izforge.izpack.installer.console; import com.izforge.izpack.api.data.Info; import com.izforge.izpack.api.exception.IzPackException; import com.izforge.izpack.api.exception.UserInterruptException; import com.izforge.izpack.api.resource.Messages; import com.izforge.izpack.installer.base.InstallerBase; import com.izforge.izpack.installer.data.ConsoleInstallData; import com.izforge.izpack.installer.data.UninstallData; import com.izforge.izpack.installer.data.UninstallDataWriter; import com.izforge.izpack.util.Console; import com.izforge.izpack.util.Housekeeper; import com.izforge.izpack.util.PrivilegedRunner; import org.apache.commons.io.IOUtils; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Enumeration; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; /** * Runs the console installer. * * @author Mounir el hajj * @author Tim Anderson */ public class ConsoleInstaller implements InstallerBase { /** * The logger. */ private static final Logger logger = Logger.getLogger(ConsoleInstaller.class.getName()); /** * The panels. */ private final ConsolePanels panels; /** * The installation data. */ private ConsoleInstallData installData; /** * The uninstallation data writer. */ private UninstallDataWriter uninstallDataWriter; /** * The console. */ private Console console; /** * The house-keeper. */ private final Housekeeper housekeeper; /** * Whether the console installation has been aborted by the user */ private boolean interrupted = false; /** * Constructs a <tt>ConsoleInstaller</tt> * * @param panels the panels * @param installData the installation data * @param uninstallDataWriter the uninstallation data writer * @param console the console * @param housekeeper the house-keeper * @throws IzPackException for any IzPack error */ public ConsoleInstaller(ConsolePanels panels, ConsoleInstallData installData, UninstallDataWriter uninstallDataWriter, Console console, Housekeeper housekeeper) { this.panels = panels; this.installData = installData; this.uninstallDataWriter = uninstallDataWriter; this.console = console; this.housekeeper = housekeeper; } /** * Sets the media path for multi-volume installations. * * @param path the media path. May be <tt>null</tt> */ public void setMediaPath(String path) { installData.setMediaPath(path); } /** * Runs the installation. * <p/> * This method does not return - it invokes {@code System.exit(0)} on successful installation, or * {@code System.exit(1)} on failure. * * @param type the type of the console action to perform * @param path the path to use for the action. May be <tt>null</tt> */ public void run(ConsoleInstallerAction type, String path, String[] args) { PrivilegedRunner runner = new PrivilegedRunner(installData.getPlatform()); if (!runner.hasCorrectPermissions(installData.getInfo(), installData.getRules())) { try { runner.relaunchWithElevatedRights(args); } catch (Exception e) { console.println(installData.getMessages().get("ConsoleInstaller.permissionError")); } System.exit(0); } boolean success = false; ConsoleAction action = null; panels.initialise(); try { action = createConsoleAction(type, path, console); panels.setAction(action); while (panels.hasNext()) { success = panels.next(action.isValidating()); if (action.isValidating()) { success = panels.getView().handlePanelValidationResult(success); } if (!success) { break; } } if (success) { if (action.isValidating()) { // last panel needs to be validated success = panels.getView().handlePanelValidationResult(panels.isValid()); } if (success) { success = action.complete(); } } } catch (UserInterruptException uie) { interrupted = true; success = false; console.println(uie.getMessage()); } catch (Throwable t) { success = false; logger.log(Level.SEVERE, t.getMessage(), t); } finally { if (action != null && action.isInstall()) { shutdown(success, console); } else { shutdown(success, false); } } } /** * Shuts down the installer, rebooting if necessary. * * @param exitSuccess if <tt>true</tt>, exits with a <tt>0</tt> exit code, else exits with a <tt>1</tt> exit code * @param console the console */ protected void shutdown(boolean exitSuccess, Console console) { // TODO - fix reboot handling boolean reboot = false; final Messages messages = installData.getMessages(); if (installData.isRebootNecessary()) { console.println("[ " + messages.get("ConsoleInstaller.shutdown.pendingFileOperations") + " ]"); switch (installData.getInfo().getRebootAction()) { case Info.REBOOT_ACTION_ALWAYS: reboot = true; } if (reboot) { console.println("[ " + messages.get("ConsoleInstaller.shutdown.rebootingNow") + " ]"); } } shutdown(exitSuccess, reboot); } /** * Shuts down the installer. * * @param exitSuccess if <tt>true</tt>, exits with a <tt>0</tt> exit code, else exits with a <tt>1</tt> exit code * @param reboot if <tt>true</tt> perform a reboot */ protected void shutdown(boolean exitSuccess, boolean reboot) { final Messages messages = installData.getMessages(); if (exitSuccess && !installData.isInstallSuccess()) { logger.severe("Expected successful exit status, but installation data is reporting failure"); exitSuccess = false; } installData.setInstallSuccess(exitSuccess); if (exitSuccess) { console.println("[ " + messages.get("ConsoleInstaller.shutdown.done") + " ]"); } else { if (interrupted) { console.println("[ " + messages.get("ConsoleInstaller.shutdown.aborted") + " ]"); } else { console.println("[ " + messages.get("ConsoleInstaller.shutdown.failed") + " ]"); } } terminate(exitSuccess, reboot); } /** * Terminates the installation process. * * @param exitSuccess if <tt>true</tt>, exits with a <tt>0</tt> exit code, else exits with a <tt>1</tt> exit code * @param reboot if <tt>true</tt> perform a reboot */ protected void terminate(boolean exitSuccess, boolean reboot) { housekeeper.shutDown(exitSuccess ? 0 : 1, reboot); } /** * Returns the console. * * @return the console */ protected Console getConsole() { return console; } /** * Creates a new console action. * * @param type the type of the action to perform * @param path the path to use for the action. May be <tt>null</tt> * @param console the console * @return a new {@link ConsoleAction} * @throws IOException for any I/O error */ private ConsoleAction createConsoleAction(ConsoleInstallerAction type, String path, Console console) throws IOException { ConsoleAction action; switch (type) { case CONSOLE_GEN_TEMPLATE: action = createGeneratePropertiesAction(path); break; case CONSOLE_FROM_TEMPLATE: action = createInstallFromPropertiesFileAction(path); break; case CONSOLE_FROM_SYSTEMPROPERTIES: action = new PropertyInstallAction(installData, uninstallDataWriter, System.getProperties()); break; case CONSOLE_FROM_SYSTEMPROPERTIESMERGE: action = createInstallFromSystemPropertiesMergeAction(path, console); break; default: action = createInstallAction(); } return action; } /** * Creates a new action to perform installation. * * @return a new {@link ConsoleInstallAction} */ private ConsoleAction createInstallAction() { return new ConsoleInstallAction(console, installData, uninstallDataWriter); } /** * Creates a new action to generate installation properties. * * @param path the property file path * @return a new {@link GeneratePropertiesAction} * @throws IOException for any I/O error */ private ConsoleAction createGeneratePropertiesAction(String path) throws IOException { return new GeneratePropertiesAction(installData, path); } /** * Creates a new action to perform installation from a properties file. * * @param path the property file path * @return a new {@link PropertyInstallAction} * @throws IOException for any I/O error */ private ConsoleAction createInstallFromPropertiesFileAction(String path) throws IOException { FileInputStream in = new FileInputStream(path); try { Properties properties = new Properties(); properties.load(in); return new PropertyInstallAction(installData, uninstallDataWriter, properties); } finally { IOUtils.closeQuietly(in); } } /** * Creates a new action to perform installation from a properties file. * * @param path the property file path * @param console the console * @return a new {@link PropertyInstallAction} * @throws IOException for any I/O error */ private ConsoleAction createInstallFromSystemPropertiesMergeAction(String path, Console console) throws IOException { FileInputStream in = new FileInputStream(path); try { Properties properties = new Properties(); properties.load(in); Properties systemProperties = System.getProperties(); Enumeration<?> e = systemProperties.propertyNames(); while (e.hasMoreElements()) { String key = (String) e.nextElement(); String newValue = systemProperties.getProperty(key); String oldValue = (String) properties.setProperty(key, newValue); if (oldValue != null) { console.println( "Warning: Property " + key + " overwritten: '" + oldValue + "' --> '" + newValue + "'"); } } return new PropertyInstallAction(installData, uninstallDataWriter, properties); } finally { IOUtils.closeQuietly(in); } } @Override public void writeInstallationRecord(File file, UninstallData uninstallData) throws Exception { panels.writeInstallationRecord(file, uninstallData); } }