/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
/*
* so that it works with installer(LogDomains esp.).
*/
public class FileUtils {
final static Logger _utillogger = com.sun.logging.LogDomains.getLogger(FileUtils.class,com.sun.logging.LogDomains.UTIL_LOGGER);
/*
* Wrapper for File.listFiles
* Guaranteed to return an array in all cases.
* File.listFiles() returns either null or an empty array. This is annoying and results in harder
* than neccessry to read code -- i.e. there are 3 results possible:
* an array with files in it
* an empty array
* a null
*/
try {
return files;
}
catch(Exception e) {
// fall through
}
return new File[0];
}
try {
return files;
}
catch(Exception e) {
// fall through
}
return new File[0];
}
try {
return files;
}
catch(Exception e) {
// fall through
}
return new File[0];
}
///////////////////////////////////////////////////////////////////////////
return false;
return true;
}
///////////////////////////////////////////////////////////////////////////
return safeIsRealDirectory(new File(s));
}
///////////////////////////////////////////////////////////////////////////
if (safeIsDirectory(f) == false)
return false;
// these 2 values while be different for symbolic links
return true;
/* Bug 4715043 -- WHOA -- Bug Obscura!!
* In Windows, if you create the File object with, say, "d:/foo", then the
* absolute path will be "d:\foo" and the canonical path will be "D:\foo"
* and they won't match!!!
**/
return true;
return false;
}
///////////////////////////////////////////////////////////////////////////
return safeIsDirectory(new File(s));
}
///////////////////////////////////////////////////////////////////////////
if (f == null)
return null;
try {
return f.getCanonicalPath();
}
catch (IOException e) {
return f.getAbsolutePath();
}
}
///////////////////////////////////////////////////////////////////////////
if (f == null)
return null;
try {
return f.getCanonicalFile();
}
catch (IOException e) {
return f.getAbsoluteFile();
}
}
///////////////////////////////////////////////////////////////////////////
return false;
}
///////////////////////////////////////////////////////////////////////////
return false;
}
///////////////////////////////////////////////////////////////////////////
return false;
}
///////////////////////////////////////////////////////////////////////////
return false;
}
///////////////////////////////////////////////////////////////////////////
if (!isValidString(filename))
return false;
return false;
return true;
}
///////////////////////////////////////////////////////////////////////////
if (!isValidString(filename))
return false;
return false;
return isLegalFilename(filename);
}
///////////////////////////////////////////////////////////////////////////
if (isLegalFilename(filename))
return filename;
// let's use "__" to replace "/" and "\" (on Windows) so less chance
// to collide with the actual name when reverting
return filename;
}
///////////////////////////////////////////////////////////////////////////
{
}
///////////////////////////////////////////////////////////////////////////
if (isFriendlyFilename(filename))
return filename;
return ret;
}
///////////////////////////////////////////////////////////////////////////
if (index > 0)
return (makeFriendlyFilename(filename));
}
///////////////////////////////////////////////////////////////////////////
return null;
}
extension = "_ear";
extension = "_war";
extension = "_jar";
extension = "_rar";
}
}
return filename;
}
extension = ".ear";
extension = ".war";
extension = ".jar";
extension = ".rar";
}
}
//first, revert the file extension
//then, revert the rest of the string
}
/////////////////////////////////////////////////////////
}
///////////////////////////////////////////////////////////////////////////
{
}
///////////////////////////////////////////////////////////////////////////
{
}
///////////////////////////////////////////////////////////////////////////
{
return hasExtension(f, ".jar");
}
///////////////////////////////////////////////////////////////////////////
{
return hasExtensionIgnoreCase(f, ".zip");
}
/**
* Deletes a directory and its contents.
* <p/>
* If this method encounters a symbolic link in the subtree below "parent"
* then it deletes the link but not any of the files pointed to by the link.
* Note that whack will delete files if a symbolic link appears in the
* path above the specified parent directory in the path.
*
* @param parent the File at the top of the subtree to delete
* @return success or failure of deleting the directory
*/
}
/**
* Deletes a directory and its contents.
* <p/>
* If this method encounters a symbolic link in the subtree below "parent"
* then it deletes the link but not any of the files pointed to by the link.
* Note that whack will delete files if a symbolic link appears in the
* path above the specified parent directory in the path.
*
* @param parent the File at the top of the subtree to delete
* @return success or failure of deleting the directory
*/
try {
/*
*Resolve any links up-stream from this parent directory and
*then whack the resulting resolved directory.
*/
} catch (IOException ioe) {
return false;
}
}
/**
* Deletes a directory and its contents.
* <p/>
* The whackResolvedDirectory method is invoked with a File argument
* in which any upstream file system links have already been resolved.
* This method will treate Any file passed in that does not have the same
* absolute and canonical path - as evaluated in safeIsRealDirectory -
* as a link and will delete the link without deleting any files in the
* linked directory.
*
* @param parent the File at the top of the subtree to delete
* @return success or failure of deleting the directory
*/
/*
*Do not recursively delete the contents if the current parent
*is a symbolic link.
*/
if (safeIsRealDirectory(parent)) {
if (f.isDirectory())
undeletedFiles.add(f);
}
}
}
/*
*Delete the directory or symbolic link.
*/
return deleteFile(parent);
}
/**
* Delete a file. If on Windows and the delete fails, run the gc and retry the deletion.
*
* @param f file to delete
* @return boolean indicating success or failure of the deletion atttempt; returns true if file is absent
*/
/*
*The operation succeeds immediately if the file is deleted
*successfully. On systems that support symbolic links, the file
*will be reported as non-existent if the file is a sym link to a
*non-existent directory. In that case invoke delete to remove
*the link before checking for existence, since File.exists on
*a symlink checks for the existence of the linked-to directory or
*file rather than of the link itself.
*/
if (f.delete()) {
return true;
}
;
/*
*The deletion failed. This could be simply because the file
*does not exist. In that case, log an appropriate message and
*return.
*/
if (!f.exists()) {
if (log) {
}
return true;
} else {
/*
*The delete failed and the file exists. Log a message if that
*level is enabled and return false to indicate the failure.
*/
if (log) {
}
return false;
}
}
/**
* Opens a stream to the specified output file, retrying if necessary.
*
* @param out the output File for which a stream is needed
* @return the FileOutputStream
* @throws IOException for any errors opening the stream
*/
if (retries > 0) {
}
if (work.workComplete()) {
} else {
throw ioe;
}
}
/**
* Return a set of all the files (File objects) under the directory specified, with
* relative pathnames filtered with the filename filter (can be null for all files).
*/
public static Set getAllFilesUnder(File directory, FilenameFilter filenameFilter) throws IOException {
}
}
public static Set getAllFilesUnder(File directory, FilenameFilter filenameFilter, boolean relativize) throws IOException {
allFiles, false );
return allFiles;
}
}
return allFiles;
}
// relativizingRoot can be null, in which case no relativizing is
// performed.
private static void recursiveGetFilesUnder(File relativizingRoot, File directory, FilenameFilter filenameFilter, Set set, boolean returnDirectories) {
if (files[i].isDirectory()) {
if (returnDirectories) {
if( relativizingRoot != null ) {
} else {
}
}
} else {
if( relativizingRoot != null ) {
} else {
}
}
}
}
/**
* Given a directory and a fully-qualified file somewhere
* under that directory, return the portion of the child
* that is relative to the parent.
*/
// Strip off any extraneous file separator character.
}
}
/**
* Executes the supplied work object until the work is done or the max.
* retry count is reached.
*
* @param work the RetriableWork implementation to be run
* @return the number of retries performed; 0 indicates the work succeeded without having to retry
*/
int retries = 0;
/*
*Try the work the first time. Ideally this will work.
*/
/*
*If the work failed and this is Windows - on which running gc may
*unlock the locked file - then begin the retries.
*/
try {
} catch (InterruptedException ex) {
}
}
}
return retries;
}
/**
* Creates a String listing the absolute paths of files, separated by
* the platform's line separator.
*
* @param files the Collection of File objects to be listed
* @return String containing the absolute paths of the files with the line separator between them
*/
}
}
///////////////////////////////////////////////////////////////////////////
}
///////////////////////////////////////////////////////////////////////////
try {
}
catch (IOException ioe) {
//Bug 4677074 ioe.printStackTrace();
//Bug 4677074 begin
//Bug 4677074 end
}
f.deleteOnExit(); // just in case
return f;
}
/**
* Returns an array of abstract pathnames that matches with the given
* file extension. If the given abstract pathname does not denote a
* directory, then this method returns null. If there is no matching
* file under the given directory and its sub directories,
* it returns null;
*
* @param dirName dir name under which search will begin
* @param ext file extension to look for
* @return an array of abstract pathnames that matches with the extension
*/
}
return target;
}
/**
* Returns a list of abstract pathnames that matches with the given
* file extension. If the given abstract pathname does not denote a
* directory, then this method returns null. If there is no matching
* file under the given directory and its sub directories, it returns
* an empty list.
*
* @param dirName dir name under which search will begin
* @param ext file extension to look for
* @return a list of abstract pathnames of type java.io.File
* that matches with the given extension
*/
if (dirName.isDirectory()) {
targetList = new ArrayList();
if (list[i].isDirectory()) {
} else {
}
}
}
}
return targetList;
}
/**
* Copies a file.
*
* @param from Name of file to copy
* @param to Name of new file
* @throws IOException if an error while copying the content
*/
//if(!StringUtils.ok(from) || !StringUtils.ok(to))
throw new IllegalArgumentException("null or empty filename argument");
}
/**
* Copies a file.
*
* @param fin File to copy
* @param fout New file
* @throws IOException if an error while copying the content
*/
if (safeIsDirectory(fin)) {
return;
}
throw new IllegalArgumentException("File source doesn't exist");
}
/**
* Copies the entire tree to a new location.
*
* @param din File pointing at root of tree to copy
* @param dout File pointing at root of new tree
* @throws IOException if an error while copying the content
*/
throws IOException {
if (!safeIsDirectory(din))
throw new IllegalArgumentException("Source isn't a directory");
if (!safeIsDirectory(dout))
throw new IllegalArgumentException("Can't create destination directory");
}
}
/**
* Returns a String with uniform slashes such that all the
* occurances of '\\' are replaced with '/'.
* In other words, the returned string will have all forward slashes.
* Accepts non-null strings only.
*
* @param inputStr non null String
* @return a String which <code> does not contain `\\` character </code>
*/
throw new IllegalArgumentException("null String FileUtils.makeForwardSlashes");
}
/**
* Given a string (typically a path), quote the string such that spaces
* are protected from interpretation by a Unix or Windows command shell.
* Note that this method does not handle quoting for all styles of special
* characters. Just for the basic case of strings with spaces.
*
* @param s input string
* @return a String which is quoted to protect spaces
*/
if (s == null) {
throw new IllegalArgumentException("null string");
}
if (!s.contains("\'")) {
return("\'" + s + "\'");
} else if(!s.contains("\"")) {
return("\"" + s + "\"");
} else {
// Contains a single quote and a double quote. Use backslash
// On Unix. Double quotes on Windows. This method does not claim
// to support this case well if at all
return("\"" + s + "\"");
} else {
}
}
}
///////////////////////////////////////////////////////////////////////////
return ILLEGAL_FILENAME_STRING;
}
///////////////////////////////////////////////////////////////////////////
}
/**
* This method is used to copy a given file to another file
* using the buffer sixe specified
*
* @param fin the source file
* @param fout the destination file
*/
}
try {
} finally {
}
}
public static void copyWithoutClose(InputStream in, FileOutputStream out, long size) throws IOException {
}
if (os instanceof FileOutputStream) {
} else {
if (size==0) {
int read;
do {
if (read>0) {
byteBuffer.rewind();
byteBuffer.clear();
}
} while (read!=-1);
} else {
byteBuffer.rewind();
}
}
}
/**
*Rename, running gc on Windows if needed to try to force open streams to close.
*@param fromFile to be renamed
*@param toFile name for the renamed file
*@return boolean result of the rename attempt
*/
boolean log = _utillogger.isLoggable(FILE_OPERATION_LOG_LEVEL) || _utillogger.isLoggable(Level.FINE);
}
/*
*If the rename worked, then write an appropriate log message if the
*logging level allows.
*/
if (result) {
if (log) {
/*
*If the rename worked without retries, then log a FINE message.
*If retries were needed then use the configured
*FILE_OPERATION_LOG_LEVEL.
*/
if (retries == 0) {
fromFilePath, toFilePath } ));
}
} else {
_utillogger.log(FILE_OPERATION_LOG_LEVEL, Strings.get("enterprise_util.retry_rename_success", new Object []
}
}
} else {
/*
*The rename has failed. Write a warning message.
*/
}
return result;
}
/** Appends the given line at the end of given text file. If the given
* file does not exist, an attempt is made to create it.
* Note that this method can handle only text files.
* @param fileName name of the text file that needs to be appended to
* @param line the line to append to
* @throws RuntimeException in case of any error - that makes it callable
* from a code not within try-catch. Note that NPE will be thrown if either
* argument is null.
* Note that this method is not tested with String containing characters
* with 2 bytes.
*/
try {
}
catch(Exception e) {
throw new RuntimeException("FileUtils.appendText()", e);
}
finally {
try {
}
catch(Exception e){}
}
}
throws IOException, FileNotFoundException
{
}
///////////////////////////////////////////////////////////////////////////
/** A utility routine to read a <b> text file </b> efficiently and return
* the contents as a String. Sometimes while reading log files of spawned
* processes this kind of facility is handy. Instead of opening files, coding
* FileReaders etc. this method could be employed. It is expected that the
* file to be read is <code> small </code>.
* @param fileName String representing absolute path of the file
* @return String representing the contents of the file, empty String for an empty file
* @throws java.io.IOException if there is an i/o error.
* @throws java.io.FileNotFoundException if the file could not be found
*/
throws IOException, FileNotFoundException {
}
throws IOException {
try {
}
}
finally {
try {
}
catch (Exception e) {}
}
}
/**
*
* @param file - path to look for
* @param dir - directory where the path file should exist
* @throws IOException
*/
if (f.exists())
return f;
return null;
f.getParentFile().mkdirs();
byte buf[] = new byte[10240];
int len = 0;
}
return f;
}
/**
* Write the String to a file. Then make the file readable and writable.
* If the file already exists it will be truncated and the contents replaced
* with the String argument.
* @param s The String to write to the file
* @param f The file to write the String to
* @throws IOException if any errors
*/
try {
writer = new PrintWriter(f);
}
finally {
try {
}
catch(Exception e) {
//ignore
}
f.setReadable(true);
f.setWritable(true);
}
}
}
/**
* Find files matching the regular expression in the given directory
* @param dir the directory to search
* @param regexp the regular expression pattern
* @return either an array of matching File objects or an empty array. Guaranteed
* to never return null
*/
try {
}
});
return matches;
}
catch (Exception e) {
// fall through
}
return new File[0];
}
/**
* Represents a unit of work that should be retried, if needed, until it
* succeeds or the configured retry limit is reached.
* <p/>
* The <code>run</code> method required by the Runnable interface is invoked
* to perform the work.
*/
/**
* Returns whether the work to be done by this instance of RetriableWork
* has been completed successfully.
* <p/>
* This method may be invoked multiple times and so should not have
* side effects.
*
* @return whether the work has been successfully completed
*/
public boolean workComplete();
}
/**
*Retriable work for renaming a file.
*/
private boolean renameResult = false;
this.originalFile = originalFile;
}
public boolean workComplete() {
return renameResult;
}
public void run() {
}
}
/**
* Retriable work for opening a FileOutputStream.
*/
}
public boolean workComplete() {
}
public void run() {
try {
} catch (IOException ioe) {
}
}
return fos;
}
return lastError;
}
}
///////////////////////////////////////////////////////////////////////////
private final static char[] ILLEGAL_FILENAME_CHARS = {'/', '\\', ':', '*', '?', '"', '<', '>', '|'};
/*
*The following property names are private, unsupported, and unpublished.
*/
private static final int FILE_OPERATION_MAX_RETRIES = Integer.getInteger("com.sun.appserv.winFileLockRetryLimit", 5).intValue();
private static final int FILE_OPERATION_SLEEP_DELAY_MS = Integer.getInteger("com.sun.appserv.winFileLockRetryDelay", 1000).intValue();
}