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 }