View Javadoc

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