Author: chris.laprun(a)jboss.com
Date: 2007-02-16 18:29:18 -0500 (Fri, 16 Feb 2007)
New Revision: 6326
Added:
trunk/wsrp/src/main/org/jboss/portal/wsrp/servlet/WSDLPortFixFilter.java
Modified:
trunk/wsrp/src/resources/portal-wsrp-war/WEB-INF/web.xml
Log:
- Created Filter to fix ports in WSDL returned by JBoss WS 1.0.3.sp1 and below since JBWS
doesn't handle port
change very gracefully. This is kinda fixed in 1.0.4.GA but it has other issues that
make it impossible to
use (doesn't transmit cookies properly). JBWS 1.2.1 should behave properly but we
can't wait for it...
This class should be removed when we can switch to JBWS 1.2.1...
Added: trunk/wsrp/src/main/org/jboss/portal/wsrp/servlet/WSDLPortFixFilter.java
===================================================================
--- trunk/wsrp/src/main/org/jboss/portal/wsrp/servlet/WSDLPortFixFilter.java
(rev 0)
+++ trunk/wsrp/src/main/org/jboss/portal/wsrp/servlet/WSDLPortFixFilter.java 2007-02-16
23:29:18 UTC (rev 6326)
@@ -0,0 +1,319 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2007, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated 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.portal.wsrp.servlet;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A Filter that fixes the ports returned by JBWS. This is a hack and this class will be
removed when JBWS 1.2.1 is
+ * available. This includes code from URLTools that has been duplicated and simplified
here for either inclusion.
+ * Post-processing based on a <a
href="http://www.ftponline.com/javapro/2002_02/magazine/features/kjo...
+ * Pro article</a>.
+ *
+ * @author <a href="mailto:chris.laprun@jboss.com">Chris
Laprun</a>
+ * @version $Revision$
+ * @since 2.6
+ */
+public class WSDLPortFixFilter implements Filter
+{
+ private String processedWSDL;
+ private StringWriter cachedWriter;
+
+ public void init(FilterConfig filterConfig) throws ServletException
+ {
+ }
+
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException
+ {
+ doFilter((HttpServletRequest)servletRequest, (HttpServletResponse)servletResponse,
filterChain);
+ }
+
+ public void doFilter(HttpServletRequest req, HttpServletResponse resp, FilterChain
chain) throws IOException, ServletException
+ {
+ // only process if we request the WSDL
+ if ("wsdl".equalsIgnoreCase(req.getQueryString()))
+ {
+ // wrap the response to capture the data and be able to post-process it later
+ WSDLProcessorResponseWrapper wrappedResponse = new
WSDLProcessorResponseWrapper(resp);
+
+ // continue processing
+ chain.doFilter(req, wrappedResponse);
+
+ // get the data
+ String wsdl = wrappedResponse.getData();
+
+ // if we don't have any data, just finish
+ if (wsdl == null || wsdl.length() == 0)
+ {
+ return;
+ }
+
+ // create the processed wsdl if required and cache the value
+ synchronized (this)
+ {
+ if (processedWSDL == null)
+ {
+ processedWSDL = replaceURLsBy(wsdl, new
PortReplacementGenerator(req.getServerPort()));
+ cachedWriter = new StringWriter(processedWSDL.length());
+ cachedWriter.write(processedWSDL);
+ }
+ }
+
+ resp.setContentType("text/xml");
+
+ resp.setContentLength(cachedWriter.toString().length());
+
+ resp.getWriter().print(cachedWriter.toString());
+ }
+ else
+ {
+ chain.doFilter(req, resp);
+ }
+ }
+
+ public void destroy()
+ {
+ }
+
+ /** ServletOutputStream backed by a ByteArrayOutputStream to capture data (and more
importantly access it later) */
+ private static class ByteArrayServletStream extends ServletOutputStream
+ {
+ ByteArrayOutputStream baos;
+
+ ByteArrayServletStream(ByteArrayOutputStream baos)
+ {
+ this.baos = baos;
+ }
+
+ public void write(int param) throws java.io.IOException
+ {
+ baos.write(param);
+ }
+ }
+
+ /** Hybrid PrintWriter / ServletOutputStream to capture the data during the filtering
process */
+ private static class ByteArrayPrintWriter
+ {
+ private ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ private PrintWriter pw = new PrintWriter(baos);
+ private ServletOutputStream sos = new ByteArrayServletStream(baos);
+
+ public PrintWriter getWriter()
+ {
+ return pw;
+ }
+
+ public ServletOutputStream getStream()
+ {
+ return sos;
+ }
+
+ byte[] toByteArray()
+ {
+ return baos.toByteArray();
+ }
+
+ public String toString()
+ {
+ return baos.toString();
+ }
+ }
+
+ /** Response wrapper using the hybrid PrintWriter / ServletOutputStream */
+ public class WSDLProcessorResponseWrapper extends HttpServletResponseWrapper
+ {
+ public WSDLProcessorResponseWrapper(HttpServletResponse response)
+ {
+ super(response);
+ }
+
+ ByteArrayPrintWriter bapw = new ByteArrayPrintWriter();
+
+ public PrintWriter getWriter()
+ {
+ return bapw.getWriter();
+ }
+
+ public ServletOutputStream getOutputStream() throws IOException
+ {
+ return bapw.getStream();
+ }
+
+ public String getData()
+ {
+ return bapw.toString();
+ }
+ }
+
+ // === Code duplicated from URLTools for easier inclusion === //
+
+ private static final Pattern LINK =
Pattern.compile("(?:location)\\s*=\\s*('|\")\\s*([^'\"]*)\\s*('|\")",
+ Pattern.CASE_INSENSITIVE);
+
+ public static final String HTTP_PREFIX = "http://";
+ public static final String HTTPS_PREFIX = "https://";
+
+ public static boolean isNetworkURL(String url)
+ {
+ if (url == null || url.length() == 0)
+ {
+ return false;
+ }
+
+ return url.startsWith(HTTP_PREFIX) || url.startsWith(HTTPS_PREFIX);
+ }
+
+ public static URLMatch[] extractURLsFrom(String markup)
+ {
+ int length;
+ if (markup != null && (length = markup.length()) != 0)
+ {
+ Matcher matcher = LINK.matcher(markup);
+ int currentIndex = 0;
+ List links = new ArrayList();
+ while (matcher.find(currentIndex) && currentIndex < length)
+ {
+ links.add(new URLMatch(matcher.start(2), matcher.end(2), matcher.group(2)));
+ currentIndex = matcher.end();
+ }
+
+ return (URLMatch[])links.toArray(new URLMatch[0]);
+ }
+ throw new IllegalArgumentException("Cannot extract URLs from a null or empty
markup string!");
+ }
+
+ public static String replaceURLsBy(String markup, URLReplacementGenerator generator)
+ {
+
+ URLMatch[] urls = extractURLsFrom(markup);
+ if (urls.length > 0)
+ {
+ StringBuffer newMarkup = new StringBuffer(markup.length());
+ int currentIndex = 0;
+ for (int i = 0; i < urls.length; i++)
+ {
+ URLMatch url = urls[i];
+ newMarkup.append(markup.substring(currentIndex,
url.getStart())).append(generator.getReplacementFor(i, url));
+ currentIndex = url.getEnd();
+ }
+ newMarkup.append(markup.substring(currentIndex));
+ markup = newMarkup.toString();
+ }
+ return markup;
+ }
+
+ public static class URLMatch
+ {
+ private int start;
+ private int end;
+ private String urlAsString;
+
+ private URLMatch(int start, int end, String urlAsString)
+ {
+ this.start = start;
+ this.end = end;
+ this.urlAsString = urlAsString;
+ }
+
+ public int getStart()
+ {
+ return start;
+ }
+
+ public int getEnd()
+ {
+ return end;
+ }
+
+ public String getURLAsString()
+ {
+ return urlAsString;
+ }
+ }
+
+ public abstract static class URLReplacementGenerator
+ {
+ public abstract String getReplacementFor(int currentIndex, URLMatch currentMatch);
+ }
+
+ public static class PortReplacementGenerator extends URLReplacementGenerator
+ {
+ private int replacementPort;
+
+ public PortReplacementGenerator(int replacementPort)
+ {
+ this.replacementPort = replacementPort;
+ }
+
+ public String getReplacementFor(int currentIndex, URLMatch currentMatch)
+ {
+ return replaceServerPortInURL(currentMatch.getURLAsString(), replacementPort);
+ }
+ }
+
+ public static String replaceServerPortInURL(String url, int newPort)
+ {
+ if (!isNetworkURL(url))
+ {
+ return url;
+ }
+
+ StringBuffer buf = new StringBuffer(url);
+ int afterProtocol = url.indexOf("://") + 3;
+ int beforePort = url.indexOf(':', afterProtocol);
+ int afterPort;
+
+ if (beforePort != -1)
+ {
+ afterPort = url.indexOf('/', beforePort);
+ buf.delete(beforePort + 1, afterPort);
+ buf.insert(beforePort + 1, newPort);
+ }
+ else
+ {
+ // port number was not present
+ afterPort = url.indexOf('/', afterProtocol);
+ buf.insert(afterPort, ":" + newPort);
+ }
+
+ return buf.toString();
+ }
+}
Property changes on:
trunk/wsrp/src/main/org/jboss/portal/wsrp/servlet/WSDLPortFixFilter.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
Modified: trunk/wsrp/src/resources/portal-wsrp-war/WEB-INF/web.xml
===================================================================
--- trunk/wsrp/src/resources/portal-wsrp-war/WEB-INF/web.xml 2007-02-16 21:18:32 UTC (rev
6325)
+++ trunk/wsrp/src/resources/portal-wsrp-war/WEB-INF/web.xml 2007-02-16 23:29:18 UTC (rev
6326)
@@ -36,6 +36,10 @@
<filter-name>TransactionFilter</filter-name>
<filter-class>org.jboss.portal.wsrp.servlet.TransactionFilter</filter-class>
</filter>
+ <filter>
+ <filter-name>WSDLPortFixFilter</filter-name>
+
<filter-class>org.jboss.portal.wsrp.servlet.WSDLPortFixFilter</filter-class>
+ </filter>
<filter-mapping>
<filter-name>ServletAccessFilter</filter-name>
<url-pattern>/*</url-pattern>
@@ -44,6 +48,10 @@
<filter-name>TransactionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
+ <filter-mapping>
+ <filter-name>WSDLPortFixFilter</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
<!--<listener>
<description>Listen for session events so that we can call releaseSessions
appropriately</description>