summaryrefslogtreecommitdiffstats
path: root/branches/sca-java-0.91/modules/http-jetty/src
diff options
context:
space:
mode:
authordims <dims@13f79535-47bb-0310-9956-ffa450edef68>2008-06-17 00:23:01 +0000
committerdims <dims@13f79535-47bb-0310-9956-ffa450edef68>2008-06-17 00:23:01 +0000
commitbdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a (patch)
tree38a92061c0793434c4be189f1d70c3458b6bc41d /branches/sca-java-0.91/modules/http-jetty/src
Move Tuscany from Incubator to top level.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'branches/sca-java-0.91/modules/http-jetty/src')
-rw-r--r--branches/sca-java-0.91/modules/http-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyDefaultServlet.java62
-rw-r--r--branches/sca-java-0.91/modules/http-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyLogger.java87
-rw-r--r--branches/sca-java-0.91/modules/http-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyServer.java299
-rw-r--r--branches/sca-java-0.91/modules/http-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/module/JettyRuntimeModuleActivator.java54
-rw-r--r--branches/sca-java-0.91/modules/http-jetty/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator18
-rw-r--r--branches/sca-java-0.91/modules/http-jetty/src/test/java/org/apache/tuscany/sca/http/jetty/JettyServerTestCase.java254
-rw-r--r--branches/sca-java-0.91/modules/http-jetty/src/test/resources/content/test.html21
7 files changed, 795 insertions, 0 deletions
diff --git a/branches/sca-java-0.91/modules/http-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyDefaultServlet.java b/branches/sca-java-0.91/modules/http-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyDefaultServlet.java
new file mode 100644
index 0000000000..8932898ba4
--- /dev/null
+++ b/branches/sca-java-0.91/modules/http-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyDefaultServlet.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.http.jetty;
+
+import org.mortbay.jetty.servlet.DefaultServlet;
+import org.mortbay.resource.Resource;
+
+/**
+ * Customizes the Jetty default servlet.
+ *
+ * @version $Rev$ $Date$
+ */
+public class JettyDefaultServlet extends DefaultServlet {
+ private static final long serialVersionUID = 7000218247190209353L;
+
+ private String documentRoot;
+ private String servletPath;
+
+ public JettyDefaultServlet(String servletPath, String documentRoot) {
+ this.servletPath = servletPath + '/';
+ this.documentRoot = documentRoot;
+ }
+
+ @Override
+ public Resource getResource(String pathInContext) {
+ if (pathInContext.startsWith(servletPath)) {
+ if (pathInContext.length() > servletPath.length()) {
+ pathInContext = pathInContext.substring(servletPath.length());
+ } else {
+ pathInContext = "";
+ }
+ }
+ return super.getResource(pathInContext);
+ }
+
+ @Override
+ public String getInitParameter(String name) {
+ if ("resourceBase".equals(name)) {
+ return documentRoot;
+ } else {
+ return super.getInitParameter(name);
+ }
+ }
+
+}
diff --git a/branches/sca-java-0.91/modules/http-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyLogger.java b/branches/sca-java-0.91/modules/http-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyLogger.java
new file mode 100644
index 0000000000..1ecf1bca1b
--- /dev/null
+++ b/branches/sca-java-0.91/modules/http-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyLogger.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.http.jetty;
+
+import org.mortbay.log.Logger;
+
+/**
+ * Replaces Jetty's logging mechanism
+ *
+ * @version $Rev$ $Date$
+ */
+public class JettyLogger implements Logger {
+
+ private boolean debugEnabled;
+
+ public boolean isDebugEnabled() {
+ return debugEnabled;
+ }
+
+ public void setDebugEnabled(boolean debugEnabled) {
+ this.debugEnabled = debugEnabled;
+ }
+
+ public void info(String msg, Object arg0, Object arg1) {
+ if (debugEnabled) {
+ System.err.println(":INFO: " + format(msg, arg0, arg1));
+ }
+ }
+
+ public void debug(String msg, Throwable th) {
+ if (debugEnabled) {
+ System.err.println(":DEBUG: " + msg);
+ th.printStackTrace();
+ }
+ }
+
+ public void debug(String msg, Object arg0, Object arg1) {
+ if (debugEnabled) {
+ System.err.println(":DEBUG: " + format(msg, arg0, arg1));
+ }
+ }
+
+ public void warn(String msg, Object arg0, Object arg1) {
+ if (debugEnabled) {
+ System.err.println(":WARN: " + format(msg, arg0, arg1));
+ }
+ }
+
+ public void warn(String msg, Throwable th) {
+ if (debugEnabled) {
+ System.err.println(":WARN: " + msg);
+ th.printStackTrace();
+ }
+ }
+
+ public Logger getLogger(String name) {
+ return this;
+ }
+
+ private String format(String msg, Object arg0, Object arg1) {
+ int i0 = msg.indexOf("{}");
+ int i1 = i0 < 0 ? -1 : msg.indexOf("{}", i0 + 2);
+ if (arg1 != null && i1 >= 0) {
+ msg = msg.substring(0, i1) + arg1 + msg.substring(i1 + 2);
+ }
+ if (arg0 != null && i0 >= 0) {
+ msg = msg.substring(0, i0) + arg0 + msg.substring(i0 + 2);
+ }
+ return msg;
+ }
+}
diff --git a/branches/sca-java-0.91/modules/http-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyServer.java b/branches/sca-java-0.91/modules/http-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyServer.java
new file mode 100644
index 0000000000..c0f33e1522
--- /dev/null
+++ b/branches/sca-java-0.91/modules/http-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyServer.java
@@ -0,0 +1,299 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.http.jetty;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+
+import org.apache.tuscany.sca.http.DefaultResourceServlet;
+import org.apache.tuscany.sca.http.ServletHost;
+import org.apache.tuscany.sca.http.ServletMappingException;
+import org.apache.tuscany.sca.work.WorkScheduler;
+import org.mortbay.jetty.Connector;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.handler.ContextHandler;
+import org.mortbay.jetty.nio.SelectChannelConnector;
+import org.mortbay.jetty.security.SslSocketConnector;
+import org.mortbay.jetty.servlet.DefaultServlet;
+import org.mortbay.jetty.servlet.ServletHandler;
+import org.mortbay.jetty.servlet.ServletHolder;
+import org.mortbay.jetty.servlet.ServletMapping;
+import org.mortbay.jetty.servlet.SessionHandler;
+import org.mortbay.log.Log;
+import org.mortbay.log.Logger;
+import org.mortbay.thread.ThreadPool;
+
+/**
+ * Implements an HTTP transport service using Jetty.
+ *
+ * @version $$Rev$$ $$Date: 2007-02-21 13:28:30 +0000 (Wed, 21 Feb
+ * 2007) $$
+ */
+public class JettyServer implements ServletHost {
+
+ private static final String ROOT = "/";
+ private static final int ERROR = 0;
+ private static final int UNINITIALIZED = 0;
+ private static final int STARTING = 1;
+ private static final int STARTED = 2;
+ private static final int STOPPING = 3;
+ private static final int STOPPED = 4;
+ private static final int DEFAULT_PORT = 8080;
+
+ private final Object joinLock = new Object();
+ private int state = UNINITIALIZED;
+ private String keystore;
+ private String certPassword;
+ private String keyPassword;
+ private boolean sendServerVersion;
+ private boolean https;
+ private int httpsPort = 8484;
+ private boolean debug;
+ private Server server;
+ private Connector connector;
+ private ServletHandler servletHandler;
+ private WorkScheduler workScheduler;
+
+ static {
+ // hack to replace the static Jetty logger
+ System.setProperty("org.mortbay.log.class", JettyLogger.class.getName());
+
+ }
+
+ public JettyServer(WorkScheduler workScheduler) {
+ this.workScheduler = workScheduler;
+
+ // Configure the Jetty logger
+ Logger logger = Log.getLogger(null);
+ if (logger instanceof JettyLogger) {
+ JettyLogger jettyLogger = (JettyLogger)logger;
+ if (debug) {
+ jettyLogger.setDebugEnabled(true);
+ }
+ }
+ }
+
+ public void setSendServerVersion(boolean sendServerVersion) {
+ this.sendServerVersion = sendServerVersion;
+ }
+
+ public void setHttps(boolean https) {
+ this.https = https;
+ }
+
+ public void setKeystore(String keystore) {
+ this.keystore = keystore;
+ }
+
+ public void setCertPassword(String certPassword) {
+ this.certPassword = certPassword;
+ }
+
+ public void setKeyPassword(String keyPassword) {
+ this.keyPassword = keyPassword;
+ }
+
+ public void setDebug(boolean val) {
+ debug = val;
+ }
+
+ public void init() {
+ state = STARTING;
+ }
+
+ public void destroy() {
+ if (state == STARTED) {
+ state = STOPPING;
+ synchronized (joinLock) {
+ joinLock.notifyAll();
+ }
+ try {
+ server.stop();
+ } catch (Exception e) {
+ throw new ServletMappingException(e);
+ }
+ state = STOPPED;
+ }
+ }
+
+ public void addServletMapping(String uriStr, Servlet servlet) throws ServletMappingException {
+ URI uri = URI.create(uriStr);
+ if (state == STARTING) {
+
+ int port = uri.getPort();
+ if (port == -1) {
+ port = DEFAULT_PORT;
+ }
+
+ try {
+ server = new Server();
+ server.setThreadPool(new WorkSchedulerThreadPool());
+ if (connector == null) {
+ if (https) {
+ Connector httpConnector = new SelectChannelConnector();
+ httpConnector.setPort(port);
+ SslSocketConnector sslConnector = new SslSocketConnector();
+ sslConnector.setPort(httpsPort);
+ sslConnector.setKeystore(keystore);
+ sslConnector.setPassword(certPassword);
+ sslConnector.setKeyPassword(keyPassword);
+ server.setConnectors(new Connector[] {httpConnector, sslConnector});
+ } else {
+ SelectChannelConnector selectConnector = new SelectChannelConnector();
+ selectConnector.setPort(port);
+ server.setConnectors(new Connector[] {selectConnector});
+ }
+ } else {
+ connector.setPort(port);
+ server.setConnectors(new Connector[] {connector});
+ }
+
+ ContextHandler contextHandler = new ContextHandler();
+ contextHandler.setContextPath(ROOT);
+ server.setHandler(contextHandler);
+
+ SessionHandler sessionHandler = new SessionHandler();
+ servletHandler = new ServletHandler();
+ sessionHandler.addHandler(servletHandler);
+
+ contextHandler.setHandler(sessionHandler);
+
+ server.setStopAtShutdown(true);
+ server.setSendServerVersion(sendServerVersion);
+ // monitor.started();
+ server.start();
+ state = STARTED;
+ } catch (Exception e) {
+ state = ERROR;
+ throw new ServletMappingException(e);
+ }
+ }
+
+ // Register the servlet mapping
+ ServletHolder holder;
+ if (servlet instanceof DefaultResourceServlet) {
+
+ // Optimize the handling of resource requests, use the Jetty default servlet
+ // instead of our default resource servlet
+ String servletPath = uri.getPath();
+ if (servletPath.endsWith("*")) {
+ servletPath = servletPath.substring(0, servletPath.length()-1);
+ }
+ if (servletPath.endsWith("/")) {
+ servletPath = servletPath.substring(0, servletPath.length()-1);
+ }
+ DefaultResourceServlet resourceServlet = (DefaultResourceServlet)servlet;
+ DefaultServlet defaultServlet = new JettyDefaultServlet(servletPath, resourceServlet.getDocumentRoot());
+ holder = new ServletHolder(defaultServlet);
+
+ } else {
+ holder = new ServletHolder(servlet);
+ }
+ servletHandler.addServlet(holder);
+ ServletMapping mapping = new ServletMapping();
+ mapping.setServletName(holder.getName());
+ String path = uri.getPath();
+ mapping.setPathSpec(path);
+ servletHandler.addServletMapping(mapping);
+ }
+
+ public Servlet removeServletMapping(String uri) {
+ Servlet removedServlet = null;
+ List<ServletMapping> mappings =
+ new ArrayList<ServletMapping>(Arrays.asList(servletHandler.getServletMappings()));
+ String path = URI.create(uri).getPath();
+ for (ServletMapping mapping : mappings) {
+ if (Arrays.asList(mapping.getPathSpecs()).contains(path)) {
+ try {
+ removedServlet = servletHandler.getServlet(mapping.getServletName()).getServlet();
+ } catch (ServletException e) {
+ throw new IllegalStateException(e);
+ }
+ mappings.remove(mapping);
+ break;
+ }
+ }
+ if (removedServlet != null) {
+ servletHandler.setServletMappings((ServletMapping[])mappings.toArray(new ServletMapping[mappings.size()]));
+ }
+ return removedServlet;
+ }
+
+ /**
+ * An integration wrapper to enable use of a {@link WorkScheduler} with Jetty
+ */
+ private class WorkSchedulerThreadPool implements ThreadPool {
+
+ public boolean dispatch(Runnable work) {
+ workScheduler.scheduleWork(work);
+ return true;
+ }
+
+ public void join() throws InterruptedException {
+ synchronized (joinLock) {
+ joinLock.wait();
+ }
+ }
+
+ public int getThreads() {
+ throw new UnsupportedOperationException();
+ }
+
+ public int getIdleThreads() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isLowOnThreads() {
+ // TODO FIXME
+ return false;
+ }
+
+ public void start() throws Exception {
+ }
+
+ public void stop() throws Exception {
+ }
+
+ public boolean isRunning() {
+ return state == STARTING || state == STARTED;
+ }
+
+ public boolean isStarted() {
+ return state == STARTED;
+ }
+
+ public boolean isStarting() {
+ return state == STARTING;
+ }
+
+ public boolean isStopping() {
+ return state == STOPPING;
+ }
+
+ public boolean isFailed() {
+ return state == ERROR;
+ }
+ }
+
+}
diff --git a/branches/sca-java-0.91/modules/http-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/module/JettyRuntimeModuleActivator.java b/branches/sca-java-0.91/modules/http-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/module/JettyRuntimeModuleActivator.java
new file mode 100644
index 0000000000..dfc2c18a53
--- /dev/null
+++ b/branches/sca-java-0.91/modules/http-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/module/JettyRuntimeModuleActivator.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.http.jetty.module;
+
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ModuleActivator;
+import org.apache.tuscany.sca.http.ServletHostExtensionPoint;
+import org.apache.tuscany.sca.http.jetty.JettyServer;
+import org.apache.tuscany.sca.work.WorkScheduler;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JettyRuntimeModuleActivator implements ModuleActivator {
+
+ private JettyServer server;
+
+ public Object[] getExtensionPoints() {
+ return null;
+ }
+
+ public void start(ExtensionPointRegistry extensionPointRegistry) {
+
+ // Register a Jetty servlet host
+ ServletHostExtensionPoint servletHosts =
+ extensionPointRegistry.getExtensionPoint(ServletHostExtensionPoint.class);
+ WorkScheduler workScheduler = extensionPointRegistry.getExtensionPoint(WorkScheduler.class);
+ server = new JettyServer(workScheduler);
+ servletHosts.addServletHost(server);
+ server.init();
+ }
+
+ public void stop(ExtensionPointRegistry registry) {
+ server.destroy();
+ }
+
+}
diff --git a/branches/sca-java-0.91/modules/http-jetty/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator b/branches/sca-java-0.91/modules/http-jetty/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator
new file mode 100644
index 0000000000..f61708de90
--- /dev/null
+++ b/branches/sca-java-0.91/modules/http-jetty/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# Implementation class for the ModuleActivator
+org.apache.tuscany.sca.http.jetty.module.JettyRuntimeModuleActivator
diff --git a/branches/sca-java-0.91/modules/http-jetty/src/test/java/org/apache/tuscany/sca/http/jetty/JettyServerTestCase.java b/branches/sca-java-0.91/modules/http-jetty/src/test/java/org/apache/tuscany/sca/http/jetty/JettyServerTestCase.java
new file mode 100644
index 0000000000..d540e9514e
--- /dev/null
+++ b/branches/sca-java-0.91/modules/http-jetty/src/test/java/org/apache/tuscany/sca/http/jetty/JettyServerTestCase.java
@@ -0,0 +1,254 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.http.jetty;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.ConnectException;
+import java.net.Socket;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.http.DefaultResourceServlet;
+import org.apache.tuscany.sca.work.NotificationListener;
+import org.apache.tuscany.sca.work.WorkScheduler;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JettyServerTestCase extends TestCase {
+
+ private static final String REQUEST1_HEADER =
+ "GET / HTTP/1.0\n" + "Host: localhost\n"
+ + "Content-Type: text/xml\n"
+ + "Connection: close\n"
+ + "Content-Length: ";
+ private static final String REQUEST1_CONTENT = "";
+ private static final String REQUEST1 =
+ REQUEST1_HEADER + REQUEST1_CONTENT.getBytes().length + "\n\n" + REQUEST1_CONTENT;
+
+ private static final String REQUEST2_HEADER =
+ "GET /webcontent/test.html HTTP/1.0\n" + "Host: localhost\n"
+ + "Content-Type: text/xml\n"
+ + "Connection: close\n"
+ + "Content-Length: ";
+ private static final String REQUEST2_CONTENT = "";
+ private static final String REQUEST2 =
+ REQUEST2_HEADER + REQUEST2_CONTENT.getBytes().length + "\n\n" + REQUEST2_CONTENT;
+
+ private static final int HTTP_PORT = 8085;
+
+ private WorkScheduler workScheduler = new WorkScheduler() {
+
+ public <T extends Runnable> void scheduleWork(T work) {
+ Thread thread = new Thread(work);
+ thread.start();
+ }
+
+ public <T extends Runnable> void scheduleWork(T work, NotificationListener<T> listener) {
+ scheduleWork(work);
+ }
+ };
+
+ /**
+ * Verifies requests are properly routed according to the servlet mapping
+ */
+ public void testRegisterServletMapping() throws Exception {
+ JettyServer service = new JettyServer(workScheduler);
+ service.init();
+ TestServlet servlet = new TestServlet();
+ service.addServletMapping("http://127.0.0.1:" + HTTP_PORT + "/", servlet);
+ Socket client = new Socket("127.0.0.1", HTTP_PORT);
+ OutputStream os = client.getOutputStream();
+ os.write(REQUEST1.getBytes());
+ os.flush();
+ read(client);
+ service.destroy();
+ assertTrue(servlet.invoked);
+ }
+
+ public void testUnregisterMapping() throws Exception {
+ JettyServer service = new JettyServer(workScheduler);
+ service.init();
+ TestServlet servlet = new TestServlet();
+ String uri = "http://127.0.0.1:" + HTTP_PORT + "/foo";
+ service.addServletMapping(uri, servlet);
+ service.removeServletMapping(uri);
+ Socket client = new Socket("127.0.0.1", HTTP_PORT);
+ OutputStream os = client.getOutputStream();
+ os.write(REQUEST1.getBytes());
+ os.flush();
+ read(client);
+ service.destroy();
+ assertFalse(servlet.invoked);
+ }
+
+ public void testRequestSession() throws Exception {
+ JettyServer service = new JettyServer(workScheduler);
+ service.setDebug(true);
+ service.init();
+ TestServlet servlet = new TestServlet();
+ service.addServletMapping("http://127.0.0.1:" + HTTP_PORT + "/", servlet);
+ Socket client = new Socket("127.0.0.1", HTTP_PORT);
+ OutputStream os = client.getOutputStream();
+ os.write(REQUEST1.getBytes());
+ os.flush();
+ read(client);
+ service.destroy();
+ assertTrue(servlet.invoked);
+ assertNotNull(servlet.sessionId);
+ }
+
+ public void testRestart() throws Exception {
+ JettyServer service = new JettyServer(workScheduler);
+ service.init();
+ service.destroy();
+ service.init();
+ service.destroy();
+ }
+
+ public void testNoMappings() throws Exception {
+ JettyServer service = new JettyServer(workScheduler);
+ service.init();
+ Exception ex = null;
+ try {
+ new Socket("127.0.0.1", HTTP_PORT);
+ } catch (ConnectException e) {
+ ex = e;
+ }
+ assertNotNull(ex);
+ service.destroy();
+ }
+
+ public void testResourceServlet() throws Exception {
+ JettyServer service = new JettyServer(workScheduler);
+ service.init();
+
+ String documentRoot = getClass().getClassLoader().getResource("content/test.html").toString();
+ documentRoot = documentRoot.substring(0, documentRoot.lastIndexOf('/'));
+ DefaultResourceServlet resourceServlet = new DefaultResourceServlet(documentRoot);
+ TestResourceServlet servlet = new TestResourceServlet(resourceServlet);
+ service.addServletMapping("http://127.0.0.1:" + HTTP_PORT + "/webcontent/*", servlet);
+
+ Socket client = new Socket("127.0.0.1", HTTP_PORT);
+ OutputStream os = client.getOutputStream();
+ os.write(REQUEST2.getBytes());
+ os.flush();
+
+ String document = read(client);
+ assertTrue(document.indexOf("<body><p>hello</body>") != -1);
+
+ service.destroy();
+ }
+
+ public void testDefaultServlet() throws Exception {
+ JettyServer service = new JettyServer(workScheduler);
+ service.init();
+
+ String documentRoot = getClass().getClassLoader().getResource("content/test.html").toString();
+ documentRoot = documentRoot.substring(0, documentRoot.lastIndexOf('/'));
+ DefaultResourceServlet resourceServlet = new DefaultResourceServlet(documentRoot);
+ service.addServletMapping("http://127.0.0.1:" + HTTP_PORT + "/webcontent/*", resourceServlet);
+
+ Socket client = new Socket("127.0.0.1", HTTP_PORT);
+ OutputStream os = client.getOutputStream();
+ os.write(REQUEST2.getBytes());
+ os.flush();
+
+ String document = read(client);
+ assertTrue(document.indexOf("<body><p>hello</body>") != -1);
+
+ service.destroy();
+ }
+
+ private static String read(Socket socket) throws IOException {
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+ StringBuffer sb = new StringBuffer();
+ String str;
+ while ((str = reader.readLine()) != null) {
+ sb.append(str);
+ }
+ return sb.toString();
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+ }
+
+ private class TestServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+ boolean invoked;
+ String sessionId;
+
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ invoked = true;
+ sessionId = req.getSession().getId();
+ OutputStream writer = resp.getOutputStream();
+ try {
+ writer.write("result".getBytes());
+ } finally {
+ writer.close();
+ }
+ }
+
+ }
+
+ private class TestResourceServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+ private HttpServlet delegate;
+
+ public TestResourceServlet(HttpServlet delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void init() throws ServletException {
+ super.init();
+ delegate.init();
+ }
+
+ @Override
+ public void init(ServletConfig config) throws ServletException {
+ super.init();
+ delegate.init(config);
+ }
+
+ @Override
+ protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ delegate.service(req, resp);
+ }
+
+ @Override
+ public void destroy() {
+ super.destroy();
+ delegate.destroy();
+ }
+ }
+}
diff --git a/branches/sca-java-0.91/modules/http-jetty/src/test/resources/content/test.html b/branches/sca-java-0.91/modules/http-jetty/src/test/resources/content/test.html
new file mode 100644
index 0000000000..f4b79d7f01
--- /dev/null
+++ b/branches/sca-java-0.91/modules/http-jetty/src/test/resources/content/test.html
@@ -0,0 +1,21 @@
+<html>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<body><p>hello</body>
+</html> \ No newline at end of file