| /******************************************************************************* |
| * Copyright (c) 2010, 2016 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.debug.ui.actions; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.SubMonitor; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IMethod; |
| import org.eclipse.jdt.core.ISourceRange; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.search.IJavaSearchConstants; |
| import org.eclipse.jdt.core.search.IJavaSearchScope; |
| import org.eclipse.jdt.core.search.SearchEngine; |
| import org.eclipse.jdt.core.search.SearchMatch; |
| import org.eclipse.jdt.core.search.SearchParticipant; |
| import org.eclipse.jdt.core.search.SearchPattern; |
| import org.eclipse.jdt.core.search.SearchRequestor; |
| import org.eclipse.jdt.core.search.TypeNameMatch; |
| import org.eclipse.jdt.core.search.TypeNameMatchRequestor; |
| import org.eclipse.jdt.debug.ui.console.JavaStackTraceConsoleFactory; |
| import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants; |
| import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; |
| import org.eclipse.jdt.internal.debug.ui.console.JavaStackTraceConsole; |
| import org.eclipse.jdt.ui.JavaElementLabelProvider; |
| import org.eclipse.jdt.ui.JavaUI; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.dialogs.DialogSettings; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.dialogs.IInputValidator; |
| import org.eclipse.jface.dialogs.InputDialog; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.text.BadLocationException; |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.swt.dnd.Clipboard; |
| import org.eclipse.swt.dnd.TextTransfer; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.IWorkbenchWindowActionDelegate; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.console.ConsolePlugin; |
| import org.eclipse.ui.console.IConsole; |
| import org.eclipse.ui.console.IConsoleManager; |
| import org.eclipse.ui.dialogs.ElementListSelectionDialog; |
| import org.eclipse.ui.texteditor.IDocumentProvider; |
| import org.eclipse.ui.texteditor.ITextEditor; |
| |
| /** |
| * Action delegate for Open from Clipboard action. |
| * |
| * @since 3.7 |
| */ |
| public class OpenFromClipboardAction implements IWorkbenchWindowActionDelegate { |
| |
| /** |
| * Pattern to match a simple name e.g. <code>OpenFromClipboardAction</code> |
| */ |
| private static final String SIMPLE_NAME_PATTERN= "\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*"; //$NON-NLS-1$ |
| |
| /** |
| * Pattern to match a qualified name e.g. |
| * <code>org.eclipse.jdt.internal.debug.ui.actions.OpenFromClipboardAction</code>, or match a |
| * simple name e.g. <code>OpenFromClipboardAction</code>. |
| */ |
| private static final String QUALIFIED_NAME_PATTERN = "(" + SIMPLE_NAME_PATTERN //$NON-NLS-1$ |
| + "\\.)*" + SIMPLE_NAME_PATTERN; //$NON-NLS-1$ |
| |
| /** |
| * Pattern to match a qualified name e.g. |
| * <code>org.eclipse.jdt.internal.debug.ui.actions.OpenFromClipboardAction</code>. |
| */ |
| private static final String STRICT_QUALIFIED_NAME_PATTERN = "(" + SIMPLE_NAME_PATTERN //$NON-NLS-1$ |
| + "\\.)+" + SIMPLE_NAME_PATTERN; //$NON-NLS-1$ |
| |
| /** |
| * Pattern to match whitespace characters. |
| */ |
| private static final String WS = "\\s*"; //$NON-NLS-1$ |
| |
| /** |
| * Pattern to match a java file name e.g. <code>OpenFromClipboardAction.java</code> |
| */ |
| private static final String JAVA_FILE_PATTERN = SIMPLE_NAME_PATTERN + "\\.java"; //$NON-NLS-1$ |
| |
| /** |
| * Pattern to match a java file name followed by line number e.g. |
| * <code>OpenFromClipboardAction.java : 21</code> |
| */ |
| private static final String JAVA_FILE_LINE_PATTERN = JAVA_FILE_PATTERN + WS + ":" + WS + "\\d+"; //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| /** |
| * Pattern to match a qualified name followed by line number e.g. |
| * <code>org.eclipse.jdt.internal.debug.ui.actions.OpenFromClipboardAction : 21</code> |
| */ |
| private static final String TYPE_LINE_PATTERN = QUALIFIED_NAME_PATTERN + WS + ":" + WS + "\\d+"; //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| /** |
| * Pattern to match a line from a stack trace e.g. |
| * <code>(Assert.java:41)</code> |
| */ |
| private static final String STACK_TRACE_PARENTHESIZED_PATTERN = "\\(" + WS + JAVA_FILE_LINE_PATTERN + WS + "\\)"; //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| /** |
| * Pattern to match a line from a stack trace e.g. |
| * <code> at org.eclipse.core.runtime.Assert.isLegal(Assert.java:41)</code> |
| */ |
| private static final String STACK_TRACE_LINE_PATTERN = "[^()]*?" + STACK_TRACE_PARENTHESIZED_PATTERN; //$NON-NLS-1$ |
| |
| /** |
| * Pattern to match a line from a stack trace e.g. |
| * <code> at org.eclipse.core.runtime.Assert.isLegal(Assert.java:41)</code> |
| */ |
| private static final String STACK_TRACE_QUALIFIED_LINE_PATTERN = "[^()]*?(" + STRICT_QUALIFIED_NAME_PATTERN + ")" + WS + STACK_TRACE_PARENTHESIZED_PATTERN; //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| /** |
| * Pattern to match a method e.g. |
| * <code>org.eclipse.jdt.internal.debug.ui.actions.OpenFromClipboardAction.run(IAction)</code> , |
| * <code>Worker.run()</code> |
| */ |
| private static final String METHOD_PATTERN = QUALIFIED_NAME_PATTERN + "\\(.*\\)"; //$NON-NLS-1$ |
| |
| /** |
| * Pattern to match a stack element e.g. <code>java.lang.String.valueOf(char) line: 1456</code> |
| */ |
| private static final String STACK_PATTERN = METHOD_PATTERN + ".*\\d+"; //$NON-NLS-1$ |
| |
| /** |
| * Pattern to match a member (field or method) of a type e.g. |
| * <code>OpenFromClipboardAction#run</code>, <code>Worker#run</code> |
| */ |
| private static final String MEMBER_PATTERN = QUALIFIED_NAME_PATTERN + "#" //$NON-NLS-1$ |
| + SIMPLE_NAME_PATTERN; |
| |
| /** |
| * Pattern to match a method e.g. <code>OpenFromClipboardAction#run(IAction)</code>, |
| * <code>Worker#run()</code> |
| */ |
| private static final String METHOD_JAVADOC_REFERENCE_PATTERN = QUALIFIED_NAME_PATTERN + "#" //$NON-NLS-1$ |
| + SIMPLE_NAME_PATTERN + "\\(.*\\)"; //$NON-NLS-1$ |
| |
| /* |
| * Constants to indicate the pattern matched |
| */ |
| private static final int INVALID = 0; |
| |
| private static final int QUALIFIED_NAME = 1; |
| |
| private static final int JAVA_FILE = 2; |
| |
| private static final int JAVA_FILE_LINE = 3; |
| |
| private static final int TYPE_LINE = 4; |
| |
| private static final int STACK_TRACE_LINE = 5; |
| |
| private static final int METHOD = 6; |
| |
| private static final int STACK = 7; |
| |
| private static final int MEMBER = 8; |
| |
| private static final int METHOD_JAVADOC_REFERENCE = 9; |
| |
| private static final String TASK_NAME = ActionMessages.OpenFromClipboardAction_OpeningFromClipboard; |
| |
| /* |
| * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) |
| */ |
| @Override |
| public void run(IAction action) { |
| Clipboard clipboard = new Clipboard(Display.getDefault()); |
| TextTransfer textTransfer = TextTransfer.getInstance(); |
| final String inputText = (String) clipboard.getContents(textTransfer); |
| if (inputText == null || inputText.length() == 0) { |
| openInputEditDialog(""); //$NON-NLS-1$ |
| return; |
| } |
| |
| String trimmedText = inputText.replaceAll("\\s+", " "); //$NON-NLS-1$ //$NON-NLS-2$ |
| List<Object> matches = new ArrayList<>(); |
| int line = 0; |
| try { |
| line = getJavaElementMatches(trimmedText, matches); |
| } |
| catch (InterruptedException e) { |
| matches.clear(); // don't show partial matches |
| } |
| if (matches.size() > 0 || isSingleLineInput(inputText)) { |
| handleMatches(matches, line, trimmedText); |
| return; |
| } |
| handleMultipleLineInput(inputText); |
| |
| return; |
| } |
| |
| private static JavaStackTraceConsole getJavaStackTraceConsole() { |
| IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager(); |
| IConsole[] consoles = consoleManager.getConsoles(); |
| for (int i = 0; i < consoles.length; i++) { |
| if (consoles[i] instanceof JavaStackTraceConsole) { |
| return (JavaStackTraceConsole) consoles[i]; |
| } |
| } |
| return null; |
| } |
| |
| private static void handleMultipleLineInput(String inputText) { |
| // multiple lines - simply paste to the console and open it |
| IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager(); |
| JavaStackTraceConsole console = getJavaStackTraceConsole(); |
| if (console != null) { |
| console.getDocument().set(inputText); |
| consoleManager.showConsoleView(console); |
| } else { |
| JavaStackTraceConsoleFactory javaStackTraceConsoleFactory = new JavaStackTraceConsoleFactory(); |
| javaStackTraceConsoleFactory.openConsole(inputText); |
| console = getJavaStackTraceConsole(); |
| } |
| IPreferenceStore preferenceStore = JDIDebugUIPlugin.getDefault().getPreferenceStore(); |
| if (preferenceStore.getBoolean(IJDIPreferencesConstants.PREF_AUTO_FORMAT_JSTCONSOLE)) { |
| console.format(); |
| } |
| } |
| |
| private static boolean isSingleLineInput(String inputText) { |
| String lineDelimiter = System.lineSeparator(); |
| String s = inputText.trim(); |
| return s.indexOf(lineDelimiter) == -1; |
| } |
| |
| private static int getMatchingPattern(String s) { |
| if (s.matches(JAVA_FILE_LINE_PATTERN)) { |
| return JAVA_FILE_LINE; |
| } |
| if (s.matches(JAVA_FILE_PATTERN)) { |
| return JAVA_FILE; |
| } |
| if (s.matches(TYPE_LINE_PATTERN)) { |
| return TYPE_LINE; |
| } |
| if (s.matches(STACK_TRACE_LINE_PATTERN)) { |
| return STACK_TRACE_LINE; |
| } |
| if (s.matches(METHOD_PATTERN)) { |
| return METHOD; |
| } |
| if (s.matches(STACK_PATTERN)) { |
| return STACK; |
| } |
| if (s.matches(MEMBER_PATTERN)) { |
| return MEMBER; |
| } |
| if (s.matches(METHOD_JAVADOC_REFERENCE_PATTERN)) { |
| return METHOD_JAVADOC_REFERENCE; |
| } |
| if (s.matches(QUALIFIED_NAME_PATTERN)) { |
| return QUALIFIED_NAME; |
| } |
| return INVALID; |
| } |
| |
| private static void handleSingleLineInput(String inputText) { |
| List<Object> matches = new ArrayList<>(); |
| try { |
| int line= getJavaElementMatches(inputText, matches); |
| handleMatches(matches, line, inputText); |
| } catch (InterruptedException ex) { |
| // Do nothing |
| } |
| } |
| |
| /** |
| * Parse the input text and search for the corresponding Java elements. |
| * |
| * @param inputText the line number |
| * @param matches matched Java elements |
| * @return the line number |
| * @throws InterruptedException if canceled by the user |
| */ |
| private static int getJavaElementMatches(String inputText, List<Object> matches) throws InterruptedException { |
| String s = inputText.trim(); |
| switch (getMatchingPattern(s)) { |
| case JAVA_FILE_LINE: { |
| int index = s.indexOf(':'); |
| String typeName = s.substring(0, index); |
| typeName = s.substring(0, typeName.indexOf(".java")); //$NON-NLS-1$ |
| String lineNumber = s.substring(index + 1, s.length()); |
| lineNumber = lineNumber.trim(); |
| int line = (Integer.valueOf(lineNumber)).intValue(); |
| getTypeMatches(typeName, matches); |
| return line; |
| } |
| case JAVA_FILE: { |
| String typeName = s.substring(0, s.indexOf(".java")); //$NON-NLS-1$ |
| getTypeMatches(typeName, matches); |
| return -1; |
| } |
| case TYPE_LINE: { |
| int index = s.indexOf(':'); |
| String typeName = s.substring(0, index); |
| typeName = typeName.trim(); |
| String lineNumber = s.substring(index + 1, s.length()); |
| lineNumber = lineNumber.trim(); |
| int line = (Integer.valueOf(lineNumber)).intValue(); |
| getTypeMatches(typeName, matches); |
| return line; |
| } |
| case STACK_TRACE_LINE: { |
| int index1 = s.lastIndexOf('('); |
| int index2 = s.lastIndexOf(')'); |
| String typeLine = s.substring(index1 + 1, index2).trim(); |
| int index = typeLine.indexOf(':'); |
| String lineNumber = typeLine.substring(index + 1, typeLine.length()).trim(); |
| int line = (Integer.valueOf(lineNumber)).intValue(); |
| |
| Pattern pattern = Pattern.compile(STACK_TRACE_QUALIFIED_LINE_PATTERN); |
| Matcher matcher = pattern.matcher(s); |
| if (matcher.find()) { |
| String qualifiedName = matcher.group(1); |
| index = qualifiedName.lastIndexOf('.'); |
| qualifiedName = qualifiedName.substring(0, index); |
| getTypeMatches(qualifiedName, matches); |
| } else { |
| String typeName = typeLine.substring(0, index); |
| typeName = typeLine.substring(0, typeName.indexOf(".java")); //$NON-NLS-1$ |
| getTypeMatches(typeName, matches); |
| } |
| return line; |
| } |
| case METHOD: { |
| getMethodMatches(s, matches); |
| return -1; |
| } |
| case STACK: { |
| int index = s.indexOf(')'); |
| String method = s.substring(0, index + 1); |
| index = s.indexOf(':'); |
| String lineNumber = s.substring(index + 1).trim(); |
| int line = (Integer.valueOf(lineNumber)).intValue(); |
| getMethodMatches(method, matches); |
| return line; |
| } |
| case MEMBER: |
| getMemberMatches(s.replace('#', '.'), matches); |
| return -1; |
| case METHOD_JAVADOC_REFERENCE: |
| getMethodMatches(s.replace('#', '.'), matches); |
| return -1; |
| case QUALIFIED_NAME: |
| getNameMatches(s, matches); |
| return -1; |
| default: |
| return -1; |
| } |
| } |
| |
| /** |
| * Perform a Java search for the type and return the corresponding Java elements. |
| * |
| * @param typeName the Type name |
| * @param matches matched Java elements |
| * @throws InterruptedException if canceled by the user |
| */ |
| private static void getTypeMatches(final String typeName, final List<Object> matches) throws InterruptedException { |
| executeRunnable(new IRunnableWithProgress() { |
| @Override |
| public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { |
| doTypeSearch(typeName, matches, monitor); |
| } |
| }); |
| } |
| |
| /** |
| * Perform a Java search for methods and constructors and return the corresponding Java |
| * elements. |
| * |
| * @param s the method pattern |
| * @param matches matched Java elements |
| * @throws InterruptedException if canceled by the user |
| */ |
| private static void getMethodMatches(final String s, final List<Object> matches) throws InterruptedException { |
| executeRunnable(new IRunnableWithProgress() { |
| @Override |
| public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { |
| doMemberSearch(s, matches, true, true, false, monitor, 100); |
| } |
| }); |
| } |
| |
| /** |
| * Perform a Java search for fields, methods and constructors and return the corresponding Java |
| * elements. |
| * |
| * @param s the member pattern |
| * @param matches matched Java elements |
| * @throws InterruptedException if canceled by the user |
| */ |
| private static void getMemberMatches(final String s, final List<Object> matches) throws InterruptedException { |
| executeRunnable(new IRunnableWithProgress() { |
| @Override |
| public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { |
| doMemberSearch(s, matches, true, true, true, monitor, 100); |
| } |
| }); |
| } |
| |
| /** |
| * Perform a Java search for types, fields and methods and return the corresponding Java |
| * elements. |
| * |
| * @param s the qualified name pattern |
| * @param matches matched Java elements |
| * @throws InterruptedException if canceled by the user |
| */ |
| private static void getNameMatches(final String s, final List<Object> matches) throws InterruptedException { |
| executeRunnable(new IRunnableWithProgress() { |
| @Override |
| public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { |
| SubMonitor progress = SubMonitor.convert(monitor, 100); |
| progress.beginTask(TASK_NAME, 100); |
| doTypeSearch(s, matches, progress.newChild(34)); |
| doMemberSearch(s, matches, true, false, true, progress.newChild(34), 66); |
| } |
| }); |
| } |
| |
| private static void executeRunnable(IRunnableWithProgress runnableWithProgress) throws InterruptedException { |
| try { |
| PlatformUI.getWorkbench().getProgressService().busyCursorWhile(runnableWithProgress); |
| } catch (InvocationTargetException e) { |
| JDIDebugUIPlugin.log(e); |
| } |
| } |
| |
| /** |
| * Handles the given matches. |
| * |
| * @param matches matched Java elements |
| * @param line the line number |
| * @param inputText the input text |
| * @throws InterruptedException if canceled by the user |
| */ |
| private static void handleMatches(List<Object> matches, int line, String inputText) { |
| if (matches.size() > 1) { |
| int flags = JavaElementLabelProvider.SHOW_DEFAULT | JavaElementLabelProvider.SHOW_QUALIFIED | JavaElementLabelProvider.SHOW_ROOT; |
| IWorkbenchWindow window = JDIDebugUIPlugin.getActiveWorkbenchWindow(); |
| ElementListSelectionDialog dialog = new ElementListSelectionDialog(window.getShell(), new JavaElementLabelProvider(flags)) { |
| /* |
| * @see org.eclipse.ui.dialogs.SelectionDialog#getDialogBoundsSettings() |
| * @since 4.3 |
| */ |
| @Override |
| protected IDialogSettings getDialogBoundsSettings() { |
| IDialogSettings settings = JDIDebugUIPlugin.getDefault().getDialogSettings(); |
| return DialogSettings.getOrCreateSection(settings, "OpenFromClipboardAction_dialogBounds"); //$NON-NLS-1$ |
| } |
| }; |
| dialog.setTitle(ActionMessages.OpenFromClipboardAction_OpenFromClipboard); |
| dialog.setMessage(ActionMessages.OpenFromClipboardAction_SelectOrEnterTheElementToOpen); |
| dialog.setElements(matches.toArray()); |
| dialog.setMultipleSelection(true); |
| |
| int result = dialog.open(); |
| if (result != IDialogConstants.OK_ID) { |
| return; |
| } |
| |
| Object[] elements = dialog.getResult(); |
| if (elements != null && elements.length > 0) { |
| openJavaElements(elements, line); |
| } |
| } else if (matches.size() == 1) { |
| openJavaElements(matches.toArray(), line); |
| } else if (matches.isEmpty()) { |
| openInputEditDialog(inputText); |
| } |
| } |
| |
| /** |
| * Opens each specified Java element in a Java editor and navigates to the specified line |
| * number. |
| * |
| * @param elements |
| * the Java elements |
| * @param line |
| * the line number |
| */ |
| private static void openJavaElements(Object[] elements, int line) { |
| for (int i = 0; i < elements.length; i++) { |
| Object ob = elements[i]; |
| if (ob instanceof IJavaElement) { |
| IJavaElement element = (IJavaElement) ob; |
| try { |
| IEditorPart editorPart = JavaUI.openInEditor(element); |
| gotoLine(editorPart, line, element); |
| } catch (PartInitException e) { |
| JDIDebugUIPlugin.log(e); |
| } catch (JavaModelException e) { |
| JDIDebugUIPlugin.log(e); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Jumps to the given line in the editor if the line number lies within the given Java element. |
| * |
| * @param editorPart the Editor part |
| * @param line the line to jump to |
| * @param element the Java Element |
| * @throws JavaModelException if fetching the Java element's source range fails |
| */ |
| private static void gotoLine(IEditorPart editorPart, int line, IJavaElement element) throws JavaModelException { |
| if (line <= 0) { |
| return; |
| } |
| ITextEditor editor = (ITextEditor) editorPart; |
| IDocumentProvider provider = editor.getDocumentProvider(); |
| IDocument document = provider.getDocument(editor.getEditorInput()); |
| try { |
| if (element instanceof IMethod) { |
| ISourceRange sourceRange = ((IMethod) element).getSourceRange(); |
| int start = sourceRange.getOffset(); |
| int end = start + sourceRange.getLength(); |
| start = document.getLineOfOffset(start); |
| end = document.getLineOfOffset(end); |
| if (start > line || end < line) { |
| return; |
| } |
| } |
| int start = document.getLineOffset(line - 1); |
| editor.selectAndReveal(start, 0); |
| IWorkbenchPage page = editor.getSite().getPage(); |
| page.activate(editor); |
| } catch (BadLocationException e) { |
| // ignore |
| } |
| } |
| |
| /** |
| * Opens an text input dialog to let the user refine the input text. |
| * |
| * @param inputText the input text |
| */ |
| private static void openInputEditDialog(String inputText) { |
| IWorkbenchWindow window = JDIDebugUIPlugin.getActiveWorkbenchWindow(); |
| IInputValidator validator = new IInputValidator() { |
| @Override |
| public String isValid(String newText) { |
| return newText.length() == 0 ? "" : null; //$NON-NLS-1$ |
| } |
| }; |
| InputDialog dialog = new InputDialog(window.getShell(), ActionMessages.OpenFromClipboardAction_OpenFromClipboard, ActionMessages.OpenFromClipboardAction_ElementToOpen, inputText, validator); |
| int result = dialog.open(); |
| if (result != IDialogConstants.OK_ID) { |
| return; |
| } |
| |
| inputText = dialog.getValue(); |
| handleSingleLineInput(inputText); |
| } |
| |
| private static SearchPattern createSearchPattern(String s, int searchFor) { |
| return SearchPattern.createPattern(s, searchFor, IJavaSearchConstants.DECLARATIONS, getSearchFlags()); |
| } |
| |
| private static int getSearchFlags() { |
| return SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_ERASURE_MATCH; |
| } |
| |
| private static SearchRequestor createSearchRequestor(final List<Object> matches) { |
| return new SearchRequestor() { |
| @Override |
| public void acceptSearchMatch(SearchMatch match) { |
| if (match.getAccuracy() == SearchMatch.A_ACCURATE) { |
| matches.add(match.getElement()); |
| } |
| } |
| }; |
| } |
| |
| private static SearchParticipant[] createSearchParticipant() { |
| return new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }; |
| } |
| |
| /** |
| * Perform a Java search for the type and return the corresponding Java elements. |
| * |
| * <p> |
| * TODO: Because of faster performance SearchEngine.searchAllTypeNames(...) is used to do the |
| * Java Search, instead of the usual SearchEngine.search(...) API. This logic should be moved to |
| * JDT/Core. |
| * </p> |
| * |
| * @param typeName |
| * the Type Name |
| * @param matches |
| * matched Java Elements |
| * @param monitor |
| * the Progress Monitor |
| */ |
| private static void doTypeSearch(String typeName, final List<Object> matches, IProgressMonitor monitor) { |
| IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); |
| SearchEngine searchEngine = new SearchEngine(); |
| |
| String packageName = null; |
| int index = typeName.lastIndexOf('.'); |
| if (index != -1) { |
| packageName = typeName.substring(0, index); |
| typeName = typeName.substring(index + 1); |
| } |
| try { |
| searchEngine.searchAllTypeNames(packageName == null ? null : packageName.toCharArray(), packageName == null ? SearchPattern.R_EXACT_MATCH : getSearchFlags(), typeName.toCharArray(), |
| getSearchFlags(), IJavaSearchConstants.TYPE, scope, new TypeNameMatchRequestor() { |
| @Override |
| public void acceptTypeNameMatch(TypeNameMatch match) { |
| matches.add(match.getType()); |
| } |
| }, IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, monitor); |
| } catch (CoreException e) { |
| JDIDebugUIPlugin.log(e); |
| } |
| } |
| |
| /** |
| * Perform a Java search for one or more of fields, methods and constructors and return the |
| * corresponding Java elements. |
| * |
| * <p> |
| * TODO: Because of faster performance, if the type name is available |
| * SearchEngine.searchAllTypeNames(...) is used to narrow the scope of Java Search. This logic |
| * should be moved to JDT/Core. |
| * </p> |
| * |
| * @param memberName |
| * the Member Name |
| * @param matches |
| * matched Java Elements |
| * @param searchForMethods |
| * if <code>true</code>, a method search is performed |
| * @param searchForConstructors |
| * if <code>true</code>, a constructor search is performed |
| * @param searchForFields |
| * if <code>true</code>, a field search is performed |
| * @param monitor |
| * the Progress Monitor |
| * @param work |
| * the remaining Work |
| */ |
| private static void doMemberSearch(String memberName, final List<Object> matches, boolean searchForMethods, boolean searchForConstructors, boolean searchForFields, IProgressMonitor monitor, int work) { |
| int noOfSearches = 0; |
| noOfSearches = searchForMethods ? noOfSearches + 1 : noOfSearches; |
| noOfSearches = searchForConstructors ? noOfSearches + 1 : noOfSearches; |
| noOfSearches = searchForFields ? noOfSearches + 1 : noOfSearches; |
| if (noOfSearches == 0) { |
| return; |
| } |
| |
| SubMonitor progress = SubMonitor.convert(monitor); |
| progress.beginTask(TASK_NAME, work); |
| |
| IJavaSearchScope scope = null; |
| SearchRequestor requestor = createSearchRequestor(matches); |
| SearchEngine searchEngine = new SearchEngine(); |
| |
| String typeName = null; |
| int index = memberName.lastIndexOf('.'); |
| if (index != -1) { |
| typeName = memberName.substring(0, index); |
| memberName = memberName.substring(index + 1); |
| final List<Object> typeMatches = new ArrayList<>(); |
| noOfSearches++; |
| doTypeSearch(typeName, typeMatches, progress.newChild(work / noOfSearches)); |
| IType[] types = new IType[typeMatches.size()]; |
| for (int i = 0; i < typeMatches.size(); i++) { |
| types[i] = (IType) typeMatches.get(i); |
| } |
| scope = SearchEngine.createJavaSearchScope(types); |
| } else { |
| scope = SearchEngine.createWorkspaceScope(); |
| } |
| try { |
| int workPerSearch = work / noOfSearches; |
| if (searchForMethods) { |
| doMemberSearch(searchEngine, memberName, IJavaSearchConstants.METHOD, scope, requestor, progress.newChild(workPerSearch)); |
| } |
| if (searchForConstructors) { |
| doMemberSearch(searchEngine, memberName, IJavaSearchConstants.CONSTRUCTOR, scope, requestor, progress.newChild(workPerSearch)); |
| } |
| if (searchForFields) { |
| doMemberSearch(searchEngine, memberName, IJavaSearchConstants.FIELD, scope, requestor, progress.newChild(workPerSearch)); |
| } |
| } catch (CoreException e) { |
| JDIDebugUIPlugin.log(e); |
| } |
| } |
| |
| private static void doMemberSearch(SearchEngine searchEngine, String memberName, int searchFor, IJavaSearchScope scope, SearchRequestor requestor, SubMonitor progressMonitor) throws CoreException { |
| SearchPattern pattern = createSearchPattern(memberName, searchFor); |
| if (pattern != null) { |
| searchEngine.search(pattern, createSearchParticipant(), scope, requestor, progressMonitor); |
| } |
| } |
| |
| /* |
| * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action .IAction, |
| * org.eclipse.jface.viewers.ISelection) |
| */ |
| @Override |
| public void selectionChanged(IAction action, ISelection selection) { |
| } |
| |
| /* |
| * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose() |
| */ |
| @Override |
| public void dispose() { |
| } |
| |
| /* |
| * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui. IWorkbenchWindow) |
| */ |
| @Override |
| public void init(IWorkbenchWindow window) { |
| } |
| } |