View Javadoc

1   /*
2    * Copyright 2002,2004 The Apache Software Foundation.
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    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.commons.jelly.tags.jetty;
18  
19  import java.io.IOException;
20  import java.net.UnknownHostException;
21  import java.net.URL;
22  
23  import org.apache.commons.jelly.JellyTagException;
24  import org.apache.commons.jelly.TagSupport;
25  import org.apache.commons.jelly.XMLOutput;
26  import org.apache.commons.logging.LogFactory;
27  import org.mortbay.http.HttpContext;
28  import org.mortbay.http.HttpListener;
29  import org.mortbay.http.HttpServer;
30  import org.mortbay.http.SocketListener;
31  import org.mortbay.http.UserRealm;
32  import org.mortbay.http.handler.NotFoundHandler;
33  import org.mortbay.http.handler.ResourceHandler;
34  import org.mortbay.util.Log;
35  import org.mortbay.util.MultiException;
36  import org.mortbay.util.OutputStreamLogSink;
37  import org.mortbay.util.Resource;
38  
39  /***
40   * Declare an instance of a Jetty http server
41   *
42   * @author  rtl
43   * @version $Id: JettyHttpServerTag.java 155420 2005-02-26 13:06:03Z dirkv $
44   */
45  public class JettyHttpServerTag extends TagSupport {
46  
47      /*** default port to create listeners for */
48      public static final int DEFAULT_PORT = 8100;
49  
50      /*** default host to create listeners/context for */
51      public static final String DEFAULT_HOST = "localhost";
52  
53      /*** default context to create context for */
54      public static final String DEFAULT_CONTEXT_PATH = "/";
55  
56      /*** default resource base to use for context */
57      public static final String DEFAULT_RESOURCE_BASE = "./docRoot";
58  
59      /*** default log file for Jetty */
60      public static final String DEFAULT_LOG_FILE = "jetty.log";
61  
62      /*** The Log to which logging calls will be made. */
63      private static final org.apache.commons.logging.Log log =
64          LogFactory.getLog(JettyHttpServerTag.class);
65  
66      /*** the log sink for the Jety server */
67      private static OutputStreamLogSink _logSink;
68  
69      // static initialisation
70      {
71          // setup a log for Jetty with a default filename
72          try {
73              _logSink = new OutputStreamLogSink(DEFAULT_LOG_FILE);
74              //_logSink.start();
75              Log.instance().add(_logSink);
76          } catch (Exception ex ) {
77              log.error(ex.getLocalizedMessage());
78          }
79  
80      }
81  
82      /*** unique identifier of the tag/ variable to store result in */
83      private String _var;
84  
85      /*** the http server for this tag */
86      private HttpServer _server;
87  
88      /*** filename of Jetty log file - with default */
89      private String _logFileName = DEFAULT_LOG_FILE;
90  
91      /*** Creates a new instance of JettyHttpServerTag */
92      public JettyHttpServerTag() {
93  
94          // Create the server
95          _server=new HttpServer();
96  
97          // turn off alias checking in Jetty's FileResource,
98          // so that we don't need exact case in resource names
99          System.setProperty("org.mortbay.util.FileResource.checkAliases", "false");
100     }
101 
102     /***
103      * Perform the tag functionality. In this case, create an http server after
104      * making sure that it has at least one context and associated http handler,
105      * creating defaults if it doesn't
106      *
107      * @param xmlOutput where to send output
108      * @throws Exception when an error occurs
109      */
110     public void doTag(XMLOutput xmlOutput) throws JellyTagException {
111 
112         try {
113             URL logFileURL = getContext().getResource(getLogFileName());
114             _logSink.setFilename(logFileURL.getPath());
115             _logSink.start();
116         } catch (Exception ex ) {
117             log.error(ex.getLocalizedMessage());
118         }
119 
120         // allow nested tags first, e.g body
121         invokeBody(xmlOutput);
122 
123         try {
124             // if no listeners create a default port listener
125             if (_server.getListeners().length == 0) {
126                 SocketListener listener=new SocketListener();
127                 listener.setPort(DEFAULT_PORT);
128                 listener.setHost(DEFAULT_HOST);
129                 _server.addListener(listener);
130             }
131 
132             // if no context/s create a default context
133             if (_server.getContexts().length == 0) {
134                 log.info("Creating a default context");
135                 // Create a context
136                 HttpContext context = _server.getContext(DEFAULT_HOST,
137                                                         DEFAULT_CONTEXT_PATH);
138 
139                 // Serve static content from the context
140                 URL baseResourceURL = getContext().getResource(DEFAULT_RESOURCE_BASE);
141                 Resource resource = Resource.newResource(baseResourceURL);
142                 context.setBaseResource(resource);
143                 _server.addContext(context);
144             }
145         }
146         catch (UnknownHostException e) {
147             throw new JellyTagException(e);
148         }
149         catch (IOException e) {
150             throw new JellyTagException(e);
151         }
152 
153         // check that all the contexts have at least one handler
154         // if not then add a default resource handler and a not found handler
155         HttpContext[] allContexts = _server.getContexts();
156         for (int i = 0; i < allContexts.length; i++) {
157             HttpContext currContext = allContexts[i];
158             if (currContext.getHandlers().length == 0) {
159                 log.info("Adding resource and not found handlers to context:" +
160                          currContext.getContextPath());
161                 currContext.addHandler(new ResourceHandler());
162                 currContext.addHandler(new NotFoundHandler());
163             }
164         }
165 
166         // Start the http server
167         try {
168             _server.start();
169         }
170         catch (MultiException e) {
171             throw new JellyTagException(e);
172         }
173 
174         // set variable to value if required
175         if (getVar() != null) {
176             getContext().setVariable(getVar(), _server);
177         }
178     }
179 
180     /***
181      * Add an http listener to the server instance
182      *
183      * @param listener the listener to add
184      */
185     public void addListener(HttpListener listener) {
186         _server.addListener(listener);
187     }
188 
189     /***
190      * Add an http context to the server instance
191      *
192      * @param context the context to add
193      */
194     public void addContext(HttpContext context) {
195         _server.addContext(context);
196     }
197 
198     /* ------------------------------------------------------------ */
199     /***
200      * Add a user authentication realm to the server instance
201      *
202      * @param realm the realm to add
203      * @return the realm added
204      */
205     public UserRealm addRealm(UserRealm realm)
206     {
207         return _server.addRealm(realm);
208     }
209 
210     //--------------------------------------------------------------------------
211     // Property accessors/mutators
212     //--------------------------------------------------------------------------
213 
214     /***
215      * Getter for property var.
216      *
217      * @return Value of property var.
218      */
219     public String getVar() {
220         return _var;
221     }
222 
223     /***
224      * Setter for property var.
225      *
226      * @param var New value of property var.
227      */
228     public void setVar(String var) {
229         _var = var;
230     }
231 
232     /***
233      * Getter for property logFileName.
234      *
235      * @return Value of property logFileName.
236      */
237     public String getLogFileName() {
238         return _logFileName;
239     }
240 
241     /***
242      * Setter for property logFileName.
243      *
244      * @param logFileName New value of property logFileName.
245      */
246     public void setLogFileName(String logFileName) {
247         _logFileName = logFileName;
248     }
249 
250 }