AbstractInstall.java :  » Installer » VAInstall » com » memoire » vainstall » Java Open Source

Java Open Source » Installer » VAInstall 
VAInstall » com » memoire » vainstall » AbstractInstall.java
/*
 * $RCSfile: AbstractInstall.java,v $
 * @modification $Date: 2005/05/12 22:13:02 $
 * @version      $Id: AbstractInstall.java,v 1.18 2005/05/12 22:13:02 deniger Exp $
 *
 */
/**
 * This is an abstract base class that defines some methods an
 * installer/uninstaller need to implement. It has some concrete helper methods.
 * 
 * Both the Setup and the Uninstall class is a kind of installation.
 * 
 * This first version have some methods copied from the Setup class that should
 * not be in this class. The goal is to create a more clean class.
 * 
 * @see com.memoire.vainstall.Setup
 * @see com.memoire.vainstall.Uninstall
 * 
 * @author Henrik Falk
 * @version $Id: AbstractInstall.java,v 1.18 2005/05/12 22:13:02 deniger Exp $
 */
package com.memoire.vainstall;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.LineNumberReader;
import java.util.Arrays;
import java.util.Vector;

public abstract class AbstractInstall {
  public static final int CANCEL = 0x01;

  public static final int BACK = 0x02;

  public static final int NEXT = 0x04;

  public static final int FINISH = 0x08;

  public static final boolean IS_WIN = System.getProperty("os.name")
      .startsWith("Win");

  //MAC_OS X
  public static final boolean IS_MAC_OS_X = System.getProperty("os.name")
      .startsWith("Mac OS X");

  public static final boolean IS_MAC = System.getProperty("os.name")
      .startsWith("Mac")
      && !IS_MAC_OS_X;

  public static final boolean IS_UNIX = !IS_WIN && !IS_MAC || IS_MAC_OS_X;

  public static final boolean IS_ROOT = (IS_UNIX && "root".equals(System
      .getProperty("user.name")))
      || (IS_WIN && new File("C:\\").canWrite());

  protected VAStep step_;

  protected boolean dirty_;

  /**
   *  
   */
  protected VAStepFactory ui_;

  /**
   *  
   */
  protected VAStats stats_;

  protected static final int LANGUAGE = 0;

  protected static final int START = 1;

  protected static final int WELCOME = 2;

  protected static final int LICENSE = 3;

  protected static final int README = 4;

  protected static final int LICENSE_KEY = 5;

  protected static final int UPGRADE = 6;

  protected static final int DIRECTORY = 7;

  protected static final int INSTALL = 8;

  protected static final int SHORTCUTS = 9;

  protected static final int END = 10;

  protected int state_;

  protected int actionEnabled_;

  protected File sharedDir_;

  protected File classloaderTempDir_;

  protected UpgradeInfo uInfo_;

  /**
   * The current language that is choosen
   */
  protected String language;

  public AbstractInstall() {
    super();
    if (IS_WIN) {
      extractJniDll("/JNIWinShortcut.dll",true);
      extractJniDll("/ICE_JNIRegistry.dll",false);
    }
    actionEnabled_ = 0;
    stats_ = new VAStats();
    sharedDir_ = null;
    uInfo_ = null;
    dirty_ = false;
    state_ = START;
  }

  /**
   * This method deletes all files in a directory and updates failures to the
   * 'stats_' variable This method should moved to a support class and thats
   * why I made it public.
   * 
   * @author Henrik Falk
   * @param dir
   *            File Directory to delete
   * @return void
   */
  public void deleteDirRecursive(File dir) {
    // verify parameter
    if (dir == null || dir.exists() == false) {
      return;
    }
    // get list of files in directory if any
    File[] filelist = dir.listFiles();
    for (int i = 0; i < filelist.length; i++) {
      boolean isdir = filelist[i].isDirectory();
      if (isdir == true) {
        // delete everything in the directory
        deleteDirRecursive(filelist[i]);
      } else {
        // delete the file
        if (filelist[i].delete() == false) {
          stats_.addFile(filelist[i], VAStats.FAILURE);
          filelist[i].deleteOnExit();
          VAGlobals.printDebug("F " + filelist[i] + " not deleted");
        } // endif
      } // endif
    } // endfor
    // delete the directory
    if (dir.delete() == false) {
      dir.deleteOnExit();
      stats_.addDirectory(dir, VAStats.FAILURE);
      VAGlobals.printDebug("D " + dir + " not deleted");
    } // endif
  }

  public boolean cleanShortcuts(File shortcutLogDir) throws IOException {
    boolean value;
    File logFile;
    Vector directories;
    logFile = new File(shortcutLogDir, "shortcuts.vai");
    value = false;
    if (logFile.exists()) {
      value = true;
      directories = deleteFiles(logFile);
      deleteDirectories(directories);
    }
    return value;
  }

  protected Vector deleteFiles(File log) throws IOException {
    Vector dirs = new Vector();
    LineNumberReader logReader = new LineNumberReader(new FileReader(log));
    String line = logReader.readLine();
    while (line != null) {
      File del = new File(line);
      if (del.isDirectory()) {

        dirs.add(del);
      } else if (del.delete()) {
        stats_.addFile(del, VAStats.SUCCESS);
      } else {
        del.deleteOnExit();
        stats_.addFile(del, VAStats.FAILURE);
        VAGlobals.printDebug("F " + del + " not deleted");
      }
      line = logReader.readLine();
    }
    logReader.close();
    return dirs;
  }

  protected void deleteDirectories(Vector directories) throws IOException {
    Object[] dirs = directories.toArray();
    Arrays.sort(dirs);
    for (int i = dirs.length - 1; i >= 0; i--) {
      File del = (File) dirs[i];
      if (del.delete()) {
        stats_.addDirectory(del, VAStats.SUCCESS);
      } else {
        del.deleteOnExit();
        stats_.addDirectory(del, VAStats.FAILURE);
        VAGlobals.printDebug("D " + del + " not deleted");
      }
    }
  }

  private void restoreLastVersion(File sharedDir, UpgradeInfo uInfo) {
    File destPath = new File(sharedDir, "vai_" + VAGlobals.APP_NAME + "_"
        + VAGlobals.APP_VERSION);
    // eliminate new install info
    if (destPath.exists())
      deleteDirRecursive(destPath);
    if ((uInfo == null) || (!uInfo.upgrade))
      return;
    File lastVerPath = new File(sharedDir, "vai_" + VAGlobals.APP_NAME
        + "_" + uInfo.lastVersion());
    // restore old install info if versions are the same
    if (destPath.equals(lastVerPath)) {
      lastVerPath = new File(destPath.getAbsolutePath() + ".bak");
      lastVerPath.renameTo(destPath);
    }
  }

  public void setActionEnabled(int a) {
    actionEnabled_ = a;
    ui_.setActionEnabled(a);
  }

  public void cancel() {
    cleanInstall(sharedDir_, uInfo_);
    quit();
  }

  protected void cleanInstall(File sharedDir, UpgradeInfo uInfo) {
    if ((!dirty_) || (sharedDir == null) || (!sharedDir.exists())) {
      VAGlobals.printDebug("No cleaning needed");
      return;
    }
    File uninstDir = new File(sharedDir.getAbsolutePath() + File.separator
        + "vai_" + VAGlobals.APP_NAME + "_" + VAGlobals.APP_VERSION);
    if (!uninstDir.exists()) {
      VAGlobals.printDebug("No cleaning needed");
      return;
    }
    VAGlobals.printDebug("Deleting uninstall files...");
    if ((uInfo != null) && (uInfo.upgrade)) {
      restoreLastVersion(sharedDir, uInfo);
    } else {
      // delete all in the uninstall directory
      deleteDirRecursive(uninstDir);
    }
    VAGlobals.printDebug("All cleaned OK");
  }

  protected void checkUpgrade(File sharedDir, UpgradeInfo uInfo) {
    VAUpgradeStep step = (VAUpgradeStep) step_;
    step.status(VAGlobals.i18n("Setup_LookPreviousVersions"));
    ui_.uiSleep(2000);
    checkVersions(sharedDir, uInfo);
    if (uInfo.upgrade) {
      VAGlobals.printDebug("Previous version found : "
          + uInfo.lastVersion());
      step.status(VAGlobals.i18n("Setup_PreviousVersionFound") + " "
          + uInfo.lastVersion());
      step.version(uInfo.lastVersion());
      step.directory(uInfo.lastPath().getAbsolutePath());
    } else {
      VAGlobals.printDebug("No previous version found");
      step.status(VAGlobals.i18n("Setup_NoPreviousVersionFound"));
      step.version(VAGlobals.i18n("Setup_None"));
      step.directory(VAGlobals.i18n("Setup_None"));
    }
  }

  private void checkVersions(File sharedDir, UpgradeInfo uInfo) {
    String[] ls = sharedDir.list(new SetupFileFilter("vai_"
        + VAGlobals.APP_NAME + "_", SetupFileFilter.STARTS_WITH,
        SetupFileFilter.FILTER));
    if ((ls != null) && (ls.length > 0)) {
      Arrays.sort(ls);
      uInfo.versions = new String[ls.length];
      uInfo.paths = new File[ls.length];
      for (int i = 0; i < ls.length; i++) {
        uInfo.versions[i] = ls[i].substring(ls[i].lastIndexOf('_') + 1);
        try {
          LineNumberReader log = new LineNumberReader(new FileReader(
              new File(new File(sharedDir, ls[i]),
                  "uninstall.vai")));
          String f = log.readLine();
          if (f != null)
            uInfo.paths[i] = new File(f);
          log.close();
        } catch (IOException ex) {
          System.err.println(ex.getMessage());
          uInfo.paths[i] = null;
        }
      }
    }
    uInfo.upgrade = (uInfo.lastVersion() != null)
        && (uInfo.lastPath() != null);
  }

  /**
   * @param entryName
   *            the name of the dll file
   * @param isWinShortcut
   *            true if it's the dll for the JNIWindowsShortcut
   */
  private void extractJniDll(String entryName, boolean isWinShortcut) {
    try {
      InputStream dll = getClass().getResourceAsStream(entryName);
      File dllFile = new File(System.getProperty("java.io.tmpdir")
          + File.separator
          + entryName.substring(entryName.lastIndexOf('/') + 1));
      VAGlobals.printDebug("Extracting library " + dllFile);
      System.out.println(dllFile.getAbsolutePath());
      FileOutputStream dllout = new FileOutputStream(dllFile);
      byte[] data = new byte[512];
      int read = dll.read(data, 0, data.length);
      while (read > 0) {
        dllout.write(data, 0, read);
        read = dll.read(data, 0, data.length);
      }
      dll.close();
      dllout.close();
      VAGlobals.printDebug(" library extracted");
      if (isWinShortcut) {
        JNIWindowsShortcut.LIB_NAME = dllFile.getAbsolutePath();;
      } else
        VAGlobals.JNI_DLL_FILE = dllFile.getAbsolutePath();
      dllFile.deleteOnExit();
    } catch (IOException e) {
      exitOnError(e);
    }
  }

  protected void exitOnError(Throwable e) {
    if (ui_ != null)
      ui_.showFatalError(e);
    else
      e.printStackTrace();
    deleteTmpFile();
    System.exit(1);
  }
  
  private void deleteTmpFile(){
    if (classloaderTempDir_ != null) {
      VAGlobals.printDebug("Temporary directory deleted: "
          + classloaderTempDir_.getAbsolutePath());
      deleteDirRecursive(classloaderTempDir_);
    }
  }

  protected void quit() {
    // delete classloader
    //File classloaderDir = new
    // File(System.getProperty("user.dir")+File.separator+"com");
    deleteTmpFile();
    ui_ = null;
    VAGlobals.printDebug("Exiting");
    System.exit(0);
  }

  /**
   * The next step in an install/uninstall
   * 
   * @return void
   */
  public abstract void nextStep();

  /**
   * A previous step in an install/uninstall
   * 
   * @return void
   */
  public abstract void previousStep();

  /**
   * A redo step in an install/uninstall This is conceptually an 'again' step.
   * Only 'tui' uses the redo feature at the moment.
   * 
   * @return void
   */
  public abstract void redoStep();
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.