Created
September 21, 2010 12:21
-
-
Save anonymous/589600 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* ver0.1 殴り書き | |
* ver0.2 半角スペースを含んでいる場合に、別の文節として処理できるように修正 | |
* ver0.3 課題を模索中 | |
* ver0.4 リファクタリング & エスケープ処理以外はほぼ完成 | |
* ver0.5 HTML用エスケープ処理を実装 & テストコード拡充 | |
*/ | |
public class Autolink { | |
/* | |
* ブランクを、(半角スペース || タブ || 全角スペース)と定義する | |
*/ | |
public static final String PATTERN_BLANK = " |\t| "; | |
/* | |
* Test code | |
*/ | |
public static void main(String[] args) { | |
Autolink a = new Autolink(); | |
// normal test | |
String code1 = a.expandString("リンク http://example.com/"); | |
String code2 = a.expandString("https://twitter.com/"); | |
String code3 = a.expandString("@liquidfunc こんにちはこんにちは!!"); | |
String code4 = a.expandString("#nicovideo"); | |
String code5 = a.expandString("hoge"); | |
// xss test | |
String code6 = a.expandString("<>&\"'<>&\"'<>&\"'"); | |
String code7 = a.expandString("@javascript:alert('hello');"); | |
String code8 = a.expandString("<script>alert('hello');</script>"); | |
String code9 = a.expandString("<script src=\"http://example.jp/malicious.js\">"); | |
// HTML maker | |
StringBuilder sb = new StringBuilder(); | |
sb.append("<html>\n"); | |
sb.append("<head>\n"); | |
sb.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n"); | |
sb.append("</head>\n"); | |
sb.append("<body>\n"); | |
sb.append("<pre>\n"); | |
sb.append(code1).append("\n"); | |
sb.append(code2).append("\n"); | |
sb.append(code3).append("\n"); | |
sb.append(code4).append("\n"); | |
sb.append(code5).append("\n"); | |
sb.append(code6).append("\n"); | |
sb.append(code7).append("\n"); | |
sb.append(code8).append("\n"); | |
sb.append(code9).append("\n"); | |
sb.append("</pre>\n"); | |
sb.append("</body>\n"); | |
sb.append("</html>\n"); | |
System.out.println(sb.toString()); | |
} | |
/* | |
* URL: http,httpsのURLを、そのURLへリンクする | |
* @: @(ユーザid)を、http://twitter.com/(ユーザid)へリンクする | |
* ハッシュタグ: #(ハッシュタグ名)を、http://twitter.com/#search&q=%23(ハッシュタグ名)へリンクする | |
*/ | |
public String expandString(String str) { | |
String escapedStr = escape(str); | |
String[] words = escapedStr.split(PATTERN_BLANK); | |
StringBuilder sb = new StringBuilder(140); | |
for (String s : words) { | |
if (s.startsWith("http://") || s.startsWith("https://")) { | |
sb.append(makeHttpLink(s)); | |
} else if (s.startsWith("@")) { | |
sb.append(makeUserLink(s)); | |
} else if (s.startsWith("#")) { | |
sb.append(makeHashLink(s)); | |
} else { | |
sb.append(s); | |
} | |
sb.append(" "); | |
} | |
return sb.toString().trim(); | |
} | |
/* | |
* '<', '>', '&', '"', '''の5文字を文字参照へとエスケープする。 | |
*/ | |
public String escape(String str) { | |
StringBuilder sb = new StringBuilder(140); | |
for (char c : str.toCharArray()) { | |
switch (c) { | |
case '<': | |
sb.append("<"); | |
break; | |
case '>': | |
sb.append(">"); | |
break; | |
case '&': | |
sb.append("&"); | |
break; | |
case '"': | |
sb.append("""); | |
break; | |
case '\'': | |
sb.append("'"); | |
break; | |
default: | |
sb.append(c); | |
} | |
} | |
return sb.toString(); | |
} | |
/* | |
* <a href="{url}">{value}</a>の形式で、HTMLリンクを作成する。 | |
*/ | |
public String makeLink(String url, String value) { | |
StringBuilder sb = new StringBuilder(140); | |
sb.append("<a href=\""); | |
sb.append(url); | |
sb.append("\">"); | |
sb.append(value); | |
sb.append("</a>"); | |
return sb.toString(); | |
} | |
public String makeHttpLink(String str) { | |
return makeLink(str, str); | |
} | |
public String makeUserLink(String str) { | |
String url = "http://twitter.com/" + str.substring(1); | |
return makeLink(url, str); | |
} | |
public String makeHashLink(String str) { | |
String url = "http://twitter.com/#search?q=%23" + str.substring(1); | |
return makeLink(url, str); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment