1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.util;
18
19 import java.io.File;
20 import java.util.HashMap;
21 import java.util.Map;
22 import java.util.concurrent.ConcurrentHashMap;
23 import java.util.concurrent.ConcurrentMap;
24 import java.util.concurrent.ScheduledFuture;
25 import java.util.concurrent.TimeUnit;
26
27 import org.apache.logging.log4j.Logger;
28 import org.apache.logging.log4j.core.AbstractLifeCycle;
29 import org.apache.logging.log4j.core.config.ConfigurationScheduler;
30 import org.apache.logging.log4j.status.StatusLogger;
31
32
33
34
35 public class WatchManager extends AbstractLifeCycle {
36
37 private static Logger logger = StatusLogger.getLogger();
38 private final ConcurrentMap<File, FileMonitor> watchers = new ConcurrentHashMap<>();
39 private int intervalSeconds = 0;
40 private ScheduledFuture<?> future;
41 private final ConfigurationScheduler scheduler;
42
43 public WatchManager(final ConfigurationScheduler scheduler) {
44 this.scheduler = scheduler;
45 }
46
47 public void setIntervalSeconds(final int intervalSeconds) {
48 if (!isStarted()) {
49 if (this.intervalSeconds > 0 && intervalSeconds == 0) {
50 scheduler.decrementScheduledItems();
51 } else if (this.intervalSeconds == 0 && intervalSeconds > 0) {
52 scheduler.incrementScheduledItems();
53 }
54 this.intervalSeconds = intervalSeconds;
55 }
56 }
57
58 public int getIntervalSeconds() {
59 return this.intervalSeconds;
60 }
61
62 @Override
63 public void start() {
64 super.start();
65 if (intervalSeconds > 0) {
66 future = scheduler.scheduleWithFixedDelay(new WatchWorker(), intervalSeconds, intervalSeconds,
67 TimeUnit.SECONDS);
68 }
69 }
70
71 @Override
72 public void stop() {
73 future.cancel(true);
74 super.stop();
75 }
76
77 public void watchFile(final File file, final FileWatcher watcher) {
78 watchers.put(file, new FileMonitor(file.lastModified(), watcher));
79
80 }
81
82 public Map<File, FileWatcher> getWatchers() {
83 final Map<File, FileWatcher> map = new HashMap<>();
84 for (final Map.Entry<File, FileMonitor> entry : watchers.entrySet()) {
85 map.put(entry.getKey(), entry.getValue().fileWatcher);
86 }
87 return map;
88 }
89
90 private class WatchWorker implements Runnable {
91
92 @Override
93 public void run() {
94 for (final Map.Entry<File, FileMonitor> entry : watchers.entrySet()) {
95 final File file = entry.getKey();
96 final FileMonitor fileMonitor = entry.getValue();
97 final long lastModfied = file.lastModified();
98 if (fileModified(fileMonitor, lastModfied)) {
99 logger.info("File {} was modified", file.toString());
100 fileMonitor.lastModified = lastModfied;
101 fileMonitor.fileWatcher.fileModified(file);
102 }
103 }
104 }
105
106 private boolean fileModified(final FileMonitor fileMonitor, final long lastModfied) {
107 return lastModfied != fileMonitor.lastModified;
108 }
109 }
110
111 private class FileMonitor {
112 private final FileWatcher fileWatcher;
113 private long lastModified;
114
115 public FileMonitor(final long lastModified, final FileWatcher fileWatcher) {
116 this.fileWatcher = fileWatcher;
117 this.lastModified = lastModified;
118 }
119 }
120 }