From 9bd333482dc7fd7804bc522631ad7eca6e456ef2 Mon Sep 17 00:00:00 2001 From: kohsuke Date: Thu, 11 Mar 2010 17:44:31 +0000 Subject: [PATCH] URLs in the console output are now hyperlinks. git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@28514 71c3de6d-444a-0410-be80-ed276b4c234a --- core/src/main/java/hudson/MarkupText.java | 7 ++++ .../console/ConsoleAnnotatorFactory.java | 4 +++ .../java/hudson/console/UrlAnnotator.java | 31 ++++++++++++++++ .../java/hudson/console/UrlAnnotatorTest.java | 35 +++++++++++++++++++ 4 files changed, 77 insertions(+) create mode 100644 core/src/main/java/hudson/console/UrlAnnotator.java create mode 100644 test/src/test/java/hudson/console/UrlAnnotatorTest.java diff --git a/core/src/main/java/hudson/MarkupText.java b/core/src/main/java/hudson/MarkupText.java index 5196fe4fe2..2a7b813659 100644 --- a/core/src/main/java/hudson/MarkupText.java +++ b/core/src/main/java/hudson/MarkupText.java @@ -119,6 +119,13 @@ public class MarkupText extends AbstractMarkupText { addMarkup(0,length(),startTag,endTag); } + /** + * Surrounds this subtext with <a>...</a>. + */ + public void href(String url) { + addHyperlink(0,length(),url); + } + /** * Gets the start index of the captured group within {@link MarkupText#getText()}. * diff --git a/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java b/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java index c4c06356b1..7cf4fd4601 100644 --- a/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java +++ b/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java @@ -23,6 +23,7 @@ */ package hudson.console; +import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.model.Hudson; @@ -53,6 +54,9 @@ import java.net.URL; * Because of this, {@link ConsoleAnnotatorFactory} is generally suitable for peep-hole local annotation * that only requires a small contextual information, such as keyword coloring, URL hyperlinking, and so on. * + *

+ * To register, put @{@link Extension} on your {@link ConsoleAnnotatorFactory} subtype. + * * @author Kohsuke Kawaguchi * @since 1.349 */ diff --git a/core/src/main/java/hudson/console/UrlAnnotator.java b/core/src/main/java/hudson/console/UrlAnnotator.java new file mode 100644 index 0000000000..89c71c77c3 --- /dev/null +++ b/core/src/main/java/hudson/console/UrlAnnotator.java @@ -0,0 +1,31 @@ +package hudson.console; + +import hudson.Extension; +import hudson.MarkupText; +import hudson.MarkupText.SubText; + +import java.util.regex.Pattern; + +/** + * Annotates URLs in the console output to hyperlink. + * + * @author Kohsuke Kawaguchi + */ +@Extension +public class UrlAnnotator extends ConsoleAnnotatorFactory { + @Override + public ConsoleAnnotator newInstance(Object context) { + return new UrlConsoleAnnotator(); + } + + private static class UrlConsoleAnnotator extends ConsoleAnnotator { + public ConsoleAnnotator annotate(Object context, MarkupText text) { + for (SubText t : text.findTokens(URL)) + t.href(t.getText()); + return this; + } + + private static final long serialVersionUID = 1L; + private static final Pattern URL = Pattern.compile("\\b(http|https|ftp)://[^\\s<>]+"); + } +} diff --git a/test/src/test/java/hudson/console/UrlAnnotatorTest.java b/test/src/test/java/hudson/console/UrlAnnotatorTest.java new file mode 100644 index 0000000000..62bdb0d05c --- /dev/null +++ b/test/src/test/java/hudson/console/UrlAnnotatorTest.java @@ -0,0 +1,35 @@ +package hudson.console; + +import com.gargoylesoftware.htmlunit.html.HtmlPage; +import hudson.Launcher; +import hudson.model.AbstractBuild; +import hudson.model.BuildListener; +import hudson.model.FreeStyleBuild; +import hudson.model.FreeStyleProject; +import org.jvnet.hudson.test.HudsonTestCase; +import org.jvnet.hudson.test.TestBuilder; + +import java.io.IOException; + +/** + * @author Kohsuke Kawaguchi + */ +public class UrlAnnotatorTest extends HudsonTestCase { + public void test1() throws Exception { + FreeStyleProject p = createFreeStyleProject(); + p.getBuildersList().add(new TestBuilder() { + @Override + public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { + listener.getLogger().println("http://www.sun.com/"); + listener.getLogger().println(""); + return true; + } + }); + FreeStyleBuild b = buildAndAssertSuccess(p); + + HtmlPage c = createWebClient().getPage(b, "console"); + String rsp = c.getWebResponse().getContentAsString(); + assertTrue(rsp, rsp.contains("http://www.sun.com/")); + assertTrue(rsp, rsp.contains("http://www.kohsuke.org/")); + } +}