diff options
author | Jayaprakash Arthanareeswaran | 2014-04-09 09:27:14 +0000 |
---|---|---|
committer | Jayaprakash Arthanareeswaran | 2014-04-09 14:04:28 +0000 |
commit | d43bd70d5c6c4fa98b6c25564f2818572a108eac (patch) | |
tree | dc0b0cabf21a717b413eab8f15ff41aa4a266e57 | |
parent | cd169c7695d941d4918a15490c18d5c9ea399e1c (diff) | |
download | eclipse.jdt.core-d43bd70d5c6c4fa98b6c25564f2818572a108eac.tar.gz eclipse.jdt.core-d43bd70d5c6c4fa98b6c25564f2818572a108eac.tar.xz eclipse.jdt.core-d43bd70d5c6c4fa98b6c25564f2818572a108eac.zip |
Bug 403154 - IJavaElement.getAttachedJavadoc(IProgressMonitor) should
throw exception if base URL is wrong
4 files changed, 142 insertions, 6 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java index d441819d73..0ddf66498b 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java @@ -96,6 +96,7 @@ public class AttachedJavadocTests extends ModifyingResourceTests { suite.addTest(new AttachedJavadocTests("testBug394382")); suite.addTest(new AttachedJavadocTests("testBug398272")); suite.addTest(new AttachedJavadocTests("testBug426058")); + suite.addTest(new AttachedJavadocTests("testBug403154")); return suite; } @@ -1232,4 +1233,99 @@ public class AttachedJavadocTests extends ModifyingResourceTests { this.project.setRawClasspath(oldClasspath, null); } } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=403154 + public void testBug403154() throws Exception { + IClasspathEntry[] oldClasspath = this.project.getRawClasspath(); + try { + IResource invalid = this.project.getProject().getFolder("invalid"); + IResource valid = this.project.getProject().getFolder("valid"); + createFolder("/AttachedJavadocProject/valid"); + URL validUrl = null; + URL invalidUrl = null; + try { + validUrl = valid.getLocationURI().toURL(); + invalidUrl = invalid.getLocationURI().toURL(); + } catch (Exception e) { + fail("Should not be an exception"); + } + addLibrary(this.project, "valid.jar", null, + new String[]{ + "p/X.java", + "package p;\n" + + "/** Javadoc for class X */\n" + + "public class X {}" }, + JavaCore.VERSION_1_4); + addLibrary(this.project, "invalid.jar", null, + new String[]{ + "q/Y.java", + "package q;\n" + + "/** Javadoc for class Y */\n" + + "public class Y {}" }, + JavaCore.VERSION_1_4); + + IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, validUrl.toExternalForm()); + IClasspathEntry validEntry = + JavaCore.newLibraryEntry(new Path("/AttachedJavadocProject/valid.jar"), + null, + null, + new IAccessRule[]{}, + new IClasspathAttribute[] { attribute }, + false); + + attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, invalidUrl.toExternalForm()); + IClasspathEntry invalidEntry = + JavaCore.newLibraryEntry(new Path("/AttachedJavadocProject/invalid.jar"), + null, + null, + new IAccessRule[]{}, + new IClasspathAttribute[] { attribute }, + false); + + IClasspathEntry[] newClasspath = new IClasspathEntry[oldClasspath.length + 2]; + System.arraycopy(oldClasspath, 0, newClasspath, 0, oldClasspath.length); + newClasspath[oldClasspath.length] = validEntry; + newClasspath[oldClasspath.length + 1] = invalidEntry; + this.project.setRawClasspath(newClasspath, null); + waitForAutoBuild(); + + IPackageFragmentRoot[] roots = this.project.getAllPackageFragmentRoots(); + IPackageFragmentRoot validRoot = null; + IPackageFragmentRoot invalidRoot = null; + for(int i=0; i < roots.length; i++) { + IPath path = roots[i].getPath(); + if (path.segment(path.segmentCount() - 1).equals("valid.jar")) { + validRoot = roots[i]; + } else if (path.segment(path.segmentCount() - 1).equals("invalid.jar")) { + invalidRoot = roots[i]; + } + } + + IPackageFragment packageFragment = validRoot.getPackageFragment("p"); + IClassFile classFile = packageFragment.getClassFile("X.class"); + IType type = classFile.getType(); + String javadoc = null; + try { + javadoc = type.getAttachedJavadoc(new NullProgressMonitor()); + } catch(JavaModelException e) { + fail("Should not throw JavaModelException"); + } + assertNull("Should not have a javadoc", javadoc); + + packageFragment = invalidRoot.getPackageFragment("q"); + classFile = packageFragment.getClassFile("Y.class"); + type = classFile.getType(); + try { + type.getAttachedJavadoc(new NullProgressMonitor()); + fail("Should throw JavaModelException"); + } catch(JavaModelException e) { + // This is expected + } + } catch(Exception e) { + // ignore + } + finally { + deleteFolder("/AttachedJavadocProject/valid"); + this.project.setRawClasspath(oldClasspath, null); + } + } } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java index e26c0b820c..de21d04422 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation and others. + * Copyright (c) 2000, 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 @@ -1035,7 +1035,7 @@ public JavadocContents getJavadocContents(IProgressMonitor monitor) throws JavaM pathBuffer.append(pack.getElementName().replace('.', '/')).append('/').append(typeQualifiedName).append(JavadocConstants.HTML_EXTENSION); if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException(); - final String contents = getURLContents(String.valueOf(pathBuffer)); + final String contents = getURLContents(baseLocation, String.valueOf(pathBuffer)); JavadocContents javadocContents = new JavadocContents(this, contents); synchronized (projectInfo.javadocCache) { projectInfo.javadocCache.put(this, javadocContents); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java index 6abc0d1ddb..36ec69e5f6 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java @@ -26,6 +26,8 @@ import java.net.URLConnection; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.*; @@ -98,6 +100,9 @@ public abstract class JavaElement extends PlatformObject implements IJavaElement protected static final JavaElement[] NO_ELEMENTS = new JavaElement[0]; protected static final Object NO_INFO = new Object(); + + private static Set<String> invalidURLs = null; + private static Set<String> validURLs = null; /** * Constructs a handle for a java element with @@ -767,10 +772,45 @@ public abstract class JavaElement extends PlatformObject implements IJavaElement } /* + * This method caches a list of good and bad Javadoc locations in the current eclipse session. + */ + protected void validateAndCache(URL baseLoc, FileNotFoundException e) throws JavaModelException { + String url = baseLoc.toString(); + if (validURLs != null && validURLs.contains(url)) return; + + if (invalidURLs != null && invalidURLs.contains(url)) + throw new JavaModelException(e, IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC); + + InputStream input = null; + try { + URLConnection connection = baseLoc.openConnection(); + input = connection.getInputStream(); + if (validURLs == null) { + validURLs = new HashSet<String>(1); + } + validURLs.add(url); + } catch (Exception e1) { + if (invalidURLs == null) { + invalidURLs = new HashSet<String>(1); + } + invalidURLs.add(url); + throw new JavaModelException(e, IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC); + } finally { + if (input != null) { + try { + input.close(); + } catch (Exception e1) { + // Ignore + } + } + } + } + + /* * We don't use getContentEncoding() on the URL connection, because it might leave open streams behind. * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=117890 */ - protected String getURLContents(String docUrlValue) throws JavaModelException { + protected String getURLContents(URL baseLoc, String docUrlValue) throws JavaModelException { InputStream stream = null; JarURLConnection connection2 = null; try { @@ -854,8 +894,8 @@ public abstract class JavaElement extends PlatformObject implements IJavaElement } catch (MalformedURLException e) { throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC, this)); } catch (FileNotFoundException e) { - // Ignore, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=120559 & - // https://bugs.eclipse.org/bugs/show_bug.cgi?id=403036 + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=403154 + validateAndCache(baseLoc, e); } catch (SocketException e) { // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=247845 & // https://bugs.eclipse.org/bugs/show_bug.cgi?id=400060 diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java index 9db976f3c4..9ccad47da3 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java @@ -491,7 +491,7 @@ public String getAttachedJavadoc(IProgressMonitor monitor) throws JavaModelExcep pathBuffer.append(packPath).append('/').append(JavadocConstants.PACKAGE_FILE_NAME); if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException(); - String contents = getURLContents(String.valueOf(pathBuffer)); + String contents = getURLContents(baseLocation, String.valueOf(pathBuffer)); if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException(); if (contents == null) return null; |