/** * Copyright (C) 2012 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.io.StringReader; import java.lang.reflect.Method; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclim.annotation.Command; import org.eclim.command.CommandLine; import org.eclim.command.Options; import org.eclim.plugin.core.command.AbstractCommand; import org.eclim.plugin.jdt.util.JavaUtils; import org.eclim.util.IOUtils; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.ITypeRoot; 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.viewsupport.JavaElementLinks; import org.eclipse.jface.internal.text.html.HTML2TextReader; import org.eclipse.jface.text.IRegion; /** * Command to retrieve the java docs for an element. * * @author Eric Van Dewoestine */ @Command( name = "java_element_doc", options = "OPTIONAL p project ARG," + "OPTIONAL f file ARG," + "OPTIONAL o offset ARG," + "OPTIONAL l length ARG," + "OPTIONAL e encoding ARG," + "OPTIONAL u url ARG," + "OPTIONAL h html NOARG" ) public class GetElementDocCommand extends AbstractCommand { private static final Pattern LINKS = Pattern.compile( "<a\\s+[^>]*?href=(['\"])(.*?)\\1[^>]*>\\s*(.*?)</a>"); @Override public Object execute(CommandLine commandLine) throws Exception { IJavaElement[] elements = null; Object url = commandLine.getRawValue(Options.URL_OPTION); if (url != null){ IJavaElement target = JavaElementLinks.parseURI(new URI((String)url)); if (target != null){ elements = new IJavaElement[]{target}; } }else{ String project = commandLine.getValue(Options.PROJECT_OPTION); String file = commandLine.getValue(Options.FILE_OPTION); int offset = getOffset(commandLine); int length = commandLine.getIntValue(Options.LENGTH_OPTION); ICompilationUnit src = JavaUtils.getCompilationUnit(project, file); elements = src.codeSelect(offset, length); } if(elements == null || elements.length == 0){ return null; } Method getHoverInfo = JavadocHover.class.getDeclaredMethod( "getHoverInfo", IJavaElement[].class, ITypeRoot.class, IRegion.class, JavadocBrowserInformationControlInput.class); getHoverInfo.setAccessible(true); JavadocBrowserInformationControlInput info = (JavadocBrowserInformationControlInput) getHoverInfo.invoke(null, elements, null, null, null); if (info == null){ return null; } if(commandLine.hasOption(Options.HTML_OPTION)){ return info.getHtml(); } ArrayList<HashMap<String,String>> links = new ArrayList<HashMap<String,String>>(); Matcher matcher = LINKS.matcher(info.getHtml()); StringBuffer buffer = new StringBuffer(); int index = 0; while (matcher.find()){ String href = matcher.group(2); String text = matcher.group(3); HashMap<String,String> link = new HashMap<String,String>(); link.put("href", href); link.put("text", text); links.add(link); matcher.appendReplacement(buffer, "|$3[" + (index++) + "]|"); } matcher.appendTail(buffer); String html = buffer.toString(); String result = IOUtils.toString( new HTML2TextReader(new StringReader(html), null)); // remove \r for windows result = result.replaceAll("\r", ""); // compact excessive spacing between sig and doc. result = result.replaceFirst("\n\n\n", "\n\n"); HashMap<String,Object> response = new HashMap<String,Object>(); response.put("text", result); response.put("links", links); return response; } }