Package org.eclipse.core.internal.utils

Source Code of org.eclipse.core.internal.utils.FileUtil

/*******************************************************************************
* Copyright (c) 2005, 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.core.internal.utils;

import java.io.*;
import java.net.URI;
import org.eclipse.core.filesystem.*;
import org.eclipse.core.internal.resources.ResourceException;
import org.eclipse.core.internal.resources.Workspace;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.ResourceAttributes;
import org.eclipse.core.runtime.*;
import org.eclipse.osgi.util.NLS;

/**
* Static utility methods for manipulating Files and URIs.
*/
public class FileUtil {
  /**
   * Singleton buffer created to prevent buffer creations in the
   * transferStreams method.  Used as an optimization, based on the assumption
   * that multiple writes won't happen in a given instance of FileStore.
   */
  private static final byte[] buffer = new byte[8192];

  /**
   * Converts a ResourceAttributes object into an IFileInfo object.
   * @param attributes The resource attributes
   * @return The file info
   */
  public static IFileInfo attributesToFileInfo(ResourceAttributes attributes) {
    IFileInfo fileInfo = EFS.createFileInfo();
    fileInfo.setAttribute(EFS.ATTRIBUTE_READ_ONLY, attributes.isReadOnly());
    fileInfo.setAttribute(EFS.ATTRIBUTE_EXECUTABLE, attributes.isExecutable());
    fileInfo.setAttribute(EFS.ATTRIBUTE_ARCHIVE, attributes.isArchive());
    fileInfo.setAttribute(EFS.ATTRIBUTE_HIDDEN, attributes.isHidden());
    return fileInfo;
  }

  /**
   * Converts an IPath into its canonical form for the local file system.
   */
  public static IPath canonicalPath(IPath path) {
    if (path == null)
      return null;
    try {
      final String pathString = path.toOSString();
      final String canonicalPath = new java.io.File(pathString).getCanonicalPath();
      //only create a new path if necessary
      if (canonicalPath.equals(pathString))
        return path;
      return new Path(canonicalPath);
    } catch (IOException e) {
      return path;
    }
  }

  /**
   * Converts a URI into its canonical form.
   */
  public static URI canonicalURI(URI uri) {
    if (uri == null)
      return null;
    if (EFS.SCHEME_FILE.equals(uri.getScheme())) {
      //only create a new URI if it is different
      final IPath inputPath = URIUtil.toPath(uri);
      final IPath canonicalPath = canonicalPath(inputPath);
      if (inputPath == canonicalPath)
        return uri;
      return URIUtil.toURI(canonicalPath);
    }
    return uri;
  }

  /**
   * Returns true if the given file system locations overlap. If "bothDirections" is true,
   * this means they are the same, or one is a proper prefix of the other.  If "bothDirections"
   * is false, this method only returns true if the locations are the same, or the first location
   * is a prefix of the second.  Returns false if the locations do not overlap
   * Does the right thing with respect to case insensitive platforms.
   */
  private static boolean computeOverlap(IPath location1, IPath location2, boolean bothDirections) {
    IPath one = location1;
    IPath two = location2;
    // If we are on a case-insensitive file system then convert to all lower case.
    if (!Workspace.caseSensitive) {
      one = new Path(location1.toOSString().toLowerCase());
      two = new Path(location2.toOSString().toLowerCase());
    }
    return one.isPrefixOf(two) || (bothDirections && two.isPrefixOf(one));
  }

  /**
   * Returns true if the given file system locations overlap. If "bothDirections" is true,
   * this means they are the same, or one is a proper prefix of the other.  If "bothDirections"
   * is false, this method only returns true if the locations are the same, or the first location
   * is a prefix of the second.  Returns false if the locations do not overlap
   */
  private static boolean computeOverlap(URI location1, URI location2, boolean bothDirections) {
    if (location1.equals(location2))
      return true;
    String scheme1 = location1.getScheme();
    String scheme2 = location2.getScheme();
    if (scheme1 == null ? scheme2 != null : !scheme1.equals(scheme2))
      return false;
    if (EFS.SCHEME_FILE.equals(scheme1) && EFS.SCHEME_FILE.equals(scheme2))
      return computeOverlap(URIUtil.toPath(location1), URIUtil.toPath(location2), bothDirections);
    IFileSystem system = null;
    try {
      system = EFS.getFileSystem(scheme1);
    } catch (CoreException e) {
      //handled below
    }
    if (system == null) {
      //we are stuck with string comparison
      String string1 = location1.toString();
      String string2 = location2.toString();
      return string1.startsWith(string2) || (bothDirections && string2.startsWith(string1));
    }
    IFileStore store1 = system.getStore(location1);
    IFileStore store2 = system.getStore(location2);
    return store1.equals(store2) || store1.isParentOf(store2) || (bothDirections && store2.isParentOf(store1));
  }

  /**
   * Converts an IFileInfo object into a ResourceAttributes object.
   * @param fileInfo The file info
   * @return The resource attributes
   */
  public static ResourceAttributes fileInfoToAttributes(IFileInfo fileInfo) {
    ResourceAttributes attributes = new ResourceAttributes();
    attributes.setReadOnly(fileInfo.getAttribute(EFS.ATTRIBUTE_READ_ONLY));
    attributes.setArchive(fileInfo.getAttribute(EFS.ATTRIBUTE_ARCHIVE));
    attributes.setExecutable(fileInfo.getAttribute(EFS.ATTRIBUTE_EXECUTABLE));
    attributes.setHidden(fileInfo.getAttribute(EFS.ATTRIBUTE_HIDDEN));
    return attributes;
  }

  /**
   * Returns true if the given file system locations overlap, and false otherwise.
   * Overlap means the locations are the same, or one is a proper prefix of the other.
   */
  public static boolean isOverlapping(URI location1, URI location2) {
    return computeOverlap(location1, location2, true);
  }

  /**
   * Returns true if location1 is the same as, or a proper prefix of, location2.
   * Returns false otherwise.
   */
  public static boolean isPrefixOf(IPath location1, IPath location2) {
    return computeOverlap(location1, location2, false);
  }

  /**
   * Returns true if location1 is the same as, or a proper prefix of, location2.
   * Returns false otherwise.
   */
  public static boolean isPrefixOf(URI location1, URI location2) {
    return computeOverlap(location1, location2, false);
  }

  /**
   * Closes a stream and ignores any resulting exception. This is useful
   * when doing stream cleanup in a finally block where secondary exceptions
   * are not worth logging.
   */
  public static void safeClose(InputStream in) {
    try {
      if (in != null)
        in.close();
    } catch (IOException e) {
      //ignore
    }
  }

  /**
   * Closes a stream and ignores any resulting exception. This is useful
   * when doing stream cleanup in a finally block where secondary exceptions
   * are not worth logging.
   */
  public static void safeClose(OutputStream out) {
    try {
      if (out != null)
        out.close();
    } catch (IOException e) {
      //ignore
    }
  }

  /**
   * Converts a URI to an IPath.  Returns null if the URI cannot be represented
   * as an IPath.
   * <p>
   * Note this method differs from URIUtil in its handling of relative URIs
   * as being relative to path variables.
   */
  public static IPath toPath(URI uri) {
    if (uri == null)
      return null;
    final String scheme = uri.getScheme();
    // null scheme represents path variable
    if (scheme == null || EFS.SCHEME_FILE.equals(scheme))
      return new Path(uri.getSchemeSpecificPart());
    return null;
  }

  public static final void transferStreams(InputStream source, OutputStream destination, String path, IProgressMonitor monitor) throws CoreException {
    monitor = Policy.monitorFor(monitor);
    try {
      /*
       * Note: although synchronizing on the buffer is thread-safe,
       * it may result in slower performance in the future if we want
       * to allow concurrent writes.
       */
      synchronized (buffer) {
        while (true) {
          int bytesRead = -1;
          try {
            bytesRead = source.read(buffer);
          } catch (IOException e) {
            String msg = NLS.bind(Messages.localstore_failedReadDuringWrite, path);
            throw new ResourceException(IResourceStatus.FAILED_READ_LOCAL, new Path(path), msg, e);
          }
          if (bytesRead == -1)
            break;
          try {
            destination.write(buffer, 0, bytesRead);
          } catch (IOException e) {
            String msg = NLS.bind(Messages.localstore_couldNotWrite, path);
            throw new ResourceException(IResourceStatus.FAILED_WRITE_LOCAL, new Path(path), msg, e);
          }
          monitor.worked(1);
        }
      }
    } finally {
      safeClose(source);
      safeClose(destination);
    }
  }

  /**
   * Not intended for instantiation.
   */
  private FileUtil() {
    super();
  }
}
TOP

Related Classes of org.eclipse.core.internal.utils.FileUtil

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.