/* JarUtils.java -- Utility methods for reading/writing Manifest[-like] files
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.util.jar;

import gnu.classpath.SystemProperties;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.JarException;
import java.util.jar.Attributes.Name;
import java.util.logging.Logger;

/**
 * Utility methods for reading and writing JAR <i>Manifest</i> and
 * <i>Manifest-like</i> files.
 * <p>
 * JAR-related files that resemble <i>Manifest</i> files are Signature files
 * (with an <code>.SF</code> extension) found in signed JARs.
 */
public abstract class JarUtils
{
  private static final Logger log = Logger.getLogger(JarUtils.class.getName());
  public static final String META_INF = "META-INF/";
  public static final String DSA_SUFFIX = ".DSA";
  public static final String SF_SUFFIX = ".SF";
  public static final String NAME = "Name";

  /**
   * The original string representation of the manifest version attribute name.
   */ 
  public static final String MANIFEST_VERSION = "Manifest-Version";

  /**
   * The original string representation of the signature version attribute
   * name.
   */
  public static final String SIGNATURE_VERSION = "Signature-Version";

  /** Platform-independent line-ending. */
  public static final byte[] CRLF = new byte[] { 0x0D, 0x0A };
  private static final String DEFAULT_MF_VERSION = "1.0";
  private static final String DEFAULT_SF_VERSION = "1.0";
  private static final Name CREATED_BY = new Name("Created-By");
  private static final String CREATOR = SystemProperties.getProperty("java.version")
                                        + " ("
                                        + SystemProperties.getProperty("java.vendor")
                                        + ")";

  // default 0-arguments constructor

  // Methods for reading Manifest files from InputStream ----------------------

  public static void
  readMFManifest(Attributes attr, Map entries, InputStream in)
      throws IOException
  {
    BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
    readMainSection(attr, br);
    readIndividualSections(entries, br);
  }

  public static void
  readSFManifest(Attributes attr, Map entries, InputStream in)
      throws IOException
  {
    BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
    String version_header = Name.SIGNATURE_VERSION.toString();
    try
      {
        String version = expectHeader(version_header, br);
        attr.putValue(SIGNATURE_VERSION, version);
        if (! DEFAULT_SF_VERSION.equals(version))
          log.warning("Unexpected version number: " + version
                      + ". Continue (but may fail later)");
      }
    catch (IOException ioe)
      {
        throw new JarException("Signature file MUST start with a "
                               + version_header + ": " + ioe.getMessage());
      }
    read_attributes(attr, br);

    // read individual sections
    String s = br.readLine();
    while (s != null && s.length() > 0)
      {
        Attributes eAttr = readSectionName(s, br, entries);
        read_attributes(eAttr, br);
        s = br.readLine();
      }
  }

  private static void readMainSection(Attributes attr, BufferedReader br)
      throws IOException
  {
    // According to the spec we should actually call read_version_info() here.
    read_attributes(attr, br);
    // Explicitly set Manifest-Version attribute if not set in Main
    // attributes of Manifest.
    // XXX (rsn): why 0.0 and not 1.0?
    if (attr.getValue(Name.MANIFEST_VERSION) == null)
      attr.putValue(MANIFEST_VERSION, "0.0");
  }

  private static void readIndividualSections(Map entries, BufferedReader br)
      throws IOException
  {
    String s = br.readLine();
    while (s != null && (! s.equals("")))
      {
        Attributes attr = readSectionName(s, br, entries);
        read_attributes(attr, br);
        s = br.readLine();
      }
  }

  /**
   * Pedantic method that requires the next attribute in the Manifest to be the
   * "Manifest-Version". This follows the Manifest spec closely but reject some
   * jar Manifest files out in the wild.
   */
  private static void readVersionInfo(Attributes attr, BufferedReader br)
      throws IOException
  {
    String version_header = Name.MANIFEST_VERSION.toString();
    try
      {
        String value = expectHeader(version_header, br);
        attr.putValue(MANIFEST_VERSION, value);
      }
    catch (IOException ioe)
      {
        throw new JarException("Manifest should start with a " + version_header
                               + ": " + ioe.getMessage());
      }
  }

  private static String expectHeader(String header, BufferedReader br)
      throws IOException
  {
    String s = br.readLine();
    if (s == null)
      throw new JarException("unexpected end of file");

    return expectHeader(header, br, s);
  }

  private static void read_attributes(Attributes attr, BufferedReader br)
      throws IOException
  {
    String s = br.readLine();
    while (s != null && (! s.equals("")))
      {
        readAttribute(attr, s, br);
        s = br.readLine();
      }
  }

  private static void
  readAttribute(Attributes attr, String s, BufferedReader br) throws IOException
  {
    try
      {
        int colon = s.indexOf(": ");
        String name = s.substring(0, colon);
        String value_start = s.substring(colon + 2);
        String value = readHeaderValue(value_start, br);
        attr.putValue(name, value);
      }
    catch (IndexOutOfBoundsException iobe)
      {
        throw new JarException("Manifest contains a bad header: " + s);
      }
  }

  private static String readHeaderValue(String s, BufferedReader br)
      throws IOException
  {
    boolean try_next = true;
    while (try_next)
      {
        // Lets see if there is something on the next line
        br.mark(1);
        if (br.read() == ' ')
          s += br.readLine();
        else
          {
            br.reset();
            try_next = false;
          }
      }
    return s;
  }

  private static Attributes
  readSectionName(String s, BufferedReader br, Map entries) throws JarException
  {
    try
      {
        String name = expectHeader(NAME, br, s);
        Attributes attr = new Attributes();
        entries.put(name, attr);
        return attr;
      }
    catch (IOException ioe)
      {
        throw new JarException("Section should start with a Name header: "
                               + ioe.getMessage());
      }
  }

  private static String expectHeader(String header, BufferedReader br, String s)
      throws IOException
  {
    try
      {
        String name = s.substring(0, header.length() + 1);
        if (name.equalsIgnoreCase(header + ":"))
          {
            String value_start = s.substring(header.length() + 2);
            return readHeaderValue(value_start, br);
          }
      }
    catch (IndexOutOfBoundsException ignored)
      {
      }
    // If we arrive here, something went wrong
    throw new JarException("unexpected '" + s + "'");
  }

  // Methods for writing Manifest files to an OutputStream --------------------

  public static void
  writeMFManifest(Attributes attr, Map entries, OutputStream stream)
      throws IOException
  {
    BufferedOutputStream out = stream instanceof BufferedOutputStream
                               ? (BufferedOutputStream) stream
                               : new BufferedOutputStream(stream, 4096);
    writeVersionInfo(attr, out);
    Iterator i;
    Map.Entry e;
    for (i = attr.entrySet().iterator(); i.hasNext();)
      {
        e = (Map.Entry) i.next();
        // Don't print the manifest version again
        if (! Name.MANIFEST_VERSION.equals(e.getKey()))
          writeAttributeEntry(e, out);
      }
    out.write(CRLF);

    Iterator j;
    for (i = entries.entrySet().iterator(); i.hasNext();)
      {
        e = (Map.Entry) i.next();
        writeHeader(NAME, e.getKey().toString(), out);
        Attributes eAttr = (Attributes) e.getValue();
        for (j = eAttr.entrySet().iterator(); j.hasNext();)
          {
            Map.Entry e2 = (Map.Entry) j.next();
            writeAttributeEntry(e2, out);
          }
        out.write(CRLF);
      }

    out.flush();
  }

  public static void
  writeSFManifest(Attributes attr, Map entries, OutputStream stream)
      throws IOException
  {
    BufferedOutputStream out = stream instanceof BufferedOutputStream
                               ? (BufferedOutputStream) stream
                               : new BufferedOutputStream(stream, 4096);
    writeHeader(Name.SIGNATURE_VERSION.toString(), DEFAULT_SF_VERSION, out);
    writeHeader(CREATED_BY.toString(), CREATOR, out);
    Iterator i;
    Map.Entry e;
    for (i = attr.entrySet().iterator(); i.hasNext();)
      {
        e = (Map.Entry) i.next();
        Name name = (Name) e.getKey();
        if (Name.SIGNATURE_VERSION.equals(name) || CREATED_BY.equals(name))
          continue;

        writeHeader(name.toString(), (String) e.getValue(), out);
      }
    out.write(CRLF);

    Iterator j;
    for (i = entries.entrySet().iterator(); i.hasNext();)
      {
        e = (Map.Entry) i.next();
        writeHeader(NAME, e.getKey().toString(), out);
        Attributes eAttr = (Attributes) e.getValue();
        for (j = eAttr.entrySet().iterator(); j.hasNext();)
          {
            Map.Entry e2 = (Map.Entry) j.next();
            writeHeader(e2.getKey().toString(), (String) e2.getValue(), out);
          }
        out.write(CRLF);
      }

    out.flush();
  }

  private static void writeVersionInfo(Attributes attr, OutputStream out)
      throws IOException
  {
    // First check if there is already a version attribute set
    String version = attr.getValue(Name.MANIFEST_VERSION);
    if (version == null)
      version = DEFAULT_MF_VERSION;

    writeHeader(Name.MANIFEST_VERSION.toString(), version, out);
  }

  private static void writeAttributeEntry(Map.Entry entry, OutputStream out)
      throws IOException
  {
    String name = entry.getKey().toString();
    String value = entry.getValue().toString();
    if (name.equalsIgnoreCase(NAME))
      throw new JarException("Attributes cannot be called 'Name'");

    if (name.startsWith("From"))
      throw new JarException("Header cannot start with the four letters 'From'"
                             + name);

    writeHeader(name, value, out);
  }

  /**
   * The basic method for writing <code>Mainfest</code> attributes. This
   * implementation respects the rule stated in the Jar Specification concerning
   * the maximum allowed line length; i.e.
   * 
   * <pre>
   * No line may be longer than 72 bytes (not characters), in its UTF8-encoded
   * form. If a value would make the initial line longer than this, it should
   * be continued on extra lines (each starting with a single SPACE).
   * </pre>
   * 
   * and
   * 
   * <pre>
   * Because header names cannot be continued, the maximum length of a header
   * name is 70 bytes (there must be a colon and a SPACE after the name).
   * </pre>
   * 
   * @param name the name of the attribute.
   * @param value the value of the attribute.
   * @param out the output stream to write the attribute's name/value pair to.
   * @throws IOException if an I/O related exception occurs during the process.
   */
  private static void writeHeader(String name, String value, OutputStream out)
      throws IOException
  {
    String target = name + ": ";
    byte[] b = target.getBytes("UTF-8");
    if (b.length > 72)
      throw new IOException("Attribute's name already longer than 70 bytes");

    if (b.length == 72)
      {
        out.write(b);
        out.write(CRLF);
        target = " " + value;
      }
    else
      target = target + value;

    int n;
    while (true)
      {
        b = target.getBytes("UTF-8");
        if (b.length < 73)
          {
            out.write(b);
            break;
          }

        // find an appropriate character position to break on
        n = 72;
        while (true)
          {
            b = target.substring(0, n).getBytes("UTF-8");
            if (b.length < 73)
              break;

            n--;
            if (n < 1)
              throw new IOException("Header is unbreakable and longer than 72 bytes");
          }

        out.write(b);
        out.write(CRLF);
        target = " " + target.substring(n);
      }

    out.write(CRLF);
  }
}
