1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.common.util;
17
18 import java.io.File;
19 import java.io.IOException;
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.List;
23
24 import org.apache.commons.io.FileUtils;
25 import org.apache.commons.lang3.StringUtils;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 public class FileSystemUtils {
30
31 private static final Logger logger = LoggerFactory.getLogger(FileSystemUtils.class);
32
33
34
35
36 public static MonitorTextFileResult monitorTextFile(File file, String token, int intervalMillis, int timeoutMillis, String encoding) {
37
38
39 Assert.notNull(file, "file is null");
40 Assert.hasText(token, "token has no text");
41 Assert.hasText(encoding, "encoding has no text");
42 Assert.isTrue(intervalMillis > 0, "interval must be a positive integer");
43 Assert.isTrue(intervalMillis > 0, "timeout must be a positive integer");
44
45
46 long start = System.currentTimeMillis();
47 long stop = start + timeoutMillis;
48 boolean exists = false;
49 boolean contains = false;
50 boolean timeoutExceeded = false;
51 long now = -1;
52 String content = null;
53
54
55 for (;;) {
56
57
58 if (now != -1) {
59 ThreadUtils.sleep(intervalMillis);
60 }
61
62
63 now = System.currentTimeMillis();
64 if (now > stop) {
65 timeoutExceeded = true;
66 break;
67 }
68
69
70 exists = LocationUtils.exists(file);
71 if (!exists) {
72 continue;
73 }
74
75
76 content = LocationUtils.toString(file, encoding);
77 contains = StringUtils.contains(content, token);
78 if (contains) {
79
80 break;
81 }
82 }
83
84
85 long elapsed = now - start;
86
87
88 MonitorTextFileResult mtfr = new MonitorTextFileResult(exists, contains, timeoutExceeded, elapsed);
89 mtfr.setAbsolutePath(LocationUtils.getCanonicalPath(file));
90 mtfr.setContent(content);
91 return mtfr;
92 }
93
94 public static List<SyncResult> syncFiles(List<SyncRequest> requests) throws IOException {
95 List<SyncResult> results = new ArrayList<SyncResult>();
96 for (SyncRequest request : requests) {
97 SyncResult result = syncFiles(request);
98 results.add(result);
99 }
100 return results;
101 }
102
103 public static SyncResult syncFiles(SyncRequest request) throws IOException {
104 logger.info("Sync [{}] -> [{}]", request.getSrcDir(), request.getDstDir());
105 List<File> dstFiles = getAllFiles(request.getDstDir());
106 List<File> srcFiles = request.getSrcFiles();
107
108 List<String> dstPaths = getRelativePaths(request.getDstDir(), dstFiles);
109 List<String> srcPaths = getRelativePaths(request.getSrcDir(), srcFiles);
110
111 List<String> adds = new ArrayList<String>();
112 List<String> updates = new ArrayList<String>();
113 List<String> deletes = new ArrayList<String>();
114
115 for (String srcPath : srcPaths) {
116 boolean existing = dstPaths.contains(srcPath);
117 if (existing) {
118 updates.add(srcPath);
119 } else {
120 adds.add(srcPath);
121 }
122 }
123 for (String dstPath : dstPaths) {
124 boolean extra = !srcPaths.contains(dstPath);
125 if (extra) {
126 deletes.add(dstPath);
127 }
128 }
129
130 copyFiles(request.getSrcDir(), request.getSrcFiles(), request.getDstDir());
131
132 SyncResult result = new SyncResult();
133 result.setAdds(getFullPaths(request.getDstDir(), adds));
134 result.setUpdates(getFullPaths(request.getDstDir(), updates));
135 result.setDeletes(getFullPaths(request.getDstDir(), deletes));
136 return result;
137 }
138
139 protected static void copyFiles(File srcDir, List<File> files, File dstDir) throws IOException {
140 for (File file : files) {
141 String relativePath = getRelativePath(srcDir, file);
142 File dstFile = new File(dstDir, relativePath);
143 FileUtils.copyFile(file, dstFile);
144 }
145 }
146
147 protected static List<File> getFullPaths(File dir, List<String> relativePaths) {
148 List<File> files = new ArrayList<File>();
149 for (String relativePath : relativePaths) {
150 File file = new File(dir, relativePath);
151 files.add(file);
152 }
153 return files;
154 }
155
156 protected static List<String> getRelativePaths(File dir, List<File> files) {
157 List<String> relativePaths = new ArrayList<String>();
158 for (File file : files) {
159 String relativePath = getRelativePath(dir, file);
160 relativePaths.add(relativePath);
161 }
162 return relativePaths;
163 }
164
165 protected static String getRelativePath(File dir, File file) {
166 String dirPath = LocationUtils.getCanonicalPath(dir);
167 String filePath = LocationUtils.getCanonicalPath(file);
168 if (!StringUtils.contains(filePath, dirPath)) {
169 throw new IllegalArgumentException(file + " does not reside under " + dir);
170 }
171 return StringUtils.remove(filePath, dirPath);
172 }
173
174 protected static List<File> getAllFiles(File dir) {
175 SimpleScanner scanner = new SimpleScanner(dir, Arrays.asList("**/*"), Arrays.asList("**/.svn/**", "**/.git/**"));
176 return scanner.getFiles();
177 }
178
179 }