/*
 * 
 * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
 * 
 * The contents of this file are subject to the Sun Community Source
 * License v3.0/Jini Technology Specific Attachment v 1.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://wwws.sun.com/software/jini/licensing/SCSL3_JiniTSA1.html.
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 * 
 * The Reference Code is Jini Technology Core Platform code, v2.0. The
 * Developer of the Reference Code is Sun Microsystems, Inc.
 * 
 * Contributor(s): Sun Microsystems, Inc.
 * 
 * The contents of this file comply with the Jini Technology Core
 * Platform Compatibility Kit, v2.0A.
 * 
 * Tester(s): Sun Microsystems, Inc.
 * 
 * Test Platform(s):
 * Java 2 SDK, Standard Edition, Version 1.4.2_03 for Solaris(TM)SPARC/x86
 * Java 2 SDK, Standard Edition, Version 1.4.2_03 for Linux (Intel x86)
 * Java 2 SDK, Standard Edition, Version 1.4.2_03 for Windows (Intel Platform)
 * 
 */
package com.sun.jini.system;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import java.util.Collection;
import java.util.ArrayList;

/**
 * Miscellaneous file system manipulation methods.
 *
 * @author Sun Microsystems, Inc.
 *
 */
public class FileSystem {
    /**
     * Remove this completely.  If the parameter is a directory, it is
     * removed after recursively destroying all its contents, including
     * subdirectories.  If the named file does not exist,
     * <code>destroy</code> simply returns.
     *
     * @param proceed
     *	    Proceed in the face of errors; otherwise the first error stops
     *	    the execution of the method.
     * @throws IOException
     *	    The list of files that couldn't be removed (in the detail string).
     */
    public static void destroy(File file, boolean proceed) throws IOException {
	if (!file.exists() || file.delete())	// that was easy
	    return;

	ArrayList errors = (proceed ? new ArrayList() : null);
	destroyDir(file, errors);

	if (errors != null && errors.size() != 0) {
	    StringBuffer buf = new StringBuffer("couldn't delete:");
	    for (int i = 0; i < errors.size(); i++)
		buf.append('\n').append(errors.get(i));
	    throw new IOException(buf.toString());
	}
    }

    /**
     * Perform the recursion for <code>destroy</code>.
     */
    private static void destroyDir(File dir, Collection errors)
	throws IOException
    {
	if (!dir.isDirectory()) {	// catch assumption that this is a dir
	    handleError(errors, dir);
	    return;
	}

	String[] names = dir.list();
	for (int i = 0; i < names.length; i++) {
	    File file = new File(dir, names[i]);
	    if (!file.delete())		// assume it's a dir
		destroyDir(file, errors);
	}
	if (!dir.delete())
	    handleError(errors, dir);
    }

    /**
     * Handle an error, either by adding to the list, or if there is no
     * list, throwing an <code>IOException</code>.
     */
    private static void handleError(Collection errors, File path)
	throws IOException
    {
	if (errors == null)
	    throw new IOException("couldn't delete " + path);
	errors.add(path);
    }

    /**
     * Ensure that the given path is a directory, creating it if
     * necessary.  If the path exists it must be a directory.
     * It the path does not exist this method uses
     * <code>File.mkdirs</code> to create the directory along with any
     * intermediate paths.
     *
     * @throws IllegalArgumentException
     *	    if the path already exists but is not a
     *      directory, or it does not exist and cannot be created.
     */
    public static void ensureDir(String path) throws IllegalArgumentException {
	File dir = new File(path);
	if (dir.isDirectory())
	    return;
	else if (dir.exists())
	    throw new IllegalArgumentException(path + " exists, but not a dir");
	if (!dir.mkdirs())
	    throw new IllegalArgumentException(path + ": cannot create");
    }
}
