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