View Javadoc

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