/** * Puts the uninstaller. * * @exception Exception Description of the Exception */ private void putUninstaller() throws Exception { // Me make the .uninstaller directory String dest = translatePath("$INSTALL_PATH") + File.separator + "Uninstaller"; String jar = dest + File.separator + "uninstaller.jar"; File pathMaker = new File(dest); pathMaker.mkdirs(); // We log the uninstaller deletion information UninstallData udata = UninstallData.getInstance(); udata.setUninstallerJarFilename(jar); udata.setUninstallerPath(dest); // We open our final jar file FileOutputStream out = new FileOutputStream(jar); ZipOutputStream outJar = new ZipOutputStream(out); idata.uninstallOutJar = outJar; outJar.setLevel(9); udata.addFile(jar); // We copy the uninstaller InputStream in = getClass().getResourceAsStream("/res/IzPack.uninstaller"); ZipInputStream inRes = new ZipInputStream(in); ZipEntry zentry = inRes.getNextEntry(); while (zentry != null) { // Puts a new entry outJar.putNextEntry(new ZipEntry(zentry.getName())); // Byte to byte copy int unc = inRes.read(); while (unc != -1) { outJar.write(unc); unc = inRes.read(); } // Next one please inRes.closeEntry(); outJar.closeEntry(); zentry = inRes.getNextEntry(); } inRes.close(); // We put the langpack in = getClass().getResourceAsStream("/langpacks/" + idata.localeISO3 + ".xml"); outJar.putNextEntry(new ZipEntry("langpack.xml")); int read = in.read(); while (read != -1) { outJar.write(read); read = in.read(); } outJar.closeEntry(); }
/** The run method. */ public void run() { instances.add(this); try { listener.startUnpack(); String currentOs = System.getProperty("os.name").toLowerCase(); // // Initialisations FileOutputStream out = null; ArrayList parsables = new ArrayList(); ArrayList executables = new ArrayList(); List packs = idata.selectedPacks; int npacks = packs.size(); udata = UninstallData.getInstance(); // Specific to the web installers if (idata.kind.equalsIgnoreCase("web") || idata.kind.equalsIgnoreCase("web-kunststoff")) { InputStream kin = getClass().getResourceAsStream("/res/WebInstallers.url"); BufferedReader kreader = new BufferedReader(new InputStreamReader(kin)); jarLocation = kreader.readLine(); } // We unpack the selected packs for (int i = 0; i < npacks; i++) { // We get the pack stream int n = idata.allPacks.indexOf(packs.get(i)); ObjectInputStream objIn = new ObjectInputStream(getPackAsStream(n)); // We unpack the files int nfiles = objIn.readInt(); listener.changeUnpack(0, nfiles, ((Pack) packs.get(i)).name); for (int j = 0; j < nfiles; j++) { // We read the header PackFile pf = (PackFile) objIn.readObject(); if (null == pf.os || matchOS(currentOs, pf.os.toLowerCase())) { // We translate & build the path String path = translatePath(pf.targetPath); File pathFile = new File(path); String fname = pathFile.getName(); int z = fname.length(); File dest = pathFile.getParentFile(); if (!dest.exists()) dest.mkdirs(); // We add the path to the log, udata.addFile(path); listener.progressUnpack(j, path); // if this file exists and shouldnot override skip this file if (((pf.override == false) && (pathFile.exists()))) { objIn.skip(pf.length); continue; } // We copy the file out = new FileOutputStream(path); byte[] buffer = new byte[5120]; long bytesCopied = 0; while (bytesCopied < pf.length) { int maxBytes = (pf.length - bytesCopied < buffer.length ? (int) (pf.length - bytesCopied) : buffer.length); int bytesInBuffer = objIn.read(buffer, 0, maxBytes); if (bytesInBuffer == -1) throw new IOException("Unexpected end of stream"); out.write(buffer, 0, bytesInBuffer); bytesCopied += bytesInBuffer; } // Cleanings out.close(); // Empty dirs restoring String _n = pathFile.getName(); if (_n.startsWith("izpack-keepme") && _n.endsWith(".tmp")) pathFile.delete(); } else objIn.skip(pf.length); } // Load information about parsable files int numParsables = objIn.readInt(); int k; for (k = 0; k < numParsables; k++) { ParsableFile pf = (ParsableFile) objIn.readObject(); pf.path = translatePath(pf.path); parsables.add(pf); } // Load information about executable files int numExecutables = objIn.readInt(); for (k = 0; k < numExecutables; k++) { ExecutableFile ef = (ExecutableFile) objIn.readObject(); ef.path = translatePath(ef.path); if (null != ef.argList && !ef.argList.isEmpty()) { String arg = null; for (int j = 0; j < ef.argList.size(); j++) { arg = (String) ef.argList.get(j); arg = translatePath(arg); ef.argList.set(j, arg); } } executables.add(ef); if (ef.executionStage == ExecutableFile.UNINSTALL) { udata.addExecutable(ef); } } objIn.close(); } // We use the scripts parser ScriptParser parser = new ScriptParser(parsables, vs); parser.parseFiles(); // We use the file executor FileExecutor executor = new FileExecutor(executables); if (executor.executeFiles(ExecutableFile.POSTINSTALL) != 0) javax.swing.JOptionPane.showMessageDialog( null, "The installation was not completed.", "Installation warning", javax.swing.JOptionPane.WARNING_MESSAGE); // We put the uninstaller putUninstaller(); // The end :-) listener.stopUnpack(); } catch (Exception err) { listener.stopUnpack(); listener.errorUnpack(err.toString()); } instances.remove(instances.indexOf(this)); }
/* (non-Javadoc) * @see com.izforge.izpack.installer.IUnpacker#run() */ public void run() { addToInstances(); try { // // Initialisations FileOutputStream out = null; ArrayList<ParsableFile> parsables = new ArrayList<ParsableFile>(); ArrayList<ExecutableFile> executables = new ArrayList<ExecutableFile>(); ArrayList<UpdateCheck> updatechecks = new ArrayList<UpdateCheck>(); List packs = idata.selectedPacks; int npacks = packs.size(); handler.startAction("Unpacking", npacks); udata = UninstallData.getInstance(); // Custom action listener stuff --- load listeners ---- List[] customActions = getCustomActions(); // Custom action listener stuff --- beforePacks ---- informListeners(customActions, InstallerListener.BEFORE_PACKS, idata, npacks, handler); packs = idata.selectedPacks; npacks = packs.size(); // We unpack the selected packs for (int i = 0; i < npacks; i++) { // We get the pack stream // int n = idata.allPacks.indexOf(packs.get(i)); Pack p = (Pack) packs.get(i); // evaluate condition if (p.hasCondition()) { if (rules != null) { if (!rules.isConditionTrue(p.getCondition())) { // skip pack, condition is not fullfilled. continue; } } else { // TODO: skip pack, because condition can not be checked } } // Custom action listener stuff --- beforePack ---- informListeners( customActions, InstallerListener.BEFORE_PACK, packs.get(i), npacks, handler); ObjectInputStream objIn = new ObjectInputStream(getPackAsStream(p.id, p.uninstall)); // We unpack the files int nfiles = objIn.readInt(); // We get the internationalized name of the pack final Pack pack = ((Pack) packs.get(i)); String stepname = pack.name; // the message to be passed to the // installpanel if (langpack != null && !(pack.id == null || "".equals(pack.id))) { final String name = langpack.getString(pack.id); if (name != null && !"".equals(name)) { stepname = name; } } handler.nextStep(stepname, i + 1, nfiles); for (int j = 0; j < nfiles; j++) { // We read the header PackFile pf = (PackFile) objIn.readObject(); // TODO: reaction if condition can not be checked if (pf.hasCondition() && (rules != null)) { if (!rules.isConditionTrue(pf.getCondition())) { if (!pf.isBackReference()) { // skip, condition is not fulfilled objIn.skip(pf.length()); } continue; } } if (OsConstraint.oneMatchesCurrentSystem(pf.osConstraints())) { // We translate & build the path String path = IoHelper.translatePath(pf.getTargetPath(), vs); File pathFile = new File(path); File dest = pathFile; if (!pf.isDirectory()) { dest = pathFile.getParentFile(); } if (!dest.exists()) { // If there are custom actions which would be called // at // creating a directory, create it recursively. List fileListeners = customActions[customActions.length - 1]; if (fileListeners != null && fileListeners.size() > 0) { mkDirsWithEnhancement(dest, pf, customActions); } else // Create it in on step. { if (!dest.mkdirs()) { handler.emitError( "Error creating directories", "Could not create directory\n" + dest.getPath()); handler.stopAction(); this.result = false; return; } } } if (pf.isDirectory()) { continue; } // Custom action listener stuff --- beforeFile ---- informListeners(customActions, InstallerListener.BEFORE_FILE, pathFile, pf, null); // We add the path to the log, udata.addFile(path, pack.uninstall); handler.progress(j, path); // if this file exists and should not be overwritten, // check // what to do if ((pathFile.exists()) && (pf.override() != PackFile.OVERRIDE_TRUE)) { boolean overwritefile = false; // don't overwrite file if the user said so if (pf.override() != PackFile.OVERRIDE_FALSE) { if (pf.override() == PackFile.OVERRIDE_TRUE) { overwritefile = true; } else if (pf.override() == PackFile.OVERRIDE_UPDATE) { // check mtime of involved files // (this is not 100% perfect, because the // already existing file might // still be modified but the new installed // is just a bit newer; we would // need the creation time of the existing // file or record with which mtime // it was installed...) overwritefile = (pathFile.lastModified() < pf.lastModified()); } else { int def_choice = -1; if (pf.override() == PackFile.OVERRIDE_ASK_FALSE) { def_choice = AbstractUIHandler.ANSWER_NO; } if (pf.override() == PackFile.OVERRIDE_ASK_TRUE) { def_choice = AbstractUIHandler.ANSWER_YES; } int answer = handler.askQuestion( idata.langpack.getString("InstallPanel.overwrite.title") + " - " + pathFile.getName(), idata.langpack.getString("InstallPanel.overwrite.question") + pathFile.getAbsolutePath(), AbstractUIHandler.CHOICES_YES_NO, def_choice); overwritefile = (answer == AbstractUIHandler.ANSWER_YES); } } if (!overwritefile) { if (!pf.isBackReference() && !((Pack) packs.get(i)).loose) { objIn.skip(pf.length()); } continue; } } // We copy the file InputStream pis = objIn; if (pf.isBackReference()) { InputStream is = getPackAsStream(pf.previousPackId, pack.uninstall); pis = new ObjectInputStream(is); // must wrap for blockdata use by objectstream // (otherwise strange result) // skip on underlaying stream (for some reason not // possible on ObjectStream) is.skip(pf.offsetInPreviousPack - 4); // but the stream header is now already read (== 4 // bytes) } else if (((Pack) packs.get(i)).loose) { /* Old way of doing the job by using the (absolute) sourcepath. * Since this is very likely to fail and does not confirm to the documentation, * prefer using relative path's pis = new FileInputStream(pf.sourcePath); */ File resolvedFile = new File(getAbsolutInstallSource(), pf.getRelativeSourcePath()); if (!resolvedFile.exists()) { // try alternative destination - the current working directory // user.dir is likely (depends on launcher type) the current directory of the // executable or jar-file... final File userDir = new File(System.getProperty("user.dir")); resolvedFile = new File(userDir, pf.getRelativeSourcePath()); } if (resolvedFile.exists()) { pis = new FileInputStream(resolvedFile); // may have a different length & last modified than we had at compiletime, therefore // we have to build a new PackFile for the copy process... pf = new PackFile( resolvedFile.getParentFile(), resolvedFile, pf.getTargetPath(), pf.osConstraints(), pf.override(), pf.getAdditionals()); } else { // file not found // issue a warning (logging api pending) // since this file was loosely bundled, we continue with the installation. System.out.println( "Could not find loosely bundled file: " + pf.getRelativeSourcePath()); out.close(); continue; } } if (pf.isPack200Jar()) { int key = objIn.readInt(); InputStream pack200Input = Unpacker.class.getResourceAsStream("/packs/pack200-" + key); Pack200.Unpacker unpacker = getPack200Unpacker(); java.util.jar.JarOutputStream jarOut = new java.util.jar.JarOutputStream(new FileOutputStream(pathFile)); unpacker.unpack(pack200Input, jarOut); jarOut.close(); } else { out = new FileOutputStream(pathFile); byte[] buffer = new byte[5120]; long bytesCopied = 0; while (bytesCopied < pf.length()) { if (performInterrupted()) { // Interrupt was initiated; perform it. out.close(); if (pis != objIn) { pis.close(); } return; } int maxBytes = (int) Math.min(pf.length() - bytesCopied, buffer.length); int bytesInBuffer = pis.read(buffer, 0, maxBytes); if (bytesInBuffer == -1) { throw new IOException("Unexpected end of stream (installer corrupted?)"); } out.write(buffer, 0, bytesInBuffer); bytesCopied += bytesInBuffer; } out.close(); } if (pis != objIn) { pis.close(); } // Set file modification time if specified if (pf.lastModified() >= 0) { pathFile.setLastModified(pf.lastModified()); } // Custom action listener stuff --- afterFile ---- informListeners(customActions, InstallerListener.AFTER_FILE, pathFile, pf, null); } else { if (!pf.isBackReference()) { objIn.skip(pf.length()); } } } // Load information about parsable files int numParsables = objIn.readInt(); for (int k = 0; k < numParsables; k++) { ParsableFile pf = (ParsableFile) objIn.readObject(); if (pf.hasCondition() && (rules != null)) { if (!rules.isConditionTrue(pf.getCondition())) { // skip, condition is not fulfilled continue; } } pf.path = IoHelper.translatePath(pf.path, vs); parsables.add(pf); } // Load information about executable files int numExecutables = objIn.readInt(); for (int k = 0; k < numExecutables; k++) { ExecutableFile ef = (ExecutableFile) objIn.readObject(); if (ef.hasCondition() && (rules != null)) { if (!rules.isConditionTrue(ef.getCondition())) { // skip, condition is false continue; } } ef.path = IoHelper.translatePath(ef.path, vs); if (null != ef.argList && !ef.argList.isEmpty()) { String arg = null; for (int j = 0; j < ef.argList.size(); j++) { arg = ef.argList.get(j); arg = IoHelper.translatePath(arg, vs); ef.argList.set(j, arg); } } executables.add(ef); if (ef.executionStage == ExecutableFile.UNINSTALL) { udata.addExecutable(ef); } } // Custom action listener stuff --- uninstall data ---- handleAdditionalUninstallData(udata, customActions); // Load information about updatechecks int numUpdateChecks = objIn.readInt(); for (int k = 0; k < numUpdateChecks; k++) { UpdateCheck uc = (UpdateCheck) objIn.readObject(); updatechecks.add(uc); } objIn.close(); if (performInterrupted()) { // Interrupt was initiated; perform it. return; } // Custom action listener stuff --- afterPack ---- informListeners(customActions, InstallerListener.AFTER_PACK, packs.get(i), i, handler); } // We use the scripts parser ScriptParser parser = new ScriptParser(parsables, vs); parser.parseFiles(); if (performInterrupted()) { // Interrupt was initiated; perform it. return; } // We use the file executor FileExecutor executor = new FileExecutor(executables); if (executor.executeFiles(ExecutableFile.POSTINSTALL, handler) != 0) { handler.emitError("File execution failed", "The installation was not completed"); this.result = false; } if (performInterrupted()) { // Interrupt was initiated; perform it. return; } // We put the uninstaller (it's not yet complete...) putUninstaller(); // update checks _after_ uninstaller was put, so we don't delete it performUpdateChecks(updatechecks); if (performInterrupted()) { // Interrupt was initiated; perform it. return; } // Custom action listener stuff --- afterPacks ---- informListeners(customActions, InstallerListener.AFTER_PACKS, idata, handler, null); if (performInterrupted()) { // Interrupt was initiated; perform it. return; } // write installation information writeInstallationInformation(); // The end :-) handler.stopAction(); } catch (Exception err) { // TODO: finer grained error handling with useful error messages handler.stopAction(); if ("Installation cancelled".equals(err.getMessage())) { handler.emitNotification("Installation cancelled"); } else { handler.emitError("An error occured", err.getMessage()); err.printStackTrace(); } this.result = false; Housekeeper.getInstance().shutDown(4); } finally { removeFromInstances(); } }