Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aa44476f authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Rename should behave like create: avoid conflict.

When we create a file that already exists, we try attaching a suffix
like "(1)" to the filename to avoid the conflict.  The newly added
rename method should do the same, since developers may not have
access to delete the conflicting file.

Test: boots, rename via UI, new unit tests
Bug: 31545404
Change-Id: Ie397eebb0fbf98cf079eee3bbbb6c6b7ca627d91
parent 0676aa18
Loading
Loading
Loading
Loading
+36 −11
Original line number Diff line number Diff line
@@ -605,6 +605,22 @@ public class FileUtils {
        return null;
    }

    private static File buildUniqueFileWithExtension(File parent, String name, String ext)
            throws FileNotFoundException {
        File file = buildFile(parent, name, ext);

        // If conflicting file, try adding counter suffix
        int n = 0;
        while (file.exists()) {
            if (n++ >= 32) {
                throw new FileNotFoundException("Failed to create unique file");
            }
            file = buildFile(parent, name + " (" + n + ")", ext);
        }

        return file;
    }

    /**
     * Generates a unique file name under the given parent directory. If the display name doesn't
     * have an extension that matches the requested MIME type, the default extension for that MIME
@@ -619,20 +635,29 @@ public class FileUtils {
    public static File buildUniqueFile(File parent, String mimeType, String displayName)
            throws FileNotFoundException {
        final String[] parts = splitFileName(mimeType, displayName);
        final String name = parts[0];
        final String ext = parts[1];
        File file = buildFile(parent, name, ext);

        // If conflicting file, try adding counter suffix
        int n = 0;
        while (file.exists()) {
            if (n++ >= 32) {
                throw new FileNotFoundException("Failed to create unique file");
        return buildUniqueFileWithExtension(parent, parts[0], parts[1]);
    }
            file = buildFile(parent, name + " (" + n + ")", ext);

    /**
     * Generates a unique file name under the given parent directory, keeping
     * any extension intact.
     */
    public static File buildUniqueFile(File parent, String displayName)
            throws FileNotFoundException {
        final String name;
        final String ext;

        // Extract requested extension from display name
        final int lastDot = displayName.lastIndexOf('.');
        if (lastDot >= 0) {
            name = displayName.substring(0, lastDot);
            ext = displayName.substring(lastDot + 1);
        } else {
            name = displayName;
            ext = null;
        }

        return file;
        return buildUniqueFileWithExtension(parent, name, ext);
    }

    /**
+14 −0
Original line number Diff line number Diff line
@@ -297,6 +297,20 @@ public class FileUtilsTest extends AndroidTestCase {
                FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg"));
    }

    public void testBuildUniqueFile_mimeless() throws Exception {
        assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "test.jpg"));
        new File(mTarget, "test.jpg").createNewFile();
        assertNameEquals("test (1).jpg", FileUtils.buildUniqueFile(mTarget, "test.jpg"));

        assertNameEquals("test", FileUtils.buildUniqueFile(mTarget, "test"));
        new File(mTarget, "test").createNewFile();
        assertNameEquals("test (1)", FileUtils.buildUniqueFile(mTarget, "test"));

        assertNameEquals("test.foo.bar", FileUtils.buildUniqueFile(mTarget, "test.foo.bar"));
        new File(mTarget, "test.foo.bar").createNewFile();
        assertNameEquals("test.foo (1).bar", FileUtils.buildUniqueFile(mTarget, "test.foo.bar"));
    }

    private static void assertNameEquals(String expected, File actual) {
        assertEquals(expected, actual.getName());
    }
+1 −4
Original line number Diff line number Diff line
@@ -473,10 +473,7 @@ public class ExternalStorageProvider extends DocumentsProvider {
        displayName = FileUtils.buildValidFatFilename(displayName);

        final File before = getFileForDocId(docId);
        final File after = new File(before.getParentFile(), displayName);
        if (after.exists()) {
            throw new IllegalStateException("Already exists " + after);
        }
        final File after = FileUtils.buildUniqueFile(before.getParentFile(), displayName);
        if (!before.renameTo(after)) {
            throw new IllegalStateException("Failed to rename to " + after);
        }