View Javadoc

1   // ========================================================================
2   // Copyright (c) Webtide LLC
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   //
8   // The Eclipse Public License is available at 
9   // http://www.eclipse.org/legal/epl-v10.html
10  //
11  // The Apache License v2.0 is available at
12  // http://www.apache.org/licenses/LICENSE-2.0.txt
13  //
14  // You may elect to redistribute this code under either of these licenses. 
15  // ========================================================================
16  package org.eclipse.jetty.deploy.providers;
17  
18  import java.io.File;
19  import java.io.FilenameFilter;
20  import java.io.IOException;
21  import java.util.Collections;
22  import java.util.HashMap;
23  import java.util.Map;
24  
25  import org.eclipse.jetty.deploy.App;
26  import org.eclipse.jetty.deploy.AppProvider;
27  import org.eclipse.jetty.deploy.ConfigurationManager;
28  import org.eclipse.jetty.deploy.DeploymentManager;
29  import org.eclipse.jetty.deploy.util.FileID;
30  import org.eclipse.jetty.server.handler.ContextHandler;
31  import org.eclipse.jetty.util.Scanner;
32  import org.eclipse.jetty.util.URIUtil;
33  import org.eclipse.jetty.util.component.AbstractLifeCycle;
34  import org.eclipse.jetty.util.log.Log;
35  import org.eclipse.jetty.util.resource.Resource;
36  import org.eclipse.jetty.webapp.WebAppContext;
37  import org.eclipse.jetty.xml.XmlConfiguration;
38  
39  /**
40   * AppProvider for Monitoring directories for contexts.
41   * 
42   * A Context may either be a WAR, a directory or an XML descriptor.
43   * 
44   * @deprecated - Use {@link ContextProvider} or {@link WebAppProvider}
45   */
46  public class MonitoredDirAppProvider extends AbstractLifeCycle implements AppProvider
47  {
48      class MonitoredFilenameFilter implements FilenameFilter
49      {
50          public boolean accept(File file, String name)
51          {
52              if (!file.exists())
53                  return false;
54              
55              String lowername = name.toLowerCase();
56  
57              if (_acceptContextXmlFiles && !file.isDirectory() && lowername.endsWith(".xml"))
58              {
59                  return true;
60              }
61  
62              if (_acceptWarFiles && !file.isDirectory() && lowername.endsWith(".war"))
63              {
64                  return true;
65              }
66              
67              if (_acceptDirectories && file.isDirectory())
68              {
69                  return true;
70              }
71  
72              return false;
73          }
74      }
75  
76      private boolean _acceptContextXmlFiles = true;
77      private boolean _acceptWarFiles = true;
78      private boolean _acceptDirectories = true;
79      private Resource _monitoredDir;
80      private Scanner _scanner;
81      private int _scanInterval = 10;
82      private boolean _recursive = false;
83      private boolean _extractWars = false;
84      private boolean _parentLoaderPriority = false;
85      private String _defaultsDescriptor;
86      private DeploymentManager _deploymentManager;
87      private FilenameFilter _filenamefilter;
88      private ConfigurationManager _configurationManager;
89      
90      private final Scanner.DiscreteListener _scannerListener = new Scanner.DiscreteListener()
91      {
92          public void fileAdded(String filename) throws Exception
93          {
94              Log.debug("added ",  filename);
95              addConfiguredContextApp(filename);
96          }
97  
98          public void fileChanged(String filename) throws Exception
99          {
100             System.err.println("changed "+filename);
101             // TODO should this not be an add/remove?
102             Log.debug("changed ",  filename);
103             addConfiguredContextApp(filename);
104         }
105 
106         public void fileRemoved(String filename) throws Exception
107         {
108             System.err.println("removed "+filename);
109             Log.debug("removed ",  filename);
110             
111             // TODO: How to determine ID from filename that doesn't exist?
112             // TODO: we probably need a map from discovered filename to resulting App
113         }
114     };
115     
116     public MonitoredDirAppProvider()
117     {
118         _filenamefilter = new MonitoredFilenameFilter();
119     }
120 
121     protected MonitoredDirAppProvider(boolean xml,boolean war, boolean dir)
122     {
123         _acceptContextXmlFiles=xml;
124         _acceptWarFiles=war;
125         _acceptDirectories=dir;
126         _filenamefilter = new MonitoredFilenameFilter();
127     }
128 
129     protected MonitoredDirAppProvider(FilenameFilter filter, boolean xml,boolean war, boolean dir)
130     {
131         _acceptContextXmlFiles=xml;
132         _acceptWarFiles=war;
133         _acceptDirectories=dir;
134         _filenamefilter = filter;
135     }
136     
137     private App addConfiguredContextApp(String filename)
138     {
139         App app = new App(_deploymentManager,this,filename);
140         _deploymentManager.addApp(app);
141         return app;
142     }
143 
144     /* ------------------------------------------------------------ */
145     /** Create a context Handler for an App instance.
146      * This method can create a {@link ContextHandler} from a context XML file
147      * or a {@link WebAppContext} from a WAR file or directory, depending on the 
148      * settings of the accept fields.
149      * @see #setAcceptContextXmlFiles(boolean)
150      * @see #setAcceptWarFiles(boolean)
151      * @see #setAcceptDirectories(boolean)
152      * @see org.eclipse.jetty.deploy.AppProvider#createContextHandler(org.eclipse.jetty.deploy.App)
153      */
154     public ContextHandler createContextHandler(final App app) throws Exception
155     {
156         Resource resource = Resource.newResource(app.getOriginId());
157         File file=resource.getFile();
158         
159         if (!resource.exists())
160             throw new IllegalStateException("App resouce does not exist "+resource);
161 
162         if (_acceptContextXmlFiles &&  FileID.isXmlFile(file))
163         {
164             // TODO - it is a bit wierd that this ignores 
165             // _defaultsDescriptor, _extractWars and _parentLoaderPriority
166             // This reflects that there really is the common base for Context
167             // and WebApp deployers should probably not have these bits in them
168             
169             XmlConfiguration xmlc = new XmlConfiguration(resource.getURL());
170             Map props = new HashMap();
171             props.put("Server",_deploymentManager.getServer());
172             if (getConfigurationManager() != null)
173                 props.putAll(getConfigurationManager().getProperties());
174             xmlc.setProperties(props);
175             return (ContextHandler)xmlc.configure();
176         }
177 
178         String context = file.getName();
179         
180         if (_acceptWarFiles && FileID.isWebArchiveFile(file))
181         {
182             // Context Path is the same as the archive.
183             context = context.substring(0,context.length() - 4);
184         }
185         else if (_acceptDirectories && file.isDirectory())
186         {
187             // must be a directory
188         }
189         else
190             throw new IllegalStateException("unable to create ContextHandler for "+app);
191 
192         
193         // special case of archive (or dir) named "root" is / context
194         if (context.equalsIgnoreCase("root") || context.equalsIgnoreCase("root/"))
195             context = URIUtil.SLASH;
196 
197         // Ensure "/" is Prepended to all context paths.
198         if (context.charAt(0) != '/')
199             context = "/" + context;
200 
201         // Ensure "/" is Not Trailing in context paths.
202         if (context.endsWith("/") && context.length() > 0)
203             context = context.substring(0,context.length() - 1);
204 
205         WebAppContext wah = new WebAppContext();
206         wah.setContextPath(context);
207         wah.setWar(file.getAbsolutePath());
208         if (_defaultsDescriptor != null)
209             wah.setDefaultsDescriptor(_defaultsDescriptor);
210         wah.setExtractWAR(_extractWars);
211         wah.setParentLoaderPriority(_parentLoaderPriority);
212 
213         return wah;
214         
215     }
216 
217     @Override
218     protected void doStart() throws Exception
219     {
220         Log.info(this.getClass().getSimpleName() + ".doStart()");
221         if (_monitoredDir == null)
222         {
223             throw new IllegalStateException("No configuration dir specified");
224         }
225 
226         File scandir = _monitoredDir.getFile();
227         Log.info("Deployment monitor " + scandir+ " at intervale "+_scanInterval);
228         _scanner=new Scanner();
229         _scanner.setScanDirs(Collections.singletonList(scandir));
230         _scanner.setScanInterval(_scanInterval);
231         _scanner.setRecursive(_recursive);
232         _scanner.setFilenameFilter(_filenamefilter);
233         _scanner.setReportDirs(_acceptDirectories);
234         _scanner.addListener(_scannerListener);
235         _scanner.start();
236     }
237 
238     @Override
239     protected void doStop() throws Exception
240     {
241         _scanner.stop();
242         _scanner.removeListener(_scannerListener);
243         _scanner=null;
244     }
245 
246     public ConfigurationManager getConfigurationManager()
247     {
248         return _configurationManager;
249     }
250 
251     public String getDefaultsDescriptor()
252     {
253         return _defaultsDescriptor;
254     }
255 
256     /* ------------------------------------------------------------ */
257     /** Get the deploymentManager.
258      * @return the deploymentManager
259      */
260     public DeploymentManager getDeploymentManager()
261     {
262         return _deploymentManager;
263     }
264 
265     public Resource getMonitoredDir()
266     {
267         return _monitoredDir;
268     }
269 
270     public int getScanInterval()
271     {
272         return _scanInterval;
273     }
274 
275     /* ------------------------------------------------------------ */
276     /** Get the acceptContextXmlFiles.
277      * @return the acceptContextXmlFiles
278      */
279     public boolean isAcceptContextXmlFiles()
280     {
281         return _acceptContextXmlFiles;
282     }
283 
284     /* ------------------------------------------------------------ */
285     /** Get the acceptDirectories.
286      * @return the acceptDirectories
287      */
288     public boolean isAcceptDirectories()
289     {
290         return _acceptDirectories;
291     }
292 
293     /* ------------------------------------------------------------ */
294     /** Get the acceptWarFiles.
295      * @return the acceptWarFiles
296      */
297     public boolean isAcceptWarFiles()
298     {
299         return _acceptWarFiles;
300     }
301 
302     public boolean isExtractWars()
303     {
304         return _extractWars;
305     }
306 
307     public boolean isParentLoaderPriority()
308     {
309         return _parentLoaderPriority;
310     }
311 
312     public boolean isRecursive()
313     {
314         return _recursive;
315     }
316 
317     public void setAcceptContextXmlFiles(boolean flag)
318     {
319         if (isRunning())
320             throw new IllegalStateException();
321         _acceptContextXmlFiles = flag;
322     }
323 
324     public void setAcceptDirectories(boolean flag)
325     {
326         if (isRunning())
327             throw new IllegalStateException();
328         _acceptDirectories = flag;
329     }
330 
331     public void setAcceptWarFiles(boolean flag)
332     {
333         if (isRunning())
334             throw new IllegalStateException();
335         _acceptWarFiles = flag;
336     }
337 
338     public void setConfigurationManager(ConfigurationManager configurationManager)
339     {
340         _configurationManager = configurationManager;
341     }
342 
343     public void setDefaultsDescriptor(String defaultsDescriptor)
344     {
345         _defaultsDescriptor = defaultsDescriptor;
346     }
347 
348     public void setDeploymentManager(DeploymentManager deploymentManager)
349     {
350         _deploymentManager = deploymentManager;
351     }
352 
353     public void setExtractWars(boolean extractWars)
354     {
355         _extractWars = extractWars;
356     }
357 
358     public void setMonitoredDir(Resource contextsDir)
359     {
360         _monitoredDir = contextsDir;
361     }
362 
363     /**
364      * @param dir
365      *            Directory to scan for context descriptors or war files
366      */
367     public void setMonitoredDir(String dir)
368     {
369         try
370         {
371             _monitoredDir = Resource.newResource(dir);
372         }
373         catch (Exception e)
374         {
375             throw new IllegalArgumentException(e);
376         }
377     }
378     
379     public void setParentLoaderPriority(boolean parentLoaderPriority)
380     {
381         _parentLoaderPriority = parentLoaderPriority;
382     }
383 
384     public void setRecursive(boolean recursive)
385     {
386         _recursive = recursive;
387     }
388 
389     public void setScanInterval(int scanInterval)
390     {
391         _scanInterval = scanInterval;
392     }
393 }