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.HashMap;
21  import java.util.Iterator;
22  import java.util.List;
23  import java.util.Map;
24  
25  import org.mortbay.jetty.Connector;
26  import org.mortbay.jetty.Handler;
27  import org.mortbay.jetty.RequestLog;
28  import org.mortbay.jetty.Server;
29  import org.mortbay.jetty.ant.utils.ServerProxy;
30  import org.mortbay.jetty.ant.utils.TaskLog;
31  import org.mortbay.jetty.ant.utils.WebApplicationProxy;
32  import org.mortbay.jetty.handler.ContextHandlerCollection;
33  import org.mortbay.jetty.handler.DefaultHandler;
34  import org.mortbay.jetty.handler.HandlerCollection;
35  import org.mortbay.jetty.handler.RequestLogHandler;
36  import org.mortbay.jetty.security.UserRealm;
37  import org.mortbay.resource.Resource;
38  import org.mortbay.xml.XmlConfiguration;
39  import org.xml.sax.SAXException;
40  
41  /**
42   * A proxy class for interaction with Jetty server object. Used to have some
43   * level of abstraction over standard Jetty classes.
44   * 
45   * @author Jakub Pawlowicz
46   */
47  public class ServerProxyImpl implements ServerProxy
48  {
49  
50      /** Proxied Jetty server object. */
51      private Server server;
52  
53      /** Collection of context handlers (web application contexts). */
54      private ContextHandlerCollection contexts;
55  
56      /** Location of jetty.xml file. */
57      private File jettyXml;
58  
59      /** List of connectors. */
60      private List connectors;
61  
62      /** Request logger. */
63      private RequestLog requestLog;
64  
65      /** User realms. */
66      private List userRealms;
67  
68      /** List of added web applications. */
69      private Map webApplications = new HashMap();
70  
71      /**
72       * Default constructor. Creates a new Jetty server with a standard connector
73       * listening on a given port.
74       * 
75       * @param userRealmsList
76       * 
77       * @param port default connector port number.
78       * @param maxIdleTime default connector maximum idle time of for each
79       *            connection.
80       */
81      public ServerProxyImpl(List connectors, List userRealmsList, RequestLog requestLog,
82              File jettyXml)
83      {
84          server = new Server();
85          server.setStopAtShutdown(true);
86  
87          this.connectors = connectors;
88          this.userRealms = userRealmsList;
89          this.requestLog = requestLog;
90          this.jettyXml = jettyXml;
91          configure();
92      }
93  
94      /**
95       * @see org.mortbay.jetty.ant.utils.ServerProxy#addWebApplication(WebApplicationProxy,
96       *      int)
97       */
98      public void addWebApplication(WebApplicationProxy webApp, int scanIntervalSeconds)
99      {
100         webApp.createApplicationContext(contexts);
101 
102         if (scanIntervalSeconds > 0)
103         {
104             webApplications.put(webApp, new Integer(scanIntervalSeconds));
105         }
106     }
107 
108     /**
109      * Configures Jetty server before adding any web applications to it.
110      */
111     private void configure()
112     {
113         // Applies external configuration via jetty.xml
114         applyJettyXml();
115 
116         // Configures connectores for this server instance.
117         Iterator connectorIterator = connectors.iterator();
118         while (connectorIterator.hasNext())
119         {
120             Connector jettyConnector = (Connector) connectorIterator.next();
121             server.addConnector(jettyConnector);
122         }
123 
124         // Configures user realms
125         Iterator realmsIterator = userRealms.iterator();
126         while (realmsIterator.hasNext())
127         {
128             UserRealm realm = (UserRealm) realmsIterator.next();
129             server.addUserRealm(realm);
130         }
131 
132         // Does not cache resources, to prevent Windows from locking files
133         Resource.setDefaultUseCaches(false);
134 
135         // Set default server handlers
136         configureHandlers();
137     }
138 
139     private void configureHandlers()
140     {
141         RequestLogHandler requestLogHandler = new RequestLogHandler();
142         if (requestLog != null)
143         {
144             requestLogHandler.setRequestLog(requestLog);
145         }
146 
147         contexts = (ContextHandlerCollection) server
148                 .getChildHandlerByClass(ContextHandlerCollection.class);
149         if (contexts == null)
150         {
151             contexts = new ContextHandlerCollection();
152             HandlerCollection handlers = (HandlerCollection) server
153                     .getChildHandlerByClass(HandlerCollection.class);
154             if (handlers == null)
155             {
156                 handlers = new HandlerCollection();
157                 server.setHandler(handlers);
158                 handlers.setHandlers(new Handler[] { contexts, new DefaultHandler(),
159                         requestLogHandler });
160             }
161             else
162             {
163                 handlers.addHandler(contexts);
164             }
165         }
166     }
167 
168     /**
169      * Applies jetty.xml configuration to the Jetty server instance.
170      */
171     private void applyJettyXml()
172     {
173         if (jettyXml != null && jettyXml.exists())
174         {
175             TaskLog.log("Configuring jetty from xml configuration file = "
176                     + jettyXml.getAbsolutePath());
177             XmlConfiguration configuration;
178             try
179             {
180                 configuration = new XmlConfiguration(jettyXml.toURL());
181                 configuration.configure(server);
182             }
183             catch (MalformedURLException e)
184             {
185                 throw new RuntimeException(e);
186             }
187             catch (SAXException e)
188             {
189                 throw new RuntimeException(e);
190             }
191             catch (IOException e)
192             {
193                 throw new RuntimeException(e);
194             }
195             catch (Exception e)
196             {
197                 throw new RuntimeException(e);
198             }
199         }
200     }
201 
202     /**
203      * @see org.mortbay.jetty.ant.utils.ServerProxy#start()
204      */
205     public void start()
206     {
207         try
208         {
209             server.start();
210             startScanners();
211             server.join();
212 
213         }
214         catch (InterruptedException e)
215         {
216             new RuntimeException(e);
217         }
218         catch (Exception e)
219         {
220             new RuntimeException(e);
221         }
222     }
223 
224     /**
225      * Starts web applications' scanners.
226      */
227     private void startScanners()
228     {
229         Iterator i = webApplications.keySet().iterator();
230         while (i.hasNext())
231         {
232             WebApplicationProxyImpl webApp = (WebApplicationProxyImpl) i.next();
233             Integer scanIntervalSeconds = (Integer) webApplications.get(webApp);
234             JettyRunTask.startScanner(webApp, scanIntervalSeconds.intValue());
235         }
236     }
237 
238     /**
239      * @see org.mortbay.jetty.ant.utils.ServerProxy#getProxiedObject()
240      */
241     public Object getProxiedObject()
242     {
243         return server;
244     }
245 }