1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.datadictionary;
17
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20
21 import java.io.IOException;
22 import java.net.URL;
23 import java.util.LinkedList;
24 import java.util.Map;
25 import java.util.concurrent.ConcurrentHashMap;
26 import java.util.concurrent.Executors;
27 import java.util.concurrent.ScheduledExecutorService;
28 import java.util.concurrent.TimeUnit;
29 import java.util.zip.CRC32;
30 import java.util.zip.CheckedInputStream;
31
32
33
34
35
36
37
38 public class URLMonitor {
39 private static final Log LOG = LogFactory.getLog(URLMonitor.class);
40
41 private final LinkedList<URLContentChangedListener> listeners = new LinkedList<URLContentChangedListener>();
42 private final Map<URL, Long> resourceMap = new ConcurrentHashMap();
43 private final int reloadIntervalMilliseconds;
44 private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
45
46
47 public URLMonitor(int reloadIntervalMilliseconds) {
48 this.reloadIntervalMilliseconds = reloadIntervalMilliseconds;
49 }
50
51 public synchronized void addListener(URLContentChangedListener listener) {
52
53 listeners.add(listener);
54
55 if (listeners.size() == 1) {
56 scheduler.scheduleAtFixedRate(urlPoller,
57 reloadIntervalMilliseconds, reloadIntervalMilliseconds, TimeUnit.MILLISECONDS);
58 }
59 }
60
61 public void addURI(URL zipUrl) {
62
63 resourceMap.put(zipUrl, getCRC(zipUrl));
64 }
65
66 private Long getCRC(URL zipUrl) {
67 Long result = -1l;
68 try {
69 CRC32 crc = new CRC32();
70 CheckedInputStream cis = new CheckedInputStream(zipUrl.openStream(), crc);
71
72 byte[] buffer = new byte[1024];
73 int length;
74
75
76 while( (length = cis.read(buffer)) > 0);
77
78 cis.close();
79
80 result = crc.getValue();
81 } catch (IOException e) {
82 LOG.warn("Unable to calculate CRC, resource doesn't exist?", e);
83 }
84 return result;
85 }
86
87 private final Runnable urlPoller = new Runnable() {
88
89 @Override
90 public void run() {
91 for (Map.Entry<URL, Long> entry : resourceMap.entrySet()) {
92 Long crc = getCRC(entry.getKey());
93
94 if (!entry.getValue().equals(crc)) {
95 entry.setValue(crc);
96 for (URLContentChangedListener listener : listeners) {
97 listener.urlContentChanged(entry.getKey());
98 }
99 }
100 }
101 }
102 };
103
104 public static interface URLContentChangedListener {
105 public void urlContentChanged(URL url);
106 }
107 }