/** Write an arbitrary object to primary jar. */
 protected void writeInstallerObject(String entryName, Object object) throws IOException {
   primaryJarStream.putNextEntry(new org.apache.tools.zip.ZipEntry(RESOURCES_PATH + entryName));
   ObjectOutputStream out = new ObjectOutputStream(primaryJarStream);
   out.writeObject(object);
   out.flush();
   primaryJarStream.closeEntry();
 }
Exemple #2
0
 /**
  * Write an arbitrary object to installer jar.
  *
  * @throws IOException for any I/O error
  */
 protected void writeInstallerObject(String entryName, Object object) throws IOException {
   installerJar.putNextEntry(new org.apache.tools.zip.ZipEntry(RESOURCES_PATH + entryName));
   ObjectOutputStream out = new ObjectOutputStream(installerJar);
   try {
     out.writeObject(object);
   } catch (IOException e) {
     throw new IOException(
         "Error serializing instance of "
             + object.getClass().getName()
             + " as entry \""
             + entryName
             + "\"",
         e);
   } finally {
     out.flush();
     installerJar.closeEntry();
   }
 }
  /** Write the data referenced by URL to primary jar. */
  protected void writeInstallerResources() throws IOException {
    sendMsg("Copying " + installerResourceURLMap.size() + " files into installer");

    for (Map.Entry<String, URL> stringURLEntry : installerResourceURLMap.entrySet()) {
      URL url = stringURLEntry.getValue();
      InputStream in = url.openStream();

      org.apache.tools.zip.ZipEntry newEntry =
          new org.apache.tools.zip.ZipEntry(RESOURCES_PATH + stringURLEntry.getKey());
      long dateTime = FileUtil.getFileDateTime(url);
      if (dateTime != -1) {
        newEntry.setTime(dateTime);
      }
      primaryJarStream.putNextEntry(newEntry);

      IoHelper.copyStream(in, primaryJarStream);
      primaryJarStream.closeEntry();
      in.close();
    }
  }
  /** Write Packs to primary jar or each to a separate jar. */
  protected void writePacks() throws Exception {
    final int num = packsList.size();
    sendMsg("Writing " + num + " Pack" + (num > 1 ? "s" : "") + " into installer");

    // Map to remember pack number and bytes offsets of back references
    Map<File, Object[]> storedFiles = new HashMap<File, Object[]>();

    // Pack200 files map
    Map<Integer, File> pack200Map = new HashMap<Integer, File>();
    int pack200Counter = 0;

    // Force UTF-8 encoding in order to have proper ZipEntry names.
    primaryJarStream.setEncoding("utf-8");

    // First write the serialized files and file metadata data for each pack
    // while counting bytes.

    int packNumber = 0;
    IXMLElement root = new XMLElementImpl("packs");

    for (PackInfo packInfo : packsList) {
      Pack pack = packInfo.getPack();
      pack.nbytes = 0;
      if ((pack.id == null) || (pack.id.length() == 0)) {
        pack.id = pack.name;
      }

      // create a pack specific jar if required
      // REFACTOR : Repare web installer
      // REFACTOR : Use a mergeManager for each packages that will be added to the main merger

      //            if (packJarsSeparate) {
      // See installer.Unpacker#getPackAsStream for the counterpart
      //                String name = baseFile.getName() + ".pack-" + pack.id + ".jar";
      //                packStream = IoHelper.getJarOutputStream(name, baseFile.getParentFile());
      //            }

      sendMsg("Writing Pack " + packNumber + ": " + pack.name, PackagerListener.MSG_VERBOSE);

      // Retrieve the correct output stream
      org.apache.tools.zip.ZipEntry entry =
          new org.apache.tools.zip.ZipEntry(RESOURCES_PATH + "packs/pack-" + pack.id);
      primaryJarStream.putNextEntry(entry);
      primaryJarStream.flush(); // flush before we start counting

      ByteCountingOutputStream dos = new ByteCountingOutputStream(outputStream);
      ObjectOutputStream objOut = new ObjectOutputStream(dos);

      // We write the actual pack files
      objOut.writeInt(packInfo.getPackFiles().size());

      for (PackFile packFile : packInfo.getPackFiles()) {
        boolean addFile = !pack.loose;
        boolean pack200 = false;
        File file = packInfo.getFile(packFile);

        if (file.getName().toLowerCase().endsWith(".jar")
            && info.isPack200Compression()
            && isNotSignedJar(file)) {
          packFile.setPack200Jar(true);
          pack200 = true;
        }

        // use a back reference if file was in previous pack, and in
        // same jar
        Object[] info = storedFiles.get(file);
        if (info != null && !packJarsSeparate) {
          packFile.setPreviousPackFileRef((String) info[0], (Long) info[1]);
          addFile = false;
        }

        objOut.writeObject(packFile); // base info

        if (addFile && !packFile.isDirectory()) {
          long pos = dos.getByteCount(); // get the position

          if (pack200) {
            /*
             * Warning!
             *
             * Pack200 archives must be stored in separated streams, as the Pack200 unpacker
             * reads the entire stream...
             *
             * See http://java.sun.com/javase/6/docs/api/java/util/jar/Pack200.Unpacker.html
             */
            pack200Map.put(pack200Counter, file);
            objOut.writeInt(pack200Counter);
            pack200Counter = pack200Counter + 1;
          } else {
            FileInputStream inStream = new FileInputStream(file);
            long bytesWritten = IoHelper.copyStream(inStream, objOut);
            inStream.close();
            if (bytesWritten != packFile.length()) {
              throw new IOException("File size mismatch when reading " + file);
            }
          }

          storedFiles.put(file, new Object[] {pack.id, pos});
        }

        // even if not written, it counts towards pack size
        pack.nbytes += packFile.size();
      }

      // Write out information about parsable files
      objOut.writeInt(packInfo.getParsables().size());

      for (ParsableFile parsableFile : packInfo.getParsables()) {
        objOut.writeObject(parsableFile);
      }

      // Write out information about executable files
      objOut.writeInt(packInfo.getExecutables().size());
      for (ExecutableFile executableFile : packInfo.getExecutables()) {
        objOut.writeObject(executableFile);
      }

      // Write out information about updatecheck files
      objOut.writeInt(packInfo.getUpdateChecks().size());
      for (UpdateCheck updateCheck : packInfo.getUpdateChecks()) {
        objOut.writeObject(updateCheck);
      }

      // Cleanup
      objOut.flush();
      if (!compressor.useStandardCompression()) {
        outputStream.close();
      }

      primaryJarStream.closeEntry();

      // close pack specific jar if required
      if (packJarsSeparate) {
        primaryJarStream.closeAlways();
      }

      IXMLElement child = new XMLElementImpl("pack", root);
      child.setAttribute("nbytes", Long.toString(pack.nbytes));
      child.setAttribute("name", pack.name);
      if (pack.id != null) {
        child.setAttribute("id", pack.id);
      }
      root.addChild(child);

      packNumber++;
    }

    // Now that we know sizes, write pack metadata to primary jar.
    primaryJarStream.putNextEntry(new org.apache.tools.zip.ZipEntry(RESOURCES_PATH + "packs.info"));
    ObjectOutputStream out = new ObjectOutputStream(primaryJarStream);
    out.writeInt(packsList.size());

    for (PackInfo packInfo : packsList) {
      out.writeObject(packInfo.getPack());
    }
    out.flush();
    primaryJarStream.closeEntry();

    // Pack200 files
    Pack200.Packer packer = createAgressivePack200Packer();
    for (Integer key : pack200Map.keySet()) {
      File file = pack200Map.get(key);
      primaryJarStream.putNextEntry(
          new org.apache.tools.zip.ZipEntry(RESOURCES_PATH + "packs/pack200-" + key));
      JarFile jar = new JarFile(file);
      packer.pack(jar, primaryJarStream);
      jar.close();
      primaryJarStream.closeEntry();
    }
  }