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 {
137 if (resource.exists() && resource.getFile().canRead())
138 files.add(resource.getFile());
139 else
140 LOG.warn("Does not exist: "+resource);
141 }
142
143 _scanner = new Scanner();
144 _scanner.setScanDirs(files);
145 _scanner.setScanInterval(_scanInterval);
146 _scanner.setRecursive(_recursive);
147 _scanner.setFilenameFilter(_filenameFilter);
148 _scanner.setReportDirs(true);
149 _scanner.addListener(_scannerListener);
150 _scanner.start();
151 }
152
153
154 @Override
155 protected void doStop() throws Exception
156 {
157 if (_scanner!=null)
158 {
159 _scanner.stop();
160 _scanner.removeListener(_scannerListener);
161 _scanner = null;
162 }
163 }
164
165
166 protected boolean exists(String path)
167 {
168 return _scanner.exists(path);
169 }
170
171
172 protected void fileAdded(String filename) throws Exception
173 {
174 if (LOG.isDebugEnabled())
175 LOG.debug("added {}",filename);
176 App app = ScanningAppProvider.this.createApp(filename);
177 if (app != null)
178 {
179 _appMap.put(filename,app);
180 _deploymentManager.addApp(app);
181 }
182 }
183
184
185 protected void fileChanged(String filename) throws Exception
186 {
187 if (LOG.isDebugEnabled())
188 LOG.debug("changed {}",filename);
189 App app = _appMap.remove(filename);
190 if (app != null)
191 {
192 _deploymentManager.removeApp(app);
193 }
194 app = ScanningAppProvider.this.createApp(filename);
195 if (app != null)
196 {
197 _appMap.put(filename,app);
198 _deploymentManager.addApp(app);
199 }
200 }
201
202
203 protected void fileRemoved(String filename) throws Exception
204 {
205 if (LOG.isDebugEnabled())
206 LOG.debug("removed {}",filename);
207 App app = _appMap.remove(filename);
208 if (app != null)
209 _deploymentManager.removeApp(app);
210 }
211
212
213
214
215
216
217
218 public DeploymentManager getDeploymentManager()
219 {
220 return _deploymentManager;
221 }
222
223
224
225 public Resource getMonitoredDirResource()
226 {
227 if (_monitored.size()==0)
228 return null;
229 if (_monitored.size()>1)
230 throw new IllegalStateException();
231 return _monitored.get(0);
232 }
233
234
235 public String getMonitoredDirName()
236 {
237 Resource resource=getMonitoredDirResource();
238 return resource==null?null:resource.toString();
239 }
240
241
242 @ManagedAttribute("scanning interval to detect changes which need reloaded")
243 public int getScanInterval()
244 {
245 return _scanInterval;
246 }
247
248
249 @ManagedAttribute("recursive scanning supported")
250 public boolean isRecursive()
251 {
252 return _recursive;
253 }
254
255
256 @Override
257 public void setDeploymentManager(DeploymentManager deploymentManager)
258 {
259 _deploymentManager = deploymentManager;
260 }
261
262
263 public void setMonitoredResources(List<Resource> resources)
264 {
265 _monitored.clear();
266 _monitored.addAll(resources);
267 }
268
269
270 public List<Resource> getMonitoredResources()
271 {
272 return Collections.unmodifiableList(_monitored);
273 }
274
275
276 public void setMonitoredDirResource(Resource resource)
277 {
278 setMonitoredResources(Collections.singletonList(resource));
279 }
280
281
282 public void addScannerListener(Scanner.Listener listener)
283 {
284 _scanner.addListener(listener);
285 }
286
287
288
289
290
291
292 public void setMonitoredDirName(String dir)
293 {
294 setMonitoredDirectories(Collections.singletonList(dir));
295 }
296
297
298 public void setMonitoredDirectories(Collection<String> directories)
299 {
300 try
301 {
302 List<Resource> resources = new ArrayList<>();
303 for (String dir:directories)
304 resources.add(Resource.newResource(dir));
305 setMonitoredResources(resources);
306 }
307 catch (Exception e)
308 {
309 throw new IllegalArgumentException(e);
310 }
311 }
312
313
314 protected void setRecursive(boolean recursive)
315 {
316 _recursive = recursive;
317 }
318
319
320 public void setScanInterval(int scanInterval)
321 {
322 _scanInterval = scanInterval;
323 }
324 }