View Javadoc

1   //========================================================================
2   //$Id: WebAppDeployer.java 2032 2007-07-26 06:11:24Z janb $
3   //Copyright 2006 Mort Bay Consulting Pty. Ltd.
4   //------------------------------------------------------------------------
5   //Licensed under the Apache License, Version 2.0 (the "License");
6   //you may not use this file except in compliance with the License.
7   //You may obtain a copy of the License at 
8   //http://www.apache.org/licenses/LICENSE-2.0
9   //Unless required by applicable law or agreed to in writing, software
10  //distributed under the License is distributed on an "AS IS" BASIS,
11  //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  //See the License for the specific language governing permissions and
13  //limitations under the License.
14  //========================================================================
15  
16  package org.mortbay.jetty.deployer;
17  
18  import java.util.ArrayList;
19  
20  import org.mortbay.component.AbstractLifeCycle;
21  import org.mortbay.jetty.Handler;
22  import org.mortbay.jetty.HandlerContainer;
23  import org.mortbay.jetty.handler.ContextHandler;
24  import org.mortbay.jetty.handler.ContextHandlerCollection;
25  import org.mortbay.jetty.webapp.WebAppContext;
26  import org.mortbay.resource.Resource;
27  import org.mortbay.util.URIUtil;
28  
29  /**
30   * Web Application Deployer.
31   * 
32   * The class searches a directory for and deploys standard web application.
33   * At startup, the directory specified by {@link #setWebAppDir(String)} is searched 
34   * for subdirectories (excluding hidden and CVS) or files ending with ".zip"
35   * or "*.war".  For each webapp discovered is passed to a new instance
36   * of {@link WebAppContext} (or a subclass specified by {@link #getContexts()}.
37   * {@link ContextHandlerCollection#getContextClass()}
38   * 
39   * This deployer does not do hot deployment or undeployment. Nor does
40   * it support per webapplication configuration. For these features 
41   * see {@link ContextDeployer}.
42   * 
43   * @see {@link ContextDeployer}
44   */
45  public class WebAppDeployer extends AbstractLifeCycle
46  {
47      private HandlerContainer _contexts;
48      private String _webAppDir;
49      private String _defaultsDescriptor;
50      private String[] _configurationClasses;
51      private boolean _extract;
52      private boolean _parentLoaderPriority;
53      private boolean _allowDuplicates;
54      private ArrayList _deployed;
55  
56      public String[] getConfigurationClasses()
57      {
58          return _configurationClasses;
59      }
60  
61      public void setConfigurationClasses(String[] configurationClasses)
62      {
63          _configurationClasses=configurationClasses;
64      }
65  
66      public HandlerContainer getContexts()
67      {
68          return _contexts;
69      }
70  
71      public void setContexts(HandlerContainer contexts)
72      {
73          _contexts=contexts;
74      }
75  
76      public String getDefaultsDescriptor()
77      {
78          return _defaultsDescriptor;
79      }
80  
81      public void setDefaultsDescriptor(String defaultsDescriptor)
82      {
83          _defaultsDescriptor=defaultsDescriptor;
84      }
85  
86      public boolean isExtract()
87      {
88          return _extract;
89      }
90  
91      public void setExtract(boolean extract)
92      {
93          _extract=extract;
94      }
95  
96      public boolean isParentLoaderPriority()
97      {
98          return _parentLoaderPriority;
99      }
100 
101     public void setParentLoaderPriority(boolean parentPriorityClassLoading)
102     {
103         _parentLoaderPriority=parentPriorityClassLoading;
104     }
105 
106     public String getWebAppDir()
107     {
108         return _webAppDir;
109     }
110 
111     public void setWebAppDir(String dir)
112     {
113         _webAppDir=dir;
114     }
115 
116     public boolean getAllowDuplicates()
117     {
118         return _allowDuplicates;
119     }
120 
121     /* ------------------------------------------------------------ */
122     /**
123      * @param allowDuplicates If false, do not deploy webapps that have already been deployed or duplicate context path
124      */
125     public void setAllowDuplicates(boolean allowDuplicates)
126     {
127         _allowDuplicates=allowDuplicates;
128     }
129 
130     /* ------------------------------------------------------------ */
131     /**
132      * @throws Exception 
133      */
134     public void doStart() throws Exception
135     {
136         _deployed=new ArrayList();
137         
138         scan();
139         
140     }
141     
142     /* ------------------------------------------------------------ */
143     /** Scan for webapplications.
144      * 
145      * @throws Exception
146      */
147     public void scan() throws Exception
148     {
149         if (_contexts==null)
150             throw new IllegalArgumentException("No HandlerContainer");
151 
152         Resource r=Resource.newResource(_webAppDir);
153         if (!r.exists())
154             throw new IllegalArgumentException("No such webapps resource "+r);
155 
156         if (!r.isDirectory())
157             throw new IllegalArgumentException("Not directory webapps resource "+r);
158 
159         String[] files=r.list();
160 
161         files: for (int f=0; files!=null&&f<files.length; f++)
162         {
163             String context=files[f];
164 
165             if (context.equalsIgnoreCase("CVS/")||context.equalsIgnoreCase("CVS")||context.startsWith("."))
166                 continue;
167 
168             Resource app=r.addPath(r.encode(context));
169 
170             if (context.toLowerCase().endsWith(".war")||context.toLowerCase().endsWith(".jar"))
171             {
172                 context=context.substring(0,context.length()-4);
173                 Resource unpacked=r.addPath(context);
174                 if (unpacked!=null&&unpacked.exists()&&unpacked.isDirectory())
175                     continue;
176             }
177             else if (!app.isDirectory())
178                 continue;
179 
180             if (context.equalsIgnoreCase("root")||context.equalsIgnoreCase("root/"))
181                 context=URIUtil.SLASH;
182             else
183                 context="/"+context;
184             if (context.endsWith("/")&&context.length()>0)
185                 context=context.substring(0,context.length()-1);
186 
187             // Check the context path has not already been added or the webapp itself is not already deployed
188             if (!_allowDuplicates)
189             {
190                 Handler[] installed=_contexts.getChildHandlersByClass(ContextHandler.class);
191                 for (int i=0; i<installed.length; i++)
192                 {
193                     ContextHandler c=(ContextHandler)installed[i];
194         
195                     if (context.equals(c.getContextPath()))
196                         continue files;
197                     
198                    String path;
199                    if (c instanceof WebAppContext)
200                        path = ((WebAppContext)c).getWar();
201                    else
202                        path = (c.getBaseResource()==null?"":c.getBaseResource().getFile().getAbsolutePath());
203 
204                     if (path.equals(app.getFile().getAbsolutePath()))
205                         continue files;
206    
207                 }
208             }
209 
210             // create a webapp
211             WebAppContext wah=null;
212             if (_contexts instanceof ContextHandlerCollection && 
213                 WebAppContext.class.isAssignableFrom(((ContextHandlerCollection)_contexts).getContextClass()))
214             {
215                 try
216                 {
217                     wah=(WebAppContext)((ContextHandlerCollection)_contexts).getContextClass().newInstance();
218                 }
219                 catch (Exception e)
220                 {
221                     throw new Error(e);
222                 }
223             }
224             else
225             {
226                 wah=new WebAppContext();
227             }
228             
229             // configure it
230             wah.setContextPath(context);
231             if (_configurationClasses!=null)
232                 wah.setConfigurationClasses(_configurationClasses);
233             if (_defaultsDescriptor!=null)
234                 wah.setDefaultsDescriptor(_defaultsDescriptor);
235             wah.setExtractWAR(_extract);
236             wah.setWar(app.toString());
237             wah.setParentLoaderPriority(_parentLoaderPriority);
238             // add it
239             _contexts.addHandler(wah);
240             _deployed.add(wah);
241             
242             if (_contexts.isStarted())
243                 _contexts.start();  // TODO Multi exception
244         }
245     }
246     
247     public void doStop() throws Exception
248     {
249         for (int i=_deployed.size();i-->0;)
250         {
251             ContextHandler wac = (ContextHandler)_deployed.get(i);
252             wac.stop();// TODO Multi exception
253         }
254     }
255 }