1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.deploy.providers;
20
21 import java.io.File;
22 import java.io.FilenameFilter;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.concurrent.CopyOnWriteArrayList;
30
31 import org.eclipse.jetty.deploy.App;
32 import org.eclipse.jetty.deploy.AppProvider;
33 import org.eclipse.jetty.deploy.DeploymentManager;
34 import org.eclipse.jetty.util.Scanner;
35 import org.eclipse.jetty.util.annotation.ManagedAttribute;
36 import org.eclipse.jetty.util.annotation.ManagedObject;
37 import org.eclipse.jetty.util.component.AbstractLifeCycle;
38 import org.eclipse.jetty.util.log.Log;
39 import org.eclipse.jetty.util.log.Logger;
40 import org.eclipse.jetty.util.resource.Resource;
41
42
43
44 @ManagedObject("Abstract Provider for loading webapps")
45 public abstract class ScanningAppProvider extends AbstractLifeCycle implements AppProvider
46 {
47 private static final Logger LOG = Log.getLogger(ScanningAppProvider.class);
48
49 private Map<String, App> _appMap = new HashMap<String, App>();
50
51 private DeploymentManager _deploymentManager;
52 protected FilenameFilter _filenameFilter;
53 private final List<Resource> _monitored= new CopyOnWriteArrayList<>();
54 private boolean _recursive = false;
55 private int _scanInterval = 10;
56 private Scanner _scanner;
57
58
59 private final Scanner.DiscreteListener _scannerListener = new Scanner.DiscreteListener()
60 {
61 @Override
62 public void fileAdded(String filename) throws Exception
63 {
64 ScanningAppProvider.this.fileAdded(filename);
65 }
66
67 @Override
68 public void fileChanged(String filename) throws Exception
69 {
70 ScanningAppProvider.this.fileChanged(filename);
71 }
72
73 @Override
74 public void fileRemoved(String filename) throws Exception
75 {
76 ScanningAppProvider.this.fileRemoved(filename);
77 }
78 };
79
80
81 protected ScanningAppProvider()
82 {
83 }
84
85
86 protected ScanningAppProvider(FilenameFilter filter)
87 {
88 _filenameFilter = filter;
89 }
90
91
92 protected void setFilenameFilter(FilenameFilter filter)
93 {
94 if (isRunning())
95 throw new IllegalStateException();
96 _filenameFilter = filter;
97 }
98
99
100
101
102
103 protected Map<String, App> getDeployedApps()
104 {
105 return _appMap;
106 }
107
108
109
110
111
112
113
114
115
116
117
118
119 protected App createApp(String filename)
120 {
121 return new App(_deploymentManager,this,filename);
122 }
123
124
125 @Override
126 protected void doStart() throws Exception
127 {
128 if (LOG.isDebugEnabled())
129 LOG.debug(this.getClass().getSimpleName() + ".doStart()");
130 if (_monitored.size()==0)
131 throw new IllegalStateException("No configuration dir specified");
132
133 LOG.info("Deployment monitor " + _monitored + " at interval " + _scanInterval);
134 List<File> files = new ArrayList<>();
135 for (Resource resource:_monitored)
136 files.add(resource.getFile());
137
138 _scanner = new Scanner();
139 _scanner.setScanDirs(files);
140 _scanner.setScanInterval(_scanInterval);
141 _scanner.setRecursive(_recursive);
142 _scanner.setFilenameFilter(_filenameFilter);
143 _scanner.setReportDirs(true);
144 _scanner.addListener(_scannerListener);
145 _scanner.start();
146 }
147
148
149 @Override
150 protected void doStop() throws Exception
151 {
152 if (_scanner!=null)
153 {
154 _scanner.stop();
155 _scanner.removeListener(_scannerListener);
156 _scanner = null;
157 }
158 }
159
160
161 protected boolean exists(String path)
162 {
163 return _scanner.exists(path);
164 }
165
166
167 protected void fileAdded(String filename) throws Exception
168 {
169 if (LOG.isDebugEnabled())
170 LOG.debug("added {}",filename);
171 App app = ScanningAppProvider.this.createApp(filename);
172 if (app != null)
173 {
174 _appMap.put(filename,app);
175 _deploymentManager.addApp(app);
176 }
177 }
178
179
180 protected void fileChanged(String filename) throws Exception
181 {
182 if (LOG.isDebugEnabled())
183 LOG.debug("changed {}",filename);
184 App app = _appMap.remove(filename);
185 if (app != null)
186 {
187 _deploymentManager.removeApp(app);
188 }
189 app = ScanningAppProvider.this.createApp(filename);
190 if (app != null)
191 {
192 _appMap.put(filename,app);
193 _deploymentManager.addApp(app);
194 }
195 }
196
197
198 protected void fileRemoved(String filename) throws Exception
199 {
200 if (LOG.isDebugEnabled())
201 LOG.debug("removed {}",filename);
202 App app = _appMap.remove(filename);
203 if (app != null)
204 _deploymentManager.removeApp(app);
205 }
206
207
208
209
210
211
212
213 public DeploymentManager getDeploymentManager()
214 {
215 return _deploymentManager;
216 }
217
218
219
220 public Resource getMonitoredDirResource()
221 {
222 if (_monitored.size()==0)
223 return null;
224 if (_monitored.size()>1)
225 throw new IllegalStateException();
226 return _monitored.get(0);
227 }
228
229
230 public String getMonitoredDirName()
231 {
232 Resource resource=getMonitoredDirResource();
233 return resource==null?null:resource.toString();
234 }
235
236
237 @ManagedAttribute("scanning interval to detect changes which need reloaded")
238 public int getScanInterval()
239 {
240 return _scanInterval;
241 }
242
243
244 @ManagedAttribute("recursive scanning supported")
245 public boolean isRecursive()
246 {
247 return _recursive;
248 }
249
250
251 @Override
252 public void setDeploymentManager(DeploymentManager deploymentManager)
253 {
254 _deploymentManager = deploymentManager;
255 }
256
257
258 public void setMonitoredResources(List<Resource> resources)
259 {
260 _monitored.clear();
261 _monitored.addAll(resources);
262 }
263
264
265 public List<Resource> getMonitoredResources()
266 {
267 return Collections.unmodifiableList(_monitored);
268 }
269
270
271 public void setMonitoredDirResource(Resource resource)
272 {
273 setMonitoredResources(Collections.singletonList(resource));
274 }
275
276
277 public void addScannerListener(Scanner.Listener listener)
278 {
279 _scanner.addListener(listener);
280 }
281
282
283
284
285
286
287 public void setMonitoredDirName(String dir)
288 {
289 setMonitoredDirectories(Collections.singletonList(dir));
290 }
291
292
293 public void setMonitoredDirectories(Collection<String> directories)
294 {
295 try
296 {
297 List<Resource> resources = new ArrayList<>();
298 for (String dir:directories)
299 resources.add(Resource.newResource(dir));
300 setMonitoredResources(resources);
301 }
302 catch (Exception e)
303 {
304 throw new IllegalArgumentException(e);
305 }
306 }
307
308
309 protected void setRecursive(boolean recursive)
310 {
311 _recursive = recursive;
312 }
313
314
315 public void setScanInterval(int scanInterval)
316 {
317 _scanInterval = scanInterval;
318 }
319 }