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.server.Handler;
19  import org.eclipse.jetty.server.handler.ContextHandler;
20  import org.eclipse.jetty.server.handler.ContextHandlerCollection;
21  import org.eclipse.jetty.server.handler.HandlerCollection;
22  import org.eclipse.jetty.util.AttributesMap;
23  import org.eclipse.jetty.util.URIUtil;
24  import org.eclipse.jetty.util.component.AbstractLifeCycle;
25  import org.eclipse.jetty.util.log.Log;
26  import org.eclipse.jetty.util.resource.Resource;
27  import org.eclipse.jetty.webapp.WebAppContext;
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 HandlerCollection _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      private AttributesMap _contextAttributes = new AttributesMap();
56  
57      public String[] getConfigurationClasses()
58      {
59          return _configurationClasses;
60      }
61  
62      public void setConfigurationClasses(String[] configurationClasses)
63      {
64          _configurationClasses=configurationClasses;
65      }
66  
67      public HandlerCollection getContexts()
68      {
69          return _contexts;
70      }
71  
72      public void setContexts(HandlerCollection contexts)
73      {
74          _contexts=contexts;
75      }
76  
77      public String getDefaultsDescriptor()
78      {
79          return _defaultsDescriptor;
80      }
81  
82      public void setDefaultsDescriptor(String defaultsDescriptor)
83      {
84          _defaultsDescriptor=defaultsDescriptor;
85      }
86  
87      public boolean isExtract()
88      {
89          return _extract;
90      }
91  
92      public void setExtract(boolean extract)
93      {
94          _extract=extract;
95      }
96  
97      public boolean isParentLoaderPriority()
98      {
99          return _parentLoaderPriority;
100     }
101 
102     public void setParentLoaderPriority(boolean parentPriorityClassLoading)
103     {
104         _parentLoaderPriority=parentPriorityClassLoading;
105     }
106 
107     public String getWebAppDir()
108     {
109         return _webAppDir;
110     }
111 
112     public void setWebAppDir(String dir)
113     {
114         _webAppDir=dir;
115     }
116 
117     public boolean getAllowDuplicates()
118     {
119         return _allowDuplicates;
120     }
121 
122     /* ------------------------------------------------------------ */
123     /**
124      * @param allowDuplicates If false, do not deploy webapps that have already been deployed or duplicate context path
125      */
126     public void setAllowDuplicates(boolean allowDuplicates)
127     {
128         _allowDuplicates=allowDuplicates;
129     }
130 
131     
132     /**
133      * Set a contextAttribute that will be set for every Context deployed by this deployer.
134      * @param name
135      * @param value
136      */
137     public void setAttribute (String name, Object value)
138     {
139         _contextAttributes.setAttribute(name,value);
140     }
141     
142     
143     /**
144      * Get a contextAttribute that will be set for every Context deployed by this deployer.
145      * @param name
146      * @return
147      */
148     public Object getAttribute (String name)
149     {
150         return _contextAttributes.getAttribute(name);
151     }
152     
153     
154     /**
155      * Remove a contextAttribute that will be set for every Context deployed by this deployer.
156      * @param name
157      */
158     public void removeAttribute(String name)
159     {
160         _contextAttributes.removeAttribute(name);
161     }
162 
163     /* ------------------------------------------------------------ */
164     /**
165      * @throws Exception 
166      */
167     public void doStart() throws Exception
168     {
169         _deployed=new ArrayList();
170         
171         scan();
172         
173     }
174     
175     /* ------------------------------------------------------------ */
176     /** Scan for webapplications.
177      * 
178      * @throws Exception
179      */
180     public void scan() throws Exception
181     {
182         if (_contexts==null)
183             throw new IllegalArgumentException("No HandlerContainer");
184 
185         Resource r=Resource.newResource(_webAppDir);
186         if (!r.exists())
187             throw new IllegalArgumentException("No such webapps resource "+r);
188 
189         if (!r.isDirectory())
190             throw new IllegalArgumentException("Not directory webapps resource "+r);
191 
192         String[] files=r.list();
193 
194         files: for (int f=0; files!=null&&f<files.length; f++)
195         {
196             String context=files[f];
197 
198             if (context.equalsIgnoreCase("CVS/")||context.equalsIgnoreCase("CVS")||context.startsWith("."))
199                 continue;
200 
201             Resource app=r.addPath(r.encode(context));
202 
203             if (context.toLowerCase().endsWith(".war")||context.toLowerCase().endsWith(".jar"))
204             {
205                 context=context.substring(0,context.length()-4);
206                 Resource unpacked=r.addPath(context);
207                 if (unpacked!=null&&unpacked.exists()&&unpacked.isDirectory())
208                     continue;
209             }
210             else if (!app.isDirectory())
211                 continue;
212 
213             if (context.equalsIgnoreCase("root")||context.equalsIgnoreCase("root/"))
214                 context=URIUtil.SLASH;
215             else
216                 context="/"+context;
217             if (context.endsWith("/")&&context.length()>0)
218                 context=context.substring(0,context.length()-1);
219 
220             // Check the context path has not already been added or the webapp itself is not already deployed
221             if (!_allowDuplicates)
222             {
223                 Handler[] installed=_contexts.getChildHandlersByClass(ContextHandler.class);
224                 for (int i=0; i<installed.length; i++)
225                 {
226                     ContextHandler c = (ContextHandler)installed[i];
227 
228                     if (context.equals(c.getContextPath()))
229                         continue files;
230 
231                     
232                     try
233                     {
234                         String path = null;
235                         if (c instanceof WebAppContext)
236                             path = Resource.newResource(((WebAppContext)c).getWar()).getFile().getCanonicalPath();
237                         else if (c.getBaseResource() != null)
238                             path = c.getBaseResource().getFile().getCanonicalPath();
239 
240                         if (path != null && path.equals(app.getFile().getCanonicalPath()))
241                         {
242                             Log.debug("Already deployed:"+path);
243                             continue files;
244                         }
245                     }
246                     catch (Exception e)
247                     {
248                         Log.ignore(e);
249                     }
250 
251                 }
252             }
253 
254             // create a webapp
255             WebAppContext wah=null;
256             if (_contexts instanceof ContextHandlerCollection && 
257                 WebAppContext.class.isAssignableFrom(((ContextHandlerCollection)_contexts).getContextClass()))
258             {
259                 try
260                 {
261                     wah=(WebAppContext)((ContextHandlerCollection)_contexts).getContextClass().newInstance();
262                 }
263                 catch (Exception e)
264                 {
265                     throw new Error(e);
266                 }
267             }
268             else
269             {
270                 wah=new WebAppContext();
271             }
272             
273             // configure it
274             wah.setContextPath(context);
275             if (_configurationClasses!=null)
276                 wah.setConfigurationClasses(_configurationClasses);
277             if (_defaultsDescriptor!=null)
278                 wah.setDefaultsDescriptor(_defaultsDescriptor);
279             wah.setExtractWAR(_extract);
280             wah.setWar(app.toString());
281             wah.setParentLoaderPriority(_parentLoaderPriority);
282             
283             //set up any contextAttributes
284             wah.setAttributes(new AttributesMap(_contextAttributes));
285             
286             // add it
287             _contexts.addHandler(wah);
288             _deployed.add(wah);
289             
290             if (_contexts.isStarted())
291                 _contexts.start();  // TODO Multi exception
292         }
293     }
294     
295     public void doStop() throws Exception
296     {
297         for (int i=_deployed.size();i-->0;)
298         {
299             ContextHandler wac = (ContextHandler)_deployed.get(i);
300             wac.stop();// TODO Multi exception
301         }
302     }
303 }