### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.ui Index: plugin.xml =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/plugin.xml,v retrieving revision 1.742 diff -u -r1.742 plugin.xml --- plugin.xml 23 May 2007 12:05:49 -0000 1.742 +++ plugin.xml 15 Sep 2007 01:56:58 -0000 @@ -6050,5 +6050,14 @@ + + + + Index: plugin.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/plugin.properties,v retrieving revision 1.459 diff -u -r1.459 plugin.properties --- plugin.properties 23 May 2007 12:05:49 -0000 1.459 +++ plugin.properties 15 Sep 2007 01:56:49 -0000 @@ -1056,3 +1056,5 @@ JavaElementHyperlinkDetector= Java Element NLSHyperlinkDetector= Java Property Key PropertyKeyHyperlinkDetector= Java Property Key + +LaunchQueryParticipant.name = Java Launch Configuration \ No newline at end of file Index: ui/org/eclipse/jdt/internal/ui/search/SearchMessages.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/SearchMessages.java,v retrieving revision 1.22 diff -u -r1.22 SearchMessages.java --- ui/org/eclipse/jdt/internal/ui/search/SearchMessages.java 27 Sep 2006 16:24:50 -0000 1.22 +++ ui/org/eclipse/jdt/internal/ui/search/SearchMessages.java 15 Sep 2007 01:56:59 -0000 @@ -24,6 +24,7 @@ public static String JavaSearchScopeFactory_undefined_projects; public static String JavaSearchScopeFactory_undefined_selection; public static String JavaSearchScopeFactory_undefined_workingsets; + public static String LaunchConfigurationQueryParticipant_search_errors; public static String MatchFilter_DeprecatedFilter_actionLabel; public static String MatchFilter_DeprecatedFilter_description; public static String MatchFilter_DeprecatedFilter_name; Index: ui/org/eclipse/jdt/internal/ui/search/SearchMessages.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/SearchMessages.properties,v retrieving revision 1.123 diff -u -r1.123 SearchMessages.properties --- ui/org/eclipse/jdt/internal/ui/search/SearchMessages.properties 30 Apr 2007 14:39:22 -0000 1.123 +++ ui/org/eclipse/jdt/internal/ui/search/SearchMessages.properties 15 Sep 2007 01:56:59 -0000 @@ -311,3 +311,4 @@ TextSearchLabelProvider_matchCountFormat={0} ({1} matches) +LaunchConfigurationQueryParticipant_search_errors=Errors occurred while searching launch configurations. \ No newline at end of file Index: ui/org/eclipse/jdt/internal/ui/search/LaunchConfigurationQueryParticipant.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/search/LaunchConfigurationQueryParticipant.java diff -N ui/org/eclipse/jdt/internal/ui/search/LaunchConfigurationQueryParticipant.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/jdt/internal/ui/search/LaunchConfigurationQueryParticipant.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,406 @@ +/******************************************************************************* + * Copyright (c) 2007 Ecliptical Software Inc. 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ecliptical Software Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.ui.search; + +import java.util.StringTokenizer; +import java.util.regex.Pattern; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; + +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.viewers.BaseLabelProvider; +import org.eclipse.jface.viewers.DecoratingLabelProvider; +import org.eclipse.jface.viewers.DecorationOverlayIcon; +import org.eclipse.jface.viewers.ILabelDecorator; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.StructuredSelection; + +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.IShowInTarget; +import org.eclipse.ui.part.ShowInContext; + +import org.eclipse.search.ui.text.Match; + +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchMode; +import org.eclipse.debug.core.model.IProcess; + +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.debug.ui.ILaunchGroup; + +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.search.IJavaSearchConstants; +import org.eclipse.jdt.core.search.IJavaSearchScope; + +import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; + +import org.eclipse.jdt.ui.search.ElementQuerySpecification; +import org.eclipse.jdt.ui.search.IMatchPresentation; +import org.eclipse.jdt.ui.search.IQueryParticipant; +import org.eclipse.jdt.ui.search.ISearchRequestor; +import org.eclipse.jdt.ui.search.PatternQuerySpecification; +import org.eclipse.jdt.ui.search.QuerySpecification; + +import org.eclipse.jdt.internal.ui.JavaPlugin; + +public class LaunchConfigurationQueryParticipant implements IQueryParticipant { + + private UIParticipant uiParticipant; + + public int estimateTicks(QuerySpecification query) { + if (isValid(query)) + return 50; + + return 0; + } + + public synchronized IMatchPresentation getUIParticipant() { + if (uiParticipant == null) + uiParticipant = new UIParticipant(); + + return uiParticipant; + } + + public void search(ISearchRequestor requestor, QuerySpecification query, + IProgressMonitor monitor) throws CoreException { + if (!isValid(query)) + return; + + monitor.beginTask("", 11); //$NON-NLS-1$ + try { + Pattern pattern = null; + if (query instanceof ElementQuerySpecification) { + ElementQuerySpecification elementQuery = (ElementQuerySpecification) query; + IType type = (IType) elementQuery.getElement(); + pattern = Pattern.compile(quotePattern(type + .getFullyQualifiedName('$'))); + } + + if (query instanceof PatternQuerySpecification) { + PatternQuerySpecification patternQuery = (PatternQuerySpecification) query; + int flags = patternQuery.isCaseSensitive() ? 0 + : Pattern.CASE_INSENSITIVE; + String quotedPattern = quotePattern(patternQuery.getPattern()); + pattern = Pattern.compile(quotedPattern, flags); + } + + monitor.worked(1); + if (monitor.isCanceled()) + throw new OperationCanceledException(); + + MultiStatus multiStatus = new MultiStatus( + JavaPlugin.getPluginId(), + 0, + SearchMessages.LaunchConfigurationQueryParticipant_search_errors, + null); + try { + searchLaunchConfigurations(requestor, query.getScope(), + pattern, new SubProgressMonitor(monitor, 7)); + } catch (CoreException e) { + multiStatus.merge(e.getStatus()); + } + + try { + searchLaunches(requestor, query.getScope(), pattern, + new SubProgressMonitor(monitor, 3)); + } catch (CoreException e) { + multiStatus.merge(e.getStatus()); + } + + if (!multiStatus.isOK()) + throw new CoreException(multiStatus); + } finally { + monitor.done(); + } + } + + private String quotePattern(String pattern) { + StringTokenizer t = new StringTokenizer(pattern, ".?*", true); //$NON-NLS-1$ + StringBuffer buf = new StringBuffer(); + while (t.hasMoreTokens()) { + String token = t.nextToken(); + switch (token.charAt(0)) { + case '.': + buf.append('\\'); + break; + case '?': + case '*': + buf.append('.'); + break; + } + + buf.append(token); + } + + return buf.toString(); + } + + private boolean isValid(QuerySpecification query) { + switch (query.getLimitTo()) { + case IJavaSearchConstants.REFERENCES: + case IJavaSearchConstants.ALL_OCCURRENCES: + break; + default: + return false; + } + + if (query instanceof ElementQuerySpecification) { + ElementQuerySpecification elementQuery = (ElementQuerySpecification) query; + return elementQuery.getElement().getElementType() == IJavaElement.TYPE; + } + + if (query instanceof PatternQuerySpecification) { + PatternQuerySpecification patternQuery = (PatternQuerySpecification) query; + switch (patternQuery.getSearchFor()) { + case IJavaSearchConstants.UNKNOWN: + case IJavaSearchConstants.TYPE: + case IJavaSearchConstants.CLASS: + case IJavaSearchConstants.CLASS_AND_INTERFACE: + case IJavaSearchConstants.CLASS_AND_ENUM: + return true; + } + + return false; + } + + return false; + } + + private boolean matches(ISearchRequestor requestor, IJavaSearchScope scope, + ILaunchConfiguration config, IWorkspaceRoot workspaceRoot, + Pattern pattern) throws CoreException { + // TODO resolve any string substitution variables + String mainTypeName = config.getAttribute( + IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, + (String) null); + if (mainTypeName == null) + return false; + + // use associated project to limit search scope + String projectName = config.getAttribute( + IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, + (String) null); + if (projectName != null) { + IPath[] projectsAndJars = scope.enclosingProjectsAndJars(); + IPath projectPath = workspaceRoot.getProject(projectName) + .getFullPath(); + boolean found = false; + for (int j = 0; j < projectsAndJars.length; ++j) { + if (projectsAndJars[j].equals(projectPath)) { + found = true; + break; + } + } + + if (!found) + return false; + } + + return pattern.matcher(mainTypeName).matches(); + } + + private void searchLaunchConfigurations(ISearchRequestor requestor, + IJavaSearchScope scope, Pattern pattern, IProgressMonitor monitor) + throws CoreException { + ILaunchConfiguration[] configs = DebugPlugin.getDefault() + .getLaunchManager().getLaunchConfigurations(); + + MultiStatus multiStatus = new MultiStatus(JavaPlugin.getPluginId(), 0, + null, null); + monitor.beginTask("", configs.length); //$NON-NLS-1$ + try { + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace() + .getRoot(); + for (int i = 0; i < configs.length; ++i) { + monitor.worked(1); + if (monitor.isCanceled()) + throw new OperationCanceledException(); + + monitor.subTask(configs[i].getName()); + + try { + if (matches(requestor, scope, configs[i], workspaceRoot, + pattern)) + requestor.reportMatch(new Match(configs[i], 0, 0)); + } catch (CoreException e) { + multiStatus.add(e.getStatus()); + } + } + } finally { + monitor.done(); + } + + if (!multiStatus.isOK()) + throw new CoreException(multiStatus); + } + + private void searchLaunches(ISearchRequestor requestor, + IJavaSearchScope scope, Pattern pattern, IProgressMonitor monitor) + throws CoreException { + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); + ILaunch[] launches = DebugPlugin.getDefault().getLaunchManager() + .getLaunches(); + + MultiStatus multiStatus = new MultiStatus(JavaPlugin.getPluginId(), 0, + null, null); + monitor.beginTask("", launches.length); //$NON-NLS-1$ + ILabelProvider lp = null; + try { + // TODO not sure if this is generally OK in a non-UI thread + lp = DebugUITools.newDebugModelPresentation(); + for (int i = 0; i < launches.length; ++i) { + monitor.worked(1); + if (monitor.isCanceled()) + throw new OperationCanceledException(); + + monitor.subTask(lp.getText(launches[i])); + ILaunchConfiguration config = launches[i] + .getLaunchConfiguration(); + if (config == null) + continue; + + try { + IProcess[] procs = launches[i].getProcesses(); + if (procs.length == 0) + continue; + + if (matches(requestor, scope, config, workspaceRoot, + pattern)) + requestor.reportMatch(new Match(procs[0], 0, 0)); + } catch (CoreException e) { + multiStatus.add(e.getStatus()); + } + } + } finally { + if (lp != null) + lp.dispose(); + + monitor.done(); + } + + if (!multiStatus.isOK()) + throw new CoreException(multiStatus); + } + + private static class UIParticipant implements IMatchPresentation { + + public ILabelProvider createLabelProvider() { + return new DecoratingLabelProvider(DebugUITools + .newDebugModelPresentation(), new DebugModelDecorator()); + } + + public void showMatch(Match match, int currentOffset, + int currentLength, boolean activate) throws PartInitException { + if (match.getElement() instanceof IProcess) { + // show the process in debug view + IViewPart view = JavaPlugin.getActivePage().showView( + IDebugUIConstants.ID_DEBUG_VIEW, + null, + activate ? IWorkbenchPage.VIEW_ACTIVATE + : IWorkbenchPage.VIEW_CREATE); + IShowInTarget target = null; + if (view instanceof IShowInTarget) + target = (IShowInTarget) view; + else + target = (IShowInTarget) view + .getAdapter(IShowInTarget.class); + + if (target != null) { + ShowInContext context = new ShowInContext(null, + new StructuredSelection(match.getElement())); + target.show(context); + } + + return; + } + + if (match.getElement() instanceof ILaunchConfiguration) { + if (activate) { + // open the launch config in launch dialog + ILaunchConfiguration config = (ILaunchConfiguration) match + .getElement(); + // find the first available group for any of the supported + // modes + ILaunchMode[] modes = DebugPlugin.getDefault() + .getLaunchManager().getLaunchModes(); + ILaunchGroup group = null; + for (int i = 0; i < modes.length; ++i) { + group = DebugUITools.getLaunchGroup(config, modes[i] + .getIdentifier()); + if (group != null) + break; + } + + if (group == null) + return; + + DebugUITools.openLaunchConfigurationDialog(JavaPlugin + .getActiveWorkbenchShell(), config, group + .getIdentifier(), Status.OK_STATUS); + } + } + } + } + + private static class DebugModelDecorator extends BaseLabelProvider + implements ILabelDecorator { + + private LocalResourceManager registry; + + public Image decorateImage(Image image, Object element) { + Rectangle bounds = image.getBounds(); + if (bounds.width >= 20) + return null; + + if (registry == null) + registry = new LocalResourceManager(JFaceResources + .getResources()); + + // pad the icon to match JDT icon width + // TODO is there a more generic way? + DecorationOverlayIcon result = new DecorationOverlayIcon(image, + new ImageDescriptor[0], new Point(20, 16)); + return (Image) registry.get(result); + } + + public String decorateText(String text, Object element) { + return null; + } + + public void dispose() { + if (registry != null) + registry.dispose(); + + super.dispose(); + } + } +}