/*******************************************************************************
* Copyright (c) 2012-2014 Codenvy, S.A.
* 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.jdt.javadoc;
import org.eclipse.che.jdt.util.JavaModelUtil;
import org.eclipse.che.jdt.internal.corext.CorextMessages;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModelStatusConstants;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IOpenable;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.SocketException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.UnknownHostException;
public class JavaDocLocations {
private static final Logger LOG = LoggerFactory.getLogger(JavaDocLocations.class);
private static final String JAR_PROTOCOL = "jar"; //$NON-NLS-1$
public static final String ARCHIVE_PREFIX = "jar:"; //$NON-NLS-1$
private static final String PREF_JAVADOCLOCATIONS = "org.eclipse.jdt.ui.javadoclocations"; //$NON-NLS-1$
public static final String PREF_JAVADOCLOCATIONS_MIGRATED = "org.eclipse.jdt.ui.javadoclocations.migrated"; //$NON-NLS-1$
private static final String NODE_ROOT = "javadoclocation"; //$NON-NLS-1$
private static final String NODE_ENTRY = "location_01"; //$NON-NLS-1$
private static final String NODE_PATH = "path"; //$NON-NLS-1$
private static final String NODE_URL = "url"; //$NON-NLS-1$
private static final QualifiedName PROJECT_JAVADOC = new QualifiedName("JavaUI.ID_PLUGIN", "project_javadoc_location"); //$NON-NLS-1$
// public static void migrateToClasspathAttributes() {
// final Map<IPath, String> oldLocations= loadOldForCompatibility();
// if (oldLocations.isEmpty()) {
// IPreferenceStore preferenceStore= PreferenceConstants.getPreferenceStore();
// preferenceStore.setValue(PREF_JAVADOCLOCATIONS, ""); //$NON-NLS-1$
// preferenceStore.setValue(PREF_JAVADOCLOCATIONS_MIGRATED, true);
// return;
// }
//
// Job job= new Job(CorextMessages.JavaDocLocations_migratejob_name) {
// @Override
// protected IStatus run(IProgressMonitor monitor) {
// try {
// IWorkspaceRunnable runnable= new IWorkspaceRunnable() {
// public void run(IProgressMonitor pm) throws CoreException {
// updateClasspathEntries(oldLocations, pm);
// IPreferenceStore preferenceStore= PreferenceConstants.getPreferenceStore();
// preferenceStore.setValue(PREF_JAVADOCLOCATIONS, ""); //$NON-NLS-1$
// preferenceStore.setValue(PREF_JAVADOCLOCATIONS_MIGRATED, true);
// }
// };
// new WorkbenchRunnableAdapter(runnable).run(monitor);
// } catch (InvocationTargetException e) {
// JavaPlugin.log(e);
// } catch (InterruptedException e) {
// // should not happen, cannot cancel
// }
// return Status.OK_STATUS;
// }
// };
// job.schedule();
// }
// final static void updateClasspathEntries(Map<IPath, String> oldLocationMap, IProgressMonitor monitor) throws JavaModelException {
// IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
// IJavaProject[] javaProjects= JavaCore.create(root).getJavaProjects();
// try {
// monitor.beginTask(CorextMessages.JavaDocLocations_migrate_operation, javaProjects.length);
// for (int i= 0; i < javaProjects.length; i++) {
// IJavaProject project= javaProjects[i];
// String projectJavadoc= oldLocationMap.get(project.getPath());
// if (projectJavadoc != null) {
// try {
// setProjectJavadocLocation(project, projectJavadoc);
// } catch (CoreException e) {
// // ignore
// }
// }
//
// IClasspathEntry[] rawClasspath= project.getRawClasspath();
// boolean hasChange= false;
// for (int k= 0; k < rawClasspath.length; k++) {
// IClasspathEntry updated= getConvertedEntry(rawClasspath[k], project, oldLocationMap);
// if (updated != null) {
// rawClasspath[k]= updated;
// hasChange= true;
// }
// }
// if (hasChange) {
// project.setRawClasspath(rawClasspath, new SubProgressMonitor(monitor, 1));
// } else {
// monitor.worked(1);
// }
// }
// } finally {
// monitor.done();
// }
// }
//
// private static IClasspathEntry getConvertedEntry(IClasspathEntry entry, IJavaProject project, Map<IPath, String> oldLocationMap) {
// IPath path= null;
// switch (entry.getEntryKind()) {
// case IClasspathEntry.CPE_SOURCE:
// case IClasspathEntry.CPE_PROJECT:
// return null;
// case IClasspathEntry.CPE_CONTAINER:
// convertContainer(entry, project, oldLocationMap);
// return null;
// case IClasspathEntry.CPE_LIBRARY:
// path= entry.getPath();
// break;
// case IClasspathEntry.CPE_VARIABLE:
// path= JavaCore.getResolvedVariablePath(entry.getPath());
// break;
// default:
// return null;
// }
// if (path == null) {
// return null;
// }
// IClasspathAttribute[] extraAttributes= entry.getExtraAttributes();
// for (int i= 0; i < extraAttributes.length; i++) {
// if (IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME.equals(extraAttributes[i].getName())) {
// return null;
// }
// }
// String libraryJavadocLocation= oldLocationMap.get(path);
// if (libraryJavadocLocation != null) {
// CPListElement element= CPListElement.createFromExisting(entry, project);
// element.setAttribute(CPListElement.JAVADOC, libraryJavadocLocation);
// return element.getClasspathEntry();
// }
// return null;
// }
//
// private static void convertContainer(IClasspathEntry entry, IJavaProject project, Map<IPath, String> oldLocationMap) {
// try {
// IClasspathContainer container= JavaCore.getClasspathContainer(entry.getPath(), project);
// if (container == null) {
// return;
// }
//
// IClasspathEntry[] entries= container.getClasspathEntries();
// boolean hasChange= false;
// for (int i= 0; i < entries.length; i++) {
// IClasspathEntry curr= entries[i];
// IClasspathEntry updatedEntry= getConvertedEntry(curr, project, oldLocationMap);
// if (updatedEntry != null) {
// entries[i]= updatedEntry;
// hasChange= true;
// }
// }
// if (hasChange) {
// BuildPathSupport.requestContainerUpdate(project, container, entries);
// }
// } catch (CoreException e) {
// // ignore
// }
// }
//
// /**
// * Sets the Javadoc location for an archive with the given path.
// * @param project the Java project
// * @param url the Javadoc location
// */
// public static void setProjectJavadocLocation(IJavaProject project, URL url) {
// try {
// String location= url != null ? url.toExternalForm() : null;
// setProjectJavadocLocation(project, location);
// } catch (CoreException e) {
// LOG.error(e.getMessage(), e);
// }
// }
private static void setProjectJavadocLocation(IJavaProject project, String url) throws CoreException {
project.getProject().setPersistentProperty(PROJECT_JAVADOC, url);
}
public static URL getProjectJavadocLocation(IJavaProject project) {
if (!project.getProject().isAccessible()) {
return null;
}
try {
String prop= project.getProject().getPersistentProperty(PROJECT_JAVADOC);
if (prop == null) {
return null;
}
return parseURL(prop);
} catch (CoreException e) {
LOG.error(e.getMessage(), e);
}
return null;
}
public static URL getLibraryJavadocLocation(IClasspathEntry entry) {
if (entry == null) {
throw new IllegalArgumentException("Entry must not be null"); //$NON-NLS-1$
}
int kind= entry.getEntryKind();
if (kind != IClasspathEntry.CPE_LIBRARY && kind != IClasspathEntry.CPE_VARIABLE) {
throw new IllegalArgumentException("Entry must be of kind CPE_LIBRARY or CPE_VARIABLE"); //$NON-NLS-1$
}
IClasspathAttribute[] extraAttributes= entry.getExtraAttributes();
for (int i= 0; i < extraAttributes.length; i++) {
IClasspathAttribute attrib= extraAttributes[i];
if (IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME.equals(attrib.getName())) {
return parseURL(attrib.getValue());
}
}
return null;
}
public static URL getJavadocBaseLocation(IJavaElement element) throws JavaModelException {
if (element.getElementType() == IJavaElement.JAVA_PROJECT) {
return getProjectJavadocLocation((IJavaProject) element);
}
IPackageFragmentRoot root= JavaModelUtil.getPackageFragmentRoot(element);
if (root == null) {
return null;
}
if (root.getKind() == IPackageFragmentRoot.K_BINARY) {
IClasspathEntry entry= root.getResolvedClasspathEntry();
URL javadocLocation= getLibraryJavadocLocation(entry);
if (javadocLocation != null) {
return getLibraryJavadocLocation(entry);
}
entry= root.getRawClasspathEntry();
switch (entry.getEntryKind()) {
case IClasspathEntry.CPE_LIBRARY:
case IClasspathEntry.CPE_VARIABLE:
return getLibraryJavadocLocation(entry);
default:
return null;
}
} else {
return getProjectJavadocLocation(root.getJavaProject());
}
}
// private static JavaUIException createException(Throwable t, String message) {
// return new JavaUIException(JavaUIStatus.createError(IStatus.ERROR, message, t));
// }
// private static Map<IPath, String> loadOldForCompatibility() {
// HashMap<IPath, String> resultingOldLocations= new HashMap<IPath, String>();
//
// // in 3.0, the javadoc locations were stored as one big string in the preferences
// String string= PreferenceConstants.getPreferenceStore().getString(PREF_JAVADOCLOCATIONS);
// if (string != null && string.length() > 0) {
// byte[] bytes;
// try {
// bytes= string.getBytes("UTF-8"); //$NON-NLS-1$
// } catch (UnsupportedEncodingException e) {
// bytes= string.getBytes();
// }
// InputStream is= new ByteArrayInputStream(bytes);
// try {
// loadFromStream(new InputSource(is), resultingOldLocations);
// PreferenceConstants.getPreferenceStore().setValue(PREF_JAVADOCLOCATIONS, ""); //$NON-NLS-1$
// return resultingOldLocations;
// } catch (CoreException e) {
// JavaPlugin.log(e); // log but ignore
// } finally {
// try {
// is.close();
// } catch (IOException e) {
// // ignore
// }
// }
// }
//
// // in 2.1, the Javadoc locations were stored in a file in the meta data
// // note that it is wrong to use a stream reader with XML declaring to be UTF-8
// try {
// final String STORE_FILE= "javadoclocations.xml"; //$NON-NLS-1$
// File file= JavaPlugin.getDefault().getStateLocation().append(STORE_FILE).toFile();
// if (file.exists()) {
// Reader reader= null;
// try {
// reader= new FileReader(file);
// loadFromStream(new InputSource(reader), resultingOldLocations);
// file.delete(); // remove file after successful store
// return resultingOldLocations;
// } catch (IOException e) {
// JavaPlugin.log(e); // log but ignore
// } finally {
// try {
// if (reader != null) {
// reader.close();
// }
// } catch (IOException e) {}
// }
// }
// } catch (CoreException e) {
// JavaPlugin.log(e); // log but ignore
// }
//
// // in 2.0, the Javadoc locations were stored as one big string in the persistent properties
// // note that it is wrong to use a stream reader with XML declaring to be UTF-8
// try {
// final QualifiedName QUALIFIED_NAME= new QualifiedName(JavaUI.ID_PLUGIN, "jdoclocation"); //$NON-NLS-1$
//
// IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
// String xmlString= root.getPersistentProperty(QUALIFIED_NAME);
// if (xmlString != null) { // only set when workspace is old
// Reader reader= new StringReader(xmlString);
// try {
// loadFromStream(new InputSource(reader), resultingOldLocations);
// root.setPersistentProperty(QUALIFIED_NAME, null); // clear property
// return resultingOldLocations;
// } finally {
//
// try {
// reader.close();
// } catch (IOException e) {
// // error closing reader: ignore
// }
// }
// }
// } catch (CoreException e) {
// JavaPlugin.log(e); // log but ignore
// }
// return resultingOldLocations;
// }
// private static void loadFromStream(InputSource inputSource, Map<IPath, String> oldLocations) throws CoreException {
// Element cpElement;
// try {
// DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
// parser.setErrorHandler(new DefaultHandler());
// cpElement = parser.parse(inputSource).getDocumentElement();
// } catch (SAXException e) {
// throw createException(e, CorextMessages.JavaDocLocations_error_readXML);
// } catch (ParserConfigurationException e) {
// throw createException(e, CorextMessages.JavaDocLocations_error_readXML);
// } catch (IOException e) {
// throw createException(e, CorextMessages.JavaDocLocations_error_readXML);
// }
//
// if (cpElement == null) return;
// if (!cpElement.getNodeName().equalsIgnoreCase(NODE_ROOT)) {
// return;
// }
// NodeList list= cpElement.getChildNodes();
// int length= list.getLength();
// for (int i= 0; i < length; ++i) {
// Node node= list.item(i);
// short type= node.getNodeType();
// if (type == Node.ELEMENT_NODE) {
// Element element= (Element) node;
// if (element.getNodeName().equalsIgnoreCase(NODE_ENTRY)) {
// String varPath = element.getAttribute(NODE_PATH);
// String varURL = parseURL(element.getAttribute(NODE_URL)).toExternalForm();
//
// oldLocations.put(Path.fromPortableString(varPath), varURL);
// }
// }
// }
// }
// public static URL getJavadocLocation(IJavaElement element, boolean includeMemberReference) throws JavaModelException {
// URL baseLocation= getJavadocBaseLocation(element);
// if (baseLocation == null) {
// return null;
// }
//
// String urlString= baseLocation.toExternalForm();
//
// StringBuffer urlBuffer= new StringBuffer(urlString);
// if (!urlString.endsWith("/")) { //$NON-NLS-1$
// urlBuffer.append('/');
// }
//
// StringBuffer pathBuffer= new StringBuffer();
// StringBuffer fragmentBuffer= new StringBuffer();
//
// switch (element.getElementType()) {
// case IJavaElement.PACKAGE_FRAGMENT:
// appendPackageSummaryPath((IPackageFragment) element, pathBuffer);
// break;
// case IJavaElement.JAVA_PROJECT:
// case IJavaElement.PACKAGE_FRAGMENT_ROOT :
// appendIndexPath(pathBuffer);
// break;
// case IJavaElement.IMPORT_CONTAINER :
// element= element.getParent();
// //$FALL-THROUGH$
// case IJavaElement.COMPILATION_UNIT :
// IType mainType= ((ICompilationUnit) element).findPrimaryType();
// if (mainType == null) {
// return null;
// }
// appendTypePath(mainType, pathBuffer);
// break;
// case IJavaElement.CLASS_FILE :
// appendTypePath(((IClassFile) element).getType(), pathBuffer);
// break;
// case IJavaElement.TYPE :
// appendTypePath((IType) element, pathBuffer);
// break;
// case IJavaElement.FIELD :
// IField field= (IField) element;
// appendTypePath(field.getDeclaringType(), pathBuffer);
// if (includeMemberReference) {
// appendFieldReference(field, fragmentBuffer);
// }
// break;
// case IJavaElement.METHOD :
// IMethod method= (IMethod) element;
// appendTypePath(method.getDeclaringType(), pathBuffer);
// if (includeMemberReference) {
// appendMethodReference(method, fragmentBuffer);
// }
// break;
// case IJavaElement.INITIALIZER :
// appendTypePath(((IMember) element).getDeclaringType(), pathBuffer);
// break;
// case IJavaElement.IMPORT_DECLARATION :
// IImportDeclaration decl= (IImportDeclaration) element;
//
// if (decl.isOnDemand()) {
// IJavaElement
// cont= JavaModelUtil.findTypeContainer(element.getJavaProject(), Signature.getQualifier(decl.getElementName()));
// if (cont instanceof IType) {
// appendTypePath((IType) cont, pathBuffer);
// } else if (cont instanceof IPackageFragment) {
// appendPackageSummaryPath((IPackageFragment) cont, pathBuffer);
// }
// } else {
// IType imp= element.getJavaProject().findType(decl.getElementName());
// appendTypePath(imp, pathBuffer);
// }
// break;
// case IJavaElement.PACKAGE_DECLARATION :
// IJavaElement pack= element.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
// if (pack != null) {
// appendPackageSummaryPath((IPackageFragment) pack, pathBuffer);
// } else {
// return null;
// }
// break;
// default :
// return null;
// }
//
// try {
// String fragment= fragmentBuffer.length() == 0 ? null : fragmentBuffer.toString();
// try {
// URI relativeURI= new URI(null, null, pathBuffer.toString(), fragment);
// urlBuffer.append(relativeURI.toString());
// return new URL(urlBuffer.toString());
// } catch (URISyntaxException e) {
// JavaPlugin.log(e);
// return new URL(urlBuffer.append(pathBuffer).toString());
// }
// } catch (MalformedURLException e) {
// JavaPlugin.log(e);
// }
// return null;
// }
private static void appendPackageSummaryPath(IPackageFragment pack, StringBuffer buf) {
String packPath= pack.getElementName().replace('.', '/');
buf.append(packPath);
buf.append("/package-summary.html"); //$NON-NLS-1$
}
private static void appendIndexPath(StringBuffer buf) {
buf.append("index.html"); //$NON-NLS-1$
}
private static void appendTypePath(IType type, StringBuffer buf) {
IPackageFragment pack= type.getPackageFragment();
String packPath= pack.getElementName().replace('.', '/');
String typePath= type.getTypeQualifiedName('.');
if (packPath.length() > 0) {
buf.append(packPath);
buf.append('/');
}
buf.append(typePath);
buf.append(".html"); //$NON-NLS-1$
}
private static void appendFieldReference(IField field, StringBuffer buf) {
buf.append(field.getElementName());
}
private static void appendMethodReference(IMethod meth, StringBuffer buf) throws JavaModelException {
buf.append(meth.getElementName());
/*
* The Javadoc tool for Java SE 8 changed the anchor syntax and now tries to avoid "strange" characters in URLs.
* This breaks all clients that directly create such URLs.
* We can't know what format is required, so we just guess by the project's compiler compliance.
*/
boolean is18OrHigher= JavaModelUtil.is18OrHigher(meth.getJavaProject());
buf.append(is18OrHigher ? '-' : '(');
String[] params= meth.getParameterTypes();
IType declaringType= meth.getDeclaringType();
boolean isVararg= Flags.isVarargs(meth.getFlags());
int lastParam= params.length - 1;
for (int i= 0; i <= lastParam; i++) {
if (i != 0) {
buf.append(is18OrHigher ? "-" : ", "); //$NON-NLS-1$ //$NON-NLS-2$
}
String curr= Signature.getTypeErasure(params[i]);
String fullName= JavaModelUtil.getResolvedTypeName(curr, declaringType);
if (fullName == null) { // e.g. a type parameter "QE;"
fullName= Signature.toString(Signature.getElementType(curr));
}
if (fullName != null) {
buf.append(fullName);
int dim= Signature.getArrayCount(curr);
if (i == lastParam && isVararg) {
dim--;
}
while (dim > 0) {
buf.append(is18OrHigher ? ":A" : "[]"); //$NON-NLS-1$ //$NON-NLS-2$
dim--;
}
if (i == lastParam && isVararg) {
buf.append("..."); //$NON-NLS-1$
}
}
}
buf.append(is18OrHigher ? '-' : ')');
}
// /**
// * Returns the location of the Javadoc.
// *
// * @param element whose Javadoc location has to be found
// * @param isBinary <code>true</code> if the Java element is from a binary container
// * @return the location URL of the Javadoc or <code>null</code> if the location cannot be found
// * @throws org.eclipse.jdt.core.JavaModelException thrown when the Java element cannot be accessed
// * @since 3.9
// */
// public static String getBaseURL(IJavaElement element, boolean isBinary) throws JavaModelException {
// if (isBinary) {
// // Source attachment usually does not include Javadoc resources
// // => Always use the Javadoc location as base:
// URL baseURL= JavaUI.getJavadocLocation(element, false);
// if (baseURL != null) {
// if (baseURL.getProtocol().equals(JAR_PROTOCOL)) {
// // It's a JarURLConnection, which is not known to the browser widget.
// // Let's start the help web server:
// URL baseURL2= PlatformUI.getWorkbench().getHelpSystem().resolve(baseURL.toExternalForm(), true);
// if (baseURL2 != null) { // can be null if org.eclipse.help.ui is not available
// baseURL= baseURL2;
// }
// }
// return baseURL.toExternalForm();
// }
// } else {
// IResource resource= element.getResource();
// if (resource != null) {
// /*
// * Too bad: Browser widget knows nothing about EFS and custom URL handlers,
// * so IResource#getLocationURI() does not work in all cases.
// * We only support the local file system for now.
// * A solution could be https://bugs.eclipse.org/bugs/show_bug.cgi?id=149022 .
// */
// IPath location= resource.getLocation();
// if (location != null)
// return location.toFile().toURI().toString();
// }
// }
// return null;
// }
/**
* Returns the reason for why the Javadoc of the Java element could not be retrieved.
*
* @param element whose Javadoc could not be retrieved
* @param root the root of the Java element
* @return the String message for why the Javadoc could not be retrieved for the Java element or
* <code>null</code> if the Java element is from a source container
* @since 3.9
*/
public static String getExplanationForMissingJavadoc(IJavaElement element, IPackageFragmentRoot root) {
String message= null;
try {
boolean isBinary= (root.exists() && root.getKind() == IPackageFragmentRoot.K_BINARY);
if (isBinary) {
boolean hasAttachedJavadoc= JavaDocLocations.getJavadocBaseLocation(element) != null;
boolean hasAttachedSource= root.getSourceAttachmentPath() != null;
IOpenable openable= element.getOpenable();
boolean hasSource= openable.getBuffer() != null;
// Provide hint why there's no Java doc
if (!hasAttachedSource && !hasAttachedJavadoc)
message= CorextMessages.JavaDocLocations_noAttachments;
else if (!hasAttachedJavadoc && !hasSource)
message= CorextMessages.JavaDocLocations_noAttachedJavadoc;
else if (!hasAttachedSource)
message= CorextMessages.JavaDocLocations_noAttachedSource;
else if (!hasSource)
message= CorextMessages.JavaDocLocations_noInformation;
}
} catch (JavaModelException e) {
message= CorextMessages.JavaDocLocations_error_gettingJavadoc;
LOG.error(message, e);
}
return message;
}
/**
* Handles the exception thrown from JDT Core when the attached Javadoc
* cannot be retrieved due to accessibility issues or location URL issue. This exception is not
* logged but the exceptions occurred due to other reasons are logged.
*
* @param e the exception thrown when retrieving the Javadoc fails
* @return the String message for why the Javadoc could not be retrieved
* @since 3.9
*/
public static String handleFailedJavadocFetch(CoreException e) {
IStatus status= e.getStatus();
if (JavaCore.PLUGIN_ID.equals(status.getPlugin())) {
Throwable cause= e.getCause();
int code= status.getCode();
// See bug 120559, bug 400060 and bug 400062
if (code == IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC_TIMEOUT
|| (code == IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC && (cause instanceof FileNotFoundException || cause instanceof SocketException
|| cause instanceof UnknownHostException
|| cause instanceof ProtocolException)))
return CorextMessages.JavaDocLocations_error_gettingAttachedJavadoc;
}
LOG.error(e.getMessage(), e);
return CorextMessages.JavaDocLocations_error_gettingJavadoc;
}
/**
* Parse a URL from a String. This method first tries to treat <code>url</code> as a valid, encoded URL.
* If that didn't work, it tries to recover from bad URLs, e.g. the unencoded form we used to use in persistent storage.
*
* @param url a URL
* @return the parsed URL or <code>null</code> if the URL couldn't be parsed
* @since 3.9
*/
public static URL parseURL(String url) {
try {
try {
return new URI(url).toURL();
} catch (URISyntaxException e) {
try {
// don't log, since we used to store bad (unencoded) URLs
if (url.startsWith("file:/")) { //$NON-NLS-1$
// workaround for a bug in the 3-arg URI constructor for paths that contain '[' or ']':
return new URI("file", null, url.substring(5), null).toURL(); //$NON-NLS-1$
} else {
return URIUtil.fromString(url).toURL();
}
} catch (URISyntaxException e1) {
// last try, not expected to happen
LOG.error(e.getMessage(), e);
return new URL(url);
}
}
} catch (MalformedURLException e) {
LOG.error(e.getMessage(), e);
return null;
}
}
/**
* Returns the {@link java.io.File} of a <code>file:</code> URL. This method tries to recover from bad URLs,
* e.g. the unencoded form we used to use in persistent storage.
*
* @param url a <code>file:</code> URL
* @return the file
* @since 3.9
*/
public static File toFile(URL url) {
try {
return URIUtil.toFile(url.toURI());
} catch (URISyntaxException e) {
LOG.error(e.getMessage(), e);
return new File(url.getFile());
}
}
}