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