1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.jci.listeners;
19
20 import java.io.File;
21 import java.io.FileInputStream;
22 import java.util.Collection;
23 import java.util.HashSet;
24 import java.util.Iterator;
25 import java.util.Set;
26
27 import org.apache.commons.io.IOUtils;
28 import org.apache.commons.jci.ReloadingClassLoader;
29 import org.apache.commons.jci.monitor.FilesystemAlterationObserver;
30 import org.apache.commons.jci.stores.MemoryResourceStore;
31 import org.apache.commons.jci.stores.ResourceStore;
32 import org.apache.commons.jci.stores.Transactional;
33 import org.apache.commons.jci.utils.ConversionUtils;
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36
37
38
39
40
41
42
43 public class ReloadingListener extends AbstractFilesystemAlterationListener {
44
45 private final Log log = LogFactory.getLog(ReloadingListener.class);
46
47 private final Set notificationListeners = new HashSet();
48 private final ResourceStore store;
49
50 public ReloadingListener() {
51 this(new MemoryResourceStore());
52 }
53
54 public ReloadingListener( final ResourceStore pStore ) {
55 store = pStore;
56 }
57
58 public ResourceStore getStore() {
59 return store;
60 }
61
62 public void addReloadNotificationListener( final ReloadNotificationListener pNotificationListener ) {
63 notificationListeners.add(pNotificationListener);
64
65 if (pNotificationListener instanceof ReloadingClassLoader) {
66 ((ReloadingClassLoader)pNotificationListener).addResourceStore(store);
67 }
68
69 }
70
71 public boolean isReloadRequired( final FilesystemAlterationObserver pObserver ) {
72 boolean reload = false;
73
74 final Collection created = getCreatedFiles();
75 final Collection changed = getChangedFiles();
76 final Collection deleted = getDeletedFiles();
77
78 log.debug("created:" + created.size() + " changed:" + changed.size() + " deleted:" + deleted.size() + " resources");
79
80 if (deleted.size() > 0) {
81 for (Iterator it = deleted.iterator(); it.hasNext();) {
82 final File file = (File) it.next();
83 final String resourceName = ConversionUtils.getResourceNameFromFileName(ConversionUtils.relative(pObserver.getRootDirectory(), file));
84 store.remove(resourceName);
85 }
86 reload = true;
87 }
88
89 if (created.size() > 0) {
90 for (Iterator it = created.iterator(); it.hasNext();) {
91 final File file = (File) it.next();
92 FileInputStream is = null;
93 try {
94 is = new FileInputStream(file);
95 final byte[] bytes = IOUtils.toByteArray(is);
96 final String resourceName = ConversionUtils.getResourceNameFromFileName(ConversionUtils.relative(pObserver.getRootDirectory(), file));
97 store.write(resourceName, bytes);
98 } catch(final Exception e) {
99 log.error("could not load " + file, e);
100 } finally {
101 IOUtils.closeQuietly(is);
102 }
103 }
104 }
105
106 if (changed.size() > 0) {
107 for (Iterator it = changed.iterator(); it.hasNext();) {
108 final File file = (File) it.next();
109 FileInputStream is = null;
110 try {
111 is = new FileInputStream(file);
112 final byte[] bytes = IOUtils.toByteArray(is);
113 final String resourceName = ConversionUtils.getResourceNameFromFileName(ConversionUtils.relative(pObserver.getRootDirectory(), file));
114 store.write(resourceName, bytes);
115 } catch(final Exception e) {
116 log.error("could not load " + file, e);
117 } finally {
118 IOUtils.closeQuietly(is);
119 }
120 }
121 reload = true;
122 }
123
124 return reload;
125 }
126
127 public void onStop( final FilesystemAlterationObserver pObserver ) {
128
129
130 if (store instanceof Transactional) {
131 ((Transactional)store).onStart();
132 }
133
134 final boolean reload = isReloadRequired(pObserver);
135
136 if (store instanceof Transactional) {
137 ((Transactional)store).onStop();
138 }
139
140 if (reload) {
141 notifyReloadNotificationListeners();
142 }
143
144 super.onStop(pObserver);
145 }
146
147 void notifyReloadNotificationListeners() {
148
149 for (Iterator it = notificationListeners.iterator(); it.hasNext();) {
150 final ReloadNotificationListener listener = (ReloadNotificationListener) it.next();
151
152 log.debug("notifying listener " + listener);
153
154 listener.handleNotification();
155 }
156 }
157
158 public void onDirectoryCreate( final File pDir ) {
159 }
160 public void onDirectoryChange( final File pDir ) {
161 }
162 public void onDirectoryDelete( final File pDir ) {
163 }
164 }