@NotNull
  protected Map<String, EntryInfo> initEntries() {
    synchronized (lock) {
      Map<String, EntryInfo> map = myRelPathsToEntries.get();
      if (map == null) {
        final ZipInputStream zip = getZip();

        map = new HashMap<String, EntryInfo>();
        if (zip != null) {
          map.put("", new EntryInfo("", null, true, new byte[0]));
          try {
            ZipEntry entry = zip.getNextEntry();
            while (entry != null) {
              final String name = entry.getName();
              final boolean isDirectory = name.endsWith("/");
              if (entry.getExtra() == null) {
                byte[] cont = new byte[(int) entry.getSize()];
                ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
                InputStream stream = getZip();
                if (stream != null) {
                  int tmp;
                  if ((tmp = stream.read(cont)) == entry.getSize()) {
                    byteArray.write(cont, 0, tmp);
                    entry.setExtra(byteArray.toByteArray());
                  } else {
                    int readFromIS = tmp;
                    if (tmp < entry.getSize()) {
                      byteArray.write(cont, 0, tmp);
                      while (((tmp = stream.read(cont)) != -1)
                          && (tmp + readFromIS <= entry.getSize())) {
                        byteArray.write(cont, 0, tmp);
                        readFromIS += tmp;
                      }
                      entry.setExtra(byteArray.toByteArray());
                    }
                  }
                }
              }
              getOrCreate(
                  isDirectory ? name.substring(0, name.length() - 1) : name,
                  isDirectory,
                  map,
                  entry.getExtra());

              entry = zip.getNextEntry();
            }
          } catch (IOException e) {
            e.printStackTrace();
          }
          myRelPathsToEntries = new SoftReference<Map<String, EntryInfo>>(map);
        }
      }
      return map;
    }
  }
  /**
   * Open the next entry from the zip archive, and return its description. If the previous entry
   * wasn't closed, this method will close it.
   */
  public ZipEntry getNextEntry() throws IOException {
    if (crc == null) throw new IOException("Stream closed.");
    if (entry != null) closeEntry();

    int header = readLeInt();
    if (header == CENSIG) {
      /* Central Header reached. */
      close();
      return null;
    }
    if (header != LOCSIG)
      throw new ZipException("Wrong Local header signature: " + Integer.toHexString(header));
    /* skip version */
    readLeShort();
    flags = readLeShort();
    method = readLeShort();
    int dostime = readLeInt();
    int crc = readLeInt();
    csize = readLeInt();
    size = readLeInt();
    int nameLen = readLeShort();
    int extraLen = readLeShort();

    if (method == ZipOutputStream.STORED && csize != size)
      throw new ZipException("Stored, but compressed != uncompressed");

    byte[] buffer = new byte[nameLen];
    readFully(buffer);
    String name;
    try {
      name = new String(buffer, "UTF-8");
    } catch (UnsupportedEncodingException uee) {
      throw new AssertionError(uee);
    }

    entry = createZipEntry(name);
    entryAtEOF = false;
    entry.setMethod(method);
    if ((flags & 8) == 0) {
      entry.setCrc(crc & 0xffffffffL);
      entry.setSize(size & 0xffffffffL);
      entry.setCompressedSize(csize & 0xffffffffL);
    }
    entry.setDOSTime(dostime);
    if (extraLen > 0) {
      byte[] extra = new byte[extraLen];
      readFully(extra);
      entry.setExtra(extra);
    }

    if (method == ZipOutputStream.DEFLATED && avail > 0) {
      System.arraycopy(buf, len - avail, buf, 0, avail);
      len = avail;
      avail = 0;
      inf.setInput(buf, 0, len);
    }
    return entry;
  }
Beispiel #3
0
  protected void writeDocument(String path, ExportedDocument doc) throws IOException {

    if (path.equals("/") || path.length() == 0) {
      path = "";
    } else { // avoid adding a root entry
      path += '/';
      ZipEntry entry = new ZipEntry(path);
      // store the number of child as an extra info on the entry
      entry.setExtra(new DWord(doc.getFilesCount()).getBytes());
      out.putNextEntry(entry);
      out.closeEntry();
      // System.out.println(">> add entry: "+entry.getName());
    }

    // write metadata
    ZipEntry entry = new ZipEntry(path + ExportConstants.DOCUMENT_FILE);
    out.putNextEntry(entry);
    try {
      writeXML(doc.getDocument(), out);
    } finally {
      out.closeEntry();
      // System.out.println(">> add entry: "+entry.getName());
    }

    // write external documents
    for (Map.Entry<String, Document> ext : doc.getDocuments().entrySet()) {
      String fileName = ext.getKey() + ".xml";
      entry = new ZipEntry(path + fileName);
      out.putNextEntry(entry);
      try {
        writeXML(ext.getValue(), out);
      } finally {
        out.closeEntry();
      }
    }

    // write blobs
    Map<String, Blob> blobs = doc.getBlobs();
    for (Map.Entry<String, Blob> blobEntry : blobs.entrySet()) {
      String fileName = blobEntry.getKey();
      entry = new ZipEntry(path + fileName);
      out.putNextEntry(entry);
      try (InputStream in = blobEntry.getValue().getStream()) {
        IOUtils.copy(in, out);
      }
      // DO NOT CALL out.close(), we want to keep writing to it
      out.closeEntry();
    }
  }
 /**
  * Unfortunately {@link java.util.zip.ZipOutputStream java.util.zip.ZipOutputStream} seems to
  * access the extra data directly, so overriding getExtra doesn't help - we need to modify super's
  * data directly.
  */
 protected void setExtra() {
   super.setExtra(ExtraFieldUtils.mergeLocalFileDataData(getAllExtraFieldsNoCopy()));
 }
Beispiel #5
0
 /**
  * Unfortunately {@link java.util.zip.ZipOutputStream java.util.zip.ZipOutputStream} seems to
  * access the extra data directly, so overriding getExtra doesn't help - we need to modify super's
  * data directly.
  *
  * @since 1.1
  */
 protected void setExtra() {
   super.setExtra(ExtraFieldUtils.mergeLocalFileDataData(getExtraFields(true)));
 }
Beispiel #6
0
  /** Updates an existing jar file. */
  boolean update(InputStream in, OutputStream out, InputStream newManifest, JarIndex jarIndex)
      throws IOException {
    ZipInputStream zis = new ZipInputStream(in);
    ZipOutputStream zos = new JarOutputStream(out);
    ZipEntry e = null;
    boolean foundManifest = false;
    boolean updateOk = true;

    if (jarIndex != null) {
      addIndex(jarIndex, zos);
    }

    // put the old entries first, replace if necessary
    while ((e = zis.getNextEntry()) != null) {
      String name = e.getName();

      boolean isManifestEntry = equalsIgnoreCase(name, MANIFEST_NAME);

      if ((jarIndex != null && equalsIgnoreCase(name, INDEX_NAME)) || (Mflag && isManifestEntry)) {
        continue;
      } else if (isManifestEntry && ((newManifest != null) || (ename != null) || (pname != null))) {
        foundManifest = true;
        if (newManifest != null) {
          // Don't read from the newManifest InputStream, as we
          // might need it below, and we can't re-read the same data
          // twice.
          FileInputStream fis = new FileInputStream(mname);
          boolean ambiguous = isAmbiguousMainClass(new Manifest(fis));
          fis.close();
          if (ambiguous) {
            return false;
          }
        }

        // Update the manifest.
        Manifest old = new Manifest(zis);
        if (newManifest != null) {
          old.read(newManifest);
        }
        if (!updateManifest(old, zos)) {
          return false;
        }
      } else {
        if (!entryMap.containsKey(name)) { // copy the old stuff
          // do our own compression
          ZipEntry e2 = new ZipEntry(name);
          e2.setMethod(e.getMethod());
          e2.setTime(e.getTime());
          e2.setComment(e.getComment());
          e2.setExtra(e.getExtra());
          if (e.getMethod() == ZipEntry.STORED) {
            e2.setSize(e.getSize());
            e2.setCrc(e.getCrc());
          }
          zos.putNextEntry(e2);
          copy(zis, zos);
        } else { // replace with the new files
          File f = entryMap.get(name);
          addFile(zos, f);
          entryMap.remove(name);
          entries.remove(f);
        }
      }
    }

    // add the remaining new files
    for (File f : entries) {
      addFile(zos, f);
    }
    if (!foundManifest) {
      if (newManifest != null) {
        Manifest m = new Manifest(newManifest);
        updateOk = !isAmbiguousMainClass(m);
        if (updateOk) {
          if (!updateManifest(m, zos)) {
            updateOk = false;
          }
        }
      } else if (ename != null || pname != null) {
        if (!updateManifest(new Manifest(), zos)) {
          updateOk = false;
        }
      }
    }
    zis.close();
    zos.close();
    return updateOk;
  }