Author: ffang
Date: Tue Sep 19 19:16:39 2006
New Revision: 448031
URL: http://svn.apache.org/viewvc?view=rev&rev=448031
Log:
[JIRA CXF-68] get servlet working - phase 1
Added:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractCachedOutputStream.java
(with props)
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractWrappedOutputStream.java
(with props)
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/CXFServlet.java
(with props)
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletDestination.java
(with props)
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletTransportFactory.java
(with props)
incubator/cxf/trunk/rt/frontend/jaxws/src/main/resources/META-INF/bus-extensions.xml
(with props)
Added:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractCachedOutputStream.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractCachedOutputStream.java?view=auto&rev=448031
==============================================================================
---
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractCachedOutputStream.java
(added)
+++
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractCachedOutputStream.java
Tue Sep 19 19:16:39 2006
@@ -0,0 +1,196 @@
+/**
+ * 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.cxf.jaxws.servlet;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+
+public abstract class AbstractCachedOutputStream extends OutputStream {
+
+ protected OutputStream currentStream;
+
+ private long threshold = 8 * 1024;
+
+ private int totalLength;
+
+ private boolean inmem;
+
+ private File tempFile;
+
+ private File outputDir;
+
+ public AbstractCachedOutputStream(PipedInputStream stream) throws
IOException {
+ currentStream = new PipedOutputStream(stream);
+ inmem = true;
+ }
+
+ public AbstractCachedOutputStream() {
+ currentStream = new ByteArrayOutputStream();
+ inmem = true;
+ }
+
+ /**
+ * Perform any actions required on stream flush (freeze headers, reset
+ * output stream ... etc.)
+ */
+ protected abstract void doFlush() throws IOException;
+
+ public void flush() throws IOException {
+ currentStream.flush();
+ doFlush();
+ }
+
+ /**
+ * Perform any actions required on stream closure (handle response etc.)
+ */
+ protected abstract void doClose() throws IOException;
+
+ public void close() throws IOException {
+ currentStream.close();
+ doClose();
+ }
+
+ public boolean equals(Object obj) {
+ return currentStream.equals(obj);
+ }
+
+ /**
+ * Replace the original stream with the new one, when with Attachment,
needs
+ * to replace the xml writer stream with the stream used by
+ * AttachmentSerializer Or Copy the cached output stream to the "real"
+ * output stream, i.e. onto the wire.
+ *
+ * @param realOS
+ * the real output stream
+ * @throws IOException
+ */
+ public void resetOut(OutputStream out, boolean copyOldContent) throws
IOException {
+ ByteArrayOutputStream bout = (ByteArrayOutputStream) currentStream;
+ if (copyOldContent && bout.size() > 0) {
+ bout.writeTo(out);
+ }
+ currentStream = out;
+ }
+
+ /**
+ * @return the underlying output stream
+ */
+ public OutputStream getOut() {
+ return currentStream;
+ }
+
+ public int hashCode() {
+ return currentStream.hashCode();
+ }
+
+ public String toString() {
+ return currentStream.toString();
+ }
+
+ protected abstract void onWrite() throws IOException;
+
+ public void write(byte[] b, int off, int len) throws IOException {
+ onWrite();
+ this.totalLength += len;
+ if (inmem && totalLength > threshold) {
+ createFileOutputStream();
+ }
+ currentStream.write(b, off, len);
+ }
+
+ public void write(byte[] b) throws IOException {
+ onWrite();
+ this.totalLength += b.length;
+ if (inmem && totalLength > threshold) {
+ createFileOutputStream();
+ }
+ currentStream.write(b);
+ }
+
+ public void write(int b) throws IOException {
+ onWrite();
+ this.totalLength++;
+ if (inmem && totalLength > threshold) {
+ createFileOutputStream();
+ }
+ currentStream.write(b);
+ }
+
+ private void createFileOutputStream() throws IOException {
+ byte[] bytes = ((ByteArrayOutputStream) currentStream).toByteArray();
+ if (outputDir == null) {
+ tempFile = File.createTempFile("att", "tmp");
+ } else {
+ tempFile = File.createTempFile("att", "tmp", outputDir);
+ }
+ currentStream = new BufferedOutputStream(new
FileOutputStream(tempFile));
+ currentStream.write(bytes);
+ inmem = false;
+ }
+
+ public File getTempFile() {
+ return tempFile;
+ }
+
+ public InputStream getInputStream() throws IOException {
+ if (inmem) {
+ if (currentStream instanceof ByteArrayOutputStream) {
+ return new
ByteArrayInputStream(((ByteArrayOutputStream)currentStream).toByteArray());
+ } else if (currentStream instanceof PipedOutputStream) {
+ return new PipedInputStream((PipedOutputStream)currentStream);
+ } else {
+ return null;
+ }
+ } else {
+ try {
+ return new FileInputStream(tempFile);
+ } catch (FileNotFoundException e) {
+ throw new IOException("Cached file was deleted, " +
e.toString());
+ }
+ }
+ }
+
+ public void dispose() {
+ if (!inmem) {
+ tempFile.delete();
+ }
+ }
+
+ public void setOutputDir(File outputDir) throws IOException {
+ this.outputDir = outputDir;
+ createFileOutputStream();
+ }
+
+ public void setThreshold(long threshold) {
+ this.threshold = threshold;
+ }
+
+}
Propchange:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractCachedOutputStream.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractCachedOutputStream.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractWrappedOutputStream.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractWrappedOutputStream.java?view=auto&rev=448031
==============================================================================
---
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractWrappedOutputStream.java
(added)
+++
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractWrappedOutputStream.java
Tue Sep 19 19:16:39 2006
@@ -0,0 +1,45 @@
+/**
+ * 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.cxf.jaxws.servlet;
+
+
+import org.apache.cxf.message.Message;
+
+public abstract class AbstractWrappedOutputStream extends
AbstractCachedOutputStream {
+
+ protected Message outMessage;
+ private boolean flushed;
+
+ AbstractWrappedOutputStream(Message m) {
+ super();
+ outMessage = m;
+ }
+
+ /**
+ * @return true if already flushed
+ */
+ protected boolean alreadyFlushed() {
+ boolean ret = flushed;
+ flushed = true;
+ return ret;
+ }
+
+}
Propchange:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractWrappedOutputStream.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractWrappedOutputStream.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/CXFServlet.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/CXFServlet.java?view=auto&rev=448031
==============================================================================
---
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/CXFServlet.java
(added)
+++
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/CXFServlet.java
Tue Sep 19 19:16:39 2006
@@ -0,0 +1,288 @@
+/**
+ * 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.cxf.jaxws.servlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.WeakReference;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+import org.apache.cxf.Bus;
+
+import org.apache.cxf.bus.CXFBusFactory;
+import org.apache.cxf.jaxws.EndpointImpl;
+import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
+import org.apache.cxf.jaxws.support.JaxwsImplementorInfo;
+import org.apache.cxf.service.Service;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.DestinationFactory;
+import org.apache.cxf.transport.DestinationFactoryManager;
+import org.apache.cxf.ws.addressing.EndpointReferenceType;
+import org.apache.cxf.wsdl.EndpointReferenceUtils;
+
+
+
+
+public class CXFServlet extends HttpServlet {
+ static final String HTTP_REQUEST =
+ CXFServlet.class.getName() + ".REQUEST";
+ static final String HTTP_RESPONSE =
+ CXFServlet.class.getName() + ".RESPONSE";
+
+ static final Map<String, WeakReference<Bus>> BUS_MAP = new
Hashtable<String, WeakReference<Bus>>();
+
+ protected Bus bus;
+ protected Map<String, ServletDestination> servantMap
+ = new HashMap<String, ServletDestination>();
+
+
+ EndpointReferenceType reference;
+ ServletTransportFactory servletTransportFactory;
+ EndpointImpl ep;
+ EndpointInfo ei;
+
+ public void init(ServletConfig servletConfig) throws ServletException {
+ super.init(servletConfig);
+
+ List<String> list = new ArrayList<String>();
+ String busid = servletConfig.getInitParameter("bus.id");
+ if (null != busid) {
+ list.add("-BUSid");
+ list.add(busid);
+ WeakReference<Bus> ref = BUS_MAP.get(busid);
+ if (null != ref) {
+ bus = ref.get();
+ }
+ }
+ if (null == bus) {
+ //bus = Bus.init(list.toArray(new String[list.size()]));
+ bus = new CXFBusFactory().createBus();
+
+ }
+ if (null != busid) {
+ BUS_MAP.put(busid, new WeakReference<Bus>(bus));
+ }
+
+ InputStream ins = servletConfig.getServletContext()
+ .getResourceAsStream("/WEB-INF/cxf-servlet.xml");
+ if (ins != null) {
+ DocumentBuilderFactory builderFactory =
DocumentBuilderFactory.newInstance();
+ builderFactory.setNamespaceAware(true);
+ builderFactory.setValidating(false);
+
+
+ try {
+ Document doc = builderFactory.newDocumentBuilder().parse(ins);
+ Node nd = doc.getDocumentElement().getFirstChild();
+ while (nd != null) {
+ if ("endpoint".equals(nd.getLocalName())) {
+ loadEndpoint(servletConfig, nd);
+ }
+ nd = nd.getNextSibling();
+ }
+ } catch (SAXException ex) {
+ // TODO Auto-generated catch block
+ ex.printStackTrace();
+ } catch (IOException ex) {
+ // TODO Auto-generated catch block
+ ex.printStackTrace();
+ } catch (ParserConfigurationException ex) {
+ // TODO Auto-generated catch block
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ private void deregisterTransport(String transportId) {
+
bus.getExtension(DestinationFactoryManager.class).deregisterDestinationFactory(transportId);
+ }
+
+ /**
+ * @return
+ */
+ protected DestinationFactory createServletTransportFactory() {
+ if (servletTransportFactory == null) {
+ servletTransportFactory = new ServletTransportFactory(bus,
reference);
+ }
+ return servletTransportFactory;
+ }
+
+ private void registerTransport(DestinationFactory factory, String
namespace) {
+
bus.getExtension(DestinationFactoryManager.class).registerDestinationFactory(
+ namespace,
+ factory);
+ }
+
+ public void loadEndpoint(String implName,
+ String serviceName,
+ String wsdlName,
+ String portName,
+ String urlPat) {
+
+ try {
+
+ URL url = null;
+ if (wsdlName != null) {
+ try {
+ url =
getServletConfig().getServletContext().getResource(wsdlName);
+ } catch (MalformedURLException ex) {
+ try {
+ url = new URL(wsdlName);
+ } catch (MalformedURLException ex2) {
+ try {
+ url =
getServletConfig().getServletContext().getResource("/" + wsdlName);
+ } catch (MalformedURLException ex3) {
+ url = null;
+ }
+ }
+ }
+ }
+ Class cls = Class.forName(implName, false,
Thread.currentThread().getContextClassLoader());
+ Object impl = cls.newInstance();
+ reference = EndpointReferenceUtils
+ .getEndpointReference(url,
+ QName.valueOf(serviceName),
+ portName);
+
+
+
+ ep = new EndpointImpl(bus, impl, url.toString());
+ replaceDestionFactory();
+// doesn't really matter what URL is used here
+ ep.publish("http://localhost" + (urlPat.charAt(0) == '/' ? "" :
"/") + urlPat);
+ JaxwsImplementorInfo implInfo = new
JaxwsImplementorInfo(impl.getClass());
+ // build up the Service model
+ JaxWsServiceFactoryBean serviceFactory = new
JaxWsServiceFactoryBean(implInfo);
+ serviceFactory.setBus(bus);
+ serviceFactory.setServiceClass(impl.getClass());
+ Service service = serviceFactory.create();
+
+ // create the endpoint
+ QName endpointName = implInfo.getEndpointName();
+ ei = service.getServiceInfo().getEndpoint(endpointName);
+
+ } catch (ClassNotFoundException ex) {
+ ex.printStackTrace();
+ } catch (InstantiationException ex) {
+ ex.printStackTrace();
+ } catch (IllegalAccessException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ private void replaceDestionFactory() {
+ DestinationFactory factory = createServletTransportFactory();
+ deregisterTransport("http://schemas.xmlsoap.org/wsdl/soap/");
+ deregisterTransport("http://schemas.xmlsoap.org/wsdl/soap/http");
+ deregisterTransport("http://schemas.xmlsoap.org/wsdl/http/");
+ deregisterTransport("http://celtix.objectweb.org/bindings/xmlformat");
+
deregisterTransport("http://celtix.objectweb.org/transports/http/configuration");
+ registerTransport(factory, "http://schemas.xmlsoap.org/wsdl/soap/");
+ registerTransport(factory,
"http://schemas.xmlsoap.org/wsdl/soap/http");
+ registerTransport(factory, "http://schemas.xmlsoap.org/wsdl/http/");
+ registerTransport(factory,
"http://celtix.objectweb.org/bindings/xmlformat");
+ registerTransport(factory,
"http://celtix.objectweb.org/transports/http/configuration");
+ }
+
+ public void loadEndpoint(ServletConfig servletConfig, Node node) {
+ Element el = (Element)node;
+ String implName = el.getAttribute("implementation");
+ String serviceName = el.getAttribute("service");
+ String wsdlName = el.getAttribute("wsdl");
+ String portName = el.getAttribute("port");
+ String urlPat = el.getAttribute("url-pattern");
+
+ loadEndpoint(implName, serviceName, wsdlName, portName, urlPat);
+ }
+
+ public void destroy() {
+ String s = bus.getId();
+ BUS_MAP.remove(s);
+
+ bus.shutdown(true);
+ }
+
+ void addServant(URL url, ServletDestination servant) {
+ servantMap.put(url.getPath(), servant);
+ }
+ void removeServant(URL url, ServletDestination servant) {
+ servantMap.remove(url.getPath());
+ }
+
+ protected void doPost(HttpServletRequest request, HttpServletResponse
response) throws ServletException {
+ System.out.println("do post is invoked");
+ try {
+
((ServletDestination)ep.getServer().getDestination()).doService(request,
response);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ /*ServletServerTransport tp = servantMap.get(request.getPathInfo());
+ if (tp == null) {
+ throw new ServletException("Unknown servlet mapping " +
request.getPathInfo());
+ }
+ try {
+ tp.doPost(request, response);
+ } catch (IOException ex) {
+ throw new ServletException(ex.getMessage());
+ }*/
+ }
+
+ protected void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException {
+ System.out.println("do get is invoked");
+ try {
+ ((ServletDestination)servletTransportFactory.
+ getDestination(ei)).doService(request, response);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ /*ServletServerTransport tp = servantMap.get(request.getPathInfo());
+ if (tp == null) {
+ throw new ServletException("Unknown servlet mapping " +
request.getPathInfo());
+ }
+ try {
+ tp.doGet(request, response);
+ } catch (IOException ex) {
+ throw new ServletException(ex.getMessage());
+ }*/
+ }
+
+}
Propchange:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/CXFServlet.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/CXFServlet.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletDestination.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletDestination.java?view=auto&rev=448031
==============================================================================
---
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletDestination.java
(added)
+++
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletDestination.java
Tue Sep 19 19:16:39 2006
@@ -0,0 +1,471 @@
+/**
+ * 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.cxf.jaxws.servlet;
+
+
+
+
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.wsdl.Definition;
+import javax.wsdl.Port;
+import javax.wsdl.extensions.ExtensibilityElement;
+import javax.wsdl.extensions.soap.SOAPAddress;
+import javax.wsdl.factory.WSDLFactory;
+import javax.wsdl.xml.WSDLWriter;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.util.Base64Exception;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.configuration.security.AuthorizationPolicy;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.Conduit;
+import org.apache.cxf.transport.ConduitInitiator;
+import org.apache.cxf.transport.Destination;
+import org.apache.cxf.transport.MessageObserver;
+import org.apache.cxf.ws.addressing.EndpointReferenceType;
+
+
+import org.apache.cxf.wsdl11.ServiceWSDLBuilder;
+import org.xmlsoap.schemas.wsdl.http.AddressType;
+
+
+public class ServletDestination implements Destination {
+
+ public static final String HTTP_REQUEST =
+ ServletDestination.class.getName() + ".REQUEST";
+ public static final String HTTP_RESPONSE =
+ ServletDestination.class.getName() + ".RESPONSE";
+
+ static final Logger LOG =
Logger.getLogger(ServletDestination.class.getName());
+
+ private static final long serialVersionUID = 1L;
+
+ protected final Bus bus;
+ protected final ConduitInitiator conduitInitiator;
+ //protected final HTTPDestinationConfiguration config;
+ protected final EndpointInfo endpointInfo;
+ protected final EndpointReferenceType reference;
+ protected String name;
+ protected URL nurl;
+ protected MessageObserver incomingObserver;
+
+
+ /**
+ * Constructor, allowing subsititution of configuration.
+ *
+ * @param b the associated Bus
+ * @param ci the associated conduit initiator
+ * @param ei the endpoint info of the destination
+ * @param cfg the configuration
+ * @throws IOException
+ */
+ public ServletDestination(Bus b,
+ ConduitInitiator ci,
+ EndpointInfo ei,
+ EndpointReferenceType ref)
+ throws IOException {
+ bus = b;
+ conduitInitiator = ci;
+ endpointInfo = ei;
+
+ reference = ref;
+
+ // get url (publish address) from endpoint reference
+ /*nurl = new URL(EndpointReferenceUtils.getAddress(ref));
+
+
+ name = nurl.getPath();*/
+
+
+ }
+
+ /**
+ * @return the reference associated with this Destination
+ */
+ public EndpointReferenceType getAddress() {
+ return reference;
+ }
+
+ /**
+ * Cache HTTP headers in message.
+ *
+ * @param message the current message
+ */
+ protected void setHeaders(Message message) {
+ Map<String, List<String>> requestHeaders = new HashMap<String,
List<String>>();
+ copyRequestHeaders(message, requestHeaders);
+ message.put(Message.PROTOCOL_HEADERS, requestHeaders);
+
+ if (requestHeaders.containsKey("Authorization")) {
+ List<String> authorizationLines =
requestHeaders.get("Authorization");
+ String credentials = authorizationLines.get(0);
+ String authType = credentials.split(" ")[0];
+ if ("Basic".equals(authType)) {
+ String authEncoded = credentials.split(" ")[1];
+ try {
+ String authDecoded = new
String(Base64Utility.decode(authEncoded));
+ String authInfo[] = authDecoded.split(":");
+ String username = authInfo[0];
+ String password = authInfo[1];
+
+ AuthorizationPolicy policy = new AuthorizationPolicy();
+ policy.setUserName(username);
+ policy.setPassword(password);
+
+ message.put(AuthorizationPolicy.class, policy);
+ } catch (Base64Exception ex) {
+ //ignore, we'll leave things alone. They can try decoding
it themselves
+ }
+ }
+ }
+
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void updateResponseHeaders(Message message) {
+ Map<String, List<String>> responseHeaders =
+ (Map<String, List<String>>)message.get(Message.PROTOCOL_HEADERS);
+ if (responseHeaders == null) {
+ responseHeaders = new HashMap<String, List<String>>();
+ message.put(Message.PROTOCOL_HEADERS, responseHeaders);
+ }
+ }
+
+
+
+ /**
+ * Register a message observer for incoming messages.
+ *
+ * @param observer the observer to notify on receipt of incoming
+ */
+ public synchronized void setMessageObserver(MessageObserver observer) {
+ incomingObserver = observer;
+ }
+
+ /**
+ * Retreive a back-channel Conduit, which must be policy-compatible
+ * with the current Message and associated Destination. For example
+ * compatible Quality of Protection must be asserted on the back-channel.
+ * This would generally only be an issue if the back-channel is decoupled.
+ *
+ * @param inMessage the current inbound message (null to indicate a
+ * disassociated back-channel)
+ * @param partialResponse in the decoupled case, this is expected to be the
+ * outbound Message to be sent over the in-built back-channel.
+ * @param address the backchannel address (null to indicate anonymous)
+ * @return a suitable Conduit
+ */
+ public Conduit getBackChannel(Message inMessage,
+ Message partialResponse,
+ EndpointReferenceType address) throws
IOException {
+ HttpServletResponse response =
(HttpServletResponse)inMessage.get(HTTP_RESPONSE);
+ Conduit backChannel = null;
+ if (address == null) {
+ backChannel = new BackChannelConduit(address, response);
+ } else {
+ if (partialResponse != null) {
+ // setup the outbound message to for 202 Accepted
+ partialResponse.put(Message.RESPONSE_CODE,
+ HttpURLConnection.HTTP_ACCEPTED);
+ backChannel = new BackChannelConduit(address, response);
+ } else {
+ backChannel = conduitInitiator.getConduit(endpointInfo,
address);
+ // ensure decoupled back channel input stream is closed
+ backChannel.setMessageObserver(new MessageObserver() {
+ public void onMessage(Message m) {
+ if (m.getContentFormats().contains(InputStream.class))
{
+ InputStream is = m.getContent(InputStream.class);
+ try {
+ is.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+ });
+ }
+ }
+ return backChannel;
+ }
+
+ /**
+ * Shutdown the Destination, i.e. stop accepting incoming messages.
+ */
+ public void shutdown() {
+ }
+
+ /**
+ * Copy the request headers into the message.
+ *
+ * @param message the current message
+ * @param headers the current set of headers
+ */
+ protected void copyRequestHeaders(Message message,
+ Map<String, List<String>> headers) {
+
+ }
+
+ /**
+ * Copy the response headers into the response.
+ *
+ * @param message the current message
+ * @param headers the current set of headers
+ */
+ protected void copyResponseHeaders(Message message, HttpServletResponse
response) {
+ }
+
+ protected void doService(HttpServletRequest req, HttpServletResponse resp)
+ throws IOException {
+
+
+ if ("GET".equals(req.getMethod())) {
+ doGet(req, resp);
+ } else {
+ doPost(req, resp);
+ }
+
+
+ // REVISIT: service on executor if associated with endpoint
+ //serviceRequest(req, resp);
+ }
+
+ private void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
+ try {
+ if (LOG.isLoggable(Level.INFO)) {
+ LOG.info("Service http request on thread: " +
Thread.currentThread());
+ }
+
+ MessageImpl inMessage = new MessageImpl();
+ inMessage.setContent(InputStream.class, req.getInputStream());
+ inMessage.put(HTTP_REQUEST, req);
+ inMessage.put(HTTP_RESPONSE, resp);
+ inMessage.put(Message.HTTP_REQUEST_METHOD, req.getMethod());
+ inMessage.put(Message.PATH_INFO, req.getPathInfo());
+ inMessage.put(Message.QUERY_STRING, req.getQueryString());
+
+ setHeaders(inMessage);
+
+ inMessage.setDestination(this);
+
+
+ incomingObserver.onMessage(inMessage);
+
+ } finally {
+ if (LOG.isLoggable(Level.INFO)) {
+ LOG.info("Finished servicing http request on thread: " +
Thread.currentThread());
+ }
+ }
+
+ }
+
+ private void doGet(HttpServletRequest req, HttpServletResponse resp) {
+ try {
+
+
+ resp.setHeader("Content-Type", "text/xml");
+
+ OutputStream os = resp.getOutputStream();
+
+ WSDLWriter wsdlWriter = WSDLFactory.newInstance().newWSDLWriter();
+ Definition def =
+
ServiceWSDLBuilder.getServiceWSDLBuilder().buildDefinition(endpointInfo.getService());
+ Port port = def.getService(
+
endpointInfo.getService().getName()).getPort(
+ endpointInfo.getName().getLocalPart());
+ List<?> exts = port.getExtensibilityElements();
+ if (exts.size() > 0) {
+ ExtensibilityElement el = (ExtensibilityElement)exts.get(0);
+ if (el instanceof SOAPAddress) {
+ SOAPAddress add = (SOAPAddress)el;
+ add.setLocationURI(req.getRequestURL().toString());
+ }
+ if (el instanceof AddressType) {
+ AddressType add = (AddressType)el;
+ add.setLocation(req.getRequestURL().toString());
+ }
+ }
+
+ wsdlWriter.writeWSDL(def, os);
+ resp.getOutputStream().flush();
+ return;
+ } catch (Exception ex) {
+
+ ex.printStackTrace();
+ }
+ }
+
+ protected class BackChannelConduit implements Conduit {
+
+ protected HttpServletResponse response;
+ protected EndpointReferenceType target;
+
+ BackChannelConduit(EndpointReferenceType ref, HttpServletResponse
resp) {
+ response = resp;
+ target = ref;
+ }
+ public void close(Message msg) throws IOException {
+ msg.getContent(OutputStream.class).close();
+ }
+
+ /**
+ * Register a message observer for incoming messages.
+ *
+ * @param observer the observer to notify on receipt of incoming
+ */
+ public void setMessageObserver(MessageObserver observer) {
+ // shouldn't be called for a back channel conduit
+ }
+
+ /**
+ * Send an outbound message, assumed to contain all the name-value
+ * mappings of the corresponding input message (if any).
+ *
+ * @param message the message to be sent.
+ */
+ public void send(Message message) throws IOException {
+ message.put(HTTP_RESPONSE, response);
+ message.setContent(OutputStream.class,
+ new WrappedOutputStream(message, response));
+ }
+
+ /**
+ * @return the reference associated with the target Destination
+ */
+ public EndpointReferenceType getTarget() {
+ return target;
+ }
+
+ /**
+ * Retreive the back-channel Destination.
+ *
+ * @return the backchannel Destination (or null if the backchannel is
+ * built-in)
+ */
+ public Destination getBackChannel() {
+ return null;
+ }
+
+ /**
+ * Close the conduit
+ */
+ public void close() {
+ }
+ }
+
+ private class WrappedOutputStream extends AbstractWrappedOutputStream {
+
+ protected HttpServletResponse response;
+
+ WrappedOutputStream(Message m, HttpServletResponse resp) {
+ super(m);
+ response = resp;
+ }
+
+ /**
+ * Perform any actions required on stream flush (freeze headers,
+ * reset output stream ... etc.)
+ */
+ protected void doFlush() throws IOException {
+ OutputStream responseStream = flushHeaders(outMessage);
+ if (null != responseStream && !alreadyFlushed()) {
+ resetOut(responseStream, true);
+ }
+ }
+
+ /**
+ * Perform any actions required on stream closure (handle response
etc.)
+ */
+ protected void doClose() {
+ commitResponse();
+ }
+
+ protected void onWrite() throws IOException {
+ }
+
+ private void commitResponse() {
+ try {
+ response.flushBuffer();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ protected OutputStream flushHeaders(Message outMessage) throws IOException
{
+ updateResponseHeaders(outMessage);
+ Object responseObj = outMessage.get(HTTP_RESPONSE);
+ OutputStream responseStream = null;
+ if (responseObj instanceof HttpServletResponse) {
+ HttpServletResponse response = (HttpServletResponse)responseObj;
+
+ Integer i = (Integer)outMessage.get(Message.RESPONSE_CODE);
+ if (i != null) {
+ int status = i.intValue();
+ if (status == HttpURLConnection.HTTP_INTERNAL_ERROR) {
+ response.setStatus(status, "Fault Occurred");
+ } else if (status == HttpURLConnection.HTTP_ACCEPTED) {
+ response.setStatus(status, "Accepted");
+ } else {
+ response.setStatus(status);
+ }
+ } else {
+ response.setStatus(HttpURLConnection.HTTP_OK);
+ }
+
+ copyResponseHeaders(outMessage, response);
+ responseStream = response.getOutputStream();
+
+ if (isOneWay(outMessage)) {
+ response.flushBuffer();
+ }
+ } else {
+ LOG.log(Level.WARNING, "UNEXPECTED_RESPONSE_TYPE_MSG",
responseObj.getClass());
+ throw new IOException("UNEXPECTED_RESPONSE_TYPE_MSG" +
responseObj.getClass());
+ }
+
+ if (isOneWay(outMessage)) {
+ outMessage.remove(HTTP_RESPONSE);
+ }
+ return responseStream;
+ }
+
+ protected boolean isOneWay(Message message) {
+ Boolean oneway =
(Boolean)message.get(org.apache.cxf.message.Message.ONEWAY_MESSAGE);
+ return oneway != null && oneway.booleanValue();
+ }
+
+}
Propchange:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletDestination.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletDestination.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletTransportFactory.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletTransportFactory.java?view=auto&rev=448031
==============================================================================
---
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletTransportFactory.java
(added)
+++
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletTransportFactory.java
Tue Sep 19 19:16:39 2006
@@ -0,0 +1,93 @@
+/**
+ * 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.cxf.jaxws.servlet;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.Conduit;
+import org.apache.cxf.transport.ConduitInitiator;
+import org.apache.cxf.transport.ConduitInitiatorManager;
+import org.apache.cxf.transport.Destination;
+import org.apache.cxf.transport.DestinationFactory;
+import org.apache.cxf.transport.DestinationFactoryManager;
+import org.apache.cxf.ws.addressing.EndpointReferenceType;
+
+public class ServletTransportFactory implements ConduitInitiator,
DestinationFactory {
+
+ Bus bus;
+ EndpointReferenceType reference;
+ @Resource
+ Collection<String> activationNamespaces;
+
+
+ public ServletTransportFactory(Bus b, EndpointReferenceType ref) {
+ bus = b;
+
+ reference = ref;
+ }
+
+ public ServletTransportFactory() {
+ // TODO Auto-generated constructor stub
+ }
+
+ @PostConstruct
+ void registerWithBindingManager() {
+ ConduitInitiatorManager cim =
bus.getExtension(ConduitInitiatorManager.class);
+ for (String ns : activationNamespaces) {
+ cim.registerConduitInitiator(ns, this);
+ }
+ DestinationFactoryManager dfm =
bus.getExtension(DestinationFactoryManager.class);
+ for (String ns : activationNamespaces) {
+ dfm.registerDestinationFactory(ns, this);
+ }
+ }
+
+ public Conduit getConduit(EndpointInfo endpointInfo)
+ throws IOException {
+ return null;
+ }
+
+ public Conduit getConduit(EndpointInfo endpointInfo, EndpointReferenceType
target)
+ throws IOException {
+ return null;
+ }
+
+ public Destination getDestination(EndpointInfo endpointInfo)
+ throws IOException {
+ return new ServletDestination(bus, null, endpointInfo, reference);
+ }
+
+ public Bus getBus() {
+ return bus;
+ }
+
+ @Resource
+ public void setBus(Bus bus) {
+ this.bus = bus;
+ }
+
+}
Propchange:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletTransportFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletTransportFactory.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/resources/META-INF/bus-extensions.xml
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/resources/META-INF/bus-extensions.xml?view=auto&rev=448031
==============================================================================
---
incubator/cxf/trunk/rt/frontend/jaxws/src/main/resources/META-INF/bus-extensions.xml
(added)
+++
incubator/cxf/trunk/rt/frontend/jaxws/src/main/resources/META-INF/bus-extensions.xml
Tue Sep 19 19:16:39 2006
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<extensions xmlns="http://cxf.apache.org/bus/extension">
+
+ <extension class="org.apache.cxf.jaxws.servlet.ServletTransportFactory"
deferred="true">
+ <namespace>http://schemas.xmlsoap.org/wsdl/servlet</namespace>
+ </extension>
+</extensions>
Propchange:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/resources/META-INF/bus-extensions.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/resources/META-INF/bus-extensions.xml
------------------------------------------------------------------------------
svn:keywords = Rev Date
Propchange:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/resources/META-INF/bus-extensions.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml