/**
* This file Copyright (c) 2005-2008 Aptana, Inc. This program is
* dual-licensed under both the Aptana Public License and the GNU General
* Public license. You may elect to use one or the other of these licenses.
*
* This program is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. Redistribution, except as permitted by whichever of
* the GPL or APL you select, is prohibited.
*
* 1. For the GPL license (GPL), you can redistribute and/or modify this
* program under the terms of the GNU General Public License,
* Version 3, as published by the Free Software Foundation. You should
* have received a copy of the GNU General Public License, Version 3 along
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Aptana provides a special exception to allow redistribution of this file
* with certain other free and open source software ("FOSS") code and certain additional terms
* pursuant to Section 7 of the GPL. You may view the exception and these
* terms on the web at http://www.aptana.com/legal/gpl/.
*
* 2. For the Aptana Public License (APL), this program and the
* accompanying materials are made available under the terms of the APL
* v1.0 which accompanies this distribution, and is available at
* http://www.aptana.com/legal/apl/.
*
* You may view the GPL, Aptana's exception and additional terms, and the
* APL in the file titled license.html at the root of the corresponding
* plugin containing this source file.
*
* Any modifications to this file must keep this entire header intact.
*/
package com.aptana.ide.core;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Map;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.osgi.service.datalocation.Location;
import com.aptana.ide.core.io.IFileProgressMonitor;
import com.aptana.ide.internal.core.CoreNatives;
/**
* FileUtils
*/
public class FileUtils
{
/**
* The newline separator character
*/
public static String NEW_LINE = System.getProperty("line.separator"); //$NON-NLS-1$
/**
* The file separator character.
*/
private static final char ALT_SEPARATOR_CHAR = File.separatorChar == '/' ? '\\' : '/';
/**
* The file directory hashtable
*/
private static Hashtable fileDirectoryStatus = new Hashtable();
/**
* The temp directory of the system;
*/
public static String systemTempDir = getTempDir();
/**
* Protected constructor for utility class.
*/
protected FileUtils()
{
}
/**
* copies a file or a directory from one directory to another
*
* @param from
* directory from where to copy
* @param to
* directory where to copy
* @param what
* what to copy (file or directory, recursively)
* @return true if successful <br>
* <br>
* <b>Example</b>:
* <li><code>copy("c:\\home\\vlad\\dev", "c:\\home\\vlad\\rtm", "contents.xml")</code></li>
*/
public static boolean copy(String from, String to, String what)
{
return copy(new File(from, what), new File(to, what));
}
/**
* copy copies a file or a directory from one directory to another
*
* @param from
* directory from where to copy
* @param to
* directory where to copy
* @param what
* what to copy (file or directory, recursively)
* @return true if successful <br>
* <br>
* <b>Example</b>:
* <li><code>copy(new File(myHomeDir, "dev"), new File(myHomeDir, "rtm"), "contents.xml")</code></li>
*/
public static boolean copy(File from, File to, String what)
{
return copy(new File(from, what), new File(to, what));
}
/**
* In a "creative" way checks whether a string or a container is empty. <br>
* Accepts a <code>Collection</code>, a <code>Map</code>, an array, a <code>String</code>.
*
* @param data
* a Collection or a Map or an array or a string to check
* @return true if data is empty <br>
* <br>
* <b>Examples</b>:
* <li><code>isEmpty(StringUtils.EMPTY), isEmpty(null), isEmpty(new HashMap())</code> all return <b>true</b>;</li>
* <li><code>isEmpty(" "), isEmpty(new int[] {1})</code> returns <b>false</b>.</li>
*/
public static final boolean isEmpty(Object data)
{
if (data == null)
{
return true;
}
if (data instanceof Collection)
{
return ((Collection) data).isEmpty();
}
if (data instanceof Map)
{
return ((Map) data).isEmpty();
}
if (data instanceof Object[])
{
return ((Object[]) data).length == 0;
}
return (data.toString().length() == 0) || "null".equals(data.toString()); //$NON-NLS-1$
}
/**
* copy copies a file or a directory to another.
*
* @param from
* the source path
* @param to
* the destination path
* @return true if successful <br>
* <br>
* <b>Example</b>:
* <li><code>copy("c:\\home\\vlad\\dev\\contents.xml", "c:\\home\\vlad\\rtm\\contents.rss")</code></li>
*/
public static boolean copy(String from, String to)
{
return copy(new File(from), new File(to));
}
/**
* copy copies a file or a directory to another.
*
* @param from
* the source path
* @param to
* the destination path
* @return true if successful <br>
* <br>
* <b>Example</b>:
* <li><code>copy(new File(myHomeDir, "contents.xml"), new File(mySite, "contents.rss")</code></li>
*/
public static boolean copy(File from, File to)
{
if (from.isDirectory())
{
String[] contents = from.list();
for (int i = 0; contents != null && i < contents.length; i++)
{
copy(from, to, contents[i]);
}
}
else
{
try
{
OutputStream os = makeFile(to);
InputStream is = new FileInputStream(from);
pipe(is, os, false);
is.close();
os.close();
}
catch (IOException ex)
{
return false;
}
}
long time = from.lastModified();
if (!to.setLastModified(time))
{
return false;
}
long newtime = to.lastModified();
return time == newtime;
}
/**
* pipes data from input stream to output stream, possibly pumping them through the filter (if any)
*
* @param in
* InputStream the source of data
* @param out
* OutputStream where the output goes, filtered if filter is present, or unfiltered otherwise
* @param isBlocking
* boolean whether input is blocking (in this case the maximum amount is read in one operation; for
* nonblocking in.available() determines how many bytes can be read)
* @param filter
* ByteFilter the filter that applies to data; can be null
* @param monitor
* the monitor to receive feedbacks on the transferring progress
* @throws IOException
* when input or output fails see the test for examples
*/
public static void pipe(InputStream in, OutputStream out, boolean isBlocking, ByteFilter filter, IFileProgressMonitor monitor) throws IOException
{
byte[] buf = new byte[50000];
int nread;
int navailable;
int total = 0;
synchronized (in)
{
navailable = isBlocking ? buf.length : in.available();
nread = in.read(buf, 0, Math.min(buf.length, navailable));
while (navailable > 0 && nread >= 0)
{
if (filter == null)
{
out.write(buf, 0, nread);
}
else
{
byte[] filtered = filter.filter(buf, nread);
out.write(filtered);
}
total += nread;
if (monitor != null)
{
monitor.bytesTransferred(total);
}
navailable = isBlocking ? buf.length : in.available();
nread = in.read(buf, 0, Math.min(buf.length, navailable));
}
}
out.flush();
buf = null;
}
/**
* pipes data from input stream to output stream, possibly pumping them through the filter (if any)
*
* @param in
* InputStream the source of data
* @param out
* OutputStream where the output goes, filtered if filter is present, or unfiltered otherwise
* @param isBlocking
* boolean whether input is blocking (in this case the maximum amount is read in one operation; for
* nonblocking in.available() determines how many bytes can be read)
* @param filter
* ByteFilter the filter that applies to data; can be null
* @throws IOException
* when input or output fails see the test for examples
*/
public static void pipe(InputStream in, OutputStream out, boolean isBlocking, ByteFilter filter) throws IOException
{
pipe(in, out, isBlocking, filter, null);
}
/**
* <p>
* Description: The interface is used to define filters for filtering data in pipes. Filters, similar to those in
* JSPs, can modify the bytes going from one end of the pipe to another, or just sniff them and act based on results -
* e.g. count bytes, calculate crc, you name it.
* </p>
*/
public interface ByteFilter
{
/**
* filters data coming from input
*
* @param input
* byte[] input data
* @param length
* int number of meaningful bytes
* @return byte[] result of filtering
*/
byte[] filter(byte[] input, int length);
}
/**
* pipes data from input stream to output stream
*
* @param in
* InputStream the source of data
* @param out
* OutputStream where the output goes, filtered if filter is present, or unfiltered otherwise
* @param isBlocking
* boolean whether input is blocking (in this case the maximum amount is read in one operation; for
* nonblocking in.available() determines how many bytes can be read)
* @throws IOException
* when input or output fails see the test for examples
*/
public static void pipe(InputStream in, OutputStream out, boolean isBlocking) throws IOException
{
pipe(in, out, isBlocking, null);
}
/**
* pipes data from input stream to output stream
*
* @param in
* Reader the source of data
* @param out
* Writer where the output goes, filtered if filter is present, or unfiltered otherwise
* @return boolean true if successful, false otherwise see the test for examples
*/
public static boolean pipe(Reader in, Writer out)
{
if (in == null)
{
return false;
}
if (out == null)
{
return false;
}
try
{
int c;
synchronized (in)
{
c = in.read();
while (in.ready() && c > 0)
{ // have to have in.ready() here, otherwise it will hang!
out.write(c);
c = in.read();
}
}
out.flush();
}
catch (Exception e)
{
return false;
}
return true;
}
/**
* Creates or opens a file for output. If subdirectories in the path do not exist, they are created too. If the file
* exists, it is overwritten, unless <code>append</code> is <b>true</b>. <code>append</code> determines whether
* to open in <i>append</i> mode
*
* @param dirname
* file location
* @param filename
* the name of the file
* @param append
* <b>true</b> if open in <i>append</i> mode
* @return file output stream
* @throws IOException
* if unable to write to the file
*/
public static FileOutputStream makeFile(String dirname, String filename, boolean append) throws IOException
{
if (!isEmpty(dirname))
{
File dir = new File(dirname);
if (!dir.isDirectory())
{
if (dir.exists())
{
dir.delete();
}
dir.mkdirs();
}
}
return new FileOutputStream(new File(dirname, filename), append);
}
/**
* Creates or opens a file for output. If subdirectories in the path do not exist, they are created too. If the file
* exists, it is overwritten.
*
* @param dir
* file location
* @param filename
* the name of the file
* @return file output stream
* @throws IOException
* if unable to write to the file
*/
public static FileOutputStream makeFile(String dir, String filename) throws IOException
{
return makeFile(dir, filename, false);
}
/**
* Creates or opens a file for output. If subdirectories in the path do not exist, they are created too. If the file
* exists, it is overwritten, unless <code>append</code> is <b>true</b>. <code>append</code> determines whether
* to open in <i>append</i> mode
*
* @param path
* [0] is directory name, [1] is file name
* @param append
* <b>true</b> if open in <i>append</i> mode
* @return file output stream
* @throws IOException
* if unable to write to the file
*/
public static FileOutputStream makeFile(String[] path, boolean append) throws IOException
{
return makeFile(path[0], path[1], append);
}
/**
* Creates or opens a file for output. If subdirectories in the path do not exist, they are created too. If the file
* exists, it is overwritten.
*
* @param path
* [0] is directory name, [1] is file name
* @return file output stream
* @throws IOException
* if unable to write to the file
*/
public static FileOutputStream makeFile(String[] path) throws IOException
{
return makeFile(path[0], path[1]);
}
/**
* Creates or opens a file for output. If subdirectories in the path do not exist, they are created too. If the file
* exists, it is overwritten, unless <code>append</code> is <b>true</b>. <code>append</code> determines whether
* to open in <i>append</i> mode
*
* @param path
* file path
* @param append
* <b>true</b> if open in <i>append</i> mode
* @return file output stream
* @throws IOException
* if unable to write to the file
*/
public static FileOutputStream makeFile(String path, boolean append) throws IOException
{
return makeFile(splitPath(path), append);
}
/**
* Creates or opens a file for output. If subdirectories in the path do not exist, they are created too. If the file
* exists, it is overwritten.
*
* @param path
* file path
* @return file output stream
* @throws IOException
* if unable to write to the file
*/
public static FileOutputStream makeFile(String path) throws IOException
{
return makeFile(splitPath(path));
}
/**
* Splits a path into directory name and file name.
*
* @param path
* the path to split
* @return String array consisting of two elements <br>
* <br>
* <b>Examples</b>:
* <li><code>splitPath("/home/zaphod/jbuilder8/samples/welcome")</code> returns
* {"/home/zaphod/jbuilder8/samples", "welcome"};</li>
* <li><code>splitPath("src.java")</code> returns {".", "src.java"};</li>
* <li><code>splitPath("MyHome\\dev")</code> returns {"MyHome", "dev"}.</li>
*/
public static String[] splitPath(String path)
{
return new String[] { dirname(path), new File(path).getName() };
}
/**
* Creates or opens a file for output. If subdirectories in the path do not exist, they are created too. If the file
* exists, it is overwritten, unless <code>append</code> is <b>true</b>. <code>append</code> determines whether
* to open in <i>append</i> mode
*
* @param file
* the file to open
* @param append
* <b>true</b> if open in <i>append</i> mode
* @return file output stream
* @throws IOException
* if unable to write to the file
*/
public static FileOutputStream makeFile(File file, boolean append) throws IOException
{
return makeFile(file.getCanonicalPath(), append);
}
/**
* Calculates directory path for a file (like in Perl).
*
* @param file
* the file to calculate from
* @return directory path Unlike java.io.File.getParent(), never returns null (see example 2 below). <br>
* <br>
* <b>Examples</b>:
* <li><code>dirname(new File("/home/zaphod/jbuilder11/samples/welcome"))</code> returns
* "/home/zaphod/jbuilder8/samples";</li>
* <li><code>dirname(new File("src.java"))</code> returns ".";</li>
* <li><code>dirname(new File("MyHome\\dev"))</code> returns "MyHome".</li>
*/
public static String dirname(File file)
{
String parent = file.getParent();
if (parent == null)
{
parent = "."; //$NON-NLS-1$
}
if (file.getPath().indexOf(File.separatorChar) < 0 && file.getPath().indexOf(ALT_SEPARATOR_CHAR) >= 0
&& parent.indexOf(File.separatorChar) >= 0)
{
parent = parent.replace(File.separatorChar, ALT_SEPARATOR_CHAR);
}
return parent;
}
/**
* Calculates directory path by file path (like in Perl)
*
* @param path
* the path to use
* @return directory path Unlike java.io.File.getParent(), never returns null (see example 2 below). <br>
* <br>
* <b>Examples</b>:
* <li><code>dirname("/home/zaphod/jbuilder11/samples/welcome")</code> returns
* "/home/zaphod/jbuilder8/samples";</li>
* <li><code>dirname("src.java")</code> returns ".";</li>
* <li><code>dirname("MyHome\\dev")</code> returns "MyHome".</li>
*/
public static String dirname(String path)
{
String dirname = dirname(new File(path));
if (path.indexOf(ALT_SEPARATOR_CHAR) >= 0 && path.indexOf(File.separatorChar) < 0)
{
return dirname.replace(File.separatorChar, ALT_SEPARATOR_CHAR);
}
return dirname;
}
/**
* Creates or opens a file for output. If subdirectories in the path do not exist, they are created too. If the file
* exists, it is overwritten.
*
* @param file
* the file to open
* @return file output stream
* @throws IOException
* if unable to write to the file
*/
public static FileOutputStream makeFile(File file) throws IOException
{
return makeFile(file.getCanonicalPath());
}
/**
* Creates or opens a file for output. If subdirectories in the path do not exist, they are created too. If the file
* exists, it is overwritten.
*
* @param path
* the file to open
* @param encoding
* the encoding to use
* @return output stream writer
* @throws IOException
* if unable to write to the file
*/
public static final OutputStreamWriter makeFileWriter(String path, String encoding) throws IOException
{
return new OutputStreamWriter(makeFile(path), encoding);
}
/**
* Returns all files in the current directory.
*
* @param file
* The file to grab files in reference to
* @return A list of files, or a empty directory
*/
public static File[] getFilesInDirectory(File file)
{
Path path = new Path(file.toString());
String lastSegment = path.lastSegment();
File[] files = new File[0];
if (file.isDirectory())
{
files = file.listFiles();
}
else
{
File parent = file.getParentFile();
files = parent.listFiles();
}
if (lastSegment != null && lastSegment.indexOf('*') >= 0)
{
return matchFiles(lastSegment, files);
}
else
{
return files;
}
}
/**
* Given a list of files and a regular expression pattern, return a list of files that match the pattern
*
* @param pattern
* The pattern to check. Currently only really works with patterns like *.js
* @param files
* The list of files
* @return The filtered list
*/
public static File[] matchFiles(String pattern, File[] files)
{
if (pattern == null || files == null || files.length < 1)
return new File[0];
String newPattern = StringUtils.replace(pattern, "\\", "\\\\"); //$NON-NLS-1$ //$NON-NLS-2$
newPattern = StringUtils.replace(newPattern, ".", "\\."); //$NON-NLS-1$ //$NON-NLS-2$
newPattern = StringUtils.replace(newPattern, "*", ".*"); //$NON-NLS-1$ //$NON-NLS-2$
ArrayList al = new ArrayList();
for (int i = 0; i < files.length; i++)
{
File fileTest = files[i];
if (fileTest.toString().matches(newPattern))
{
al.add(fileTest);
}
}
return (File[]) al.toArray(new File[0]);
}
/**
* Returns a relative path for the second file compared to the first
*
* @param fileA
* The "reference" file path
* @param fileB
* The file to make relative
* @return String
*/
public static String makeFilePathRelative(File fileA, File fileB)
{
String separator = System.getProperty("file.separator"); //$NON-NLS-1$
String a = fileA.toString();
if (!fileA.isDirectory())
{
a = fileA.getParent().toString() + separator;
}
String b = fileB.toString();
if (fileB.isDirectory())
{
b = b + separator;
}
String r = StringUtils.replace(b, a, StringUtils.EMPTY);
if (r.endsWith(separator))
{
r = r.substring(0, r.length() - 1);
}
return r;
}
/**
* Get the extension.
*
* @param fileName
* File name
* @return the extension
*/
public static String getExtension(String fileName)
{
// We need kernel api to validate the extension or a filename
if (fileName == null || StringUtils.EMPTY.equals(fileName))
{
return fileName;
}
int index = fileName.lastIndexOf('.');
if (index == -1)
{
return StringUtils.EMPTY;
}
if (index == fileName.length())
{
return StringUtils.EMPTY;
}
return fileName.substring(index + 1, fileName.length());
}
/**
* Remove the extension.
*
* @param fileName
* File name
* @return the extension
*/
public static String stripExtension(String fileName)
{
// We need kernel api to validate the extension or a filename
if (fileName == null || StringUtils.EMPTY.equals(fileName))
{
return fileName;
}
int index = fileName.lastIndexOf('.');
if (index == -1)
{
return fileName;
}
if (index == fileName.length())
{
return fileName;
}
return fileName.substring(0, index);
}
/**
* Is the current file a directory?
*
* @param f
* The file to test
* @return True if yes, false if no
*/
public static boolean isDirectory(File f)
{
if (System.getProperty("os.name").startsWith("Mac OS")) //$NON-NLS-1$ //$NON-NLS-2$
{
return f.isDirectory();
}
else
{
String filePath = f.getAbsolutePath();
if (fileDirectoryStatus.containsKey(filePath))
{
return fileDirectoryStatus.get(filePath).equals(Boolean.TRUE);
}
else
{
File fShell = FileTricks.attemptReplaceWithShellFolder(f);
boolean isDirectory = fShell.isDirectory();
if (isDirectory)
{
fileDirectoryStatus.put(filePath, Boolean.TRUE);
}
else
{
fileDirectoryStatus.put(filePath, Boolean.FALSE);
}
return isDirectory;
}
}
}
private static String getTempDir()
{
if (systemTempDir == null)
{
// [IM] use non-Sun method for geting the temp directory.
// See
// http://developer.classpath.org/mediation/ClasspathMigration#head-885c2d3603cee96158c92b1942ac830af1986e6a
// for rationale
// This removes necessity for Sun JVM
PrivilegedAction pa = new java.security.PrivilegedAction()
{
public Object run()
{
return System.getProperty("java.io.tmpdir"); //$NON-NLS-1$
}
};
systemTempDir = ((String) AccessController.doPrivileged(pa));
}
return systemTempDir;
}
/**
* Ensures that the string passed in starts with a "."
*
* @param extension
* @return String
*/
public static String ensureExtension(String extension)
{
if (extension == null || StringUtils.EMPTY.equals(extension))
{
return extension;
}
else
{
if (extension.startsWith(".")) //$NON-NLS-1$
{
return extension;
}
else
{
return "." + extension; //$NON-NLS-1$
}
}
}
/**
* Removes invalid characters (such as file separator characters) from the file name. Replaces with underscores
*
* @param fileName
* @return
*/
public static String ensureValidFilename(String fileName)
{
String newName = StringUtils.replace(fileName, File.separatorChar + "", "_"); //$NON-NLS-1$ //$NON-NLS-2$
newName = StringUtils.replace(newName, ":", "_"); //$NON-NLS-1$ //$NON-NLS-2$
newName = StringUtils.replace(newName, "|", "_"); //$NON-NLS-1$ //$NON-NLS-2$
newName = StringUtils.replace(newName, "<", "_"); //$NON-NLS-1$ //$NON-NLS-2$
newName = StringUtils.replace(newName, ">", "_"); //$NON-NLS-1$ //$NON-NLS-2$
newName = StringUtils.replace(newName, "*", "_"); //$NON-NLS-1$ //$NON-NLS-2$
newName = StringUtils.replace(newName, "?", "_"); //$NON-NLS-1$ //$NON-NLS-2$
return newName;
}
/**
* removes the leading period from an extension
*
* @param extension
* @return String
*/
public static String stripExtensionPeriod(String extension)
{
if (extension == null || StringUtils.EMPTY.equals(extension))
{
return extension;
}
else
{
if (extension.startsWith(".")) //$NON-NLS-1$
{
return extension.substring(1);
}
else
{
return extension;
}
}
}
/**
* Removes the "middle" part from a path to make it short enough to fit within the specified length, i.e. c:/Documents
* and Settings/username/My Documents/workspace/whatever.txt would become c:/Documents and
* Settings/.../workspace/whatever.txt.
*
* @param path
* the path to compress
* @param pathLength
* the length to shorten it to. This is more of a guideline
* @return a compressed path
*/
public static String compressPath(String path, int pathLength)
{
path = path.replace('\\', '/');
if (path.length() > pathLength)
{
// We want the second '/', as the path might begin with a '/'
int firstSlash = path.indexOf('/', 1);
int endSearch = path.length() - pathLength - firstSlash;
if (firstSlash < 0 || endSearch < 0)
{
return path;
}
else
{
int lastSlash = path.indexOf('/', endSearch);
if (lastSlash > firstSlash)
{
return path.substring(0, firstSlash) + "/..." + path.substring(lastSlash); //$NON-NLS-1$
}
else
{
// case where last segment is longer than the path length, but we could end with a '/'
lastSlash = path.lastIndexOf('/', path.length() - 2);
return path.substring(0, firstSlash) + "/..." + path.substring(lastSlash); //$NON-NLS-1$
}
}
}
else
{
return path;
}
}
/**
* Removes the "leading" part from a path to make it short enough to fit
* within the specified length, i.e. "c:/Documents and Settings/username/My
* Documents/workspace/whatever.txt" would become ".../My
* Documents/workspace/whatever.txt".
*
* @param path
* the path to compress
* @param pathLength
* the length to shorten it to. This is more of a guideline
* @return a compressed path
*/
public static String compressLeadingPath(String path, int pathLength) {
path = path.replace('\\', '/');
if (path.length() <= pathLength) {
return path;
}
int endSearch = path.length() - pathLength;
int lastSlash = path.indexOf('/', endSearch);
if (lastSlash < 0) {
return path;
}
return "..." + path.substring(lastSlash); //$NON-NLS-1$
}
/**
* Creates a file name with a random integer number inserted between the prefix and suffix
*
* @param prefix
* the name of the file (sans extension)
* @param suffix
* the extension of the file (including the '.')
* @return a new file name like test12534.txt
*/
public static String getRandomFileName(String prefix, String suffix)
{
if (suffix == null)
{
return prefix + (long) (Integer.MAX_VALUE * Math.random());
}
else
{
return prefix + (long) (Integer.MAX_VALUE * Math.random()) + suffix;
}
}
/**
* Deletes the directory at the named location
*
* @param parentDirectory
* The location of the parent directory
* @param directoryName
* The name of the directory to delete.
* @return True if the directory was deleted, false if not.
*/
public static boolean deleteDirectory(String parentDirectory, String directoryName)
{
File newDirectory = new File(parentDirectory + File.separator + directoryName);
if (newDirectory.exists())
{
return deleteDirectory(newDirectory);
}
return false;
}
/**
* Deletes the directory at the named location
*
* @param directory
* The location of the parent directory
* @return True if the directory was deleted, false if not.
*/
public static boolean deleteDirectory(File directory)
{
if (directory.isDirectory())
{
String[] children = directory.list();
for (int i = 0; i < children.length; i++)
{
boolean success = deleteDirectory(new File(directory, children[i]));
if (!success)
{
return false;
}
}
}
// The directory is now empty so delete it
return directory.delete();
}
/**
* setHidden
*
* @param file
* @return boolean
*/
public static boolean setHidden(File file)
{
if (Platform.OS_WIN32.equals(Platform.getOS()))
{
try
{
return CoreNatives.SetFileAttributes(file.getAbsolutePath(), CoreNatives.FILE_ATTRIBUTE_HIDDEN, 0);
}
catch (UnsatisfiedLinkError e)
{
IdeLog.logError(AptanaCorePlugin.getDefault(), Messages.FileUtils_CoreLibraryNotFound, e);
}
}
return false;
}
/**
* readContent
*
* @param stream
* @param charset
* @return String
* @throws IOException
*/
public static String readContent(File file) throws IOException
{
FileInputStream fis = new FileInputStream(file);
return StreamUtils.readContent(fis, null);
}
/**
* Is this url a file url?
*
* @param url
* The url
* @return true or false
*/
public static boolean isFileURL(URL url)
{
if (url == null)
{
return false;
}
String surl = url.toString();
return surl.startsWith("file:/"); //$NON-NLS-1$
}
/**
* Converts a file://-based url into a file
*
* @param url
* The url
* @return the File, or null if not a file URL
*/
public static File urlToFile(URL url)
{
try
{
URI uri = url.toURI();
if ("file".equals(uri.getScheme())) //$NON-NLS-1$
{
return new File(uri.getSchemeSpecificPart());
}
}
catch (Exception e)
{
IdeLog.logError(AptanaCorePlugin.getDefault(), StringUtils.EMPTY, e);
}
return null;
}
/**
* @param uri
* @return
*/
public static File openURL(String uri)
{
URL fileURL = uriToURL(uri);
if (fileURL == null)
{
IdeLog.logError(AptanaCorePlugin.getDefault(), StringUtils.format(Messages.FileUtils_Unable_To_Open_URL, uri));
return null;
}
File f = urlToFile(fileURL);
if (f != null)
{
return f;
}
else
{
try
{
String text = readContent(fileURL);
String[] path = fileURL.getFile().split("/"); //$NON-NLS-1$
String name = path[path.length - 1];
File temp = File.createTempFile(FileUtils.stripExtension(name), FileUtils.ensureExtension(FileUtils
.getExtension(name)));
BufferedWriter out = new BufferedWriter(new FileWriter(temp));
out.write(text);
out.close();
return temp;
}
catch (IOException e)
{
IdeLog.logError(AptanaCorePlugin.getDefault(), StringUtils
.format(Messages.FileUtils_Unable_To_Open_URL, uri), e);
return null;
}
}
}
public static URL uriToURL(String uri)
{
URI uri2;
String encodedUri;
try
{
encodedUri = URLEncoder.encode(uri, null, null);
uri2 = new URI(encodedUri);
// NOTE: normalizing causes paths with ".." to lose their drive specification
// uri2.normalize();
return uri2.toURL();
}
catch (MalformedURLException e)
{
IdeLog.logError(AptanaCorePlugin.getDefault(), StringUtils.format(
Messages.FileUtils_Malformed_URI, uri), e);
return null;
}
catch (URISyntaxException e)
{
IdeLog.logError(AptanaCorePlugin.getDefault(), StringUtils.format(
Messages.FileUtils_Invalid_URI_Syntax, uri), e);
return null;
}
}
/**
* Reads the content from the URL
*
* @param f
* @return
* @throws IOException
*/
public static String readContent(URL url) throws IOException
{
String text = null;
if (isFileURL(url))
{
File file = urlToFile(url);
return readContent(file);
}
else
{
InputStream is = url.openStream();
text = StreamUtils.readContent(is, null);
}
return text;
}
/**
* Writes a stream out to a file
*
* @param in
* The input stream to read from
* @param fileName
* The name of the file to write to
*/
public static void writeStreamToFile(InputStream in, String fileName)
{
try
{
FileOutputStream fos = new FileOutputStream(fileName);
int ch;
try
{
while (-1 != (ch = in.read()))
{
fos.write(ch);
}
}
catch (Exception e)
{
}
finally
{
if (fos != null)
{
try
{
fos.flush();
fos.close();
}
catch (IOException ex2)
{
}
}
}
}
catch (FileNotFoundException ex)
{
}
}
/**
* Writes a string out to a file
*
* @param text The text to write to the file
* @param filePath the path of the file to write to
* @throws IOException
*/
public static void writeStringToFile(String text, String filePath) throws IOException
{
File outFile = new File(filePath);
writeStringToFile(text, outFile);
}
/**
* Writes a string out to a file
*
* @param text The text to write to the file
* @param filePath the path of the file to write to
* @throws IOException
*/
public static void writeStringToFile(String text, File file) throws IOException
{
FileWriter out = null;
try
{
out = new FileWriter(file);
out.write(text);
}
finally
{
try
{
if (out != null)
out.close();
}
catch (Exception e)
{
// ignore
}
}
}
/**
* getApplicationLauncher
* @return
*/
public static IPath getApplicationLauncher() {
return getApplicationLauncher(false);
}
/**
* getApplicationLauncher
*
* @param asSplashLauncher
* @return
*/
public static IPath getApplicationLauncher(boolean asSplashLauncher) {
IPath launcher = null;
String cmdline = System.getProperty("eclipse.commands"); //$NON-NLS-1$
if ( cmdline != null && cmdline.length() > 0 ) {
String[] args = cmdline.split("\n"); //$NON-NLS-1$
for( int i = 0; i < args.length; ++i ) {
if ( "-launcher".equals(args[i]) && (i+1) < args.length ) { //$NON-NLS-1$
launcher = new Path(args[i+1]);
break;
}
}
}
if ( launcher == null ) {
Location location = Platform.getInstallLocation();
if ( location != null ) {
launcher = new Path(location.getURL().getFile());
if ( launcher.toFile().isDirectory() ) {
launcher = launcher.append("aptana"); //$NON-NLS-1$
}
}
}
if ( !launcher.toFile().exists() ) {
if ( Platform.OS_WIN32.equals(Platform.getOS()) ) {
launcher = launcher.addFileExtension("exe"); //$NON-NLS-1$
}
if ( !launcher.toFile().exists() ) {
launcher = null;
}
} else if (Platform.OS_MACOSX.equals(Platform.getOS())) {
int count = launcher.segmentCount();
int appIndex = -1;
for(int i = 0; i < count; ++i) {
if(launcher.segment(i).indexOf(".app") != -1) { //$NON-NLS-1$
if(appIndex != -1) {
if(launcher.segment(i).toLowerCase().indexOf("splash") != -1) { //$NON-NLS-1$
break;
}
}
appIndex = i;
}
}
if(!asSplashLauncher && appIndex != -1) {
launcher = launcher.removeLastSegments(count-appIndex-1).removeTrailingSeparator();
}
launcher = new Path(PlatformUtils.getApplicationExecutable(launcher.toOSString()).getAbsolutePath());
}
return launcher;
}
}