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