1 /** 2 * Licensed under the Artistic License; you may not use this file 3 * except in compliance with the License. 4 * You may obtain a copy of the License at 5 * 6 * http://displaytag.sourceforge.net/license.html 7 * 8 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR 9 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 10 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 11 */ 12 package org.displaytag.decorator; 13 14 import javax.servlet.jsp.PageContext; 15 16 import org.apache.commons.lang.ArrayUtils; 17 import org.apache.commons.lang.StringUtils; 18 import org.displaytag.properties.MediaTypeEnum; 19 import org.displaytag.util.TagConstants; 20 21 22 /** 23 * This takes the string that is passed in, and "auto-links" it, it turns email addresses into hyperlinks, and also 24 * turns things that looks like URLs into hyperlinks as well. 25 * @author Fabrizio Giustina 26 * @version $Revision: 1081 $ ($Author: fgiust $) 27 */ 28 public class AutolinkColumnDecorator implements DisplaytagColumnDecorator 29 { 30 31 /** 32 * Instance used for the "autolink" tag attribute. 33 */ 34 public static final DisplaytagColumnDecorator INSTANCE = new AutolinkColumnDecorator(); 35 36 /** 37 * "://". 38 */ 39 private static final String URL_DELIM = "://"; //$NON-NLS-1$ 40 41 /** 42 * Urls. 43 */ 44 private static final String[] URLS_PREFIXES = // 45 new String[]{"http", "https", "ftp"}; //$NON-NLS-1$ //$NON-NLS-1$ //$NON-NLS-1$ 46 47 /** 48 * @see org.displaytag.decorator.DisplaytagColumnDecorator#decorate(Object, PageContext, MediaTypeEnum) 49 */ 50 public Object decorate(Object columnValue, PageContext pageContext, MediaTypeEnum media) 51 { 52 53 if (columnValue == null) 54 { 55 return null; 56 } 57 String work = columnValue.toString(); 58 59 int urlBegin; 60 StringBuffer buffer = new StringBuffer(); 61 62 // First check for email addresses. 63 while ((urlBegin = work.indexOf('@')) != -1) 64 { 65 int start = 0; 66 int end = work.length() - 1; 67 68 // scan backwards... 69 for (int j = urlBegin; j >= 0; j--) 70 { 71 if (Character.isWhitespace(work.charAt(j))) 72 { 73 start = j + 1; 74 break; 75 } 76 } 77 78 // scan forwards... 79 for (int j = urlBegin; j <= end; j++) 80 { 81 if (Character.isWhitespace(work.charAt(j))) 82 { 83 end = j - 1; 84 break; 85 } 86 } 87 88 String email = work.substring(start, end + 1); 89 90 buffer.append(work.substring(0, start)).append("<a href=\"mailto:") //$NON-NLS-1$ 91 .append(email + "\">") //$NON-NLS-1$ 92 .append(email).append("</a>"); //$NON-NLS-1$ 93 94 if (end == work.length()) 95 { 96 work = TagConstants.EMPTY_STRING; 97 } 98 else 99 { 100 work = work.substring(end + 1); 101 } 102 } 103 104 work = buffer.toString() + work; 105 buffer = new StringBuffer(); 106 107 // Now check for urls... 108 while ((urlBegin = work.indexOf(URL_DELIM)) != -1) 109 { 110 111 // scan backwards... 112 int fullUrlBegin = urlBegin; 113 StringBuffer prefixBuffer = new StringBuffer(10); 114 for (int j = fullUrlBegin - 1; j >= 0; j--) 115 { 116 if (Character.isWhitespace(work.charAt(j))) 117 { 118 fullUrlBegin = j + 1; 119 break; 120 } 121 fullUrlBegin = j; 122 prefixBuffer.append(work.charAt(j)); 123 } 124 125 if (!ArrayUtils.contains(URLS_PREFIXES, StringUtils.reverse(prefixBuffer.toString()))) 126 { 127 128 buffer.append(work.substring(0, urlBegin + 3)); 129 work = work.substring(urlBegin + 3); 130 continue; 131 } 132 133 int urlEnd = work.length(); 134 135 // scan forwards... 136 for (int j = urlBegin; j < urlEnd; j++) 137 { 138 if (Character.isWhitespace(work.charAt(j))) 139 { 140 urlEnd = j; 141 break; 142 } 143 } 144 145 String url = work.substring(fullUrlBegin, urlEnd); 146 147 buffer.append(work.substring(0, fullUrlBegin)).append("<a href=\"")//$NON-NLS-1$ 148 .append(url).append("\">")//$NON-NLS-1$ 149 .append(url).append("</a>"); //$NON-NLS-1$ 150 151 if (urlEnd >= work.length()) 152 { 153 work = TagConstants.EMPTY_STRING; 154 } 155 else 156 { 157 work = work.substring(urlEnd); 158 } 159 } 160 161 buffer.append(work); 162 return buffer.toString(); 163 } 164 165 }