View Javadoc

    1   //========================================================================
    2   //$Id: WebAppDeployer.java 2032 2007-07-26 06:11:24Z janb $
    3   //Copyright 2006 Mort Bay Consulting Pty. Ltd.
    4   //------------------------------------------------------------------------
    5   //Licensed under the Apache License, Version 2.0 (the "License");
    6   //you may not use this file except in compliance with the License.
    7   //You may obtain a copy of the License at
    8   //http://www.apache.org/licenses/LICENSE-2.0
    9   //Unless required by applicable law or agreed to in writing, software
    10  //distributed under the License is distributed on an "AS IS" BASIS,
    11  //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  //See the License for the specific language governing permissions and
    13  //limitations under the License.
    14  //========================================================================
    15
    16  package org.mortbay.jetty.deployer;
    17
    18  import java.util.ArrayList;
    19
    20  import org.mortbay.component.AbstractLifeCycle;
    21  import org.mortbay.jetty.Handler;
    22  import org.mortbay.jetty.HandlerContainer;
    23  import org.mortbay.jetty.handler.ContextHandler;
    24  import org.mortbay.jetty.handler.ContextHandlerCollection;
    25  import org.mortbay.jetty.webapp.WebAppContext;
    26  import org.mortbay.resource.Resource;
    27  import org.mortbay.util.URIUtil;
    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 HandlerContainer _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
    56      public String[] getConfigurationClasses()
    57      {
    58          return _configurationClasses;
    59      }
    60
    61      public void setConfigurationClasses(String[] configurationClasses)
    62      {
    63          _configurationClasses=configurationClasses;
    64      }
    65
    66      public HandlerContainer getContexts()
    67      {
    68          return _contexts;
    69      }
    70
    71      public void setContexts(HandlerContainer 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      * @throws Exception
    133      */
    134     public void doStart() throws Exception
    135     {
    136         _deployed=new ArrayList();
    137
    138         scan();
    139
    140     }
    141
    142     /* ------------------------------------------------------------ */
    143     /** Scan for webapplications.
    144      *
    145      * @throws Exception
    146      */
    147     public void scan() throws Exception
    148     {
    149         if (_contexts==null)
    150             throw new IllegalArgumentException("No HandlerContainer");
    151
    152         Resource r=Resource.newResource(_webAppDir);
    153         if (!r.exists())
    154             throw new IllegalArgumentException("No such webapps resource "+r);
    155
    156         if (!r.isDirectory())
    157             throw new IllegalArgumentException("Not directory webapps resource "+r);
    158
    159         String[] files=r.list();
    160
    161         files: for (int f=0; files!=null&&f<files.length; f++)
    162         {
    163             String context=files[f];
    164
    165             if (context.equalsIgnoreCase("CVS/")||context.equalsIgnoreCase("CVS")||context.startsWith("."))
    166                 continue;
    167
    168             Resource app=r.addPath(r.encode(context));
    169
    170             if (context.toLowerCase().endsWith(".war")||context.toLowerCase().endsWith(".jar"))
    171             {
    172                 context=context.substring(0,context.length()-4);
    173                 Resource unpacked=r.addPath(context);
    174                 if (unpacked!=null&&unpacked.exists()&&unpacked.isDirectory())
    175                     continue;
    176             }
    177             else if (!app.isDirectory())
    178                 continue;
    179
    180             if (context.equalsIgnoreCase("root")||context.equalsIgnoreCase("root/"))
    181                 context=URIUtil.SLASH;
    182             else
    183                 context="/"+context;
    184             if (context.endsWith("/")&&context.length()>0)
    185                 context=context.substring(0,context.length()-1);
    186
    187             // Check the context path has not already been added or the webapp itself is not already deployed
    188             if (!_allowDuplicates)
    189             {
    190                 Handler[] installed=_contexts.getChildHandlersByClass(ContextHandler.class);
    191                 for (int i=0; i<installed.length; i++)
    192                 {
    193                     ContextHandler c=(ContextHandler)installed[i];
    194
    195                     if (context.equals(c.getContextPath()))
    196                         continue files;
    197
    198                    String path;
    199                    if (c instanceof WebAppContext)
    200                        path = ((WebAppContext)c).getWar();
    201                    else
    202                        path = (c.getBaseResource()==null?"":c.getBaseResource().getFile().getAbsolutePath());
    203
    204                     if (path.equals(app.getFile().getAbsolutePath()))
    205                         continue files;
    206
    207                 }
    208             }
    209
    210             // create a webapp
    211             WebAppContext wah=null;
    212             if (_contexts instanceof ContextHandlerCollection &&
    213                 WebAppContext.class.isAssignableFrom(((ContextHandlerCollection)_contexts).getContextClass()))
    214             {
    215                 try
    216                 {
    217                     wah=(WebAppContext)((ContextHandlerCollection)_contexts).getContextClass().newInstance();
    218                 }
    219                 catch (Exception e)
    220                 {
    221                     throw new Error(e);
    222                 }
    223             }
    224             else
    225             {
    226                 wah=new WebAppContext();
    227             }
    228
    229             // configure it
    230             wah.setContextPath(context);
    231             if (_configurationClasses!=null)
    232                 wah.setConfigurationClasses(_configurationClasses);
    233             if (_defaultsDescriptor!=null)
    234                 wah.setDefaultsDescriptor(_defaultsDescriptor);
    235             wah.setExtractWAR(_extract);
    236             wah.setWar(app.toString());
    237             wah.setParentLoaderPriority(_parentLoaderPriority);
    238             // add it
    239             _contexts.addHandler(wah);
    240             _deployed.add(wah);
    241
    242             if (_contexts.isStarted())
    243                 _contexts.start();  // TODO Multi exception
    244         }
    245     }
    246
    247     public void doStop() throws Exception
    248     {
    249         for (int i=_deployed.size();i-->0;)
    250         {
    251             ContextHandler wac = (ContextHandler)_deployed.get(i);
    252             wac.stop();// TODO Multi exception
    253         }
    254     }
    255 }