View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
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.Collections;
24  import java.util.HashMap;
25  import java.util.Map;
26  
27  import org.eclipse.jetty.deploy.App;
28  import org.eclipse.jetty.deploy.AppProvider;
29  import org.eclipse.jetty.deploy.DeploymentManager;
30  import org.eclipse.jetty.util.Scanner;
31  import org.eclipse.jetty.util.component.AbstractLifeCycle;
32  import org.eclipse.jetty.util.log.Log;
33  import org.eclipse.jetty.util.log.Logger;
34  import org.eclipse.jetty.util.resource.Resource;
35  
36  /**
37   */
38  public abstract class ScanningAppProvider extends AbstractLifeCycle implements AppProvider
39  {
40      private static final Logger LOG = Log.getLogger(ScanningAppProvider.class);
41  
42      private Map<String, App> _appMap = new HashMap<String, App>();
43  
44      private DeploymentManager _deploymentManager;
45      protected final FilenameFilter _filenameFilter;
46      private Resource _monitoredDir;
47      private boolean _recursive = false;
48      private int _scanInterval = 10;
49      private Scanner _scanner;
50  
51      /* ------------------------------------------------------------ */
52      private final Scanner.DiscreteListener _scannerListener = new Scanner.DiscreteListener()
53      {
54          public void fileAdded(String filename) throws Exception
55          {
56              ScanningAppProvider.this.fileAdded(filename);
57          }
58  
59          public void fileChanged(String filename) throws Exception
60          {
61              ScanningAppProvider.this.fileChanged(filename);
62          }
63  
64          public void fileRemoved(String filename) throws Exception
65          {
66              ScanningAppProvider.this.fileRemoved(filename);
67          }
68      };
69  
70      /* ------------------------------------------------------------ */
71      protected ScanningAppProvider(FilenameFilter filter)
72      {
73          _filenameFilter = filter;
74      }
75  
76      /* ------------------------------------------------------------ */
77      /**
78       * @return The index of currently deployed applications.
79       */
80      protected Map<String, App> getDeployedApps()
81      {
82          return _appMap;
83      }
84  
85      /* ------------------------------------------------------------ */
86      /**
87       * Called by the Scanner.DiscreteListener to create a new App object.
88       * Isolated in a method so that it is possible to override the default App
89       * object for specialized implementations of the AppProvider.
90       * 
91       * @param filename
92       *            The file that is the context.xml. It is resolved by
93       *            {@link Resource#newResource(String)}
94       * @return The App object for this particular context definition file.
95       */
96      protected App createApp(String filename)
97      {
98          return new App(_deploymentManager,this,filename);
99      }
100 
101     /* ------------------------------------------------------------ */
102     @Override
103     protected void doStart() throws Exception
104     {
105         if (LOG.isDebugEnabled()) 
106             LOG.debug(this.getClass().getSimpleName() + ".doStart()");
107         if (_monitoredDir == null)
108         {
109             throw new IllegalStateException("No configuration dir specified");
110         }
111 
112         File scandir = _monitoredDir.getFile();
113         LOG.info("Deployment monitor " + scandir + " at interval " + _scanInterval);
114         _scanner = new Scanner();
115         _scanner.setScanDirs(Collections.singletonList(scandir));
116         _scanner.setScanInterval(_scanInterval);
117         _scanner.setRecursive(_recursive);
118         _scanner.setFilenameFilter(_filenameFilter);
119         _scanner.setReportDirs(true);
120         _scanner.addListener(_scannerListener);
121         _scanner.start();
122     }
123 
124     /* ------------------------------------------------------------ */
125     @Override
126     protected void doStop() throws Exception
127     {
128         if (_scanner!=null)
129         {
130             _scanner.stop();
131             _scanner.removeListener(_scannerListener);
132             _scanner = null;
133         }
134     }
135 
136     /* ------------------------------------------------------------ */
137     protected void fileAdded(String filename) throws Exception
138     {
139         if (LOG.isDebugEnabled()) 
140             LOG.debug("added {}",filename);
141         App app = ScanningAppProvider.this.createApp(filename);
142         if (app != null)
143         {
144             _appMap.put(filename,app);
145             _deploymentManager.addApp(app);
146         }
147     }
148 
149     /* ------------------------------------------------------------ */
150     protected void fileChanged(String filename) throws Exception
151     {
152         if (LOG.isDebugEnabled()) 
153             LOG.debug("changed {}",filename);
154         App app = _appMap.remove(filename);
155         if (app != null)
156         {
157             _deploymentManager.removeApp(app);
158         }
159         app = ScanningAppProvider.this.createApp(filename);
160         if (app != null)
161         {
162             _appMap.put(filename,app);
163             _deploymentManager.addApp(app);
164         }
165     }
166     
167     /* ------------------------------------------------------------ */
168     protected void fileRemoved(String filename) throws Exception
169     {
170         if (LOG.isDebugEnabled()) 
171             LOG.debug("removed {}",filename);
172         App app = _appMap.remove(filename);
173         if (app != null)
174             _deploymentManager.removeApp(app);
175     }
176     
177     /* ------------------------------------------------------------ */
178     /**
179      * Get the deploymentManager.
180      * 
181      * @return the deploymentManager
182      */
183     public DeploymentManager getDeploymentManager()
184     {
185         return _deploymentManager;
186     }
187 
188 
189     /* ------------------------------------------------------------ */
190     public Resource getMonitoredDirResource()
191     {
192         return _monitoredDir;
193     }
194 
195     /* ------------------------------------------------------------ */
196     public String getMonitoredDirName()
197     {
198         return _monitoredDir.toString();
199     }
200 
201     /* ------------------------------------------------------------ */
202     public int getScanInterval()
203     {
204         return _scanInterval;
205     }
206 
207     /* ------------------------------------------------------------ */
208     public boolean isRecursive()
209     {
210         return _recursive;
211     }
212 
213     /* ------------------------------------------------------------ */
214     public void setDeploymentManager(DeploymentManager deploymentManager)
215     {
216         _deploymentManager = deploymentManager;
217     }
218     
219     /* ------------------------------------------------------------ */
220     public void setMonitoredDirResource(Resource contextsDir)
221     {
222         _monitoredDir = contextsDir;
223     }
224 
225     /* ------------------------------------------------------------ */
226     public void addScannerListener(Scanner.Listener listener)
227     {
228         _scanner.addListener(listener);
229     }
230 
231     /* ------------------------------------------------------------ */
232     /**
233      * @deprecated Use {@link #setMonitoredDirName(String)}
234      */
235     public void setMonitoredDir(String dir)
236     {
237         setMonitoredDirName(dir);
238     }
239     
240     /* ------------------------------------------------------------ */
241     /**
242      * @param dir
243      *            Directory to scan for context descriptors or war files
244      */
245     public void setMonitoredDirName(String dir)
246     {
247         try
248         {
249             setMonitoredDirResource(Resource.newResource(dir));
250         }
251         catch (Exception e)
252         {
253             throw new IllegalArgumentException(e);
254         }
255     }
256 
257     /* ------------------------------------------------------------ */
258     protected void setRecursive(boolean recursive)
259     {
260         _recursive = recursive;
261     }
262 
263     /* ------------------------------------------------------------ */
264     public void setScanInterval(int scanInterval)
265     {
266         _scanInterval = scanInterval;
267     }
268 }