summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main')
-rw-r--r--sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyDefaultServlet.java91
-rw-r--r--sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyLogger.java87
-rw-r--r--sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyServer.java345
-rw-r--r--sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/module/JettyRuntimeModuleActivator.java49
-rw-r--r--sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator18
5 files changed, 590 insertions, 0 deletions
diff --git a/sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyDefaultServlet.java b/sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyDefaultServlet.java
new file mode 100644
index 0000000000..d328ee7ae0
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyDefaultServlet.java
@@ -0,0 +1,91 @@
+/*
+ * 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.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.mortbay.jetty.servlet.DefaultServlet;
+import org.mortbay.resource.Resource;
+import org.mortbay.resource.URLResource;
+
+/**
+ * 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 = "";
+ }
+ } else {
+ if ((pathInContext + "/").equals(servletPath)) {
+ pathInContext = "";
+ }
+ }
+
+ try {
+ URL url = new URL(documentRoot + "/" + pathInContext);
+ return new URLResource(url, url.openConnection()) {
+ private static final long serialVersionUID = 8560952113883507717L;
+
+ @Override
+ public File getFile() throws IOException {
+ return null;
+ }
+
+ };
+ } catch (MalformedURLException e) {
+ return null;
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public String getInitParameter(String name) {
+ if ("resourceBase".equals(name)) {
+ return documentRoot;
+ } else if ("redirectWelcome".equals(name)) {
+ return "true";
+ } else {
+ return super.getInitParameter(name);
+ }
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyLogger.java b/sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyLogger.java
new file mode 100644
index 0000000000..1ecf1bca1b
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.0/modules/host-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/sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyServer.java b/sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyServer.java
new file mode 100644
index 0000000000..51d41e11c5
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/JettyServer.java
@@ -0,0 +1,345 @@
+/*
+ * 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.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.logging.Logger;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+
+import org.apache.tuscany.sca.host.http.DefaultResourceServlet;
+import org.apache.tuscany.sca.host.http.ServletHost;
+import org.apache.tuscany.sca.host.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.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 final static Logger logger = Logger.getLogger(JettyServer.class.getName());
+ private static final String ROOT = "/";
+ private static final int DEFAULT_PORT = 8080;
+
+ private final Object joinLock = new Object();
+ private String keystore;
+ private String certPassword;
+ private String keyPassword;
+ private boolean sendServerVersion;
+ private WorkScheduler workScheduler;
+
+ /**
+ * Represents a port and the server that serves it.
+ */
+ private class Port {
+ private Server server;
+ private ServletHandler servletHandler;
+
+ private Port(Server server, ServletHandler servletHandler) {
+ this.server = server;
+ this.servletHandler = servletHandler;
+ }
+
+ public Server getServer() {
+ return server;
+ }
+
+ public ServletHandler getServletHandler() {
+ return servletHandler;
+ }
+ }
+
+ private Map<Integer, Port> ports = new HashMap<Integer, Port>();
+
+ static {
+ // Hack to replace the static Jetty logger
+ System.setProperty("org.mortbay.log.class", JettyLogger.class.getName());
+ }
+
+ public JettyServer(WorkScheduler workScheduler) {
+ this.workScheduler = workScheduler;
+ }
+
+ public void setSendServerVersion(boolean sendServerVersion) {
+ this.sendServerVersion = sendServerVersion;
+ }
+
+ public void setKeystore(String keystore) {
+ this.keystore = keystore;
+ }
+
+ public void setCertPassword(String certPassword) {
+ this.certPassword = certPassword;
+ }
+
+ public void setKeyPassword(String keyPassword) {
+ this.keyPassword = keyPassword;
+ }
+
+ /**
+ * Stop all the started servers.
+ */
+ public void stop() {
+ if (!ports.isEmpty()) {
+ synchronized (joinLock) {
+ joinLock.notifyAll();
+ }
+ try {
+ Set<Entry<Integer, Port>> entries = new HashSet<Entry<Integer, Port>>(ports.entrySet());
+ for (Entry<Integer, Port> entry: entries) {
+ entry.getValue().getServer().stop();
+ ports.remove(entry.getKey());
+ }
+ } catch (Exception e) {
+ throw new ServletMappingException(e);
+ }
+ }
+ }
+
+ public void addServletMapping(String suri, Servlet servlet) throws ServletMappingException {
+ URI uri = URI.create(suri);
+
+ // Get the URI scheme and port
+ String scheme = uri.getScheme();
+ if (scheme == null) {
+ scheme = "http";
+ }
+ int portNumber = uri.getPort();
+ if (portNumber == -1) {
+ portNumber = DEFAULT_PORT;
+ }
+
+ // Get the port object associated with the given port number
+ Port port = ports.get(portNumber);
+ if (port == null) {
+
+ // Create and start a new server
+ try {
+ Server server = new Server();
+ server.setThreadPool(new WorkSchedulerThreadPool());
+ if ("https".equals(scheme)) {
+ Connector httpConnector = new SelectChannelConnector();
+ httpConnector.setPort(portNumber);
+ SslSocketConnector sslConnector = new SslSocketConnector();
+ sslConnector.setPort(portNumber);
+ sslConnector.setKeystore(keystore);
+ sslConnector.setPassword(certPassword);
+ sslConnector.setKeyPassword(keyPassword);
+ server.setConnectors(new Connector[] {httpConnector, sslConnector});
+ } else {
+ SelectChannelConnector selectConnector = new SelectChannelConnector();
+ selectConnector.setPort(portNumber);
+ server.setConnectors(new Connector[] {selectConnector});
+ }
+
+ ContextHandler contextHandler = new ContextHandler();
+ contextHandler.setContextPath(ROOT);
+ server.setHandler(contextHandler);
+
+ SessionHandler sessionHandler = new SessionHandler();
+ ServletHandler servletHandler = new ServletHandler();
+ sessionHandler.addHandler(servletHandler);
+
+ contextHandler.setHandler(sessionHandler);
+
+ server.setStopAtShutdown(true);
+ server.setSendServerVersion(sendServerVersion);
+ server.start();
+
+ // Keep track of the new server and servlet handler
+ port = new Port(server, servletHandler);
+ ports.put(portNumber, port);
+
+ } catch (Exception e) {
+ throw new ServletMappingException(e);
+ }
+ }
+
+ // Register the servlet mapping
+ ServletHandler servletHandler = port.getServletHandler();
+ 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);
+ }
+ if (!servletPath.startsWith("/")) {
+ servletPath = '/' + servletPath;
+ }
+ 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();
+ if (!path.startsWith("/")) {
+ path = '/' + path;
+ }
+ mapping.setPathSpec(path);
+ servletHandler.addServletMapping(mapping);
+
+ URI addedURI = URI.create(scheme + "://localhost:" + portNumber + path);
+ logger.info("Added Servlet mapping: " + addedURI);
+ }
+
+ public Servlet getServletMapping(String suri) throws ServletMappingException {
+ URI uri = URI.create(suri);
+
+ // Get the URI port
+ int portNumber = uri.getPort();
+ if (portNumber == -1) {
+ portNumber = DEFAULT_PORT;
+ }
+
+ // Get the port object associated with the given port number
+ Port port = ports.get(portNumber);
+ if (port == null) {
+ return null;
+ }
+
+ // Remove the servlet mapping for the given servlet
+ ServletHandler servletHandler = port.getServletHandler();
+ Servlet servlet = null;
+ List<ServletMapping> mappings =
+ new ArrayList<ServletMapping>(Arrays.asList(servletHandler.getServletMappings()));
+ String path = uri.getPath();
+ for (ServletMapping mapping : mappings) {
+ if (Arrays.asList(mapping.getPathSpecs()).contains(path)) {
+ try {
+ servlet = servletHandler.getServlet(mapping.getServletName()).getServlet();
+ } catch (ServletException e) {
+ throw new IllegalStateException(e);
+ }
+ break;
+ }
+ }
+ return servlet;
+ }
+
+ public Servlet removeServletMapping(String suri) {
+ URI uri = URI.create(suri);
+
+ // Get the URI port
+ int portNumber = uri.getPort();
+ if (portNumber == -1) {
+ portNumber = DEFAULT_PORT;
+ }
+
+ // Get the port object associated with the given port number
+ Port port = ports.get(portNumber);
+ if (port == null) {
+ throw new IllegalStateException("No servlet registered at this URI: " + suri);
+ }
+
+ // Remove the servlet mapping for the given servlet
+ ServletHandler servletHandler = port.getServletHandler();
+ Servlet removedServlet = null;
+ List<ServletMapping> mappings =
+ new ArrayList<ServletMapping>(Arrays.asList(servletHandler.getServletMappings()));
+ String path = 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(mappings.toArray(new ServletMapping[mappings.size()]));
+ }
+ return removedServlet;
+ }
+
+ public RequestDispatcher getRequestDispatcher(String suri) throws ServletMappingException {
+ //FIXME implement this later
+ return null;
+ }
+
+ public String getContextPath() {
+ return ROOT;
+ }
+
+ /**
+ * A wrapper to enable use of a 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() {
+ return false;
+ }
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/module/JettyRuntimeModuleActivator.java b/sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/module/JettyRuntimeModuleActivator.java
new file mode 100644
index 0000000000..11b8a269ab
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/java/org/apache/tuscany/sca/http/jetty/module/JettyRuntimeModuleActivator.java
@@ -0,0 +1,49 @@
+/*
+ * 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.host.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 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);
+ }
+
+ public void stop(ExtensionPointRegistry registry) {
+ server.stop();
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator b/sca-java-1.x/branches/sca-java-1.0/modules/host-jetty/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator
new file mode 100644
index 0000000000..f61708de90
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.0/modules/host-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