1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.appender.rolling.action;
18
19 import java.io.File;
20 import java.io.IOException;
21 import java.io.PrintWriter;
22 import java.nio.file.Files;
23 import java.nio.file.Paths;
24 import java.nio.file.StandardCopyOption;
25
26
27
28
29 public class FileRenameAction extends AbstractAction {
30
31
32
33
34 private final File source;
35
36
37
38
39 private final File destination;
40
41
42
43
44 private final boolean renameEmptyFiles;
45
46
47
48
49
50
51
52
53 public FileRenameAction(final File src, final File dst, final boolean renameEmptyFiles) {
54 source = src;
55 destination = dst;
56 this.renameEmptyFiles = renameEmptyFiles;
57 }
58
59
60
61
62
63
64 @Override
65 public boolean execute() {
66 return execute(source, destination, renameEmptyFiles);
67 }
68
69
70
71
72
73
74 public File getDestination() {
75 return this.destination;
76 }
77
78
79
80
81
82
83 public File getSource() {
84 return this.source;
85 }
86
87
88
89
90
91
92 public boolean isRenameEmptyFiles() {
93 return renameEmptyFiles;
94 }
95
96
97
98
99
100
101
102
103
104 public static boolean execute(final File source, final File destination, final boolean renameEmptyFiles) {
105 if (renameEmptyFiles || (source.length() > 0)) {
106 final File parent = destination.getParentFile();
107 if ((parent != null) && !parent.exists()) {
108
109
110
111 parent.mkdirs();
112 if (!parent.exists()) {
113 LOGGER.error("Unable to create directory {}", parent.getAbsolutePath());
114 return false;
115 }
116 }
117 try {
118 try {
119 Files.move(Paths.get(source.getAbsolutePath()), Paths.get(destination.getAbsolutePath()),
120 StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
121 LOGGER.trace("Renamed file {} to {} with Files.move", source.getAbsolutePath(),
122 destination.getAbsolutePath());
123 return true;
124 } catch (final IOException exMove) {
125 LOGGER.error("Unable to move file {} to {}: {} {}", source.getAbsolutePath(),
126 destination.getAbsolutePath(), exMove.getClass().getName(), exMove.getMessage());
127 boolean result = source.renameTo(destination);
128 if (!result) {
129 try {
130 Files.copy(Paths.get(source.getAbsolutePath()), Paths.get(destination.getAbsolutePath()),
131 StandardCopyOption.REPLACE_EXISTING);
132 try {
133 Files.delete(Paths.get(source.getAbsolutePath()));
134 result = true;
135 LOGGER.trace("Renamed file {} to {} using copy and delete",
136 source.getAbsolutePath(), destination.getAbsolutePath());
137 } catch (final IOException exDelete) {
138 LOGGER.error("Unable to delete file {}: {} {}", source.getAbsolutePath(),
139 exDelete.getClass().getName(), exDelete.getMessage());
140 try {
141 new PrintWriter(source.getAbsolutePath()).close();
142 LOGGER.trace("Renamed file {} to {} with copy and truncation",
143 source.getAbsolutePath(), destination.getAbsolutePath());
144 } catch (final IOException exOwerwrite) {
145 LOGGER.error("Unable to overwrite file {}: {} {}",
146 source.getAbsolutePath(), exOwerwrite.getClass().getName(),
147 exOwerwrite.getMessage());
148 }
149 }
150 } catch (final IOException exCopy) {
151 LOGGER.error("Unable to copy file {} to {}: {} {}", source.getAbsolutePath(),
152 destination.getAbsolutePath(), exCopy.getClass().getName(), exCopy.getMessage());
153 }
154 } else {
155 LOGGER.trace("Renamed file {} to {} with source.renameTo",
156 source.getAbsolutePath(), destination.getAbsolutePath());
157 }
158 return result;
159 }
160 } catch (final RuntimeException ex) {
161 LOGGER.error("Unable to rename file {} to {}: {} {}", source.getAbsolutePath(),
162 destination.getAbsolutePath(), ex.getClass().getName(), ex.getMessage());
163 }
164 } else {
165 try {
166 source.delete();
167 } catch (final Exception exDelete) {
168 LOGGER.error("Unable to delete empty file {}: {} {}", source.getAbsolutePath(),
169 exDelete.getClass().getName(), exDelete.getMessage());
170 }
171 }
172
173 return false;
174 }
175
176 @Override
177 public String toString() {
178 return FileRenameAction.class.getSimpleName() + '[' + source + " to " + destination
179 + ", renameEmptyFiles=" + renameEmptyFiles + ']';
180 }
181
182 }