View Javadoc

1   // ========================================================================
2   // Copyright (c) 2006-2009 Mort Bay Consulting Pty. Ltd.
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   // The Eclipse Public License is available at 
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses. 
12  // ========================================================================
13  
14  package org.eclipse.jetty.deploy;
15  
16  import java.util.ArrayList;
17  
18  import org.eclipse.jetty.deploy.providers.ScanningAppProvider;
19  import org.eclipse.jetty.server.Handler;
20  import org.eclipse.jetty.server.handler.ContextHandler;
21  import org.eclipse.jetty.server.handler.ContextHandlerCollection;
22  import org.eclipse.jetty.server.handler.HandlerCollection;
23  import org.eclipse.jetty.util.AttributesMap;
24  import org.eclipse.jetty.util.URIUtil;
25  import org.eclipse.jetty.util.component.AbstractLifeCycle;
26  import org.eclipse.jetty.util.log.Log;
27  import org.eclipse.jetty.util.log.Logger;
28  import org.eclipse.jetty.util.resource.Resource;
29  import org.eclipse.jetty.webapp.WebAppContext;
30  
31  /**
32   * Legacy Web Application Deployer.
33   * 
34   * <p>
35   * Note: The WebAppDeployer is being phased out of Jetty in favor of the {@link DeploymentManager} and
36   * {@link org.eclipse.jetty.deploy.providers.WebAppProvider} implementation.
37   * 
38   * <p>
39   * The class searches a directory for and deploys standard web application. At startup, the directory specified by
40   * {@link #setWebAppDir(String)} is searched for subdirectories (excluding hidden and CVS) or files ending with ".zip"
41   * or "*.war". For each webapp discovered is passed to a new instance of {@link WebAppContext} (or a subclass specified
42   * by {@link #getContexts()}. {@link ContextHandlerCollection#getContextClass()}
43   * 
44   * <p>
45   * This deployer does not do hot deployment or undeployment. Nor does it support per web application configuration. For
46   * these features see {@link ContextDeployer}.
47   * 
48   * @deprecated
49   * @see DeploymentManager
50   * @see ScanningAppProvider
51   * @see ContextDeployer
52   */
53  @SuppressWarnings("unchecked")
54  public class WebAppDeployer extends AbstractLifeCycle
55  {
56      private static final Logger LOG = Log.getLogger(WebAppDeployer.class);
57  
58      private HandlerCollection _contexts;
59      private String _webAppDir;
60      private String _defaultsDescriptor;
61      private String[] _configurationClasses;
62      private boolean _extract;
63      private boolean _parentLoaderPriority;
64      private boolean _allowDuplicates;
65      private ArrayList _deployed;
66      private AttributesMap _contextAttributes = new AttributesMap();
67      
68      
69      public WebAppDeployer()
70      {
71          LOG.warn("WebAppDeployer is deprecated. Use WebAppProvider");
72      }
73      
74      public String[] getConfigurationClasses()
75      {
76          return _configurationClasses;
77      }
78  
79      public void setConfigurationClasses(String[] configurationClasses)
80      {
81          _configurationClasses=configurationClasses;
82      }
83  
84      public HandlerCollection getContexts()
85      {
86          return _contexts;
87      }
88  
89      public void setContexts(HandlerCollection contexts)
90      {
91          _contexts=contexts;
92      }
93  
94      public String getDefaultsDescriptor()
95      {
96          return _defaultsDescriptor;
97      }
98  
99      public void setDefaultsDescriptor(String defaultsDescriptor)
100     {
101         _defaultsDescriptor=defaultsDescriptor;
102     }
103 
104     public boolean isExtract()
105     {
106         return _extract;
107     }
108 
109     public void setExtract(boolean extract)
110     {
111         _extract=extract;
112     }
113 
114     public boolean isParentLoaderPriority()
115     {
116         return _parentLoaderPriority;
117     }
118 
119     public void setParentLoaderPriority(boolean parentPriorityClassLoading)
120     {
121         _parentLoaderPriority=parentPriorityClassLoading;
122     }
123 
124     public String getWebAppDir()
125     {
126         return _webAppDir;
127     }
128 
129     public void setWebAppDir(String dir)
130     {
131         _webAppDir=dir;
132     }
133 
134     public boolean getAllowDuplicates()
135     {
136         return _allowDuplicates;
137     }
138 
139     /* ------------------------------------------------------------ */
140     /**
141      * @param allowDuplicates If false, do not deploy webapps that have already been deployed or duplicate context path
142      */
143     public void setAllowDuplicates(boolean allowDuplicates)
144     {
145         _allowDuplicates=allowDuplicates;
146     }
147 
148     
149     /**
150      * Set a contextAttribute that will be set for every Context deployed by this deployer.
151      * @param name
152      * @param value
153      */
154     public void setAttribute (String name, Object value)
155     {
156         _contextAttributes.setAttribute(name,value);
157     }
158     
159     
160     /**
161      * Get a contextAttribute that will be set for every Context deployed by this deployer.
162      * @param name
163      * @return the attribute value
164      */
165     public Object getAttribute (String name)
166     {
167         return _contextAttributes.getAttribute(name);
168     }
169     
170     
171     /**
172      * Remove a contextAttribute that will be set for every Context deployed by this deployer.
173      * @param name
174      */
175     public void removeAttribute(String name)
176     {
177         _contextAttributes.removeAttribute(name);
178     }
179 
180     /* ------------------------------------------------------------ */
181     /**
182      * @throws Exception 
183      */
184     @Override
185     public void doStart() throws Exception
186     {
187         _deployed=new ArrayList();
188         
189         scan();
190         
191     }
192     
193     /* ------------------------------------------------------------ */
194     /** Scan for webapplications.
195      * 
196      * @throws Exception
197      */
198     public void scan() throws Exception
199     {
200         if (_contexts==null)
201             throw new IllegalArgumentException("No HandlerContainer");
202 
203         Resource r=Resource.newResource(_webAppDir);
204         if (!r.exists())
205             throw new IllegalArgumentException("No such webapps resource "+r);
206 
207         if (!r.isDirectory())
208             throw new IllegalArgumentException("Not directory webapps resource "+r);
209 
210         String[] files=r.list();
211 
212         files: for (int f=0; files!=null&&f<files.length; f++)
213         {
214             String context=files[f];
215 
216             if (context.equalsIgnoreCase("CVS/")||context.equalsIgnoreCase("CVS")||context.startsWith("."))
217                 continue;
218 
219             Resource app=r.addPath(r.encode(context));
220 
221             if (context.toLowerCase().endsWith(".war")||context.toLowerCase().endsWith(".jar"))
222             {
223                 context=context.substring(0,context.length()-4);
224                 Resource unpacked=r.addPath(context);
225                 if (unpacked!=null&&unpacked.exists()&&unpacked.isDirectory())
226                     continue;
227             }
228             else if (!app.isDirectory())
229                 continue;
230 
231             if (context.equalsIgnoreCase("root")||context.equalsIgnoreCase("root/"))
232                 context=URIUtil.SLASH;
233             else
234                 context="/"+context;
235             if (context.endsWith("/")&&context.length()>0)
236                 context=context.substring(0,context.length()-1);
237 
238             // Check the context path has not already been added or the webapp itself is not already deployed
239             if (!_allowDuplicates)
240             {
241                 Handler[] installed=_contexts.getChildHandlersByClass(ContextHandler.class);
242                 for (int i=0; i<installed.length; i++)
243                 {
244                     ContextHandler c = (ContextHandler)installed[i];
245 
246                     if (context.equals(c.getContextPath()))
247                         continue files;
248 
249                     
250                     try
251                     {
252                         String path = null;
253                         if (c instanceof WebAppContext)
254                             path = Resource.newResource(((WebAppContext)c).getWar()).getFile().getCanonicalPath();
255                         else if (c.getBaseResource() != null)
256                             path = c.getBaseResource().getFile().getCanonicalPath();
257 
258                         if (path != null && path.equals(app.getFile().getCanonicalPath()))
259                         {
260                             LOG.debug("Already deployed: {}",path);
261                             continue files;
262                         }
263                     }
264                     catch (Exception e)
265                     {
266                         LOG.ignore(e);
267                     }
268 
269                 }
270             }
271 
272             // create a webapp
273             WebAppContext wah=null;
274             if (_contexts instanceof ContextHandlerCollection && 
275                 WebAppContext.class.isAssignableFrom(((ContextHandlerCollection)_contexts).getContextClass()))
276             {
277                 try
278                 {
279                     wah=(WebAppContext)((ContextHandlerCollection)_contexts).getContextClass().newInstance();
280                 }
281                 catch (Exception e)
282                 {
283                     throw new Error(e);
284                 }
285             }
286             else
287             {
288                 wah=new WebAppContext();
289             }
290             
291             // configure it
292             wah.setContextPath(context);
293             if (_configurationClasses!=null)
294                 wah.setConfigurationClasses(_configurationClasses);
295             if (_defaultsDescriptor!=null)
296                 wah.setDefaultsDescriptor(_defaultsDescriptor);
297             wah.setExtractWAR(_extract);
298             wah.setWar(app.toString());
299             wah.setParentLoaderPriority(_parentLoaderPriority);
300             
301             //set up any contextAttributes
302             wah.setAttributes(new AttributesMap(_contextAttributes));
303             
304             // add it
305             _contexts.addHandler(wah);
306             _deployed.add(wah);
307             
308             if (_contexts.isStarted())
309                 wah.start();  // TODO Multi exception
310         }
311     }
312     
313     @Override
314     public void doStop() throws Exception
315     {
316         for (int i=_deployed.size();i-->0;)
317         {
318             ContextHandler wac = (ContextHandler)_deployed.get(i);
319             wac.stop();// TODO Multi exception
320         }
321     }
322 }