Author: chris.laprun(a)jboss.com
Date: 2007-02-22 14:23:35 -0500 (Thu, 22 Feb 2007)
New Revision: 6379
Added:
branches/JBoss_Portal_Branch_2_4/wsrp/src/main/org/jboss/portal/wsrp/servlet/WSDLPortFixFilter.java
Modified:
branches/JBoss_Portal_Branch_2_4/wsrp/src/resources/portal-wsrp-war/WEB-INF/web.xml
Log:
- Fix for JBPORTAL-1290: added servlet filter to dynamically change the port on WSDL
request.
Added:
branches/JBoss_Portal_Branch_2_4/wsrp/src/main/org/jboss/portal/wsrp/servlet/WSDLPortFixFilter.java
===================================================================
---
branches/JBoss_Portal_Branch_2_4/wsrp/src/main/org/jboss/portal/wsrp/servlet/WSDLPortFixFilter.java
(rev 0)
+++
branches/JBoss_Portal_Branch_2_4/wsrp/src/main/org/jboss/portal/wsrp/servlet/WSDLPortFixFilter.java 2007-02-22
19:23:35 UTC (rev 6379)
@@ -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.4.2
+ */
+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:
branches/JBoss_Portal_Branch_2_4/wsrp/src/main/org/jboss/portal/wsrp/servlet/WSDLPortFixFilter.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
Modified:
branches/JBoss_Portal_Branch_2_4/wsrp/src/resources/portal-wsrp-war/WEB-INF/web.xml
===================================================================
---
branches/JBoss_Portal_Branch_2_4/wsrp/src/resources/portal-wsrp-war/WEB-INF/web.xml 2007-02-22
19:22:50 UTC (rev 6378)
+++
branches/JBoss_Portal_Branch_2_4/wsrp/src/resources/portal-wsrp-war/WEB-INF/web.xml 2007-02-22
19:23:35 UTC (rev 6379)
@@ -28,12 +28,6 @@
version="2.4">
<!-- Filter to put request and response in ServletAccess -->
- <!--
- <filter>
- <filter-name>RequestDumperFilter</filter-name>
-
<filter-class>org.jboss.portal.wsrp.servlet.RequestDumperFilter</filter-class>
- </filter>
- -->
<filter>
<filter-name>ServletAccessFilter</filter-name>
<filter-class>org.jboss.portal.wsrp.servlet.ServletAccessFilter</filter-class>
@@ -42,12 +36,10 @@
<filter-name>TransactionFilter</filter-name>
<filter-class>org.jboss.portal.wsrp.servlet.TransactionFilter</filter-class>
</filter>
- <!--
- <filter-mapping>
- <filter-name>RequestDumperFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
- -->
+ <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>
@@ -56,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>
<servlet>
<servlet-name>MarkupService</servlet-name>