Author: dblevins Date: Tue Apr 5 00:58:42 2005 New Revision: 160139 URL: http://svn.apache.org/viewcvs?view=rev&rev=160139 Log: Rewritten POJO WebService implementation including ServiceLifecycle support.
Added: geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/POJOWebServiceServlet.java geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/ServiceLifecycleManager.java geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/WebServiceContainerInvoker.java Modified: geronimo/trunk/modules/axis/src/java/org/apache/geronimo/axis/server/AxisWebServiceContainer.java geronimo/trunk/modules/axis/src/java/org/apache/geronimo/axis/server/POJOProvider.java geronimo/trunk/modules/axis/src/test/org/apache/geronimo/axis/AxisRequest.java geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyEJBWebServiceContext.java geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyPOJOWebServiceHolder.java Modified: geronimo/trunk/modules/axis/src/java/org/apache/geronimo/axis/server/AxisWebServiceContainer.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/axis/src/java/org/apache/geronimo/axis/server/AxisWebServiceContainer.java?view=diff&r1=160138&r2=160139 ============================================================================== --- geronimo/trunk/modules/axis/src/java/org/apache/geronimo/axis/server/AxisWebServiceContainer.java (original) +++ geronimo/trunk/modules/axis/src/java/org/apache/geronimo/axis/server/AxisWebServiceContainer.java Tue Apr 5 00:58:42 2005 @@ -54,12 +54,16 @@ * @version $Rev$ $Date$ */ public class AxisWebServiceContainer implements WebServiceContainer { + public static final String REQUEST = AxisWebServiceContainer.class.getName()+"@Request"; + public static final String RESPONSE = AxisWebServiceContainer.class.getName()+"@Response"; + private static Log log = LogFactory.getLog(AxisWebServiceContainer.class); public static final String XSD_NS = "http://www.w3.org/2001/XMLSchema"; - protected final URI location; - protected final URL wsdlURL; - protected final SOAPService service; //TODO why did i make these protected? + + private final URI location; + private final URL wsdlURL; + private final SOAPService service; private final ClassLoader classLoader; private final Byte wsdlMutext = new Byte((byte)0); @@ -75,6 +79,8 @@ public void invoke(Request req, Response res) throws Exception { org.apache.axis.MessageContext context = new org.apache.axis.MessageContext(null); + req.setAttribute(MESSAGE_CONTEXT, context); + context.setClassLoader(classLoader); Message responseMessage = null; @@ -88,6 +94,8 @@ context.setProperty(HTTPConstants.MC_HTTP_SERVLETPATHINFO, req.getURI().getPath()); context.setProperty(org.apache.axis.MessageContext.TRANS_URL, req.getURI().toString()); context.setService(service); + context.setProperty(REQUEST, req); + context.setProperty(RESPONSE, res); try { String characterEncoding = (String) requestMessage.getProperty(SOAPMessage.CHARACTER_SET_ENCODING); Modified: geronimo/trunk/modules/axis/src/java/org/apache/geronimo/axis/server/POJOProvider.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/axis/src/java/org/apache/geronimo/axis/server/POJOProvider.java?view=diff&r1=160138&r2=160139 ============================================================================== --- geronimo/trunk/modules/axis/src/java/org/apache/geronimo/axis/server/POJOProvider.java (original) +++ geronimo/trunk/modules/axis/src/java/org/apache/geronimo/axis/server/POJOProvider.java Tue Apr 5 00:58:42 2005 @@ -21,18 +21,17 @@ import org.apache.axis.providers.java.RPCProvider; import org.apache.axis.MessageContext; import org.apache.axis.Handler; +import org.apache.geronimo.webservices.WebServiceContainer; /** * @version $Rev$ $Date$ */ public class POJOProvider extends RPCProvider { - private final Class pojoClass; - - public POJOProvider(Class pojoClass) { - this.pojoClass = pojoClass; + public POJOProvider() { } public Object getServiceObject(MessageContext msgContext, Handler service, String clsName, IntHolder scopeHolder) throws Exception { - return pojoClass.newInstance(); + WebServiceContainer.Request request = (WebServiceContainer.Request) msgContext.getProperty(AxisWebServiceContainer.REQUEST); + return request.getAttribute(WebServiceContainer.POJO_INSTANCE); } } Modified: geronimo/trunk/modules/axis/src/test/org/apache/geronimo/axis/AxisRequest.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/axis/src/test/org/apache/geronimo/axis/AxisRequest.java?view=diff&r1=160138&r2=160139 ============================================================================== --- geronimo/trunk/modules/axis/src/test/org/apache/geronimo/axis/AxisRequest.java (original) +++ geronimo/trunk/modules/axis/src/test/org/apache/geronimo/axis/AxisRequest.java Tue Apr 5 00:58:42 2005 @@ -3,6 +3,7 @@ import java.io.InputStream; import java.net.URI; import java.util.Map; +import java.util.HashMap; import org.apache.geronimo.webservices.WebServiceContainer; @@ -14,6 +15,7 @@ private Map parameters; private URI uri; private Map headers; + private Map attributes; /** * @@ -32,6 +34,7 @@ this.parameters = parameters; this.uri = uri; this.headers = headers; + this.attributes = new HashMap(); } public int getContentLength() { @@ -66,4 +69,11 @@ return uri; } + public Object getAttribute(String name) { + return attributes.get(name); + } + + public void setAttribute(String name, Object value){ + attributes.put(name, value); + } } Modified: geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyEJBWebServiceContext.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyEJBWebServiceContext.java?view=diff&r1=160138&r2=160139 ============================================================================== --- geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyEJBWebServiceContext.java (original) +++ geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyEJBWebServiceContext.java Tue Apr 5 00:58:42 2005 @@ -162,6 +162,14 @@ return request.getParameters(); } + public Object getAttribute(String name) { + return request.getAttribute(name); + } + + public void setAttribute(String name, Object value){ + request.setAttribute(name, value); + } + private static final Map methods = new HashMap(); Modified: geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyPOJOWebServiceHolder.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyPOJOWebServiceHolder.java?view=diff&r1=160138&r2=160139 ============================================================================== --- geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyPOJOWebServiceHolder.java (original) +++ geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyPOJOWebServiceHolder.java Tue Apr 5 00:58:42 2005 @@ -16,32 +16,25 @@ */ package org.apache.geronimo.jetty; -import java.io.*; +import java.io.IOException; +import java.util.Collections; import java.util.Map; import java.util.Set; -import java.util.Collections; -import java.security.SignedObject; -import java.security.PrivateKey; -import java.security.Signature; -import java.security.InvalidKeyException; -import java.security.SignatureException; -import java.security.PublicKey; import javax.security.jacc.PolicyContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.UnavailableException; -import javax.servlet.Servlet; -import javax.servlet.ServletConfig; -import javax.crypto.SealedObject; +import javax.servlet.ServletContext; import org.apache.geronimo.gbean.GBeanInfo; import org.apache.geronimo.gbean.GBeanInfoBuilder; import org.apache.geronimo.gbean.GBeanLifecycle; import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; -import org.apache.geronimo.webservices.WebServiceContainer; -import org.apache.geronimo.kernel.ObjectInputStreamExt; import org.apache.geronimo.kernel.StoredObject; +import org.apache.geronimo.webservices.WebServiceContainer; +import org.apache.geronimo.webservices.POJOWebServiceServlet; +import org.apache.geronimo.webservices.WebServiceContainerInvoker; import org.mortbay.jetty.servlet.ServletHolder; import org.mortbay.jetty.servlet.ServletHttpRequest; @@ -53,35 +46,38 @@ * @version $Rev: 154436 $ $Date: 2005-02-19 10:22:02 -0800 (Sat, 19 Feb 2005) $ */ public class JettyPOJOWebServiceHolder extends ServletHolder implements GBeanLifecycle { - private WebServiceContainer webServiceContainer; private StoredObject storedWebServiceContainer; - private ClassLoader webClassLoader; + private Set servletMappings; + private Map webRoleRefPermissions; + private JettyServletRegistration context; + private String pojoClassName; //todo consider interface instead of this constructor for endpoint use. public JettyPOJOWebServiceHolder() { } - public JettyPOJOWebServiceHolder(String servletName, - Map initParams, - Integer loadOnStartup, - Set servletMappings, - Map webRoleRefPermissions, - StoredObject storedWebServiceContainer, - JettyServletRegistration context) throws Exception { - super(context == null? null: context.getServletHandler(), servletName, POJOWebServiceServlet.class.getName(), null); + public JettyPOJOWebServiceHolder(String pojoClassName, + String servletName, + Map initParams, + Integer loadOnStartup, + Set servletMappings, + Map webRoleRefPermissions, + StoredObject storedWebServiceContainer, + JettyServletRegistration context) throws Exception { + super(context == null ? null : context.getServletHandler(), servletName, POJOWebServiceServlet.class.getName(), null); //context will be null only for use as "default servlet info holder" in deployer. + this.pojoClassName = pojoClassName; + this.context = context; this.storedWebServiceContainer = storedWebServiceContainer; if (context != null) { - this.webClassLoader = context.getWebClassLoader(); putAll(initParams); if (loadOnStartup != null) { setInitOrder(loadOnStartup.intValue()); } - //this now starts the servlet in the appropriate context - context.registerServletHolder(this, servletName, servletMappings, webRoleRefPermissions == null? Collections.EMPTY_MAP: webRoleRefPermissions); -// start(); + this.servletMappings = servletMappings; + this.webRoleRefPermissions = webRoleRefPermissions == null ? Collections.EMPTY_MAP : webRoleRefPermissions; } } @@ -100,7 +96,7 @@ throws ServletException, UnavailableException, IOException { // TODO There has to be some way to get this in on the Servlet's init method. - request.setAttribute(POJOWebServiceServlet.WEBSERVICE_CONTAINER, webServiceContainer); +// request.setAttribute(POJOWebServiceServlet.WEBSERVICE_CONTAINER, webServiceContainer); JettyServletHolder.currentServletHolder.set(this); PolicyContext.setHandlerData(ServletHttpRequest.unwrap(request)); @@ -114,7 +110,8 @@ GBeanInfoBuilder infoBuilder = new GBeanInfoBuilder(JettyPOJOWebServiceHolder.class, NameFactory.SERVLET_WEB_SERVICE_TEMPLATE); //todo replace with interface infoBuilder.addInterface(ServletHolder.class); - + + infoBuilder.addAttribute("pojoClassName", String.class, true); infoBuilder.addAttribute("servletName", String.class, true); infoBuilder.addAttribute("initParams", Map.class, true); infoBuilder.addAttribute("loadOnStartup", Integer.class, true); @@ -123,13 +120,14 @@ infoBuilder.addAttribute("webServiceContainer", StoredObject.class, true); infoBuilder.addReference("JettyServletRegistration", JettyServletRegistration.class); - infoBuilder.setConstructor(new String[] {"servletName", - "initParams", - "loadOnStartup", - "servletMappings", - "webRoleRefPermissions", - "webServiceContainer", - "JettyServletRegistration"}); + infoBuilder.setConstructor(new String[]{"pojoClassName", + "servletName", + "initParams", + "loadOnStartup", + "servletMappings", + "webRoleRefPermissions", + "webServiceContainer", + "JettyServletRegistration"}); GBEAN_INFO = infoBuilder.getBeanInfo(); } @@ -139,8 +137,31 @@ } public void doStart() throws Exception { - if (webClassLoader != null){ - webServiceContainer = (WebServiceContainer) storedWebServiceContainer.getObject(webClassLoader); + if (context != null) { + + Class pojoClass = context.getWebClassLoader().loadClass(pojoClassName); + WebServiceContainer webServiceContainer = (WebServiceContainer) storedWebServiceContainer.getObject(context.getWebClassLoader()); + + /* DMB: Hack! I really just want to override initServlet and give a reference of the WebServiceContainer to the servlet before we call init on it. + * But this will have to do instead.... + */ + ServletContext servletContext = this.context.getServletHandler().getServletContext(); + + // Make up an ID for the WebServiceContainer + // put a reference the ID in the init-params + // put the WebServiceContainer in the webapp context keyed by its ID + String webServicecontainerID = getServletName() + WebServiceContainerInvoker.WEBSERVICE_CONTAINER + webServiceContainer.hashCode(); + put(WebServiceContainerInvoker.WEBSERVICE_CONTAINER, webServicecontainerID); + servletContext.setAttribute(webServicecontainerID, webServiceContainer); + + // Same for the POJO Class + String pojoClassID = getServletName() + POJOWebServiceServlet.POJO_CLASS + pojoClass.hashCode(); + put(POJOWebServiceServlet.POJO_CLASS, pojoClassID); + servletContext.setAttribute(pojoClassID, pojoClass); + + //this now starts the servlet in the appropriate context + context.registerServletHolder(this, getServletName(), this.servletMappings, this.webRoleRefPermissions); +// start(); } } @@ -149,7 +170,6 @@ public void doFail() { } - } Added: geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/POJOWebServiceServlet.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/POJOWebServiceServlet.java?view=auto&rev=160139 ============================================================================== --- geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/POJOWebServiceServlet.java (added) +++ geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/POJOWebServiceServlet.java Tue Apr 5 00:58:42 2005 @@ -0,0 +1,95 @@ +/** + * + * Copyright 2004 The Apache Software Foundation + * + * Licensed 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.geronimo.webservices; + +import java.io.IOException; +import java.security.Principal; +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import javax.xml.rpc.ServiceException; +import javax.xml.rpc.handler.MessageContext; +import javax.xml.rpc.server.ServiceLifecycle; +import javax.xml.rpc.server.ServletEndpointContext; + +/** + * Delegates requests to a WebServiceContainer which is presumably for a POJO WebService + * Nothing stopping us from using this for EJBs or other types of webservices other than + * it is more than we need. EJB webservices use the JettyEJBWebServiceContext. + * <p/> + * From a 10,000 foot view the Jetty architecture has: + * Container -> Context -> Holder -> Servlet + * <p/> + * A Container has multiple Contexts, typically webapps + * A Context provides the JNDI, TX, and Security for the webapp and has many Holders + * A Holder simply wraps each Servlet + * <p/> + * The POJO Web Service architecture on Jetty looks like this: + * Container -> WebApp Context -> JettyPOJOWebServiceHolder -> POJOWebServiceServlet + * <p/> + * The EJB Web Service architecure, on the other hand, creates one Context for each EJB: + * Container -> JettyEJBWebServiceContext + * + * @version $Rev$ $Date$ + */ +public class POJOWebServiceServlet implements Servlet { + public static final String POJO_CLASS = POJOWebServiceServlet.class.getName()+"@pojoClassName"; + private Servlet stack; + + public void init(ServletConfig config) throws ServletException { + ServletContext context = config.getServletContext(); + + String pojoClassID = config.getInitParameter(POJO_CLASS); + Class pojoClass = (Class) context.getAttribute(pojoClassID); + + Object pojo; + try { + pojo = pojoClass.newInstance(); + } catch (Exception e) { + throw new ServletException("Unable to instantiate POJO WebService class: " + pojoClass.getName(), e); + } + + stack = new WebServiceContainerInvoker(pojo); + if (pojo instanceof ServiceLifecycle) { + stack = new ServiceLifecycleManager(stack,(ServiceLifecycle)pojo); + } + + + stack.init(config); + } + + public ServletConfig getServletConfig() { + return stack.getServletConfig(); + } + + public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { + stack.service(servletRequest, servletResponse); + } + + public String getServletInfo() { + return stack.getServletInfo(); + } + + public void destroy() { + stack.destroy(); + } +} Added: geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/ServiceLifecycleManager.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/ServiceLifecycleManager.java?view=auto&rev=160139 ============================================================================== --- geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/ServiceLifecycleManager.java (added) +++ geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/ServiceLifecycleManager.java Tue Apr 5 00:58:42 2005 @@ -0,0 +1,168 @@ +/** + * + * Copyright 2005 The Apache Software Foundation + * + * Licensed 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.geronimo.webservices; + +import java.io.IOException; +import java.security.Principal; +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import javax.xml.rpc.server.ServiceLifecycle; +import javax.xml.rpc.server.ServletEndpointContext; +import javax.xml.rpc.ServiceException; +import javax.xml.rpc.handler.MessageContext; + +/** + * @version $Rev$ $Date$ + */ +public class ServiceLifecycleManager implements Servlet { + + private final ServiceLifecycle managedService; + private final Servlet next; + + public ServiceLifecycleManager(Servlet next, ServiceLifecycle managedService) { + this.next = next; + this.managedService = managedService; + } + + public void init(ServletConfig config) throws ServletException { + next.init(config); + try { + managedService.init(new InstanceContext(config.getServletContext())); + } catch (ServiceException e) { + throw new ServletException("Unable to initialize ServiceEndpoint", e); + } + } + + public ServletConfig getServletConfig() { + return next.getServletConfig(); + } + + public String getServletInfo() { + return next.getServletInfo(); + } + + public void destroy() { + managedService.destroy(); + next.destroy(); + } + + public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { + ServletEndpointContext context = getContext(); + try { + endpointContext.set(new InvocationContext((HttpServletRequest) req)); + next.service(req, res); + } finally { + endpointContext.set(context); + } + } + + private static final DefaultContext DEFAULT_CONTEXT = new DefaultContext(); + + private static final ThreadLocal endpointContext = new ThreadLocal(); + + + private static ServletEndpointContext getContext() { + ServletEndpointContext context = (ServletEndpointContext) endpointContext.get(); + return context != null ? context : DEFAULT_CONTEXT; + } + + static class InstanceContext implements ServletEndpointContext { + private final ServletContext servletContext; + + public InstanceContext(ServletContext servletContext) { + this.servletContext = servletContext; + } + + public MessageContext getMessageContext() { + return getContext().getMessageContext(); + } + + public Principal getUserPrincipal() { + return getContext().getUserPrincipal(); + } + + public HttpSession getHttpSession() { + return getContext().getHttpSession(); + } + + public ServletContext getServletContext() { + return servletContext; + } + + public boolean isUserInRole(String s) { + return getContext().isUserInRole(s); + } + } + + static class InvocationContext implements ServletEndpointContext { + + private final HttpServletRequest request; + + public InvocationContext(HttpServletRequest request) { + this.request = request; + } + + public MessageContext getMessageContext() { + return (MessageContext) request.getAttribute(WebServiceContainer.MESSAGE_CONTEXT); + } + + public Principal getUserPrincipal() { + return request.getUserPrincipal(); + } + + public HttpSession getHttpSession() { + return request.getSession(); + } + + public ServletContext getServletContext() { + throw new IllegalAccessError("InstanceContext should never delegate this method."); + } + + public boolean isUserInRole(String s) { + return request.isUserInRole(s); + } + } + + static class DefaultContext implements ServletEndpointContext { + + public MessageContext getMessageContext() { + throw new IllegalStateException("Method cannot be called outside a request context"); + } + + public Principal getUserPrincipal() { + throw new IllegalStateException("Method cannot be called outside a request context"); + } + + public HttpSession getHttpSession() { + throw new javax.xml.rpc.JAXRPCException("Method cannot be called outside an http request context"); + } + + public ServletContext getServletContext() { + throw new IllegalAccessError("InstanceContext should never delegate this method."); + } + + public boolean isUserInRole(String s) { + throw new IllegalStateException("Method cannot be called outside a request context"); + } + } +} Added: geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/WebServiceContainerInvoker.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/WebServiceContainerInvoker.java?view=auto&rev=160139 ============================================================================== --- geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/WebServiceContainerInvoker.java (added) +++ geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/WebServiceContainerInvoker.java Tue Apr 5 00:58:42 2005 @@ -0,0 +1,208 @@ +/** + * + * Copyright 2004 The Apache Software Foundation + * + * Licensed 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.geronimo.webservices; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URISyntaxException; +import java.util.Map; +import java.util.HashMap; +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletContext; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @version $Rev$ $Date$ + */ +public class WebServiceContainerInvoker implements Servlet { + + public static final String WEBSERVICE_CONTAINER = WebServiceContainerInvoker.class.getName()+"@WebServiceContainer"; + + private final Object pojo; + private WebServiceContainer service; + + public WebServiceContainerInvoker(Object pojo) { + this.pojo = pojo; + } + + public void init(ServletConfig config) throws ServletException { + ServletContext context = config.getServletContext(); + String webServiceContainerID = config.getInitParameter(WEBSERVICE_CONTAINER); + service = (WebServiceContainer) context.getAttribute(webServiceContainerID); + } + + public ServletConfig getServletConfig() { + return null; + } + + public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { + res.setContentType("text/xml"); + RequestAdapter request = new RequestAdapter((HttpServletRequest) req); + ResponseAdapter response = new ResponseAdapter((HttpServletResponse) res); + + // This is the guy the WebServiceContainer should invoke + req.setAttribute(WebServiceContainer.POJO_INSTANCE, pojo); + + if (request.getParameter("wsdl") != null) { + try { + service.getWsdl(request, response); + } catch (IOException e) { + throw e; + } catch (ServletException e) { + throw e; + } catch (Exception e) { + throw new ServletException("Could not fetch wsdl!", e); + } + } else { + try { + service.invoke(request, response); + } catch (IOException e) { + throw e; + } catch (ServletException e) { + throw e; + } catch (Exception e) { + throw new ServletException("Could not process message!", e); + } + } + } + + public String getServletInfo() { + return null; + } + + public void destroy() { + } + + private static class RequestAdapter implements WebServiceContainer.Request { + private final HttpServletRequest request; + + public RequestAdapter(HttpServletRequest request) { + this.request = request; + } + + public String getHeader(String name) { + return request.getHeader(name); + } + + public java.net.URI getURI() { + try { + String uriString = request.getRequestURI(); + return new java.net.URI(uriString); + } catch (URISyntaxException e) { + throw new IllegalStateException(e.getMessage()); + } + } + + public int getContentLength() { + return request.getContentLength(); + } + + public String getContentType() { + return request.getContentType(); + } + + public InputStream getInputStream() throws IOException { + return request.getInputStream(); + } + + public int getMethod() { + Integer method = (Integer) methods.get(request.getMethod()); + return method == null ? UNSUPPORTED : method.intValue(); + } + + public String getParameter(String name) { + return request.getParameter(name); + } + + public Map getParameters() { + return request.getParameterMap(); + } + + + private static final Map methods = new HashMap(); + + static { + methods.put("OPTIONS", new Integer(OPTIONS)); + methods.put("GET", new Integer(GET)); + methods.put("HEAD", new Integer(HEAD)); + methods.put("POST", new Integer(POST)); + methods.put("PUT", new Integer(PUT)); + methods.put("DELETE", new Integer(DELETE)); + methods.put("TRACE", new Integer(TRACE)); + methods.put("CONNECT", new Integer(CONNECT)); + } + + public Object getAttribute(String s) { + return request.getAttribute(s); + } + + public void setAttribute(String s, Object o) { + request.setAttribute(s, o); + } + + } + + private static class ResponseAdapter implements WebServiceContainer.Response { + private final HttpServletResponse response; + + public ResponseAdapter(HttpServletResponse response) { + this.response = response; + } + + public void setHeader(String name, String value) { + response.setHeader(name, value); + } + + public String getHeader(String name) { + throw new UnsupportedOperationException("Not possible to implement"); + } + + public OutputStream getOutputStream() { + try { + return response.getOutputStream(); + } catch (IOException e) { + throw (IllegalStateException) new IllegalStateException().initCause(e); + } + } + + public void setStatusCode(int code) { + response.setStatus(code); + } + + public int getStatusCode() { + throw new UnsupportedOperationException("Not possible to implement"); + } + + public void setContentType(String type) { + response.setContentType(type); + } + + public String getContentType() { + return response.getContentType(); + } + + public void setStatusMessage(String responseString) { + response.setStatus(getStatusCode(), responseString); + } + } +}