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