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 WatchRunnable(), intervalSeconds, intervalSeconds,
67 TimeUnit.SECONDS);
68 }
69 }
70
71 @Override
72 public boolean stop(final long timeout, final TimeUnit timeUnit) {
73 setStopping();
74 final boolean stopped = stop(future);
75 setStopped();
76 return stopped;
77 }
78
79 public void watchFile(final File file, final FileWatcher watcher) {
80 watchers.put(file, new FileMonitor(file.lastModified(), watcher));
81
82 }
83
84 public Map<File, FileWatcher> getWatchers() {
85 final Map<File, FileWatcher> map = new HashMap<>();
86 for (final Map.Entry<File, FileMonitor> entry : watchers.entrySet()) {
87 map.put(entry.getKey(), entry.getValue().fileWatcher);
88 }
89 return map;
90 }
91
92 private class WatchRunnable implements Runnable {
93
94 @Override
95 public void run() {
96 for (final Map.Entry<File, FileMonitor> entry : watchers.entrySet()) {
97 final File file = entry.getKey();
98 final FileMonitor fileMonitor = entry.getValue();
99 final long lastModfied = file.lastModified();
100 if (fileModified(fileMonitor, lastModfied)) {
101 logger.info("File {} was modified on {}, previous modification was {}", file, lastModfied, fileMonitor.lastModified);
102 fileMonitor.lastModified = lastModfied;
103 fileMonitor.fileWatcher.fileModified(file);
104 }
105 }
106 }
107
108 private boolean fileModified(final FileMonitor fileMonitor, final long lastModfied) {
109 return lastModfied != fileMonitor.lastModified;
110 }
111 }
112
113 private class FileMonitor {
114 private final FileWatcher fileWatcher;
115 private long lastModified;
116
117 public FileMonitor(final long lastModified, final FileWatcher fileWatcher) {
118 this.fileWatcher = fileWatcher;
119 this.lastModified = lastModified;
120 }
121 }
122 }