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.HandlerContainer;
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.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  
55      public String[] getConfigurationClasses()
56      {
57          return _configurationClasses;
58      }
59  
60      public void setConfigurationClasses(String[] configurationClasses)
61      {
62          _configurationClasses=configurationClasses;
63      }
64  
65      public HandlerCollection getContexts()
66      {
67          return _contexts;
68      }
69  
70      public void setContexts(HandlerCollection contexts)
71      {
72          _contexts=contexts;
73      }
74  
75      public String getDefaultsDescriptor()
76      {
77          return _defaultsDescriptor;
78      }
79  
80      public void setDefaultsDescriptor(String defaultsDescriptor)
81      {
82          _defaultsDescriptor=defaultsDescriptor;
83      }
84  
85      public boolean isExtract()
86      {
87          return _extract;
88      }
89  
90      public void setExtract(boolean extract)
91      {
92          _extract=extract;
93      }
94  
95      public boolean isParentLoaderPriority()
96      {
97          return _parentLoaderPriority;
98      }
99  
100     public void setParentLoaderPriority(boolean parentPriorityClassLoading)
101     {
102         _parentLoaderPriority=parentPriorityClassLoading;
103     }
104 
105     public String getWebAppDir()
106     {
107         return _webAppDir;
108     }
109 
110     public void setWebAppDir(String dir)
111     {
112         _webAppDir=dir;
113     }
114 
115     public boolean getAllowDuplicates()
116     {
117         return _allowDuplicates;
118     }
119 
120     /* ------------------------------------------------------------ */
121     /**
122      * @param allowDuplicates If false, do not deploy webapps that have already been deployed or duplicate context path
123      */
124     public void setAllowDuplicates(boolean allowDuplicates)
125     {
126         _allowDuplicates=allowDuplicates;
127     }
128 
129     /* ------------------------------------------------------------ */
130     /**
131      * @throws Exception 
132      */
133     public void doStart() throws Exception
134     {
135         _deployed=new ArrayList();
136         
137         scan();
138         
139     }
140     
141     /* ------------------------------------------------------------ */
142     /** Scan for webapplications.
143      * 
144      * @throws Exception
145      */
146     public void scan() throws Exception
147     {
148         if (_contexts==null)
149             throw new IllegalArgumentException("No HandlerContainer");
150 
151         Resource r=Resource.newResource(_webAppDir);
152         if (!r.exists())
153             throw new IllegalArgumentException("No such webapps resource "+r);
154 
155         if (!r.isDirectory())
156             throw new IllegalArgumentException("Not directory webapps resource "+r);
157 
158         String[] files=r.list();
159 
160         files: for (int f=0; files!=null&&f<files.length; f++)
161         {
162             String context=files[f];
163 
164             if (context.equalsIgnoreCase("CVS/")||context.equalsIgnoreCase("CVS")||context.startsWith("."))
165                 continue;
166 
167             Resource app=r.addPath(r.encode(context));
168 
169             if (context.toLowerCase().endsWith(".war")||context.toLowerCase().endsWith(".jar"))
170             {
171                 context=context.substring(0,context.length()-4);
172                 Resource unpacked=r.addPath(context);
173                 if (unpacked!=null&&unpacked.exists()&&unpacked.isDirectory())
174                     continue;
175             }
176             else if (!app.isDirectory())
177                 continue;
178 
179             if (context.equalsIgnoreCase("root")||context.equalsIgnoreCase("root/"))
180                 context=URIUtil.SLASH;
181             else
182                 context="/"+context;
183             if (context.endsWith("/")&&context.length()>0)
184                 context=context.substring(0,context.length()-1);
185 
186             // Check the context path has not already been added or the webapp itself is not already deployed
187             if (!_allowDuplicates)
188             {
189                 Handler[] installed=_contexts.getChildHandlersByClass(ContextHandler.class);
190                 for (int i=0; i<installed.length; i++)
191                 {
192                     ContextHandler c=(ContextHandler)installed[i];
193         
194                     if (context.equals(c.getContextPath()))
195                         continue files;
196                     
197                    String path;
198                    if (c instanceof WebAppContext)
199                        path = ((WebAppContext)c).getWar();
200                    else
201                        path = (c.getBaseResource()==null?"":c.getBaseResource().getFile().getAbsolutePath());
202 
203                     if (path.equals(app.getFile().getAbsolutePath()))
204                         continue files;
205    
206                 }
207             }
208 
209             // create a webapp
210             WebAppContext wah=null;
211             if (_contexts instanceof ContextHandlerCollection && 
212                 WebAppContext.class.isAssignableFrom(((ContextHandlerCollection)_contexts).getContextClass()))
213             {
214                 try
215                 {
216                     wah=(WebAppContext)((ContextHandlerCollection)_contexts).getContextClass().newInstance();
217                 }
218                 catch (Exception e)
219                 {
220                     throw new Error(e);
221                 }
222             }
223             else
224             {
225                 wah=new WebAppContext();
226             }
227             
228             // configure it
229             wah.setContextPath(context);
230             if (_configurationClasses!=null)
231                 wah.setConfigurationClasses(_configurationClasses);
232             if (_defaultsDescriptor!=null)
233                 wah.setDefaultsDescriptor(_defaultsDescriptor);
234             wah.setExtractWAR(_extract);
235             wah.setWar(app.toString());
236             wah.setParentLoaderPriority(_parentLoaderPriority);
237             // add it
238             _contexts.addHandler(wah);
239             _deployed.add(wah);
240             
241             if (_contexts.isStarted())
242                 _contexts.start();  // TODO Multi exception
243         }
244     }
245     
246     public void doStop() throws Exception
247     {
248         for (int i=_deployed.size();i-->0;)
249         {
250             ContextHandler wac = (ContextHandler)_deployed.get(i);
251             wac.stop();// TODO Multi exception
252         }
253     }
254 }