View Javadoc

    1   // ========================================================================
    2   // Copyright 2006-2007 Sabre Holdings.
    3   // ------------------------------------------------------------------------
    4   // Licensed under the Apache License, Version 2.0 (the "License");
    5   // you may not use this file except in compliance with the License.
    6   // You may obtain a copy of the License at
    7   // http://www.apache.org/licenses/LICENSE-2.0
    8   // Unless required by applicable law or agreed to in writing, software
    9   // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  // ========================================================================
    14
    15  package org.mortbay.jetty.ant;
    16
    17  import java.io.File;
    18  import java.io.IOException;
    19  import java.net.MalformedURLException;
    20  import java.util.Iterator;
    21  import java.util.List;
    22
    23  import org.mortbay.jetty.ant.types.FileMatchingConfiguration;
    24  import org.mortbay.jetty.ant.utils.TaskLog;
    25  import org.mortbay.jetty.ant.utils.WebApplicationProxy;
    26  import org.mortbay.jetty.handler.ContextHandler;
    27  import org.mortbay.jetty.handler.ContextHandlerCollection;
    28  import org.mortbay.jetty.plus.webapp.EnvConfiguration;
    29  import org.mortbay.jetty.webapp.Configuration;
    30  import org.mortbay.jetty.webapp.JettyWebXmlConfiguration;
    31  import org.mortbay.jetty.webapp.TagLibConfiguration;
    32  import org.mortbay.jetty.webapp.WebAppClassLoader;
    33  import org.mortbay.jetty.webapp.WebAppContext;
    34  import org.mortbay.jetty.webapp.WebInfConfiguration;
    35
    36  /**
    37   * An abstraction layer over Jetty WebAppContext.
    38   *
    39   * @author Jakub Pawlowicz
    40   */
    41  public class WebApplicationProxyImpl implements WebApplicationProxy
    42  {
    43
    44      /** Common root temp directory for all web applications. */
    45      static File baseTempDirectory = new File(".");
    46
    47      /** Name of this web application. */
    48      private String name;
    49
    50      /** Location of WAR file (either expanded or not). */
    51      private File warFile;
    52
    53      /** Application context path. */
    54      private String contextPath;
    55
    56      /** Location of web.xml file. */
    57      private File webXmlFile;
    58
    59      /** Location of jetty-env.xml file. */
    60      private File jettyEnvXml;
    61
    62      /** List of classpath files. */
    63      private List classPathFiles;
    64
    65      /** Jetty6 Web Application Context. */
    66      private WebAppContext webAppContext;
    67
    68      /** Extra scan targets. */
    69      private FileMatchingConfiguration extraScanTargetsConfiguration;
    70
    71      /** Extra context handlers. */
    72      private List contextHandlers;
    73
    74      Configuration[] configurations;
    75
    76      private FileMatchingConfiguration librariesConfiguration;
    77
    78      public static void setBaseTempDirectory(File tempDirectory)
    79      {
    80          baseTempDirectory = tempDirectory;
    81      }
    82
    83      /**
    84       * Default constructor. Takes application name as an argument.
    85       *
    86       * @param name web application name.
    87       */
    88      public WebApplicationProxyImpl(String name) throws Exception
    89      {
    90          this.name = name;
    91          TaskLog.log("\nConfiguring Jetty for web application: " + name);
    92
    93  				this.configurations = new Configuration[] { new WebInfConfiguration(),
    94  		            new EnvConfiguration(), new JettyWebAppConfiguration(), new JettyWebXmlConfiguration(),
    95  		            new TagLibConfiguration() };
    96      }
    97
    98      public List getClassPathFiles()
    99      {
    100         return classPathFiles;
    101     }
    102
    103     public String getContextPath()
    104     {
    105         return contextPath;
    106     }
    107
    108     public String getName()
    109     {
    110         return name;
    111     }
    112
    113     public File getSourceDirectory()
    114     {
    115         return warFile;
    116     }
    117
    118     public File getWebXmlFile()
    119     {
    120         return webXmlFile;
    121     }
    122
    123     public void setSourceDirectory(File warFile)
    124     {
    125         this.warFile = warFile;
    126         TaskLog.log("Webapp source directory = " + warFile);
    127     }
    128
    129     public void setContextPath(String contextPath)
    130     {
    131         if (!contextPath.startsWith("/"))
    132         {
    133             contextPath = "/" + contextPath;
    134         }
    135         this.contextPath = contextPath;
    136         TaskLog.log("Context path = " + contextPath);
    137
    138     }
    139
    140     public void setWebXml(File webXmlFile)
    141     {
    142         this.webXmlFile = webXmlFile;
    143     }
    144
    145     public void setJettyEnvXml(File jettyEnvXml)
    146     {
    147         this.jettyEnvXml = jettyEnvXml;
    148         if (this.jettyEnvXml != null)
    149         {
    150             TaskLog.log("jetty-env.xml file: = " + jettyEnvXml.getAbsolutePath());
    151         }
    152     }
    153
    154     public void setClassPathFiles(List classPathFiles)
    155     {
    156         this.classPathFiles = classPathFiles;
    157         TaskLog.log("Classpath = " + classPathFiles);
    158     }
    159
    160     /**
    161      * Checks if a given file is scanned according to the internal
    162      * configuration. This may be difficult due to use of 'includes' and
    163      * 'excludes' statements.
    164      *
    165      * @param pathToFile a fully qualified path to file.
    166      * @return true if file is being scanned, false otherwise.
    167      */
    168     public boolean isFileScanned(String pathToFile)
    169     {
    170         return librariesConfiguration.isIncluded(pathToFile)
    171                 || extraScanTargetsConfiguration.isIncluded(pathToFile);
    172     }
    173
    174     public void setLibrariesConfiguration(FileMatchingConfiguration classesConfiguration)
    175     {
    176         TaskLog.log("Default scanned paths = " + classesConfiguration.getBaseDirectories());
    177         this.librariesConfiguration = classesConfiguration;
    178     }
    179
    180     public List getLibraries()
    181     {
    182         return librariesConfiguration.getBaseDirectories();
    183     }
    184
    185     public void setExtraScanTargetsConfiguration(
    186             FileMatchingConfiguration extraScanTargetsConfiguration)
    187     {
    188         this.extraScanTargetsConfiguration = extraScanTargetsConfiguration;
    189         TaskLog.log("Extra scan targets = " + extraScanTargetsConfiguration.getBaseDirectories());
    190     }
    191
    192     public List getExtraScanTargets()
    193     {
    194         return extraScanTargetsConfiguration.getBaseDirectories();
    195     }
    196
    197     public List getContextHandlers()
    198     {
    199         return contextHandlers;
    200     }
    201
    202     public void setContextHandlers(List contextHandlers)
    203     {
    204         this.contextHandlers = contextHandlers;
    205     }
    206
    207     /**
    208      * @see com.sabre.ant.jetty.WebApplicationProxy#getProxiedObject()
    209      */
    210     public Object getProxiedObject()
    211     {
    212         return webAppContext;
    213     }
    214
    215     /**
    216      * @see com.sabre.ant.jetty.WebApplicationProxy#start()
    217      */
    218     public void start()
    219     {
    220         try
    221         {
    222             TaskLog.logWithTimestamp("Starting web application " + name + " ...\n");
    223             webAppContext.setShutdown(false);
    224             webAppContext.start();
    225         }
    226         catch (Exception e)
    227         {
    228             TaskLog.log(e.toString());
    229         }
    230     }
    231
    232     /**
    233      * @see com.sabre.ant.jetty.WebApplicationProxy#stop()
    234      */
    235     public void stop()
    236     {
    237         try
    238         {
    239             TaskLog.logWithTimestamp("Stopping web application " + name + " ...");
    240             webAppContext.setShutdown(true);
    241             Thread.currentThread().sleep(500L);
    242             webAppContext.stop();
    243         }
    244         catch (InterruptedException e)
    245         {
    246             TaskLog.log(e.toString());
    247         }
    248         catch (Exception e)
    249         {
    250             TaskLog.log(e.toString());
    251         }
    252     }
    253
    254     /**
    255      * @see com.sabre.ant.jetty.WebApplicationProxy#createApplicationContext(org.mortbay.jetty.handler.ContextHandlerCollection)
    256      */
    257     public void createApplicationContext(ContextHandlerCollection contexts)
    258     {
    259         webAppContext = new WebAppContext(contexts, warFile.getAbsolutePath(), contextPath);
    260         webAppContext.setDisplayName(name);
    261
    262         configurePaths();
    263         configureHandlers(contexts);
    264
    265         applyConfiguration();
    266     }
    267
    268     private void configureHandlers(ContextHandlerCollection contexts)
    269     {
    270         // adding extra context handlers
    271         Iterator handlersIterator = contextHandlers.iterator();
    272         while (handlersIterator.hasNext())
    273         {
    274             ContextHandler contextHandler = (ContextHandler) handlersIterator.next();
    275             contexts.addHandler(contextHandler);
    276         }
    277     }
    278
    279     private void configurePaths()
    280     {
    281         // configuring temp directory
    282         File tempDir = new File(baseTempDirectory, contextPath);
    283         if (!tempDir.exists())
    284         {
    285             tempDir.mkdirs();
    286         }
    287         webAppContext.setTempDirectory(tempDir);
    288         tempDir.deleteOnExit();
    289         TaskLog.log("Temp directory = " + tempDir.getAbsolutePath());
    290
    291         // configuring WAR directory for packaged web applications
    292         if (warFile.isFile())
    293         {
    294             warFile = new File(tempDir, "webapp");
    295             webXmlFile = new File(new File(warFile, "WEB-INF"), "web.xml");
    296         }
    297     }
    298
    299     /**
    300      * Applies web application configuration at the end of configuration process
    301      * or after application restart.
    302      */
    303     void applyConfiguration()
    304     {
    305         for (int i = 0; i < configurations.length; i++)
    306         {
    307             if (configurations[i] instanceof EnvConfiguration)
    308             {
    309                 try
    310                 {
    311                     if (jettyEnvXml != null && jettyEnvXml.exists())
    312                     {
    313                         ((EnvConfiguration) configurations[i]).setJettyEnvXml(jettyEnvXml.toURL());
    314                     }
    315                 }
    316                 catch (MalformedURLException e)
    317                 {
    318                     throw new RuntimeException(e);
    319                 }
    320             }
    321             else if (configurations[i] instanceof JettyWebAppConfiguration)
    322             {
    323                 ((JettyWebAppConfiguration) configurations[i]).setClassPathFiles(classPathFiles);
    324                 ((JettyWebAppConfiguration) configurations[i]).setWebAppBaseDir(warFile);
    325                 ((JettyWebAppConfiguration) configurations[i]).setWebXmlFile(webXmlFile);
    326                 ((JettyWebAppConfiguration) configurations[i]).setWebDefaultXmlFile(webDefaultXmlFile);
    327             }
    328         }
    329
    330         try
    331         {
    332             ClassLoader loader = new WebAppClassLoader(this.getClass().getClassLoader(),
    333                     webAppContext);
    334             webAppContext.setParentLoaderPriority(true);
    335             webAppContext.setClassLoader(loader);
    336             if (webDefaultXmlFile != null)
    337                 webAppContext.setDefaultsDescriptor(webDefaultXmlFile.getCanonicalPath());
    338
    339         }
    340         catch (IOException e)
    341         {
    342             TaskLog.log(e.toString());
    343         }
    344
    345         webAppContext.setConfigurations(configurations);
    346     }
    347
    348     private File webDefaultXmlFile;
    349
    350     public File getWebDefaultXmlFile()
    351     {
    352         return this.webDefaultXmlFile;
    353     }
    354
    355     public void setWebDefaultXmlFile(File webDefaultXmlfile)
    356     {
    357         this.webDefaultXmlFile = webDefaultXmlfile;
    358     }
    359 }