Bug 431768: Relative links don't work in Javadoc from overridden binary method with attached Javadoc
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/infoviews/JavadocView.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/infoviews/JavadocView.java
index 89a4ae1..35b199d 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/infoviews/JavadocView.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/infoviews/JavadocView.java
@@ -1049,7 +1049,10 @@
 				try {
 					boolean isBinary= root.getKind() == IPackageFragmentRoot.K_BINARY;
 					if (content != null) {
-						base= JavaDocLocations.getBaseURL(curr, isBinary);
+						base= JavadocContentAccess2.extractBaseURL(content);
+						if (base == null) {
+							base= JavaDocLocations.getBaseURL(curr, isBinary);
+						}
 						reader= new StringReader(content);
 					} else if (reader == null) {
 						String explanationForMissingJavadoc= JavaDocLocations.getExplanationForMissingJavadoc(curr, root);
@@ -1108,7 +1111,10 @@
 						} else {
 							member= (IMember) element;
 						}
-						base= JavaDocLocations.getBaseURL(member, member.isBinary());
+						base= JavadocContentAccess2.extractBaseURL(content);
+						if (base == null) {
+							base= JavaDocLocations.getBaseURL(member, member.isBinary());
+						}
 						reader= new StringReader(content);
 					} else {
 						String explanationForMissingJavadoc= JavaDocLocations.getExplanationForMissingJavadoc(element, root);
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/AbstractJavaCompletionProposal.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/AbstractJavaCompletionProposal.java
index ececa16..5549462 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/AbstractJavaCompletionProposal.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/AbstractJavaCompletionProposal.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2013 IBM Corporation and others.
+ * Copyright (c) 2005, 2014 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -97,6 +97,7 @@
 import org.eclipse.jdt.internal.ui.JavaPlugin;
 import org.eclipse.jdt.internal.ui.text.java.hover.JavadocBrowserInformationControlInput;
 import org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover;
+import org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2;
 
 
 /**
@@ -583,7 +584,10 @@
 				try {
 					element= getProposalInfo().getJavaElement();
 					if (element instanceof IMember) {
-						String base= JavaDocLocations.getBaseURL(element, ((IMember) element).isBinary());
+						String base= JavadocContentAccess2.extractBaseURL(info);
+						if (base == null) {
+							base= JavaDocLocations.getBaseURL(element, ((IMember) element).isBinary());
+						}
 						if (base != null) {
 							int endHeadIdx= buffer.indexOf("</head>"); //$NON-NLS-1$
 							buffer.insert(endHeadIdx, "\n<base href='" + base + "'>\n"); //$NON-NLS-1$ //$NON-NLS-2$
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/hover/JavadocHover.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/hover/JavadocHover.java
index 1db5410..b080616 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/hover/JavadocHover.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/hover/JavadocHover.java
@@ -692,7 +692,10 @@
 					IPackageFragmentRoot root= (IPackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
 					boolean isBinary= root.exists() && root.getKind() == IPackageFragmentRoot.K_BINARY;
 					if (content != null) {
-						base= JavaDocLocations.getBaseURL(element, isBinary);
+						base= JavadocContentAccess2.extractBaseURL(content);
+						if (base == null) {
+							base= JavaDocLocations.getBaseURL(element, isBinary);
+						}
 						reader= new StringReader(content);
 					} else {
 						String explanationForMissingJavadoc= JavaDocLocations.getExplanationForMissingJavadoc(element, root);
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/javadoc/JavadocContentAccess2.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/javadoc/JavadocContentAccess2.java
index 0e2f901..79a9b8f 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/javadoc/JavadocContentAccess2.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/javadoc/JavadocContentAccess2.java
@@ -91,6 +91,7 @@
 import org.eclipse.jdt.core.dom.TextElement;
 
 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
+import org.eclipse.jdt.internal.corext.javadoc.JavaDocLocations;
 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
 import org.eclipse.jdt.internal.corext.util.JdtFlags;
 import org.eclipse.jdt.internal.corext.util.Messages;
@@ -119,6 +120,8 @@
  */
 public class JavadocContentAccess2 {
 
+	private static final String BASE_URL_COMMENT_INTRO= "<!-- baseURL=\""; //$NON-NLS-1$
+	
 	private static final String BLOCK_TAG_START= "<dl>"; //$NON-NLS-1$
 	private static final String BLOCK_TAG_END= "</dl>"; //$NON-NLS-1$
 
@@ -831,11 +834,17 @@
 					return InheritDocVisitor.CONTINUE;
 
 				if (overridden.getOpenable().getBuffer() == null) { // only if no source available
-					//TODO: BaseURL for method can be wrong for attached Javadoc from overridden
-					// (e.g. when overridden is from rt.jar). Fix would be to add baseURL here.
 					String attachedJavadoc= overridden.getAttachedJavadoc(null);
-					if (attachedJavadoc != null)
+					if (attachedJavadoc != null) {
+						// BaseURL for the original method can be wrong for attached Javadoc from overridden
+						// (e.g. when overridden is from rt.jar).
+						// Fix is to store the baseURL inside the doc content and later fetch it with #extractBaseURL(String).
+						String baseURL= JavaDocLocations.getBaseURL(overridden, overridden.isBinary());
+						if (baseURL != null) {
+							attachedJavadoc= BASE_URL_COMMENT_INTRO + baseURL + "\"--> " + attachedJavadoc; //$NON-NLS-1$
+						}
 						return attachedJavadoc;
+					}
 				}
 				return CONTINUE;
 			}
@@ -1947,6 +1956,23 @@
 	}
 
 	/**
+	 * @param content HTML content produced by <code>getHTMLContent(...)</code>
+	 * @return the baseURL to use for the given content, or <code>null</code> if none
+	 * @since 3.10
+	 */
+	public static String extractBaseURL(String content) {
+		int introStart= content.indexOf(BASE_URL_COMMENT_INTRO);
+		if (introStart != -1) {
+			int introLength= BASE_URL_COMMENT_INTRO.length();
+			int endIndex= content.indexOf('"', introStart + introLength);
+			if (endIndex != -1) {
+				return content.substring(introStart + introLength, endIndex);
+			}
+		}
+		return null;
+	}
+
+	/**
 	 * Returns the Javadoc for a PackageDeclaration.
 	 * 
 	 * @param packageDeclaration the Java element whose Javadoc has to be retrieved