001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: TestCaseServerside.java 3643 2007-01-12 15:29:45Z gbevin $
007: */
008: package com.uwyn.rife;
009:
010: import com.uwyn.rife.engine.Gate;
011: import com.uwyn.rife.rep.Rep;
012: import com.uwyn.rife.rep.Repository;
013: import com.uwyn.rife.resources.ResourceFinderClasspath;
014: import com.uwyn.rife.servlet.RifeFilter;
015: import com.uwyn.rife.servlet.RifeServlet;
016: import java.net.URL;
017: import java.net.URLDecoder;
018: import java.util.Stack;
019: import junit.framework.TestCase;
020: import org.mortbay.http.SocketListener;
021: import org.mortbay.jetty.Server;
022: import org.mortbay.jetty.servlet.FilterHolder;
023: import org.mortbay.jetty.servlet.ServletHandler;
024: import org.mortbay.jetty.servlet.ServletHolder;
025: import org.mortbay.jetty.servlet.WebApplicationContext;
026: import org.mortbay.jetty.servlet.WebApplicationHandler;
027: import org.mortbay.util.Code;
028: import org.mortbay.util.Frame;
029: import org.mortbay.util.Log;
030: import org.mortbay.util.LogSink;
031:
032: public abstract class TestCaseServerside extends TestCase {
033: public final static int SITE_SERVLET = 1;
034: public final static int SITE_FILTER = 2;
035:
036: private int mSiteType = SITE_SERVLET;
037: private String mWebAppName = "empty";
038: private String mWebXmlPath = "/WEB-INF/web.xml";
039: private Server mServer = null;
040: private CollectingLogSink mLogSink = null;
041:
042: public TestCaseServerside(int siteType, String name) {
043: super (name);
044:
045: setSiteType(siteType);
046: }
047:
048: protected CollectingLogSink getLogSink() {
049: return mLogSink;
050: }
051:
052: private WebApplicationContext prepareWebapp(String context)
053: throws Exception {
054: // stop previous server if it was set up
055: stopServer();
056:
057: // Disable debug output
058: Log.instance().disableLog();
059: mLogSink = new CollectingLogSink();
060: mLogSink.start();
061: Log.instance().add(mLogSink);
062:
063: // Create the server
064: mServer = new Server();
065: mServer.setResolveRemoteHost(true);
066:
067: // Create a port listener
068: SocketListener listener = new SocketListener();
069: listener.setHost("localhost");
070: listener.setPort(8181);
071: mServer.addListener(listener);
072:
073: // Find the absolute path of the web application in the class path
074: ResourceFinderClasspath resource_finder = ResourceFinderClasspath
075: .getInstance();
076: URL webapp_resource = resource_finder.getResource(mWebAppName
077: + mWebXmlPath);
078: String webapp_resource_path = URLDecoder.decode(webapp_resource
079: .getFile());
080: webapp_resource_path = webapp_resource_path.substring(0,
081: webapp_resource_path.length() - mWebXmlPath.length());
082:
083: // Setup a new web application
084: WebApplicationContext webapp_context = mServer
085: .addWebApplication("localhost", context,
086: webapp_resource_path);
087: webapp_context.setDefaultsDescriptor(null);
088:
089: return webapp_context;
090: }
091:
092: private void startServer() throws Exception {
093: mServer.start();
094: }
095:
096: public void setSiteType(int type) {
097: if (type != SITE_SERVLET && type != SITE_FILTER)
098: throw new IllegalArgumentException("invalid site type.");
099:
100: mSiteType = type;
101: }
102:
103: public void setWebAppName(String name) {
104: mWebAppName = name;
105: }
106:
107: public void setWebXmlPath(String path) {
108: mWebXmlPath = path;
109: }
110:
111: protected Gate setupSite(String siteXmlPath) throws Exception {
112: return setupSite("/", siteXmlPath, null);
113: }
114:
115: protected Gate setupSite(String siteXmlPath, String[][] initParams)
116: throws Exception {
117: return setupSite("/", siteXmlPath, initParams);
118: }
119:
120: protected Gate setupSite(String context, String siteXmlPath)
121: throws Exception {
122: return setupSite(context, siteXmlPath, null);
123: }
124:
125: protected Gate setupSite(String context, String siteXmlPath,
126: String[][] initParams) throws Exception {
127: switch (mSiteType) {
128: case SITE_SERVLET:
129: return setupServlet(context, siteXmlPath, initParams);
130: case SITE_FILTER:
131: return setupFilter(context, siteXmlPath, initParams);
132: default:
133: return null;
134: }
135: }
136:
137: private Gate setupServlet(String context, String siteXmlPath,
138: String[][] initParams) throws Exception {
139: // Register the servlet
140: WebApplicationContext webapp_context = prepareWebapp(context);
141: ServletHandler servlet_handler = webapp_context
142: .getServletHandler();
143: ServletHolder servlet_holder = servlet_handler.addServlet(
144: "GATE", "/*", "com.uwyn.rife.servlet.RifeServlet");
145: servlet_holder.setInitOrder(1);
146:
147: // Setup the site if the xml path was provided
148: if (siteXmlPath != null) {
149: servlet_holder.setInitParameter("site.xml.path",
150: siteXmlPath);
151: }
152:
153: // add the provided init parameters
154: if (initParams != null) {
155: for (String[] param : initParams) {
156: servlet_holder.setInitParameter(param[0], param[1]);
157: }
158: }
159:
160: startServer();
161:
162: return (Gate) ((RifeServlet) servlet_holder.getServlet())
163: .getGate();
164: }
165:
166: private Gate setupFilter(String context, String siteXmlPath,
167: String[][] initParams) throws Exception {
168: // Register the filter
169: WebApplicationContext webapp_context = prepareWebapp(context);
170: ServletHandler servlet_handler = webapp_context
171: .getServletHandler();
172: ServletHolder servlet_holder = servlet_handler.addServlet(
173: "default", "/", "org.mortbay.jetty.servlet.Default");
174: WebApplicationHandler webapp_handler = webapp_context
175: .getWebApplicationHandler();
176: FilterHolder filter_holder = webapp_handler.defineFilter(
177: "GATE", "com.uwyn.rife.servlet.RifeFilter");
178: filter_holder.addAppliesTo("REQUEST");
179: webapp_handler.mapPathToFilter("/*", "GATE");
180:
181: // Configure the default servlet
182: servlet_holder.setInitParameter("acceptRanges", "true");
183: servlet_holder.setInitParameter("dirAllowed", "true");
184: servlet_holder.setInitParameter("putAllowed", "false");
185: servlet_holder.setInitParameter("delAllowed", "false");
186: servlet_holder.setInitParameter("redirectWelcome", "false");
187: servlet_holder.setInitOrder(0);
188:
189: // Setup the site if the xml path was provided
190: if (siteXmlPath != null) {
191: filter_holder
192: .setInitParameter("site.xml.path", siteXmlPath);
193: }
194:
195: // add the provided init parameters
196: if (initParams != null) {
197: for (String[] param : initParams) {
198: filter_holder.setInitParameter(param[0], param[1]);
199: }
200: }
201:
202: startServer();
203:
204: return (Gate) ((RifeFilter) filter_holder.getFilter())
205: .getGate();
206: }
207:
208: private void stopServer() throws Exception {
209: if (mServer != null) {
210: // disconnect default repository, otherwise it will be shutdown
211: // by the RIFE's lifecycle cleanup
212: Repository rep = Rep.getDefaultRepository();
213: Rep.setDefaultRepository(null);
214:
215: // Stop the http server
216: mServer.stop();
217: mServer = null;
218:
219: // put the default repository back
220: Rep.setDefaultRepository(rep);
221: }
222: }
223:
224: public void tearDown() throws Exception {
225: stopServer();
226: }
227:
228: protected class CollectingLogSink implements LogSink {
229: private Stack<Object> mLog = null;
230:
231: public Stack<Object> getLog() {
232: return mLog;
233: }
234:
235: public void start() throws Exception {
236: mLog = new Stack<Object>();
237: }
238:
239: public void stop() throws InterruptedException {
240: mLog = null;
241: }
242:
243: public boolean isStarted() {
244: return mLog != null;
245: }
246:
247: public void log(String tag, Object message, Frame frame,
248: long time) {
249: mLog.push(message);
250: }
251:
252: public void setOptions(String options) {
253: }
254:
255: public String getOptions() {
256: return "";
257: }
258:
259: public void log(String formattedLog) {
260: mLog.push(formattedLog);
261: }
262:
263: public Throwable getInternalException() {
264: Object last_entry = getLogSink().getLog().peek();
265: if (!(last_entry instanceof Code.LogMsg)) {
266: return null;
267: }
268:
269: return ((Code.LogMsg) last_entry).getThrowable();
270: }
271: }
272: }
|