/** * Copyright (C) 2005 - 2011 Eric Van Dewoestine * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.eclim.plugin.jdt.command.doc; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.regex.Pattern; import org.eclim.annotation.Command; import org.eclim.command.CommandLine; import org.eclim.plugin.jdt.command.search.SearchCommand; import org.eclim.plugin.jdt.util.JavaUtils; import org.eclipse.jdt.core.IClasspathAttribute; import org.eclipse.jdt.core.IClasspathContainer; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.search.SearchMatch; import org.eclipse.jdt.internal.core.JavaModelManager; import org.eclipse.jdt.internal.corext.util.JavaModelUtil; import org.eclipse.jdt.internal.launching.JREContainer; /** * Command to search for javadocs. * * @author Eric Van Dewoestine */ @Command( name = "java_docsearch", options = "REQUIRED n project ARG," + "OPTIONAL f file ARG," + "OPTIONAL o offset ARG," + "OPTIONAL e encoding ARG," + "OPTIONAL l length ARG," + "OPTIONAL p pattern ARG," + "OPTIONAL t type ARG," + "OPTIONAL x context ARG," + "OPTIONAL s scope ARG" ) public class DocSearchCommand extends SearchCommand { private static final Pattern LOCAL_URL = Pattern.compile("^file://(/|[A-Z]).*"); private static final HashMap<String, String> JRE_DOCS = new HashMap<String, String>(); static{ JRE_DOCS.put(JavaCore.VERSION_1_3, "http://java.sun.com/j2se/1.3/docs/api/"); JRE_DOCS.put(JavaCore.VERSION_1_4, "http://java.sun.com/j2se/1.4.2/docs/api/"); JRE_DOCS.put(JavaCore.VERSION_1_5, "http://java.sun.com/j2se/1.5.0/docs/api/"); JRE_DOCS.put(JavaCore.VERSION_1_6, "http://java.sun.com/javase/6/docs/api/"); } /** * {@inheritDoc} */ public Object execute(CommandLine commandLine) throws Exception { List<SearchMatch> matches = executeSearch(commandLine); ArrayList<String> results = new ArrayList<String>(); for(SearchMatch match : matches){ if (match.getElement() != null){ int elementType = ((IJavaElement)match.getElement()).getElementType(); if (elementType != IJavaElement.PACKAGE_FRAGMENT && elementType != IJavaElement.PACKAGE_FRAGMENT_ROOT) { String result = createDocSearchResult(match); if(result != null){ results.add(result); } } } } return results; } /** * Creates a javadoc url from the supplied SearchMatch. * * @param match The SearchMatch. * @return The javadoc url. */ private String createDocSearchResult(SearchMatch match) throws Exception { IJavaElement element = (IJavaElement)match.getElement(); IJavaElement parent = element; while(parent.getElementType() != IJavaElement.PACKAGE_FRAGMENT_ROOT){ parent = parent.getParent(); } IPackageFragmentRoot root = (IPackageFragmentRoot)parent; IClasspathEntry classpath = root.getRawClasspathEntry(); if(classpath.getEntryKind() == IClasspathEntry.CPE_CONTAINER) { classpath = JavaModelUtil.getClasspathEntryToEdit( element.getJavaProject(), classpath.getPath(), root.getPath()); } // may be null from JavaModelUtil.getClasspathEntryToEdit if (classpath != null){ IClasspathAttribute[] attributes = classpath.getExtraAttributes(); for(int ii = 0; ii < attributes.length; ii++){ String name = attributes[ii].getName(); if(IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME.equals(name)){ return buildUrl(attributes[ii].getValue(), element); } } } // somewhere in the eclipse 3.2 release canidate stage they stopped // providing default locations for jre javadocs, but the final version of // 3.2 seems to have it. The following will lookup the location from our // own settings should this occur again. classpath = root.getRawClasspathEntry(); if(classpath.getEntryKind() == IClasspathEntry.CPE_CONTAINER) { IClasspathContainer container = JavaModelManager.getJavaModelManager().getClasspathContainer( classpath.getPath(), element.getJavaProject()); if(container instanceof JREContainer){ String version = JavaUtils.getCompilerSourceCompliance( element.getJavaProject()); String url = (String)JRE_DOCS.get(version); if(url != null){ return buildUrl(url, element); } } } return null; } private String buildUrl(String baseUrl, IJavaElement element) throws Exception { String qualifiedName = JavaUtils.getFullyQualifiedName(element); // split up the class from the field/method String className = qualifiedName; String childElement = ""; int index = className.indexOf('#'); if(index != -1){ childElement = className.substring(index); className = className.substring(0, index); } String base = baseUrl.trim(); if(base.startsWith("file:") && !LOCAL_URL.matcher(base).matches()){ base = base.replaceFirst("file:/*(/|[A-Z])", "file://$1"); } StringBuffer url = new StringBuffer(base); if(url.charAt(url.length() - 1) != '/'){ url.append('/'); } url.append(className.replace('.', '/').replace('$', '.')) .append(".html"); /*FileSystemManager fsManager = VFS.getManager(); if(!fsManager.resolveFile(url.toString()).exists()){ logger.debug("'{}' does not exist.", url); return null; }*/ url.append(childElement); return url.toString(); } }