diff --git a/apps/webchat/source/java/org/jivesoftware/webchat/JiveChatServlet.java b/apps/webchat/source/java/org/jivesoftware/webchat/JiveChatServlet.java
index 406d8ada2..b509da321 100644
--- a/apps/webchat/source/java/org/jivesoftware/webchat/JiveChatServlet.java
+++ b/apps/webchat/source/java/org/jivesoftware/webchat/JiveChatServlet.java
@@ -84,7 +84,7 @@ public class JiveChatServlet
static protected Map PACKET_ROOT_CHATDATA_MAP = new HashMap();
static protected EmoticonFilter EMOTICONFILTER = new EmoticonFilter();
- static protected URLFilter URLFILTER = new URLFilter();
+ static protected URLTranscoder URLTRANSCODER = new URLTranscoder();
protected String host;
@@ -196,7 +196,7 @@ public class JiveChatServlet
body = this.replace(body, "\"", """);
// encode the embedded urls
- body = URLFILTER.applyFilter(body);
+ body = URLTRANSCODER.encodeURLsInText(body);
// Apply emoticons
body = EMOTICONFILTER.applyFilter(body);
diff --git a/apps/webchat/source/java/org/jivesoftware/webchat/URLTranscoder.java b/apps/webchat/source/java/org/jivesoftware/webchat/URLTranscoder.java
new file mode 100644
index 000000000..84310eca0
--- /dev/null
+++ b/apps/webchat/source/java/org/jivesoftware/webchat/URLTranscoder.java
@@ -0,0 +1,188 @@
+/**
+ * $RCSfile$
+ * $Revision$
+ * $Date$
+ *
+ * Copyright (C) 1999-2003 Jive Software. All rights reserved.
+ *
+ * This software is the proprietary information of Jive Software.
+ * Use is subject to license terms.
+ */
+
+package org.jivesoftware.webchat;
+
+import java.util.*;
+
+/**
+ * This is a really good example of why software development projects have frameworks, and the
+ * other apps in their own modules that sit on top of the frameworks... this class should not
+ * be confused with com.jivesoftware.messenger.operator.util.URLTranscoder, which does a
+ * variant of the functionality found here.
+ *
+ * The default set of patterns recognized are ftp://path-of-url
,
+ * http://path-of-url
, https://path-of-url
but can be expanded upon.
+ *
+ * This was originally URLTranscoder, from CoolServlets, but that class did basically nothing that
+ * i wanted, so i kept the schemes collection and that was about it.
+ *
+ * @author loki der quaeler
+ */
+public class URLTranscoder {
+
+ static protected final String A_HREF_PREFIX = "";
+ static protected final String A_HREF_CLOSING_TAG = "";
+
+
+ protected ArrayList schemes;
+
+ public URLTranscoder () {
+ super();
+
+ this.schemes = new ArrayList();
+
+ this.schemes.add("http://");
+ this.schemes.add("https://");
+ this.schemes.add("ftp://");
+ }
+
+ /**
+ * Sets the current supported uri schemes.
+ *
+ * @param schemeCollection a collection of String instances of uri schemes.
+ */
+ public synchronized void setSchemes (Collection schemeCollection) {
+ // MAY EXIT THIS BLOCK
+ if (schemes == null) {
+ return;
+ }
+
+ this.schemes.clear();
+
+ this.schemes.addAll(schemeCollection);
+ }
+
+ /**
+ * Returns a String based off the original text, but now with any a.href blocks html-ized
+ * inside. (for example, supplying the string "this: http://dict.leo.org/ is a cool url"
+ * returns "this: http://dict.leo.org/
+ * is a cool url"
+ */
+ public String encodeURLsInText (String text) {
+ StringBuffer rhett = null;;
+ List runs = this.getURLRunsInString(text);
+ Iterator it = null;
+ int lastStart = 0;
+
+ // MAY RETURN THIS BLOCK
+ if (runs.size() == 0) {
+ return text;
+ }
+
+ rhett = new StringBuffer();
+ it = runs.iterator();
+ while (it.hasNext()) {
+ URLRun run = (URLRun)it.next();
+ String url = text.substring(run.getStartIndex(), run.getEndIndex());
+
+ if (lastStart < run.getStartIndex()) {
+ rhett.append(text.substring(lastStart, run.getStartIndex()));
+
+ lastStart += run.getEndIndex();
+ }
+
+ rhett.append(A_HREF_PREFIX).append(url).append(A_HREF_SUFFIX).append(url);
+ rhett.append(A_HREF_CLOSING_TAG);
+ }
+
+ if (lastStart < text.length()) {
+ rhett.append(text.substring(lastStart, text.length()));
+ }
+
+ return rhett.toString();
+ }
+
+ protected List getURLRunsInString (String text) {
+ ArrayList rhett = new ArrayList();
+ Vector vStarts = new Vector();
+ Iterator sIt = this.schemes.iterator();
+ Integer[] iStarts = null;
+ char[] tArray = null;
+
+ while (sIt.hasNext()) {
+ String scheme = (String)sIt.next();
+ int index = text.indexOf(scheme);
+
+ while (index != -1) {
+ vStarts.add(new Integer(index));
+
+ index = text.indexOf(scheme, (index + 1));
+ }
+ }
+
+ // MAY RETURN THIS BLOCK
+ if (vStarts.size() == 0) {
+ return rhett;
+ }
+
+ iStarts = (Integer[])vStarts.toArray(new Integer[0]);
+ Arrays.sort(iStarts);
+
+ tArray = text.toCharArray();
+
+ for (int i = 0; i < iStarts.length; i++) {
+ int start = iStarts[i].intValue();
+ int end = start + 1;
+
+ while ((end < tArray.length) && (! this.characterIsURLTerminator(tArray[end]))) {
+ end++;
+ }
+
+ if (end == tArray.length) {
+ end--;
+ }
+
+ rhett.add(new URLRun(start, end));
+ }
+
+ return rhett;
+ }
+
+ protected boolean characterIsURLTerminator (char c) {
+ switch (c) {
+ case ' ':
+ case '\n':
+ case '(':
+ case ')':
+ case '>':
+ case '\t':
+ case '\r': return true;
+ }
+
+ return false;
+ }
+
+
+ protected class URLRun {
+
+ protected int start;
+ protected int end;
+
+ protected URLRun (int s, int e) {
+ super();
+
+ this.start = s;
+ this.end = e;
+ }
+
+ protected int getStartIndex () {
+ return this.start;
+ }
+
+ protected int getEndIndex () {
+ return this.end;
+ }
+
+ }
+
+}
\ No newline at end of file