536664: add default target to linked javadocs

Change-Id: I698b53cf0db3f29b51a374a8ea9226f2360a22f3
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=536664
diff --git a/wikitext/core/org.eclipse.mylyn.wikitext.ant/src/test/java/org/eclipse/mylyn/wikitext/ant/internal/MarkupToHtmlTaskTest.java b/wikitext/core/org.eclipse.mylyn.wikitext.ant/src/test/java/org/eclipse/mylyn/wikitext/ant/internal/MarkupToHtmlTaskTest.java
index e50b8c9..c352902 100644
--- a/wikitext/core/org.eclipse.mylyn.wikitext.ant/src/test/java/org/eclipse/mylyn/wikitext/ant/internal/MarkupToHtmlTaskTest.java
+++ b/wikitext/core/org.eclipse.mylyn.wikitext.ant/src/test/java/org/eclipse/mylyn/wikitext/ant/internal/MarkupToHtmlTaskTest.java
@@ -221,7 +221,8 @@
 
 		String content = getContent(htmlFile);
 
-		assertTrue(content, content.contains("<a href=\"index.html?org/eclipse/mylyn/wikitext/Test.html\">Test</a>"));
+		assertTrue(content, content
+				.contains("<a href=\"index.html?org/eclipse/mylyn/wikitext/Test.html\" target=\"_javadoc\">Test</a>"));
 	}
 
 	protected File createSimpleTextileMarkup() throws IOException {
diff --git a/wikitext/core/org.eclipse.mylyn.wikitext/src/main/java/org/eclipse/mylyn/wikitext/parser/builder/HtmlDocumentBuilder.java b/wikitext/core/org.eclipse.mylyn.wikitext/src/main/java/org/eclipse/mylyn/wikitext/parser/builder/HtmlDocumentBuilder.java
index af89cb5..feda0b3 100644
--- a/wikitext/core/org.eclipse.mylyn.wikitext/src/main/java/org/eclipse/mylyn/wikitext/parser/builder/HtmlDocumentBuilder.java
+++ b/wikitext/core/org.eclipse.mylyn.wikitext/src/main/java/org/eclipse/mylyn/wikitext/parser/builder/HtmlDocumentBuilder.java
@@ -30,6 +30,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Objects;
 import java.util.Stack;
 import java.util.regex.Pattern;
 
@@ -1102,8 +1103,16 @@
 		if (!hasTarget && defaultAbsoluteLinkTarget != null && href != null) {
 			if (isExternalLink(href)) {
 				writer.writeAttribute("target", defaultAbsoluteLinkTarget); //$NON-NLS-1$
+				hasTarget = true;
 			}
 		}
+		if (!hasTarget) {
+			linkUriProcessors.stream()
+					.map(s -> s.target(href))
+					.filter(Objects::nonNull)
+					.findFirst()
+					.ifPresent(target -> writer.writeAttribute("target", target));
+		}
 
 		if (rel != null) {
 			writer.writeAttribute("rel", rel); //$NON-NLS-1$
diff --git a/wikitext/core/org.eclipse.mylyn.wikitext/src/main/java/org/eclipse/mylyn/wikitext/parser/builder/JavadocShortcutUriProcessor.java b/wikitext/core/org.eclipse.mylyn.wikitext/src/main/java/org/eclipse/mylyn/wikitext/parser/builder/JavadocShortcutUriProcessor.java
index 78b744b..38f4123 100644
--- a/wikitext/core/org.eclipse.mylyn.wikitext/src/main/java/org/eclipse/mylyn/wikitext/parser/builder/JavadocShortcutUriProcessor.java
+++ b/wikitext/core/org.eclipse.mylyn.wikitext/src/main/java/org/eclipse/mylyn/wikitext/parser/builder/JavadocShortcutUriProcessor.java
@@ -34,6 +34,8 @@
  */
 public class JavadocShortcutUriProcessor implements UriProcessor {
 
+	private static final String TARGET = "_javadoc";
+
 	private static final String JAVADOC_URI_MARKER = "@";
 
 	private static final String JAVADOC_ABSOLUTE_URI_MARKER = "javadoc://";
@@ -57,13 +59,7 @@
 
 	@Override
 	public String process(String uri) {
-		String newUri = uri;
-		if (newUri.startsWith(JAVADOC_ABSOLUTE_URI_MARKER) && newUri.length() > JAVADOC_ABSOLUTE_URI_MARKER.length()) {
-			newUri = newUri.substring(JAVADOC_ABSOLUTE_URI_MARKER.length());
-		}
-		if (newUri.startsWith(JAVADOC_URI_MARKER) && newUri.length() > JAVADOC_URI_MARKER.length()) {
-			newUri = uri.substring(JAVADOC_URI_MARKER.length());
-		}
+		String newUri = preprocessUri(uri);
 		if (!newUri.equals(uri)) {
 			newUri = prependWithBasePackage(newUri);
 			if (SourceVersion.isName(newUri)) {
@@ -76,6 +72,25 @@
 		return uri;
 	}
 
+	@Override
+	public String target(String uri) {
+		if (!preprocessUri(uri).equals(uri)) {
+			return TARGET;
+		}
+		return null;
+	}
+
+	private String preprocessUri(String uri) {
+		String newUri = uri;
+		if (newUri.startsWith(JAVADOC_ABSOLUTE_URI_MARKER) && newUri.length() > JAVADOC_ABSOLUTE_URI_MARKER.length()) {
+			newUri = newUri.substring(JAVADOC_ABSOLUTE_URI_MARKER.length());
+		}
+		if (newUri.startsWith(JAVADOC_URI_MARKER) && newUri.length() > JAVADOC_URI_MARKER.length()) {
+			newUri = uri.substring(JAVADOC_URI_MARKER.length());
+		}
+		return newUri;
+	}
+
 	private String toTypePage(String newUri) {
 		return javadocFramePage() + "?" + newUri.replace('.', '/') + ".html";
 	}
diff --git a/wikitext/core/org.eclipse.mylyn.wikitext/src/main/java/org/eclipse/mylyn/wikitext/parser/builder/UriProcessor.java b/wikitext/core/org.eclipse.mylyn.wikitext/src/main/java/org/eclipse/mylyn/wikitext/parser/builder/UriProcessor.java
index d9b1ba9..5ffe654 100644
--- a/wikitext/core/org.eclipse.mylyn.wikitext/src/main/java/org/eclipse/mylyn/wikitext/parser/builder/UriProcessor.java
+++ b/wikitext/core/org.eclipse.mylyn.wikitext/src/main/java/org/eclipse/mylyn/wikitext/parser/builder/UriProcessor.java
@@ -25,4 +25,15 @@
 	 * @return the new URI, or the original if there were no changes to apply
 	 */
 	String process(String uri);
+
+	/**
+	 * Provides a target for the given URI.
+	 * 
+	 * @param uri
+	 *            the URI
+	 * @return the target, or null
+	 */
+	default String target(String uri) {
+		return null;
+	}
 }
diff --git a/wikitext/core/org.eclipse.mylyn.wikitext/src/test/java/org/eclipse/mylyn/wikitext/parser/builder/HtmlDocumentBuilderTest.java b/wikitext/core/org.eclipse.mylyn.wikitext/src/test/java/org/eclipse/mylyn/wikitext/parser/builder/HtmlDocumentBuilderTest.java
index 6d57377..a1f8c4a 100644
--- a/wikitext/core/org.eclipse.mylyn.wikitext/src/test/java/org/eclipse/mylyn/wikitext/parser/builder/HtmlDocumentBuilderTest.java
+++ b/wikitext/core/org.eclipse.mylyn.wikitext/src/test/java/org/eclipse/mylyn/wikitext/parser/builder/HtmlDocumentBuilderTest.java
@@ -255,11 +255,22 @@
 	@Test
 	public void addLinkUriProcessor() {
 		builder.setEmitAsDocument(false);
-		builder.addLinkUriProcessor(h -> "a-target");
+		builder.addLinkUriProcessor(new UriProcessor() {
+
+			@Override
+			public String process(String uri) {
+				return "a-uri";
+			}
+
+			@Override
+			public String target(String uri) {
+				return "a-target";
+			}
+		});
 		builder.beginDocument();
 		builder.link("something", "text");
 		builder.endDocument();
-		assertEquals("<a href=\"a-target\">text</a>", out.toString());
+		assertEquals("<a href=\"a-uri\" target=\"a-target\">text</a>", out.toString());
 	}
 
 	@Test
diff --git a/wikitext/core/org.eclipse.mylyn.wikitext/src/test/java/org/eclipse/mylyn/wikitext/parser/builder/JavadocShortcutUriProcessorTest.java b/wikitext/core/org.eclipse.mylyn.wikitext/src/test/java/org/eclipse/mylyn/wikitext/parser/builder/JavadocShortcutUriProcessorTest.java
index 4a21864..171d1ff 100644
--- a/wikitext/core/org.eclipse.mylyn.wikitext/src/test/java/org/eclipse/mylyn/wikitext/parser/builder/JavadocShortcutUriProcessorTest.java
+++ b/wikitext/core/org.eclipse.mylyn.wikitext/src/test/java/org/eclipse/mylyn/wikitext/parser/builder/JavadocShortcutUriProcessorTest.java
@@ -66,4 +66,11 @@
 	public void processMalformedName() {
 		assertEquals("@foo-bar", processor.process("@foo-bar"));
 	}
+
+	@Test
+	public void target() {
+		assertEquals("_javadoc", processor.target("@.Foo"));
+		assertEquals(null, processor.target("Foo"));
+
+	}
 }