Package org.emrys.webosgi.common.util

Source Code of org.emrys.webosgi.common.util.FileUtil$IFileFilter

package org.emrys.webosgi.common.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
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.net.URL;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.zip.Adler32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.emrys.webosgi.common.CommonActivator;
import org.osgi.framework.Bundle;

/**
* The utilitarian class providing many convenient method to manipulate file.
*
* @author Leo Chang
* @version 2010-10-22
*/
public class FileUtil {
  /**
   * Write input stream to a file.
   *
   * @param in
   * @param targetFile
   * @throws Exception
   */
  public static void writeToFile(InputStream in, File targetFile)
      throws Exception {
    createFile(targetFile, false);
    FileOutputStream fout = new FileOutputStream(targetFile);
    while (in.available() > 0) {
      int data = in.read();
      fout.write(data);
    }
    fout.close();
    in.close();
  }

  public static File getBundleJar(Bundle bundle) throws IOException {
    URL bundleFileUrl = FileLocator.resolve(bundle.getEntry("/"));
    return new Path(bundleFileUrl.getPath()).toFile();
  }

  /**
   * Unzip jar file to target directory.
   *
   * @param file
   * @param srcRelPath
   *            relative path to jar root. if not null, only unzip this path
   *            in jar to target file, otherwise, unzip all content. This path
   *            should not start with '/'.
   * @param targetFile
   *            if not exists, automatically create.
   * @throws IOException
   */
  public static void unZipFile(File file, String srcRelPath, File targetFile)
      throws IOException {
    if (!targetFile.exists() && !createFile(targetFile, true))
      throw new IOException("Cann't create target file:"
          + targetFile.getAbsolutePath());

    if (targetFile.isFile())
      throw new IllegalArgumentException("target file not a directory");

    ZipFile zipFile = null;
    try {
      zipFile = new ZipFile(file);
    } catch (Exception e1) {
      // e1.printStackTrace();
      throw new IllegalArgumentException("file not a zip file.");
    }

    IPath srcPath = null;
    if (srcRelPath == null || srcRelPath.length() == 0
        || srcRelPath.equals("/"))
      srcPath = null;
    else {
      // Remove the first '/' if any.
      if (srcRelPath.startsWith("/"))
        srcRelPath = srcRelPath.substring(1);
      srcPath = new Path(srcRelPath);
    }

    ZipEntry zipEntry;
    Enumeration<? extends ZipEntry> enumer;
    BufferedInputStream is = null;
    FileOutputStream fos = null;
    byte data[] = new byte[1024];
    try {
      if (zipFile.size() == 0)
        return;

      enumer = zipFile.entries();
      while (enumer.hasMoreElements()) {
        zipEntry = enumer.nextElement();
        if (srcPath != null
            && !srcPath.isPrefixOf(new Path(zipEntry.getName())))
          continue;

        if (zipEntry.isDirectory())
          continue;
        is = new BufferedInputStream(zipFile.getInputStream(zipEntry));
        // System.out.println(xJarEntry.getName());

        IPath relPath = new Path(zipEntry.getName());
        if (srcPath != null && !srcPath.equals(relPath))
          relPath = makeRelativeTo(relPath, srcPath);
        // If the src file path is a file, use the file's name as
        // relative path.
        if (srcPath != null && srcPath.equals(relPath))
          relPath = new Path(relPath.lastSegment());

        File newFile = new File(new Path(targetFile.getAbsolutePath())
            .append(relPath).toPortableString());
        FileUtil.createFile(newFile, false);
        fos = new FileOutputStream(newFile);
        int len = 0;
        while ((len = is.read(data)) != -1) {
          fos.write(data, 0, len);
        }
        fos.flush();
        fos.close();
        fos = null;

        // Copy the last modified time.
        long modifiedTime = zipEntry.getTime();
        if (modifiedTime > 0)
          newFile.setLastModified(modifiedTime);
      }
    } finally {
      try {
        zipFile.close();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

  /**
   * To support org.eclipse.equinox.common 3.4, here supply our
   * IPath.makeRelativeTo(IPath base) method in 3.5.
   *
   * Returns a path equivalent to this path, but relative to the given base
   * path if possible.
   * <p>
   * The path is only made relative if the base path if both paths have the
   * same device and have a non-zero length common prefix. If the paths have
   * different devices, or no common prefix, then this path is simply
   * returned. If the path is successfully made relative, then appending the
   * returned path to the base will always produce a path equal to this path.
   * </p>
   *
   * @param path
   *            the source path to make relative.
   * @param base
   *            The base path to make this path relative to
   * @return A path relative to the base path, or this path if it could
   */
  public static IPath makeRelativeTo(IPath path, IPath base) {
    // can't make relative if devices are not equal
    String device = path.getDevice();
    if (device != base.getDevice()
        && (device == null || !device
            .equalsIgnoreCase(base.getDevice())))
      return path;
    int commonLength = path.matchingFirstSegments(base);
    final int differenceLength = base.segmentCount() - commonLength;
    final int newSegmentLength = differenceLength + path.segmentCount()
        - commonLength;
    if (newSegmentLength == 0)
      return Path.EMPTY;
    String[] newSegments = new String[newSegmentLength];
    // add parent references for each segment different from the base
    Arrays.fill(newSegments, 0, differenceLength, ".."); //$NON-NLS-1$
    // append the segments of this path not in common with the base
    System.arraycopy(path.segments(), commonLength, newSegments,
        differenceLength, newSegmentLength - differenceLength);
    StringBuffer pathStr = new StringBuffer(newSegments[0]);
    for (int i = 1; i < newSegmentLength; i++) {
      pathStr.append(Path.SEPARATOR);
      pathStr.append(newSegments[i]);
      if (i == newSegmentLength - 1 && path.hasTrailingSeparator())
        pathStr.append(Path.SEPARATOR);
    }
    return new Path(null, pathStr.toString());
  }

  /**
   * Convert a URL to local file resource. This means if this url is local
   * file, it's easy to understand. But it this url's protocol is "http" or
   * "ftp", "jar", "zip", a local file or folder indicated by this url will be
   * created and this temporary file or folder's contents will obtained by the
   * protocol, for example, if "http", this method will request form web and
   * the folder construction will remain.
   *
   * @param fileUrl
   * @param monitor
   * @return
   * @throws CoreException
   */
  public static File convert2LocalFileByURL(URL fileUrl,
      IProgressMonitor monitor) throws CoreException {
    if (monitor == null)
      monitor = new NullProgressMonitor();

    if (fileUrl.getProtocol().equals("file")) {
      File tiLocalFile = new File(fileUrl.getFile());
      if (tiLocalFile.exists())
        return tiLocalFile;
    }

    if (fileUrl.getProtocol().equals("http")) {

      try {
        fileUrl.openConnection();
        InputStream in = fileUrl.openStream();
        String urlFileName = fileUrl.getFile();
        String path = fileUrl.getQuery();
        if (urlFileName != null && urlFileName.length() > 0) {
          int index = urlFileName.lastIndexOf(".");
          String fName = urlFileName.substring(0, index);
          String fExt = (index == -1 || index == urlFileName.length() - 1) ? ".tmp"
              : urlFileName.substring(index + 1);

          File tmpLocalTiFile = File.createTempFile(
          /* "BTOOLS_TMP_" + */fName
          /* + System.currentTimeMillis() */, fExt, getTmpFileDir(
              path, true));
          try {
            writeToFile(in, tmpLocalTiFile);
          } catch (Exception e) {
            // e.printStackTrace();
          }

          return tmpLocalTiFile;
        } else {
          // Case this url is a folder, not a web file resource.
          BufferedReader reader = new BufferedReader(
              new InputStreamReader(in, "UTF-8"));
          String line = null;
          while ((line = reader.readLine()) != null) {
            try {
              URL url = new URL(line);
              convert2LocalFileByURL(url, monitor);
            } catch (Exception e) {
              e.printStackTrace();
            }
          }
          reader.close();
          in.close();
          return getTmpFileDir(path, true);
        }
      } catch (IOException e) {
        // e.printStackTrace();
        throw new CoreException(new Status(Status.ERROR,
            CommonActivator.ID,
            "Local file for Template Information File of"
                + fileUrl.toString() + "cann't be retrieved!",
            e));
      }
    }

    throw new CoreException(new Status(Status.ERROR, CommonActivator.ID,
        "Local file for Template Information File of"
            + fileUrl.toString() + "cann't be retrieved!"));
  }

  private static File getTmpFileDir(String path, boolean forceCreate) {
    File file = CommonActivator.getInstance().getStateLocation().append(
        new Path(path)).toFile();
    if (!file.exists() && forceCreate)
      file.mkdirs();

    return file;
  }

  /**
   * Create a file or a folder and its parent folders if need.
   *
   * @param target
   * @param isDirectory
   * @throws IOException
   */
  public static boolean createFile(File target, boolean isDirectory)
      throws IOException {
    if (!target.exists() || (isDirectory && target.isFile())
        || (!isDirectory && target.isDirectory())) {

      if (createFile(target.getParentFile(), true)) {
        if (isDirectory)
          return target.mkdir();
        else
          return target.createNewFile();
      }
    } else {
      return true;
    }

    return false;
  }

  public static interface IFileVisitor {
    /**
     * @param f
     * @return whether to visit child files if the current file is a
     *         directory.
     */
    boolean visit(File f);
  }

  public static interface IFileFilter {
    boolean intersted(File f);
  }

  /**
   * Visit each child file of root file.
   *
   * @param root
   *            the root to search for files to visit, include this root file.
   * @param filter
   * @return
   */
  public static void visitFiles(File file, IFileVisitor visitor) {
    Assert.isNotNull(visitor);
    if (file.exists()) {
      if (file.isDirectory()) {
        if (visitor.visit(file)) {
          File[] fileList = file.listFiles();
          for (int i = 0; i < fileList.length; i++) {
            visitFiles(fileList[i], visitor);
          }
        }
      } else
        visitor.visit(file);
    }
  }

  /**
   * Delete the given file and its all sub contents files.
   *
   * @param file
   * @param filter
   * @return
   */
  public static boolean deleteAllFile(File file, IFileFilter filter) {
    boolean ret = false;
    if (file.exists()) {
      if (file.isDirectory()) {
        if (filter == null || filter.intersted(file)) {
          filter = null;
        }
        File[] fileList = file.listFiles();
        for (int i = 0; i < fileList.length; i++) {
          deleteAllFile(fileList[i], filter);
        }
      }

      if (filter == null || filter.intersted(file)) {
        file.delete();
      }
    }

    return ret;
  }

  /**
   * Copy source file to target file, Caution: this method will override the
   * target file.
   *
   * @param sourceFile
   * @param targetFile
   * @throws IOException
   */
  public static void copyFile(File sourceFile, File targetFile)
      throws IOException {
    if (!sourceFile.exists())
      throw new IOException("Source file to copy("
          + sourceFile.getAbsolutePath() + ") not exists!");
    // Create target file if need.
    // FIXME: Maybe override some file, caution.
    boolean targetFileExists = targetFile.exists();
    if (!targetFileExists && !createFile(targetFile, false))
      throw new IOException("Cann't create new file:"
          + targetFile.getAbsolutePath());

    FileInputStream input = new FileInputStream(sourceFile);
    BufferedInputStream inBuff = new BufferedInputStream(input);

    FileOutputStream output = new FileOutputStream(targetFile);
    BufferedOutputStream outBuff = new BufferedOutputStream(output);

    byte[] b = new byte[1024 * 5];
    int len;
    while ((len = inBuff.read(b)) != -1) {
      outBuff.write(b, 0, len);
    }

    outBuff.flush();
    inBuff.close();
    outBuff.close();
    output.close();
    input.close();

    // Copy the last modified time, if the target file is new created.
    if (!targetFileExists) {
      long modifiedTime = sourceFile.lastModified();
      if (modifiedTime > 0)
        targetFile.setLastModified(modifiedTime);
    } /*
     * else targetFile.setLastModified(System.currentTimeMillis());
     */
  }

  /**
   * Copy contents of source folder to target folder. Caution: the file with
   * duplicated name will be overwrite.
   *
   * @param sourceDir
   * @param targetDir
   * @throws IOException
   */
  public static void copyDirectiory(String sourceDir, String targetDir)
      throws IOException {
    new File(targetDir).mkdirs();
    File[] file = (new File(sourceDir)).listFiles();
    for (int i = 0; i < file.length; i++) {
      if (file[i].isFile()) {
        File sourceFile = file[i];
        File targetFile = new File(new File(targetDir)
            .getAbsolutePath()
            + File.separator + file[i].getName());
        copyFile(sourceFile, targetFile);
      }
      if (file[i].isDirectory()) {
        String dir1 = sourceDir + "/" + file[i].getName();
        String dir2 = targetDir + "/" + file[i].getName();
        copyDirectiory(dir1, dir2);
      }
    }
  }

  /**
   * Get a text file's content with default encoding "UTF-8" if not set.
   *
   * @param file
   * @param charset
   *            Can be null, and default UTF-8
   * @return
   * @throws IOException
   */
  public static StringBuffer getContent(File file, String charset)
      throws IOException {
    return getContent(new FileInputStream(file), charset);
  }

  /**
   * Convert input stream to string content with default encoding "UTF-8" if
   * not set.
   *
   * @param inputStream
   * @param charset
   *            can be null, and default is UTF-8
   * @return
   * @throws IOException
   */
  public static StringBuffer getContent(InputStream inputStream,
      String charset) throws IOException {
    if (charset == null)
      charset = "UTF-8";

    StringBuffer sb = new StringBuffer();
    InputStreamReader fileReader = new InputStreamReader(inputStream,
        charset);
    BufferedReader br = new BufferedReader(fileReader);
    String str;
    while ((str = br.readLine()) != null) {
      sb.append(str);
      sb.append(System.getProperty("line.separator"));
    }

    fileReader.close();
    br.close();

    return sb;
  }

  public static void zipFolder(String sourcePath, String targetZipFilePath)
      throws Exception {
    File inputRoot = new Path(sourcePath).toFile();
    if (!inputRoot.exists() || !inputRoot.isDirectory())
      throw new IllegalArgumentException(
          "Source folder path to zip not invalid.");

    File zipFile = new Path(targetZipFilePath).toFile();

    if (FileUtil.createFile(zipFile, false)) {
      FileOutputStream out = new FileOutputStream(zipFile);
      CheckedOutputStream cs = new CheckedOutputStream(out, new Adler32());
      ZipOutputStream zout = new ZipOutputStream(
          new BufferedOutputStream(cs));
      zip(zout, inputRoot, "", cs);
      zout.close();
    } else
      throw new IOException("target zip file create failed.");

  }

  private static void zip(ZipOutputStream out, File inFile, String root,
      CheckedOutputStream cs) throws Exception {
    if (inFile.isDirectory()) {
      File[] files = inFile.listFiles();
      if (root == null)
        root = "";
      if (root.length() != 0)
        out.putNextEntry(new ZipEntry(root + "/"));
      root = root.length() == 0 ? "" : root + "/";
      for (int i = 0; i < files.length; i++) {
        zip(out, files[i], root + files[i].getName(), cs);
      }
    } else {
      BufferedInputStream in = new BufferedInputStream(
          new FileInputStream(inFile));
      long lastModifiedTime = inFile.lastModified();
      ZipEntry entry = new ZipEntry(root);
      if (lastModifiedTime > 0)
        entry.setTime(lastModifiedTime);
      out.putNextEntry(entry);
      int c;
      while ((c = in.read()) != -1)
        out.write(c);
      in.close();
      // System.out.println("Checksum::" + cs.getChecksum().getValue());
    }
  }

  public static byte[] getByteArray(InputStream in) throws IOException {
    ByteArrayOutputStream bo = new ByteArrayOutputStream();
    while (in.available() > 0) {
      bo.write(in.read());
    }
    return bo.toByteArray();

  }
}
TOP

Related Classes of org.emrys.webosgi.common.util.FileUtil$IFileFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.