/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.xmlbeans.impl.common;

import java.io.*;
import java.util.jar.JarOutputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

/**
 * Provides utility services for jarring and unjarring files and directories.
 * Note that a given instance of JarHelper is not threadsafe with respect to
 * multiple jar operations.
 *
 * @author Patrick Calahan <pcal@bea.com>
 */
public class JarHelper
{
  // ========================================================================
  // Constants

  private static final int BUFFER_SIZE = 2156;

  // ========================================================================
  // Variables

  private byte[] mBuffer = new byte[BUFFER_SIZE];
  private int mByteCount = 0;
  private boolean mVerbose = false;
  private String mDestJarName = "";

  // ========================================================================
  // Constructor

  /**
   * Instantiates a new JarHelper.
   */
  public JarHelper() {}

  // ========================================================================
  // Public methods

  /**
   * Jars a given directory or single file into a JarOutputStream.
   */
  public void jarDir(File dirOrFile2Jar, File destJar)
          throws IOException {

    if (dirOrFile2Jar == null || destJar == null)
        throw new IllegalArgumentException();

    mDestJarName = destJar.getCanonicalPath();
    FileOutputStream fout = new FileOutputStream(destJar);
    JarOutputStream jout = new JarOutputStream(fout);
    //jout.setLevel(0);
    try {
      jarDir(dirOrFile2Jar, jout, null);
    } catch(IOException ioe) {
      throw ioe;
    } finally {
      jout.close();
      fout.close();
    }
  }

  /**
   * Unjars a given jar file into a given directory.
   */
  public void unjarDir(File jarFile, File destDir) throws IOException {
    BufferedOutputStream dest = null;
    FileInputStream fis = new FileInputStream(jarFile);
    unjar(fis,destDir);
  }

  /**
   * Given an InputStream on a jar file, unjars the contents into the given
   * directory.
   */
  public void unjar(InputStream in, File destDir) throws IOException {
    BufferedOutputStream dest = null;
    JarInputStream jis = new JarInputStream(in);
    JarEntry entry;
    while ((entry = jis.getNextJarEntry()) != null) {
      if (entry.isDirectory()) {
        File dir = new File(destDir,entry.getName());
        dir.mkdir();
        if (entry.getTime() != -1) dir.setLastModified(entry.getTime());
        continue;
      }
      int count;
      byte data[] = new byte[BUFFER_SIZE];
      File destFile = new File(destDir, entry.getName());
      if (mVerbose)
        System.out.println("unjarring " + destFile +
                           " from " + entry.getName());
      FileOutputStream fos = new FileOutputStream(destFile);
      dest = new BufferedOutputStream(fos, BUFFER_SIZE);
      while ((count = jis.read(data, 0, BUFFER_SIZE)) != -1) {
        dest.write(data, 0, count);
      }
      dest.flush();
      dest.close();
      if (entry.getTime() != -1) destFile.setLastModified(entry.getTime());
    }
    jis.close();
  }

  public void setVerbose(boolean b) {
    mVerbose = b;
  }

  // ========================================================================
  // Private methods

  private static final char SEP = '/';
  /**
   * Recursively jars up the given path under the given directory.
   */
  private void jarDir(File dirOrFile2jar, JarOutputStream jos, String path)
          throws IOException {
    if (mVerbose) System.out.println("checking " + dirOrFile2jar);
    if (dirOrFile2jar.isDirectory()) {
      String[] dirList = dirOrFile2jar.list();
      String subPath = (path == null) ? "" : (path+dirOrFile2jar.getName()+SEP);
      if (path != null) {
        JarEntry je = new JarEntry(subPath);
        je.setTime(dirOrFile2jar.lastModified());
        jos.putNextEntry(je);
        jos.flush();
        jos.closeEntry();
      }
      for (int i = 0; i < dirList.length; i++) {
        File f = new File(dirOrFile2jar, dirList[i]);
        jarDir(f,jos,subPath);
      }
    } else {
      if (dirOrFile2jar.getCanonicalPath().equals(mDestJarName))
      {
        if (mVerbose) System.out.println("skipping " + dirOrFile2jar.getPath());
        return;
      }

      if (mVerbose) System.out.println("adding " + dirOrFile2jar.getPath());
      FileInputStream fis = new FileInputStream(dirOrFile2jar);
      try {
        JarEntry entry = new JarEntry(path+dirOrFile2jar.getName());
        entry.setTime(dirOrFile2jar.lastModified());
        jos.putNextEntry(entry);
        while ((mByteCount = fis.read(mBuffer)) != -1) {
          jos.write(mBuffer, 0, mByteCount);
          if (mVerbose) System.out.println("wrote " + mByteCount + " bytes");
        }
        jos.flush();
        jos.closeEntry();
      } catch (IOException ioe) {
        throw ioe;
      } finally {
        fis.close();
      }
    }
  }

  // for debugging
  public static void main(String[] args)
      throws IOException
  {
      if (args.length < 2)
      {
        System.err.println("Usage: JarHelper jarname.jar directory");
        return;
      }

      JarHelper jarHelper = new JarHelper();
      jarHelper.mVerbose = true;

      File destJar = new File(args[0]);
      File dirOrFile2Jar = new File(args[1]);

      jarHelper.jarDir(dirOrFile2Jar, destJar);
  }
}
