1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.classpathwatch;
35
36 import info.magnolia.init.MagnoliaConfigurationProperties;
37
38 import java.io.IOException;
39 import java.net.URL;
40 import java.util.concurrent.Executors;
41 import java.util.concurrent.Future;
42 import java.util.concurrent.ScheduledExecutorService;
43 import java.util.concurrent.TimeUnit;
44
45 import javax.inject.Inject;
46 import javax.inject.Singleton;
47
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51 import com.google.common.base.Function;
52 import com.google.common.base.Predicate;
53
54
55
56
57 @Singleton
58 public class ClasspathScannerService {
59
60 private static final int SCAN_INTERVAL = 10;
61
62 private static final Logger log = LoggerFactory.getLogger(ClasspathScannerService.class);
63
64 private final boolean devMode;
65 private ScheduledExecutorService executorService;
66 private ClasspathScanner scanner;
67
68 private Future<?> scannerFuture;
69
70 @Inject
71 public ClasspathScannerService(MagnoliaConfigurationProperties mcp) throws IOException {
72 this.devMode = mcp.getBooleanProperty("magnolia.develop");
73 if (!devMode) {
74 log.info("Not in dev mode, will not watch resource changes on the classpath.");
75 }
76 }
77
78 public void start() {
79 }
80
81 public boolean isEnabled() {
82 return devMode;
83 }
84
85
86
87
88 public synchronized void watch(Predicate<String> resourcesFilter, Predicate<? super URL> urlsFilter, Function<String, Void> callbackFunction) {
89 if (!devMode) {
90 return;
91 }
92
93
94
95
96
97
98
99
100
101 if (scannerFuture == null) {
102 scanner = new ClasspathScanner(resourcesFilter, urlsFilter);
103
104
105 executorService = Executors.newSingleThreadScheduledExecutor();
106 log.info("Scheduling execution of ClasspathScanner every {}s.", SCAN_INTERVAL);
107 scannerFuture = executorService.scheduleWithFixedDelay(scanner, SCAN_INTERVAL, SCAN_INTERVAL, TimeUnit.SECONDS);
108 }
109 scanner.watchResourceChanges(callbackFunction);
110 }
111
112 public void stop() {
113 if (executorService != null) {
114 executorService.shutdownNow();
115 boolean terminated = false;
116 try {
117 terminated = executorService.awaitTermination(1, TimeUnit.SECONDS);
118 } catch (InterruptedException e) {
119 log.error("Exception during service termination", e);
120 }
121 if (terminated) {
122 log.info("{} terminated.", getClass().getSimpleName());
123 } else {
124 log.warn("{} not terminated, some tasks are still running.", getClass().getSimpleName());
125 }
126 }
127 }
128
129 }