
org.jboss.test.faces.jetty.JettyServer Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
* Copyright 2010, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.test.faces.jetty;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.EventListener;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.jboss.test.faces.ApplicationServer;
import org.jboss.test.faces.FilterHolder;
import org.jboss.test.faces.ServletHolder;
import org.jboss.test.faces.TestException;
import org.jboss.test.faces.staging.HttpConnection;
import org.jboss.test.faces.staging.ServerResourcePath;
import org.jboss.test.faces.staging.StaggingJspApplicationContext;
import org.mortbay.jetty.Handler;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.handler.DefaultHandler;
import org.mortbay.jetty.handler.HandlerList;
import org.mortbay.jetty.servlet.DefaultServlet;
import org.mortbay.jetty.webapp.WebAppContext;
import org.mortbay.resource.Resource;
/**
* @author Nick Belaevski
*
*/
public class JettyServer extends ApplicationServer {
private final class JettyConnection extends HttpConnection {
private final URL url;
private String requestContentType;
private String requestEncoding="UTF-8";
private String requestBody;
private final HttpClient client;
private HttpMethodBase httpClientMethod;
private int statusCode;
private Map requestHeaders = new HashMap();
public JettyConnection(URL url) {
client = new HttpClient();
// TODO set default values for host, port, protocol.
this.url = url;
}
@Override
public void start() {
throw new UnsupportedOperationException("Jetty server does not allow in-process requests");
}
@Override
public void setRequestContentType(String contentType) {
this.requestContentType = contentType;
}
@Override
public void setRequestCharacterEncoding(String charset) throws UnsupportedEncodingException {
this.requestEncoding = charset;
}
@Override
public void setRequestBody(String body) {
this.requestBody = body;
}
@Override
public boolean isStarted() {
return null != httpClientMethod;
}
@Override
public boolean isFinished() {
return null != httpClientMethod && httpClientMethod.isRequestSent();
}
@Override
public int getResponseStatus() {
return statusCode;
}
@Override
public Map getResponseHeaders() {
Header[] headers = httpClientMethod.getResponseHeaders();
HashMap map = new HashMap(headers.length);
for (Header header : headers) {
map.put(header.getName(), new String[]{header.getValue()});
}
return map;
}
@Override
public String getResponseContentType() {
Header responseHeader = httpClientMethod.getResponseHeader("Content-Type");
return null!=responseHeader?responseHeader.getValue():null;
}
@Override
public long getResponseContentLength() {
return httpClientMethod.getResponseContentLength();
}
@Override
public String getResponseCharacterEncoding() {
return httpClientMethod.getResponseCharSet();
}
@Override
public byte[] getResponseBody() {
try {
return httpClientMethod.getResponseBody();
} catch (IOException e) {
throw new TestException(e);
}
}
@Override
public HttpServletResponse getResponse() {
throw new UnsupportedOperationException("Jetty server does not allow in-process requests");
}
@Override
public HttpServletRequest getRequest() {
throw new UnsupportedOperationException("Jetty server does not allow in-process requests");
}
@Override
public String getErrorMessage() {
return httpClientMethod.getStatusText();
}
@Override
public String getContentAsString() {
try {
return httpClientMethod.getResponseBodyAsString();
} catch (IOException e) {
throw new TestException(e);
}
}
@Override
public void finish() {
if(null != httpClientMethod){
httpClientMethod.releaseConnection();
}
}
@Override
public void execute() {
switch (getRequestMethod()) {
case GET:
this.httpClientMethod = new GetMethod(url.toExternalForm());
break;
case POST:
PostMethod postMethod = new PostMethod(url.toExternalForm());
if(null != requestBody){
try {
RequestEntity body = new StringRequestEntity(requestBody,requestContentType,requestEncoding);
postMethod.setRequestEntity(body);
} catch (UnsupportedEncodingException e) {
throw new TestException(e);
}
}
this.httpClientMethod = postMethod;
break;
default:
throw new UnsupportedOperationException("Http Method "+getRequestMethod()+" is not supported");
}
String queryString = getRequestQueryString();
try {
if (null != queryString) {
httpClientMethod.setQueryString(queryString);
}
for (Map.Entry entry : requestHeaders.entrySet()) {
httpClientMethod.addRequestHeader(entry.getKey(), entry.getValue());
}
// TODO - add parameters to request.
this.statusCode = client.executeMethod(httpClientMethod);
} catch (IOException e) {
throw new TestException(e);
}
}
@Override
public void addRequestHeaders(Map headers) {
requestHeaders.putAll(headers);
}
@Override
protected String getRequestCharacterEncoding() {
return requestEncoding;
}
}
private static final String WEB_XML = "/WEB-INF/web.xml";
private static final String DUMMY_WEB_XML = "org/jboss/test/faces/jetty/dummy/web.xml";
private static final int DEFAULT_PORT = 8880;
private int port;
private Server server;
private WebAppContext webAppContext;
private VirtualDirectoryResource serverRoot = new VirtualDirectoryResource("");
private HttpSession session;
public JettyServer() {
this(DEFAULT_PORT);
}
public JettyServer(int port) {
this.port = port;
createContext();
}
private ClassLoader getClassLoader() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader == null) {
classLoader = getClass().getClassLoader();
}
return classLoader;
}
private void createContext() {
webAppContext = new WebAppContext();
webAppContext.setContextPath("/");
webAppContext.setBaseResource(serverRoot);
webAppContext.setClassLoader(getClassLoader());
org.mortbay.jetty.servlet.ServletHolder defaultServletHolder =
new org.mortbay.jetty.servlet.ServletHolder(new DefaultServlet());
//defaultServletHolder.setInitParameter("aliases", Boolean.FALSE.toString());
webAppContext.addServlet(defaultServletHolder, "/");
webAppContext.addEventListener(new HttpSessionListener() {
public void sessionDestroyed(HttpSessionEvent se) {
session = null;
}
public void sessionCreated(HttpSessionEvent se) {
session = se.getSession();
}
});
}
private boolean isClassAvailable(String elFactoryClass) {
try {
Class.forName(elFactoryClass);
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
@Override
public void init() {
server = new Server(port);
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { webAppContext, new DefaultHandler() });
server.setHandler(handlers);
// Try to register EL Expression factory explicitly, because we does not use JSF.
if(isClassAvailable(StaggingJspApplicationContext.SUN_EXPRESSION_FACTORY)){
addInitParameter(StaggingJspApplicationContext.FACES_EXPRESSION_FACTORY, StaggingJspApplicationContext.SUN_EXPRESSION_FACTORY);
} else if(isClassAvailable(StaggingJspApplicationContext.JBOSS_EXPRESSION_FACTORY)){
addInitParameter(StaggingJspApplicationContext.FACES_EXPRESSION_FACTORY, StaggingJspApplicationContext.JBOSS_EXPRESSION_FACTORY);
}
//JSF initialization listener requires web.xml file, so add dummy web.xml if none was registered
Resource webXml;
try {
webXml = webAppContext.getResource(WEB_XML);
if (webXml == null || !webXml.exists()) {
URL dummyWebXml = webAppContext.getClassLoader().getResource(DUMMY_WEB_XML);
addResource(WEB_XML, dummyWebXml);
}
} catch (MalformedURLException e1) {
//ignore
}
try {
server.start();
server.setStopAtShutdown(true);
} catch (Exception e) {
throw new TestException(e.getMessage(), e);
}
}
@Override
public void destroy() {
try {
server.stop();
server.setStopAtShutdown(false);
server.destroy();
} catch (Exception e) {
throw new TestException(e.getMessage(), e);
} finally {
session = null;
server = null;
}
}
@Override
@SuppressWarnings("unchecked")
public void addInitParameter(String name, String value) {
webAppContext.getInitParams().put(name, value);
}
@Override
public void addWebListener(EventListener listener) {
webAppContext.addEventListener(listener);
}
@Override
public ServletContext getContext() {
if (!webAppContext.isStarted()) {
throw new IllegalStateException("Server should be started before getContext() can be called!");
}
return webAppContext.getServletContext();
}
@Override
public void addMimeType(String extension, String mimeType) {
webAppContext.getMimeTypes().addMimeMapping(extension, mimeType);
}
@Override
public void addContent(String path, String content) {
serverRoot.addResource(path, new StringContentResource(content, path));
}
@Override
public void addResource(String path, String resource) {
serverRoot.addResource(path, Resource.newClassPathResource(resource));
}
@Override
public void addResource(String path, URL resource) {
try {
serverRoot.addResource(path, Resource.newResource(resource));
} catch (IOException e) {
throw new TestException(e.getMessage(), e);
}
}
@Override
public void addFilter(FilterHolder filerHolder) {
Map initParameters = filerHolder.getInitParameters();
String mapping = filerHolder.getMapping();
String name = filerHolder.getName();
Filter filter = filerHolder.getFilter();
org.mortbay.jetty.servlet.FilterHolder jettyFilterHolder = new org.mortbay.jetty.servlet.FilterHolder(filter);
jettyFilterHolder.setName(name);
jettyFilterHolder.setInitParameters(initParameters);
webAppContext.addFilter(jettyFilterHolder, mapping, Handler.ALL);
}
@Override
public void addServlet(ServletHolder servletHolder) {
Map initParameters = servletHolder.getInitParameters();
String mapping = servletHolder.getMapping();
String name = servletHolder.getName();
Servlet servlet = servletHolder.getServlet();
org.mortbay.jetty.servlet.ServletHolder jettyServletHolder = new org.mortbay.jetty.servlet.ServletHolder(
servlet);
jettyServletHolder.setName(name);
jettyServletHolder.setInitParameters(initParameters);
webAppContext.addServlet(jettyServletHolder, mapping);
}
@Override
public int getPort() {
return port;
}
@Override
public HttpConnection getConnection(URL url) {
return new JettyConnection(url);
}
@Override
public HttpSession getSession() {
return getSession(true);
}
@Override
public HttpSession getSession(boolean create) {
if (session == null && create) {
throw new UnsupportedOperationException("Session creation is not supported by JettyServer");
}
return session;
}
@Override
public boolean isSessionPerThread() {
return false;
}
@Override
public void setSessionPerThread(boolean sessionPerThread) {
//do nothing
}
@Override
protected void addDirectory(String directoryPath) {
serverRoot.createChildDirectory(new ServerResourcePath(directoryPath));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy