net.rim.ejde.internal.util.FileUtils.java Source code

Java tutorial

Introduction

Here is the source code for net.rim.ejde.internal.util.FileUtils.java

Source

/*
* Copyright (c) 2010-2012 Research In Motion Limited. All rights reserved.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License, Version 1.0,
* which accompanies this distribution and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*
*/
package net.rim.ejde.internal.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import net.rim.ejde.internal.core.IConstants;

import org.apache.log4j.Logger;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

/**
 * A utility class to manipulate files.
 *
 * @author dmeng
 */
public class FileUtils {
    private static final Logger log = Logger.getLogger(FileUtils.class);

    /**
     * Copy the source file to the destination file. An <code>IllegalArgumentException</code> will be thrown if the destination
     * file exists.
     *
     * @param src
     *            The source file
     * @param dest
     *            The destination file
     * @throws IOException
     *             Any error during file copy
     */
    public static void copy(File src, File dest) throws IOException {
        if ((src == null) || (dest == null)) {
            log.error("Source and Destination files cannot be null"); //$NON-NLS-1$
            throw new IllegalArgumentException("Source and Destination files cannot be null"); //$NON-NLS-1$
        }
        if (!src.exists() || !src.canRead() || !src.isFile()) {
            log.error("Could not access or read file " + src); //$NON-NLS-1$
            throw new IllegalArgumentException("Could not access or read file " + src); //$NON-NLS-1$
        }
        if (dest.exists()) {
            log.error("Destination file already exists: " + dest); //$NON-NLS-1$
            throw new IllegalArgumentException("Destination file already exists: " + dest); //$NON-NLS-1$
        }

        FileInputStream inputStream = null;
        FileOutputStream outputStream = null;
        FileChannel inputChannel = null, outputChannel = null;

        try {
            inputStream = new FileInputStream(src);
            outputStream = new FileOutputStream(dest);

            inputChannel = inputStream.getChannel();
            outputChannel = outputStream.getChannel();

            long count = 0, size = inputChannel.size();

            while ((count += outputChannel.transferFrom(inputChannel, count, size - count)) < size)
                ;

        } catch (Throwable e) {
            log.error(e.getMessage(), e);
        } finally {// just in case the Eclipse API doesn't close it for whatever
            // reason.
            try {
                if (null != inputStream)
                    inputStream.close();

                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (Throwable e) {
                ;
                log.error(e.getMessage(), e);
            }
        }
    }

    /**
     * Copy the source file to the destination file. An <code>IllegalArgumentException</code> will be thrown if the destination
     * file exists.
     *
     * @param inputStream
     *            the input stream that acts as a source
     * @param dest
     *            The destination file
     *
     * @throws IOException
     *             Any error during file copy
     */
    public static void copy(InputStream inputStream, File dest) throws IOException {
        if ((inputStream == null) || (dest == null)) {
            log.error("Source and Destination cannot be null"); //$NON-NLS-1$
            throw new IllegalArgumentException("Source and Destination cannot be null"); //$NON-NLS-1$
        }
        if (dest.exists()) {
            log.error("Destination file already exists: " + dest); //$NON-NLS-1$
            throw new IllegalArgumentException("Destination file already exists: " + dest); //$NON-NLS-1$
        }

        FileOutputStream outputStream = null;
        ReadableByteChannel inputChannel = null;
        FileChannel outputChannel = null;

        try {
            outputStream = new FileOutputStream(dest);

            inputChannel = Channels.newChannel(inputStream);
            outputChannel = outputStream.getChannel();

            long count = 0, size = Long.MAX_VALUE;

            outputChannel.transferFrom(inputChannel, count, size);

        } catch (Throwable e) {
            log.error(e.getMessage(), e);
        } finally {// just in case the Eclipse API doesn't close it for whatever
            // reason.
            try {
                inputStream.close();

                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (Throwable e) {
                log.error(e.getMessage(), e);
            }
        }
    }

    /**
     * Copy the source file to the destination file. Overwrite it if the destination file exists.
     *
     * @param src
     *            The source file
     * @param dest
     *            The destination file
     * @throws IOException
     *             Any error during file copy
     */
    public static void copyOverwrite(File src, File dest) throws IOException {
        if ((src == null) || (dest == null)) {
            log.error("Source and Destination files cannot be null"); //$NON-NLS-1$
            throw new IllegalArgumentException("Source and Destination files cannot be null"); //$NON-NLS-1$
        }

        if (!src.exists() || !src.canRead() || !src.isFile()) {
            log.error("Could not access or read file " + src); //$NON-NLS-1$
            throw new IllegalArgumentException("Could not access or read file " + src); //$NON-NLS-1$
        }

        // delete the destination file if it exists.
        if (dest.exists()) {
            if (!dest.delete()) {
                log.warn("Could not replace file " + dest); //$NON-NLS-1$
                return;
            }
        }

        copy(src, dest);
    }

    public static IStatus canChange(final java.io.File osFile) {
        return canChange(osFile, "Change Resource Problem", "Resource is read-only and cannot be changed: ", true,
                "\n\nDo you want to make the resource writable?");
    }

    public static IStatus canChange(final java.io.File osFile, final String dialogTitle, final String errorMessage,
            final boolean showResourcePath, final String questionMessage) {
        IStatus result = Status.CANCEL_STATUS;

        if ((osFile != null) && (osFile.exists())) {
            if (osFile.canWrite()) {
                result = Status.OK_STATUS;
            } else {
                // prompt for making resource writable
                Display.getDefault().syncExec(new Runnable() {
                    public void run() {
                        StringBuffer buffer = new StringBuffer();
                        buffer.append(errorMessage);
                        if (showResourcePath) {
                            buffer.append(osFile.getAbsolutePath());
                        }
                        buffer.append(questionMessage);
                        String[] buttons = new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL };
                        Shell shell = new Shell();
                        MessageDialog promptSaveDia = new MessageDialog(shell, dialogTitle, null, buffer.toString(),
                                MessageDialog.WARNING, buttons, 0);
                        int ret = promptSaveDia.open();
                        shell.dispose();
                        if (ret == Window.OK) {
                            // make this resource writable
                            setWritable(osFile);
                        }
                    }
                });

                if (osFile.canWrite()) {
                    result = Status.OK_STATUS;
                }
            }
        }

        return result;

    }

    public static void setWritable(java.io.File osFile) {
        // Since there is no method in Java to set writable directly, we have to
        // use following approach.
        java.io.File srcFile = osFile;
        java.io.File destFile = new java.io.File(srcFile.getParentFile(),
                String.valueOf(System.currentTimeMillis()));

        FileInputStream in = null;
        FileOutputStream out = null;
        FileChannel inChannel = null, outChannel = null;

        // create dest file
        try {
            destFile.createNewFile();

            // copy content from source file to dest file
            in = new FileInputStream(srcFile);
            out = new FileOutputStream(destFile);

            inChannel = in.getChannel();
            outChannel = out.getChannel();

            inChannel.transferTo(0, inChannel.size(), outChannel);
        } catch (Throwable e) {
            log.error(e.getMessage(), e);
        } finally {
            try {
                if (null != inChannel)
                    inChannel.close();

                if (null != outChannel)
                    outChannel.close();
            } catch (Throwable e) {
                log.error(e.getMessage(), e);
            }
        }

        // delete source file
        boolean success = srcFile.delete();

        if (!success) {
            destFile.delete();
            throw new RuntimeException("source file can not be deleted:" + srcFile.getAbsolutePath());
        }

        // rename dest file to source file
        destFile.renameTo(srcFile);
    }

    /**
     * Add the given <code>file</code> to the given </code>container</code>.
     *
     * @param container
     * @param file
     * @param createLink
     * @return
     */
    public static IFile addResourceToProject(IContainer container, File file, Boolean createLink) {
        // TODO:Check if has package
        IProject iProject = container.getProject();
        IFile iFile = null;

        iFile = container.getFile(new Path(file.getName()));
        if (iFile != null && !iFile.exists()) {
            if (createLink) {
                try {
                    iFile.createLink(new Path(file.getAbsolutePath()), IResource.NONE, new NullProgressMonitor());
                } catch (Exception e) {
                    log.error("Error linking resource to project");
                }
            } else {
                ImportUtils.copyFile(iProject, file, iFile.getProjectRelativePath());
            }
        }
        return iFile;
    }

    /**
     * Returns where the resources (non-package) should be created
     *
     * @param iProject
     * @return
     */
    public static IFolder getResFolder(IProject iProject) {
        IFolder sourceFolder = null;

        String resFolderName = ImportUtils.getProjectResFolderName();
        if (resFolderName.length() > 0) {
            sourceFolder = iProject.getFolder(new Path(resFolderName));
        }

        if (sourceFolder == null || !sourceFolder.exists()) {
            // Get the 1st found source folder
            sourceFolder = get1stNonDerivedSourceFolder(iProject);
        }
        return sourceFolder;
    }

    public static IFolder get1stNonDerivedSourceFolder(IProject iProject) {
        IFolder sfolder = null;
        IPackageFragmentRoot roots[] = ProjectUtils.getProjectSourceFolders(iProject);
        if (roots != null && roots.length > 0) {
            Collections.sort(Arrays.asList(roots), new Comparator<IPackageFragmentRoot>() {
                @Override
                public int compare(IPackageFragmentRoot root1, IPackageFragmentRoot root2) {
                    return root1.getElementName().compareTo(root2.getElementName());
                }
            });
            for (int i = 0; i < roots.length; i++) {
                sfolder = iProject.getFolder(roots[i].getResource().getProjectRelativePath());
                if (!sfolder.isDerived()) {
                    break;
                }
            }
        }
        return sfolder;
    }

    public static void deleteAll(File[] files) {
        if (files == null) {
            throw new IllegalArgumentException("files cannot be null"); //$NON-NLS-1$
        }
        for (File file : files) {
            if (!file.exists() || !file.canWrite()) {
                throw new IllegalArgumentException("Could not access or write file " + file); //$NON-NLS-1$
            }
            if (file.isDirectory()) {
                deleteDir(file);
            } else {
                file.delete();
            }
        }
    }

    /**
     * Reads the content of a file and returns an ArrayList with the data
     *
     * @param f
     *            File that should be read
     * @return ArrayList of data
     */
    public static List<String> readFile(File f) {
        List<String> data = new ArrayList<String>();

        try {
            BufferedReader br = new BufferedReader(new FileReader(f));
            while (br.ready()) {
                data.add(br.readLine());
            }
            return data;
        } catch (FileNotFoundException e) {
            return null;
        } catch (IOException e) {
            return null;
        }
    }

    /**
     * Returns the file extension of the given file.
     *
     * @param f
     * @return File extension
     */
    public static String getFileExtension(File f) {
        String fileName = f.getName();
        int index = fileName.lastIndexOf(IConstants.DOT_MARK);

        if (index > 0 && index < fileName.length()) {
            String fileExtension = fileName.substring(index + 1);
            return fileExtension;
        }
        return IConstants.EMPTY_STRING;
    }

    private static void deleteDir(File file) {
        if (file == null) {
            throw new IllegalArgumentException("file cannot be null"); //$NON-NLS-1$
        }
        if (!file.exists() || !file.canWrite()) {
            throw new IllegalArgumentException("Could not access or write file " + file); //$NON-NLS-1$
        }
        for (File subFile : file.listFiles()) {
            if (!subFile.exists() || !subFile.canWrite()) {
                throw new IllegalArgumentException("Could not access or write file " + subFile); //$NON-NLS-1$
            }
            if (subFile.isDirectory()) {
                deleteDir(subFile);
            } else {
                subFile.delete();
            }
        }
        file.delete();
    }
}