Package files utility : Zip Tar File « File Input Output « Java






Package files utility

     
/*   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.
 */

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Repackage {
  public static void main(String[] args) throws Exception {
    new Repackage(args).repackage();
  }

  private Repackage(String[] args) {
    String sourceDir = null;
    String targetDir = null;
    String repackageSpec = null;
    boolean failure = false;

    for (int i = 0; i < args.length; i++) {
      if (args[i].equals("-repackage") && i + 1 < args.length)
        repackageSpec = args[++i];
      else if (args[i].equals("-f") && i + 1 < args.length)
        sourceDir = args[++i];
      else if (args[i].equals("-t") && i + 1 < args.length)
        targetDir = args[++i];
      else
        failure = true;
    }

    if (failure || repackageSpec == null || (sourceDir == null ^ targetDir == null))
      throw new RuntimeException(
          "Usage: repackage -repackage [spec] [ -f [sourcedir] -t [targetdir] ]");

    _repackager = new Repackager(repackageSpec);

    if (sourceDir == null || targetDir == null)
      return;

    _sourceBase = new File(sourceDir);
    _targetBase = new File(targetDir);
  }

  public void repackage() throws Exception {
    if (_sourceBase == null || _targetBase == null) { // read from system.in,
                                                      // write on system.out
      System.out.println(_repackager.repackage(readInputStream(System.in)).toString());
      return;
    }

    _fromPackages = _repackager.getFromPackages();
    _toPackages = _repackager.getToPackages();

    _packagePattern = Pattern.compile("^\\s*package\\s+((?:\\w|\\.)*)\\s*;", Pattern.MULTILINE);

    _moveAlongFiles = new ArrayList();
    _movedDirs = new HashMap();

    // System.out.println( "Deleting repackage dir ..." );
    // recursiveDelete( _targetBase );

    _targetBase.mkdirs();

    ArrayList files = new ArrayList();

    fillFiles(files, _sourceBase);

    System.out.println("Repackaging " + files.size() + " files ...");

    int prefixLength = _sourceBase.getCanonicalPath().length();

    for (int i = 0; i < files.size(); i++) {
      File from = (File) files.get(i);

      String name = from.getCanonicalPath().substring(prefixLength + 1);

      repackageFile(name);
    }

    finishMovingFiles();

    if (_skippedFiles > 0)
      System.out.println("Skipped " + _skippedFiles + " unmodified files.");
  }

  private boolean fileIsUnchanged(String name) {
    File sourceFile = new File(_sourceBase, name);
    File targetFile = new File(_targetBase, name);
    return (sourceFile.lastModified() < targetFile.lastModified());
  }

  public void repackageFile(String name) throws IOException {
    if (name.endsWith(".java"))
      repackageJavaFile(name);
    else if (name.endsWith(".xsdconfig") || name.endsWith(".xml") || name.endsWith(".g"))
      repackageNonJavaFile(name);
    else if (name.startsWith("bin" + File.separatorChar))
      repackageNonJavaFile(name);
    else
      moveAlongWithJavaFiles(name);
  }

  public void moveAlongWithJavaFiles(String name) {
    _moveAlongFiles.add(name);
  }

  public void finishMovingFiles() throws IOException {
    for (Iterator i = _moveAlongFiles.iterator(); i.hasNext();) {
      String name = (String) i.next();
      String toName = name;

      String srcDir = Repackager.dirForPath(name);
      String toDir = (String) _movedDirs.get(srcDir);

      if (toDir != null)
        toName = new File(toDir, new File(name).getName()).toString();

      if (name.endsWith(".html"))
        repackageNonJavaFile(name, toName);
      else
        justMoveNonJavaFile(name, toName);
    }
  }

  public void repackageNonJavaFile(String name) throws IOException {
    File sourceFile = new File(_sourceBase, name);
    File targetFile = new File(_targetBase, name);

    if (sourceFile.lastModified() < targetFile.lastModified())
      _skippedFiles += 1;
    else
      writeFile(targetFile, _repackager.repackage(readFile(sourceFile)));
  }

  public void repackageNonJavaFile(String sourceName, String targetName) throws IOException {
    File sourceFile = new File(_sourceBase, sourceName);
    File targetFile = new File(_targetBase, targetName);

    if (sourceFile.lastModified() < targetFile.lastModified())
      _skippedFiles += 1;
    else
      writeFile(targetFile, _repackager.repackage(readFile(sourceFile)));
  }

  public void justMoveNonJavaFile(String sourceName, String targetName) throws IOException {
    File sourceFile = new File(_sourceBase, sourceName);
    File targetFile = new File(_targetBase, targetName);

    if (sourceFile.lastModified() < targetFile.lastModified())
      _skippedFiles += 1;
    else
      copyFile(sourceFile, targetFile);
  }

  public void repackageJavaFile(String name) throws IOException {
    File sourceFile = new File(_sourceBase, name);
    StringBuffer sb = readFile(sourceFile);

    Matcher packageMatcher = _packagePattern.matcher(sb);

    if (packageMatcher.find()) {
      String pkg = packageMatcher.group(1);
      int pkgStart = packageMatcher.start(1);
      int pkgEnd = packageMatcher.end(1);

      if (packageMatcher.find())
        throw new RuntimeException("Two package specifications found: " + name);

      List filePath = Repackager.splitPath(name, File.separatorChar);
      String srcDir = Repackager.dirForPath(name);

      // Sort the repackage spec so that longer from's are first to match
      // longest package first

      for (;;) {
        boolean swapped = false;

        for (int i = 1; i < filePath.size(); i++) {
          String spec1 = (String) filePath.get(i - 1);
          String spec2 = (String) filePath.get(i);

          if (spec1.indexOf(':') < spec2.indexOf(':')) {
            filePath.set(i - 1, spec2);
            filePath.set(i, spec1);

            swapped = true;
          }
        }

        if (!swapped)
          break;
      }

      List pkgPath = Repackager.splitPath(pkg, '.');

      int f = filePath.size() - 2;

      if (f < 0 || (filePath.size() - 1) < pkgPath.size())
        throw new RuntimeException("Package spec differs from file path: " + name);

      for (int i = pkgPath.size() - 1; i >= 0; i--) {
        if (!pkgPath.get(i).equals(filePath.get(f)))
          throw new RuntimeException("Package spec differs from file path: " + name);
        f--;
      }

      List changeTo = null;
      List changeFrom = null;

      from: for (int i = 0; i < _fromPackages.size(); i++) {
        List from = (List) _fromPackages.get(i);

        if (from.size() <= pkgPath.size()) {
          for (int j = 0; j < from.size(); j++)
            if (!from.get(j).equals(pkgPath.get(j)))
              continue from;

          changeFrom = from;
          changeTo = (List) _toPackages.get(i);

          break;
        }
      }

      if (changeTo != null) {
        String newPkg = "";
        String newName = "";

        for (int i = 0; i < changeTo.size(); i++) {
          if (i > 0) {
            newPkg += ".";
            newName += File.separatorChar;
          }

          newPkg += changeTo.get(i);
          newName += changeTo.get(i);
        }

        for (int i = filePath.size() - pkgPath.size() - 2; i >= 0; i--)
          newName = (String) filePath.get(i) + File.separatorChar + newName;

        for (int i = changeFrom.size(); i < pkgPath.size(); i++) {
          newName += File.separatorChar + (String) pkgPath.get(i);
          newPkg += '.' + (String) pkgPath.get(i);
        }

        newName += File.separatorChar + (String) filePath.get(filePath.size() - 1);

        sb.replace(pkgStart, pkgEnd, newPkg);

        name = newName;
        String newDir = Repackager.dirForPath(name);

        if (!srcDir.equals(newDir)) {
          _movedDirs.put(srcDir, newDir);
        }
      }
    }

    File targetFile = new File(_targetBase, name); // new name

    if (sourceFile.lastModified() < targetFile.lastModified()) {
      _skippedFiles += 1;
      return;
    }

    writeFile(new File(_targetBase, name), _repackager.repackage(sb));
  }

  void writeFile(File f, StringBuffer chars) throws IOException {
    f.getParentFile().mkdirs();

    OutputStream out = new FileOutputStream(f);
    Writer w = new OutputStreamWriter(out);
    Reader r = new StringReader(chars.toString());

    copy(r, w);

    r.close();
    w.close();
    out.close();
  }

  StringBuffer readFile(File f) throws IOException {
    InputStream in = new FileInputStream(f);
    Reader r = new InputStreamReader(in);
    StringWriter w = new StringWriter();

    copy(r, w);

    w.close();
    r.close();
    in.close();

    return w.getBuffer();
  }

  StringBuffer readInputStream(InputStream is) throws IOException {
    Reader r = new InputStreamReader(is);
    StringWriter w = new StringWriter();

    copy(r, w);

    w.close();
    r.close();

    return w.getBuffer();
  }

  public static void copyFile(File from, File to) throws IOException {
    to.getParentFile().mkdirs();

    FileInputStream in = new FileInputStream(from);
    FileOutputStream out = new FileOutputStream(to);

    copy(in, out);

    out.close();
    in.close();
  }

  public static void copy(InputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[1024 * 16];

    for (;;) {
      int n = in.read(buffer, 0, buffer.length);

      if (n < 0)
        break;

      out.write(buffer, 0, n);
    }
  }

  public static void copy(Reader r, Writer w) throws IOException {
    char[] buffer = new char[1024 * 16];

    for (;;) {
      int n = r.read(buffer, 0, buffer.length);

      if (n < 0)
        break;

      w.write(buffer, 0, n);
    }
  }

  public void fillFiles(ArrayList files, File file) throws IOException {
    if (!file.isDirectory()) {
      files.add(file);
      return;
    }

    // Exclude the build directory

    if (file.getName().equals("build"))
      return;

    // Exclude CVS directories
    if (file.getName().equals("CVS"))
      return;

    String[] entries = file.list();

    for (int i = 0; i < entries.length; i++)
      fillFiles(files, new File(file, entries[i]));
  }

  public void recursiveDelete(File file) throws IOException {
    if (!file.exists())
      return;

    if (file.isDirectory()) {
      String[] entries = file.list();

      for (int i = 0; i < entries.length; i++)
        recursiveDelete(new File(file, entries[i]));
    }

    file.delete();
  }

  private File _sourceBase;

  private File _targetBase;

  private List _fromPackages;

  private List _toPackages;

  private Pattern _packagePattern;

  private Repackager _repackager;

  private Map _movedDirs;

  private List _moveAlongFiles;

  private int _skippedFiles;
}

/*
 * 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.
 */

class Repackager {
  public Repackager(String repackageSpecs) {
    _fromPackages = new ArrayList();
    _toPackages = new ArrayList();

    List repackages = splitPath(repackageSpecs, ';');

    // Sort the repackage spec so that longer from's are first to match
    // longest package first

    for (;;) {
      boolean swapped = false;

      for (int i = 1; i < repackages.size(); i++) {
        String spec1 = (String) repackages.get(i - 1);
        String spec2 = (String) repackages.get(i);

        if (spec1.indexOf(':') < spec2.indexOf(':')) {
          repackages.set(i - 1, spec2);
          repackages.set(i, spec1);

          swapped = true;
        }
      }

      if (!swapped)
        break;
    }

    for (int i = 0; i < repackages.size(); i++) {
      String spec = (String) repackages.get(i);

      int j = spec.indexOf(':');

      if (j < 0 || spec.indexOf(':', j + 1) >= 0)
        throw new RuntimeException("Illegal repackage specification: " + spec);

      String from = spec.substring(0, j);
      String to = spec.substring(j + 1);

      _fromPackages.add(Repackager.splitPath(from, '.'));
      _toPackages.add(Repackager.splitPath(to, '.'));
    }

    _fromMatchers = new Matcher[_fromPackages.size() * 2];
    _toPackageNames = new String[_fromPackages.size() * 2];

    addPatterns('.', 0);
    addPatterns('/', _fromPackages.size());
  }

  void addPatterns(char sep, int off) {
    for (int i = 0; i < _fromPackages.size(); i++) {
      List from = (List) _fromPackages.get(i);
      List to = (List) _toPackages.get(i);

      String pattern = "";

      for (int j = 0; j < from.size(); j++) {
        if (j > 0)
          pattern += "\\" + sep;

        pattern += from.get(j);
      }

      String toPackage = "";

      for (int j = 0; j < to.size(); j++) {
        if (j > 0)
          toPackage += sep;

        toPackage += to.get(j);
      }

      _fromMatchers[off + i] = Pattern.compile(pattern).matcher("");
      _toPackageNames[off + i] = toPackage;
    }
  }

  public StringBuffer repackage(StringBuffer sb) {
    StringBuffer result = null;

    for (int i = 0; i < _fromMatchers.length; i++) {
      Matcher m = (Matcher) _fromMatchers[i];

      m.reset(sb);

      for (boolean found = m.find(); found; found = m.find()) {
        if (result == null)
          result = new StringBuffer();

        m.appendReplacement(result, _toPackageNames[i]);
      }

      if (result != null) {
        m.appendTail(result);
        sb = result;
        result = null;
      }
    }

    return sb;
  }

  public List getFromPackages() {
    return _fromPackages;
  }

  public List getToPackages() {
    return _toPackages;
  }

  public static ArrayList splitPath(String path, char separator) {
    ArrayList components = new ArrayList();

    for (;;) {
      int i = path.indexOf(separator);

      if (i < 0)
        break;

      components.add(path.substring(0, i));

      path = path.substring(i + 1);
    }

    if (path.length() > 0)
      components.add(path);

    return components;
  }

  public static String dirForPath(String path) {
    return new File(path).getParent();
  }

  private List _fromPackages;

  private List _toPackages;

  private Matcher[] _fromMatchers;

  private String[] _toPackageNames;
}

   
    
    
    
    
  








Related examples in the same category

1.Extract contents of a zip file
2.List the contents of a zip file
3.Read entries in a zip / compressed file
4.Decompress a zip file using ZipInputStream
5.Decompress a zip file using ZipFile
6.Create checksum for a zip file
7.Read a zip file checksum value
8.Create a zip file with java.util.zip package
9.Extract file/files from a zip file
10.Read files within a zip file
11.Retrieve a compressed file from a ZIP file
12.Retrieve the contents of a ZIP file
13.Making a zip file of directory including its subdirectories recursively
14.Displaying contents of a compressed zip file
15.Compress a Byte Array
16.Decompress a Byte Array
17.Read zip file
18.Write Zip file
19.The java.util.zip package can be used to create a checksum.
20.Read the content of a zip file ZipFile
21.List the entries of a zip file
22.Compressing Streams: Zipper, Java example
23.Compressing Streams: Parity Checksum
24.Compressing Streams: File Summer
25.Create a simple ZIP File: not retain any directory path information about the files.
26.Decompress a ZIP file.
27.Decompressing a Byte Array
28.Zip unzip byte array
29.Creating a ZIP File
30.Listing the Contents of a ZIP File
31.Retrieving a Compressed File from a ZIP File
32.Calculating the Checksum of a Byte Array (Compute Adler-32 checksum)
33.Compute CRC-32 checksum
34.Calculating the Checksum of a File
35.Compress string(byte array) by Deflater
36.Use Java code to zip a folder
37.Uses Zip compression to compress any number of files given on the command line
38.Load zip file and scan zip file
39.Reading the Contents of a ZIP File
40.UnZip -- print or unzip a JAR or PKZIP file using java.util.zip
41.Tape Archive Lister: Tar file
42.Compressing a Byte Array
43.Tar file stream
44.Tar file and untar file
45.bzip source code
46.Unpack an archive from a URL
47.Compare two zip files
48.Determine whether a file is a ZIP File.
49.Zip up a directory
50.Check sum for a path
51.Check sum for an InputStream
52.Extract zip file to destination folder
53.Return the first directory of this archive. This is needed to determine the plugin directory
54.Makes a zip file named xmlFileName from xmlURL at path
55.Unzipps a zip file placed at zipURL to path
56.A single checksum calculation for multiple files
57.Put file To Zip File
58.Provides both writing and reading from a file which is transparently compressed in Zip
59.TarInputStream reads a UNIX tar archive as an InputStream
60.TarOutputStream writes a UNIX tar archive as an OutputStream
61.Zip Compare
62.Unpack a segment from a zip
63.Unpack a zip file
64.Unzip file to a directory
65.Zip a list of file into one zip file.
66.Validate that an archive contains a named entry
67.A frame with a text area to show the contents of a file inside a ZIP archive
68.Compress object and decompress
69.Util for extracting *.jar, *.war and *.zip archives.