01: // Copyright (C) 2002 by Jason Hunter <jhunter_AT_acm_DOT_org>.
02: // All rights reserved. Use of this class is limited.
03: // Please see the LICENSE for more information.
04:
05: package com.oreilly.servlet.multipart;
06:
07: import java.io.*;
08:
09: /**
10: * Implements a renaming policy that adds increasing integers to the body of
11: * any file that collides. For example, if foo.gif is being uploaded and a
12: * file by the same name already exists, this logic will rename the upload
13: * foo1.gif. A second upload by the same name would be foo2.gif.
14: * Note that for safety the rename() method creates a zero-length file with
15: * the chosen name to act as a marker that the name is taken even before the
16: * upload starts writing the bytes.
17: *
18: * @author Jason Hunter
19: * @version 1.1, 2002/11/05, making thread safe with createNewFile()
20: * @version 1.0, 2002/04/30, initial revision, thanks to Yoonjung Lee
21: * for this idea
22: */
23: public class DefaultFileRenamePolicy implements FileRenamePolicy {
24:
25: // This method does not need to be synchronized because createNewFile()
26: // is atomic and used here to mark when a file name is chosen
27: public File rename(File f) {
28: if (createNewFile(f)) {
29: return f;
30: }
31: String name = f.getName();
32: String body = null;
33: String ext = null;
34:
35: int dot = name.lastIndexOf(".");
36: if (dot != -1) {
37: body = name.substring(0, dot);
38: ext = name.substring(dot); // includes "."
39: } else {
40: body = name;
41: ext = "";
42: }
43:
44: // Increase the count until an empty spot is found.
45: // Max out at 9999 to avoid an infinite loop caused by a persistent
46: // IOException, like when the destination dir becomes non-writable.
47: // We don't pass the exception up because our job is just to rename,
48: // and the caller will hit any IOException in normal processing.
49: int count = 0;
50: while (!createNewFile(f) && count < 9999) {
51: count++;
52: String newName = body + count + ext;
53: f = new File(f.getParent(), newName);
54: }
55:
56: return f;
57: }
58:
59: private boolean createNewFile(File f) {
60: try {
61: return f.createNewFile();
62: } catch (IOException ignored) {
63: return false;
64: }
65: }
66: }
|