View Javadoc

1   package org.eclipse.jetty.deploy.providers;
2   
3   import java.io.File;
4   import java.io.FilenameFilter;
5   import java.io.IOException;
6   import java.net.MalformedURLException;
7   
8   import org.eclipse.jetty.deploy.App;
9   import org.eclipse.jetty.deploy.util.FileID;
10  import org.eclipse.jetty.server.handler.ContextHandler;
11  import org.eclipse.jetty.util.URIUtil;
12  import org.eclipse.jetty.util.resource.Resource;
13  import org.eclipse.jetty.webapp.WebAppContext;
14  
15  /* ------------------------------------------------------------ */
16  /** Context directory App Provider.
17   * <p>This specialization of {@link ScanningAppProvider} is the
18   * replacement for old (and deprecated) <code>org.eclipse.jetty.deploy.WebAppDeployer</code> and it will scan a directory
19   * only for war files or directories files.</p>
20   * <p>
21   * Webapps with names root or starting with root- are deployed at /.
22   * If the name is in the format root-hostname, then the webapp is deployed
23   * at / in the virtual host hostname.
24   */
25  public class WebAppProvider extends ScanningAppProvider
26  {
27      private boolean _extractWars = false;
28      private boolean _parentLoaderPriority = false;
29      private String _defaultsDescriptor;
30      private Filter _filter;
31      private File _tempDirectory;
32      private String[] _configurationClasses;
33  
34      public static class Filter implements FilenameFilter
35      {
36          private File _contexts;
37          
38          public boolean accept(File dir, String name)
39          {
40              if (!dir.exists())
41              {
42                  return false;
43              }
44              String lowername = name.toLowerCase();
45              
46              File file = new File(dir,name);
47              // is it not a directory and not a war ?
48              if (!file.isDirectory() && !lowername.endsWith(".war"))
49              {
50                  return false;
51              }
52              
53              //ignore hidden files
54              if (lowername.startsWith("."))
55                  return false;
56                     
57              if (file.isDirectory())
58              {
59                  // is it a directory for an existing war file?
60                  if (new File(dir,name+".war").exists() ||
61                      new File(dir,name+".WAR").exists())
62  
63                      return false;
64   
65                  //is it a sccs dir?
66                  if ("cvs".equals(lowername) || "cvsroot".equals(lowername))
67                      return false;
68              }
69              
70              // is there a contexts config file
71              if (_contexts!=null)
72              {
73                  String context=name;
74                  if (!file.isDirectory())
75                  {
76                      context=context.substring(0,context.length()-4);
77                  }
78                  if (new File(_contexts,context+".xml").exists() ||
79                      new File(_contexts,context+".XML").exists() )
80                  {
81                      return false;
82                  }
83              }
84                 
85              return true;
86          }
87      }
88      
89      /* ------------------------------------------------------------ */
90      public WebAppProvider()
91      {
92          super(new Filter());
93          _filter=(Filter)_filenameFilter;
94          setScanInterval(0);
95      }
96  
97      /* ------------------------------------------------------------ */
98      /** Get the extractWars.
99       * @return the extractWars
100      */
101     public boolean isExtractWars()
102     {
103         return _extractWars;
104     }
105 
106     /* ------------------------------------------------------------ */
107     /** Set the extractWars.
108      * @param extractWars the extractWars to set
109      */
110     public void setExtractWars(boolean extractWars)
111     {
112         _extractWars = extractWars;
113     }
114 
115     /* ------------------------------------------------------------ */
116     /** Get the parentLoaderPriority.
117      * @return the parentLoaderPriority
118      */
119     public boolean isParentLoaderPriority()
120     {
121         return _parentLoaderPriority;
122     }
123 
124     /* ------------------------------------------------------------ */
125     /** Set the parentLoaderPriority.
126      * @param parentLoaderPriority the parentLoaderPriority to set
127      */
128     public void setParentLoaderPriority(boolean parentLoaderPriority)
129     {
130         _parentLoaderPriority = parentLoaderPriority;
131     }
132     
133     /* ------------------------------------------------------------ */
134     /** Get the defaultsDescriptor.
135      * @return the defaultsDescriptor
136      */
137     public String getDefaultsDescriptor()
138     {
139         return _defaultsDescriptor;
140     }
141 
142     /* ------------------------------------------------------------ */
143     /** Set the defaultsDescriptor.
144      * @param defaultsDescriptor the defaultsDescriptor to set
145      */
146     public void setDefaultsDescriptor(String defaultsDescriptor)
147     {
148         _defaultsDescriptor = defaultsDescriptor;
149     }
150 
151     /* ------------------------------------------------------------ */
152     public String getContextXmlDir()
153     {
154         return _filter._contexts==null?null:_filter._contexts.toString();
155     }
156 
157     /* ------------------------------------------------------------ */
158     /**
159      * Set the directory in which to look for context XML files.
160      * <p>
161      * If a webapp call "foo/" or "foo.war" is discovered in the monitored
162      * directory, then the ContextXmlDir is examined to see if a foo.xml
163      * file exists.  If it does, then this deployer will not deploy the webapp
164      * and the ContextProvider should be used to act on the foo.xml file.
165      * @see ContextProvider
166      * @param contextsDir
167      */
168     public void setContextXmlDir(String contextsDir)
169     {
170         try
171         {
172             _filter._contexts=Resource.newResource(contextsDir).getFile();
173         }
174         catch (MalformedURLException e)
175         {
176             throw new RuntimeException(e);
177         }
178         catch (IOException e)
179         {
180             throw new RuntimeException(e);
181         }
182     }
183     
184     
185     /* ------------------------------------------------------------ */
186     /**
187      * @param configurations The configuration class names.
188      */
189     public void setConfigurationClasses(String[] configurations)
190     {
191         _configurationClasses = configurations==null?null:(String[])configurations.clone();
192     }  
193     
194     /* ------------------------------------------------------------ */
195     /**
196      * 
197      */
198     public String[] getConfigurationClasses()
199     {
200         return _configurationClasses;
201     }
202     
203     /**
204      * Set the Work directory where unpacked WAR files are managed from.
205      * <p>
206      * Default is the same as the <code>java.io.tmpdir</code> System Property.
207      * 
208      * @param directory the new work directory
209      */
210     public void setTempDir(File directory)
211     {
212         _tempDirectory = directory;
213     }
214     
215     /**
216      * Get the user supplied Work Directory.
217      * 
218      * @return the user supplied work directory (null if user has not set Temp Directory yet)
219      */
220     public File getTempDir()
221     {
222         return _tempDirectory;
223     }
224     
225     /* ------------------------------------------------------------ */
226     public ContextHandler createContextHandler(final App app) throws Exception
227     {
228         Resource resource = Resource.newResource(app.getOriginId());
229         File file = resource.getFile();
230         if (!resource.exists())
231             throw new IllegalStateException("App resouce does not exist "+resource);
232 
233         String context = file.getName();
234         
235         if (file.isDirectory())
236         {
237             // must be a directory
238         }
239         else if (FileID.isWebArchiveFile(file))
240         {
241             // Context Path is the same as the archive.
242             context = context.substring(0,context.length() - 4);
243         }
244         else 
245         {
246             throw new IllegalStateException("unable to create ContextHandler for "+app);
247         }
248 
249         // Ensure "/" is Not Trailing in context paths.
250         if (context.endsWith("/") && context.length() > 0) 
251         {
252             context = context.substring(0,context.length() - 1);
253         }
254         
255         // Start building the webapplication
256         WebAppContext wah = new WebAppContext();
257         wah.setDisplayName(context);
258         
259         // special case of archive (or dir) named "root" is / context
260         if (context.equalsIgnoreCase("root"))
261         {
262             context = URIUtil.SLASH;
263         }
264         else if (context.toLowerCase().startsWith("root-"))
265         {
266             int dash=context.toLowerCase().indexOf('-');
267             String virtual = context.substring(dash+1);
268             wah.setVirtualHosts(new String[]{virtual});
269             context = URIUtil.SLASH;
270         }
271 
272         // Ensure "/" is Prepended to all context paths.
273         if (context.charAt(0) != '/') 
274         {
275             context = "/" + context;
276         }
277 
278 
279         wah.setContextPath(context);
280         wah.setWar(file.getAbsolutePath());
281         if (_defaultsDescriptor != null) 
282         {
283             wah.setDefaultsDescriptor(_defaultsDescriptor);
284         }
285         wah.setExtractWAR(_extractWars);
286         wah.setParentLoaderPriority(_parentLoaderPriority);
287         if (_configurationClasses != null) 
288         {
289             wah.setConfigurationClasses(_configurationClasses);
290         }
291 
292         if (_tempDirectory != null)
293         {
294             /* Since the Temp Dir is really a context base temp directory,
295              * Lets set the Temp Directory in a way similar to how WebInfConfiguration does it,
296              * instead of setting the
297              * WebAppContext.setTempDirectory(File).  
298              * If we used .setTempDirectory(File) all webapps will wind up in the
299              * same temp / work directory, overwriting each others work.
300              */
301             wah.setAttribute(WebAppContext.BASETEMPDIR,_tempDirectory);
302         }
303         return wah; 
304     }
305     
306 }