com.docd.purefm.utils.PFMFileUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.docd.purefm.utils.PFMFileUtils.java

Source

/*
 * Copyright 2014 Yaroslav Mytkalyk
 * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.docd.purefm.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Comparator;
import java.util.List;

import org.apache.commons.io.FileExistsException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.docd.purefm.Environment;
import com.docd.purefm.R;
import com.docd.purefm.commandline.CommandCopyRecursively;
import com.docd.purefm.commandline.CommandLine;
import com.docd.purefm.commandline.CommandMove;
import com.docd.purefm.commandline.CommandRemove;
import com.docd.purefm.commandline.CommandStat;
import com.docd.purefm.commandline.ShellHolder;
import com.docd.purefm.file.GenericFile;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.text.InputFilter;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

public final class PFMFileUtils {

    private PFMFileUtils() {
    }

    public static final class FileNameFilter implements InputFilter {

        public static final int MAX_FILENAME_LENGTH = 255;

        private static final String FILENAME_PATTERN = "\\\\|/|:|\\*|\\?|\"|<|>|\r|\n";

        @Nullable
        @Override
        public CharSequence filter(final CharSequence source, final int start, final int end, final Spanned dest,
                final int dstart, final int dend) {
            if (source.length() == 0) {
                //nothing to filter
                return null;
            }
            final CharSequence sourceSubSequence = source.subSequence(start, end);
            final String sourceSubSequenceString = sourceSubSequence.toString();
            final String sourceProcessed = sourceSubSequenceString.replaceAll(FILENAME_PATTERN, "");
            if (sourceSubSequenceString.equals(sourceProcessed)) {
                // nothing filtered
                return null;
            }
            if (source instanceof Spanned) {
                // copy spans from original source
                final Spannable processed = new SpannableString(sourceProcessed);
                TextUtils.copySpansFrom((Spanned) source, start, processed.length(), null, processed, 0);
                return processed;
            }
            return sourceProcessed;
        }
    }

    /**
     * Returns canonical path or absolute path if failed
     *
     * @param file File to get full path
     * @return canonical path or absolute path if failed
     */
    @NonNull
    public static String fullPath(@NonNull final GenericFile file) {
        try {
            return file.getCanonicalPath();
        } catch (IOException e) {
            return file.getAbsolutePath();
        }
    }

    /**
     * Returns canonical path or absolute path if failed
     *
     * @param file File to get full path
     * @return canonical path or absolute path if failed
     */
    @NonNull
    public static String fullPath(@NonNull final File file) {
        try {
            return file.getCanonicalPath();
        } catch (IOException e) {
            return file.getAbsolutePath();
        }
    }

    @NonNull
    public static String byteCountToDisplaySize(@NonNull final BigInteger size) {
        String displaySize;

        if (size.divide(FileUtils.ONE_GB_BI).compareTo(BigInteger.ZERO) > 0) {
            displaySize = String.valueOf(size.divide(FileUtils.ONE_GB_BI)) + " GiB";
        } else if (size.divide(FileUtils.ONE_MB_BI).compareTo(BigInteger.ZERO) > 0) {
            displaySize = String.valueOf(size.divide(FileUtils.ONE_MB_BI)) + " MiB";
        } else if (size.divide(FileUtils.ONE_KB_BI).compareTo(BigInteger.ZERO) > 0) {
            displaySize = String.valueOf(size.divide(FileUtils.ONE_KB_BI)) + " KiB";
        } else {
            displaySize = String.valueOf(size) + " B";
        }
        return displaySize;
    }

    @Nullable
    public static String resolveFileSystem(@NonNull final GenericFile file) {
        final String path = PFMFileUtils.fullPath(file);
        return resolveFileSystem(FilenameUtils.getFullPathNoEndSeparator(path));
    }

    @Nullable
    public static String resolveFileSystem(@NonNull final String path) {
        for (final StorageHelper.Volume v : Environment.getVolumes()) {
            if (path.startsWith(v.file.getAbsolutePath())) {
                return v.fileSystem;
            }
        }

        if (!ShellHolder.getInstance().hasShell()) {
            Log.w("resolveFileSystem()", "no shell, aborting");
            return null;
        }

        final List<String> fsTypeResult = CommandLine.executeForResult(new CommandStat(path));
        return fsTypeResult == null || fsTypeResult.isEmpty() ? null : fsTypeResult.get(0);
    }

    public static void openFileInExternalApp(@NonNull final Context context, @NonNull final File target) {
        final String mime = MimeTypes.getMimeType(target);
        if (mime != null) {
            final Intent i = new Intent(Intent.ACTION_VIEW);
            i.setDataAndType(Uri.fromFile(target), mime);
            final PackageManager packageManager = context.getPackageManager();
            if (packageManager == null) {
                throw new IllegalArgumentException("No PackageManager for context");
            }
            if (packageManager.queryIntentActivities(i, 0).isEmpty()) {
                Toast.makeText(context, R.string.no_apps_to_open, Toast.LENGTH_SHORT).show();
                return;
            }
            try {
                context.startActivity(i);
            } catch (Exception e) {
                Toast.makeText(context, context.getString(R.string.could_not_open_file_) + e.getMessage(),
                        Toast.LENGTH_SHORT).show();
            }
        }
    }

    public static void moveFile(@NonNull final GenericFile source, @NonNull final GenericFile target,
            final boolean useCommandLine) throws IOException {
        if (useCommandLine) {
            if (target.exists()) {
                throw new FileExistsException("Target exists");
            }
            final boolean result = CommandLine.execute(new CommandMove(source, target));
            if (!result) {
                throw new IOException("Move failed");
            }
        } else {
            FileUtils.moveFile(source.toFile(), target.toFile());
        }
    }

    public static void copyFile(@NonNull final GenericFile source, @NonNull final GenericFile target,
            final boolean useCommandLine) throws IOException {
        if (useCommandLine) {
            final boolean result = CommandLine.execute(new CommandCopyRecursively(source, target));
            if (!result) {
                throw new IOException("Move failed");
            }
        } else {
            FileUtils.copyFile(source.toFile(), target.toFile());
        }
    }

    public static void copyFileToDirectory(@NonNull final GenericFile source, @NonNull final GenericFile target,
            final boolean useCommandLine) throws IOException {
        if (useCommandLine) {
            if (!target.exists()) {
                throw new FileNotFoundException("Target doesn't exist");
            }
            if (!target.isDirectory()) {
                throw new IllegalArgumentException("Target is not a directory");
            }
            final boolean result = CommandLine.execute(new CommandCopyRecursively(source, target));
            if (!result) {
                throw new IOException("Move failed");
            }
        } else {
            FileUtils.copyFileToDirectory(source.toFile(), target.toFile());
        }
    }

    public static void moveDirectory(@NonNull final GenericFile source, @NonNull final GenericFile target,
            final boolean useCommandLine) throws IOException {
        if (useCommandLine) {
            if (target.exists()) {
                throw new FileExistsException("Target exists");
            }
            final boolean result = CommandLine.execute(new CommandMove(source, target));
            if (!result) {
                throw new IOException("Move failed");
            }
        } else {
            FileUtils.moveDirectory(source.toFile(), target.toFile());
        }
    }

    public static void moveToDirectory(@NonNull final GenericFile source, @NonNull final GenericFile target,
            final boolean useCommandLine, final boolean createDestDir) throws IOException {

        if (useCommandLine) {
            if (!source.exists()) {
                throw new FileNotFoundException("Source '" + source + "' does not exist");
            }
            if (target.exists()) {
                if (!target.isDirectory()) {
                    throw new IOException("Target is not a directory");
                }
            } else {
                if (createDestDir) {
                    if (!target.mkdirs()) {
                        throw new IOException("Failed to create target directory");
                    }
                } else {
                    throw new FileNotFoundException("Target directory doesn't exist");
                }
            }
            final boolean result = CommandLine.execute(new CommandMove(source, target));
            if (!result) {
                throw new IOException("Moving failed");
            }
        } else {
            FileUtils.moveToDirectory(source.toFile(), target.toFile(), createDestDir);
        }
    }

    public static void copyDirectory(@NonNull final GenericFile source, @NonNull final GenericFile target,
            final boolean useCommandLine) throws IOException {
        if (useCommandLine) {
            if (!source.exists()) {
                throw new FileNotFoundException("Source '" + source + "' does not exist");
            }
            if (!source.isDirectory()) {
                throw new IOException("Source '" + source + "' exists but is not a directory");
            }
            if (source.getCanonicalPath().equals(target.getCanonicalPath())) {
                throw new IOException("Source '" + source + "' and destination '" + target + "' are the same");
            }
            final boolean result = CommandLine.execute(new CommandCopyRecursively(source, target));
            if (!result) {
                throw new IOException("Copying failed");
            }
        } else {
            FileUtils.copyDirectory(source.toFile(), target.toFile());
        }
    }

    public static void copyDirectoryToDirectory(@NonNull final GenericFile source,
            @NonNull final GenericFile target, final boolean useCommandLine) throws IOException {
        if (useCommandLine) {
            if (!source.exists()) {
                throw new FileNotFoundException("Source '" + source + "' does not exist");
            }
            if (!source.isDirectory()) {
                throw new IOException("Source '" + source + "' exists but is not a directory");
            }
            if (source.getCanonicalPath().equals(target.getCanonicalPath())) {
                throw new IOException("Source '" + source + "' and destination '" + target + "' are the same");
            }
            if (!target.exists()) {
                throw new FileNotFoundException("Target dir does not exist");
            }
            if (!target.isDirectory()) {
                throw new IOException("Target is not a directory");
            }
            final boolean result = CommandLine.execute(new CommandCopyRecursively(source, target));
            if (!result) {
                throw new IOException("Copying failed");
            }
        } else {
            FileUtils.copyDirectoryToDirectory(source.toFile(), target.toFile());
        }
    }

    public static void forceDelete(@NonNull final GenericFile file, final boolean useCommandLine)
            throws IOException {
        if (useCommandLine) {
            if (!file.exists()) {
                throw new FileNotFoundException("File does not exist: " + file);
            }
            final boolean result = CommandLine.execute(new CommandRemove(file.toFile()));
            if (!result) {
                throw new IOException("Removing failed");
            }
        } else {
            FileUtils.forceDelete(file.toFile());
        }
    }

    public static final class NameComparator implements Comparator<GenericFile> {

        @Override
        public int compare(final GenericFile a, final GenericFile b) {
            if (a.isDirectory() && b.isDirectory()) {
                return String.CASE_INSENSITIVE_ORDER.compare(a.getName(), b.getName());
            }

            if (a.isDirectory()) {
                return -1;
            }

            if (b.isDirectory()) {
                return 1;
            }

            return a.getName().compareTo(b.getName());
        }
    }

    public static final class NameComparatorReverse implements Comparator<GenericFile> {

        @Override
        public int compare(final GenericFile a, final GenericFile b) {
            if (a.isDirectory() && b.isDirectory()) {
                final int res = String.CASE_INSENSITIVE_ORDER.compare(a.getName(), b.getName());
                if (res == 0) {
                    return 0;
                }
                if (res < 0) {
                    return 1;
                }
                return -1;
            }

            if (a.isDirectory()) {
                return -1;
            }

            if (b.isDirectory()) {
                return 1;
            }

            final int res = a.getName().compareTo(b.getName());
            if (res == 0) {
                return 0;
            }
            if (res < 0) {
                return 1;
            }
            return -1;
        }
    }

    public static final class DateComparatorAsc implements Comparator<GenericFile> {

        @Override
        public int compare(final GenericFile a, final GenericFile b) {
            final long date_a = a.lastModified();
            final long date_b = b.lastModified();

            if (date_a == date_b) {
                return 0;
            }

            if (date_a < date_b) {
                return -1;
            }

            return 1;
        }
    }

    public static final class DateComparatorDesc implements Comparator<GenericFile> {

        @Override
        public int compare(final GenericFile a, final GenericFile b) {
            final long date_a = a.lastModified();
            final long date_b = b.lastModified();

            if (date_a == date_b) {
                return 0;
            }

            if (date_a < date_b) {
                return 1;
            }

            return -1;
        }
    }

    public static final class SizeComparatorAsc implements Comparator<GenericFile> {

        @Override
        public int compare(final GenericFile a, final GenericFile b) {
            if (a.isDirectory() && b.isDirectory()) {
                return a.getName().compareTo(b.getName());
            }

            if (a.isDirectory()) {
                return -1;
            }

            if (b.isDirectory()) {
                return 1;
            }

            final long len_a = a.length();
            final long len_b = b.length();

            if (len_a == len_b) {
                return a.getName().compareTo(b.getName());
            }

            if (len_a < len_b) {
                return -1;
            }

            return 1;
        }
    }

    public static final class SizeComparatorDesc implements Comparator<GenericFile> {

        @Override
        public int compare(final GenericFile a, final GenericFile b) {
            if (a.isDirectory() && b.isDirectory()) {
                return a.getName().compareTo(b.getName());
            }

            if (a.isDirectory()) {
                return 1;
            }

            if (b.isDirectory()) {
                return -1;
            }

            final long len_a = a.length();
            final long len_b = b.length();

            if (len_a == len_b) {
                return a.getName().compareTo(b.getName());
            }

            if (len_a < len_b) {
                return 1;
            }

            return -1;
        }
    }

    public static final class TypeComparator implements Comparator<GenericFile> {

        @Override
        public int compare(final GenericFile a, final GenericFile b) {

            if (a.isDirectory() && b.isDirectory()) {
                return a.getName().compareTo(b.getName());
            }

            if (a.isDirectory()) {
                return -1;
            }

            if (b.isDirectory()) {
                return 1;
            }

            final String ext_a = FilenameUtils.getExtension(a.getName());
            final String ext_b = FilenameUtils.getExtension(b.getName());

            if (ext_a.isEmpty() && ext_b.isEmpty()) {
                return a.getName().compareTo(b.getName());
            }

            if (ext_a.isEmpty()) {
                return -1;
            }

            if (ext_b.isEmpty()) {
                return 1;
            }

            final int res = ext_a.compareTo(ext_b);
            if (res == 0) {
                return a.getName().compareTo(b.getName());
            }
            return res;
        }
    }

    public static final class TypeComparatorReverse implements Comparator<GenericFile> {

        @Override
        public int compare(final GenericFile a, final GenericFile b) {
            if (a.isDirectory() && b.isDirectory()) {
                return a.getName().compareTo(b.getName());
            }

            if (a.isDirectory()) {
                return -1;
            }

            if (b.isDirectory()) {
                return 1;
            }

            final String ext_a = FilenameUtils.getExtension(a.getName());
            final String ext_b = FilenameUtils.getExtension(b.getName());

            if (ext_a.isEmpty() && ext_b.isEmpty()) {
                return a.getName().compareTo(b.getName());
            }

            if (ext_a.isEmpty()) {
                return 1;
            }

            if (ext_b.isEmpty()) {
                return -1;
            }

            final int res = ext_a.compareTo(ext_b);
            if (res == 0) {
                return a.getName().compareTo(b.getName());
            }
            return res;
        }
    }
}