### Eclipse Workspace Patch 1.0 #P org.eclipse.mtj.ui Index: plugin.xml =================================================================== --- plugin.xml (revision 415) +++ plugin.xml (working copy) @@ -334,7 +334,7 @@ - + - - + + + + + + + @@ -355,22 +360,6 @@ - - - - - - - - - - - null if the user canceled the dialog. - */ - private ILaunchConfiguration chooseConfiguration(List configList, - String mode) { - IDebugModelPresentation labelProvider = DebugUITools - .newDebugModelPresentation(); - ElementListSelectionDialog dialog = new ElementListSelectionDialog( - getShell(), labelProvider); - dialog.setElements(configList.toArray()); - dialog.setTitle("Launch configuration"); - dialog.setMessage("Select launch configuration"); - dialog.setMultipleSelection(false); - - int result = dialog.open(); - labelProvider.dispose(); - if (result == ElementListSelectionDialog.OK) { - return (ILaunchConfiguration) dialog.getFirstResult(); - } - return null; - } - - /** - * Prompts the user to select a type - * - * @return the selected type or null if none. - */ - private IType chooseType(IType[] types, String mode) { - IType selectedType = null; - - ElementListSelectionDialog dialog = new ElementListSelectionDialog( - getShell(), new JavaElementLabelProvider()); - dialog.setElements(types); - dialog.setTitle("Type Selection"); - - if (mode.equals(ILaunchManager.DEBUG_MODE)) { - dialog.setMessage("Select the midlet to be debugged."); - } else { - dialog.setMessage("Select the midlet to be run."); - } - - dialog.setMultipleSelection(false); - if (dialog.open() == ElementListSelectionDialog.OK) { - selectedType = (IType) dialog.getFirstResult(); - } - - return selectedType; - } - - /** - * Collect up the MIDlet types related to the specified object. - * - * @param object - * @param monitor - * @param result - * @throws JavaModelException - */ - private void collectTypes(Object object, IProgressMonitor monitor, - Set result) throws JavaModelException { - IType type = null; - - if (object instanceof ICompilationUnit) { - IType[] types = ((ICompilationUnit) object).getAllTypes(); - for (int i = 0; i < types.length; i++) { - collectTypes(types[i], monitor, result); - } - } else if (object instanceof IClassFile) { - type = ((IClassFile) object).getType(); - } else if (object instanceof IJavaElement) { - type = (IType) ((IJavaElement) object) - .getAncestor(IJavaElement.TYPE); - } else if (object instanceof IResource) { - collectTypes(JavaCore.create((IResource) object), monitor, result); - } - - if (type != null) { - if (Utils.isMidlet(type, monitor)) { - result.add(type); - } - } - } - - /** - * Create & return a new configuration based on the specified - * IType. - */ - private ILaunchConfiguration createConfiguration(IType type) { - ILaunchConfiguration config = null; - try { - ILaunchConfigurationType configType = getEmulatorConfigType(); - - String launchConfigName = DebugPlugin.getDefault() - .getLaunchManager() - .generateUniqueLaunchConfigurationNameFrom( - type.getElementName()); - ILaunchConfigurationWorkingCopy wc = configType.newInstance(null, - launchConfigName); - - wc.setAttribute(ILaunchConstants.EMULATED_CLASS, Utils - .getQualifiedClassName(type)); - wc.setAttribute( - IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, type - .getJavaProject().getElementName()); - wc.setAttribute(ILaunchConstants.DO_OTA, false); - - DebugUITools.setLaunchPerspective(configType, - ILaunchManager.RUN_MODE, - IDebugUIConstants.PERSPECTIVE_DEFAULT); - DebugUITools.setLaunchPerspective(configType, - ILaunchManager.DEBUG_MODE, - IDebugUIConstants.PERSPECTIVE_DEFAULT); - - config = wc.doSave(); - - } catch (CoreException ce) { - MTJCorePlugin.log(IStatus.WARNING, "createConfiguration", ce); - } - - return config; - } - - /** - * Locate a configuration to re-launch for the given type. If one cannot be - * found, create one. - * - * @return a re-usable config or null if none - */ - private ILaunchConfiguration findLaunchConfiguration(IType type, String mode) { - ILaunchConfiguration configuration = null; - List candidateConfigs = getCandidateConfigs(type); - - // If there are no existing configs associated with the IType, create - // one. - // If there is exactly one config associated with the IType, return it. - // Otherwise, if there is more than one config associated with the - // IType, prompt the - // user to choose one. - int candidateCount = candidateConfigs.size(); - if (candidateCount < 1) { - configuration = createConfiguration(type); - } else if (candidateCount == 1) { - configuration = (ILaunchConfiguration) candidateConfigs.get(0); - } else { - // Prompt the user to choose a config. A null result means the user - // canceled the dialog, in which case this method returns null, - // since canceling the dialog should also cancel launching - // anything. - ILaunchConfiguration config = chooseConfiguration(candidateConfigs, - mode); - if (config != null) { - configuration = config; - } - } - - return configuration; - } - - /** - * Get the candidate launch configurations for the specified type. - * - * @param type - * @return - */ - private List getCandidateConfigs(IType type) { - ILaunchConfigurationType configType = getEmulatorConfigType(); - List candidateConfigs = Collections.EMPTY_LIST; - try { - ILaunchConfiguration[] configs = DebugPlugin.getDefault() - .getLaunchManager().getLaunchConfigurations(configType); - candidateConfigs = new ArrayList(configs.length); - for (int i = 0; i < configs.length; i++) { - ILaunchConfiguration config = configs[i]; - String midletName = config.getAttribute( - ILaunchConstants.EMULATED_CLASS, ""); - String projectName = config - .getAttribute( - IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, - ""); - - if (midletName.equals(Utils.getQualifiedClassName(type)) - && projectName.equals(type.getJavaProject() - .getElementName())) { - candidateConfigs.add(config); - } - } - } catch (CoreException e) { - MTJCorePlugin.log(IStatus.WARNING, "getCandidateConfigs", e); - } - - return candidateConfigs; - } - - /** - * Get the launch configuration type for wireless toolkit emulator. - * - * @return - */ - private ILaunchConfigurationType getEmulatorConfigType() { - ILaunchManager lm = DebugPlugin.getDefault().getLaunchManager(); - ILaunchConfigurationType configType = lm - .getLaunchConfigurationType(ILaunchConstants.LAUNCH_CONFIG_TYPE); - return configType; - } - - /** - * Find all of the IType instances related to the specified selection. - * - * @param selection - * @return - */ - private IType[] findTypes(final Object[] selection) { - final Set result = new HashSet(); - - if (selection.length > 0) { - IRunnableWithProgress runnable = getTypeCollectionRunnable( - selection, result); - - try { - new ProgressMonitorDialog(getShell()).run(true, true, runnable); - } catch (InvocationTargetException e) { - MTJCorePlugin.log(IStatus.WARNING, "findTypes", e); - } catch (InterruptedException e) { - // Ignore - } - } - - return (IType[]) result.toArray(new IType[result.size()]); - } - - /** - * Get the runnable to be used in collecting IType instances. - * - * @param selection - * @param result - * @return - */ - private IRunnableWithProgress getTypeCollectionRunnable( - final Object[] selection, final Set result) { - return new IRunnableWithProgress() { - public void run(IProgressMonitor pm) throws InterruptedException { - int nElements = selection.length; - pm.beginTask("Searching", nElements); - try { - for (int i = 0; i < nElements; i++) { - try { - collectTypes(selection[i], new SubProgressMonitor( - pm, 1), result); - } catch (JavaModelException e) { - MTJCorePlugin.log(IStatus.WARNING, "collectTypes", - e); - } - if (pm.isCanceled()) { - throw new InterruptedException(); - } - } - } finally { - pm.done(); - } - } - }; - } - - /** - * Get the active workbench window's shell. - * - * @return - */ - private Shell getShell() { - Shell shell = null; - - IWorkbenchWindow workbenchWindow = MTJUIPlugin.getDefault() - .getWorkbench().getActiveWorkbenchWindow(); - if (workbenchWindow != null) { - shell = workbenchWindow.getShell(); - } - - return shell; - } - - /** - * Attempt to find and launch the objects in the selection. - * - * @param selection - * @param mode - */ - private void launch(Object[] selection, String mode) { - IType type = null; - IType[] types = findTypes(selection); - - // Choose a type - if (types.length == 1) { - type = types[0]; - } else if (types.length > 1) { - type = chooseType(types, mode); - } - - if (type != null) { - ILaunchConfiguration config = findLaunchConfiguration(type, mode); - if (config != null) { - try { - config.launch(mode, null); - } catch (CoreException e) { - ErrorDialog.openError(getShell(), "Error Launching " - + config.getName(), e.getMessage(), e.getStatus()); - } - } - - } - } -} Index: src/org/eclipse/mtj/ui/internal/launching/JadLaunchShortcut.java =================================================================== --- src/org/eclipse/mtj/ui/internal/launching/JadLaunchShortcut.java (revision 415) +++ src/org/eclipse/mtj/ui/internal/launching/JadLaunchShortcut.java (working copy) @@ -182,8 +182,8 @@ ElementListSelectionDialog dialog = new ElementListSelectionDialog( getShell(), labelProvider); dialog.setElements(configList.toArray()); - dialog.setTitle(LauncherMessage.launch_configSelection_title); - dialog.setMessage(LauncherMessage.launch_configSelection_message); + dialog.setTitle(LauncherMessages.launch_configSelection_title); + dialog.setMessage(LauncherMessages.launch_configSelection_message); dialog.setMultipleSelection(false); int result = dialog.open(); labelProvider.dispose(); Index: src/org/eclipse/mtj/ui/internal/launching/MidletLaunchConfigUtils.java =================================================================== --- src/org/eclipse/mtj/ui/internal/launching/MidletLaunchConfigUtils.java (revision 0) +++ src/org/eclipse/mtj/ui/internal/launching/MidletLaunchConfigUtils.java (revision 0) @@ -0,0 +1,213 @@ +/******************************************************************************* + * Copyright (c) 2008 Sybase 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: + * Feng Wang (Sybase) - initial implementation + *******************************************************************************/ + +package org.eclipse.mtj.ui.internal.launching; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.jdt.core.IClassFile; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IMember; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.ITypeHierarchy; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jface.operation.IRunnableContext; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.mtj.core.IMTJCoreConstants; +import org.eclipse.mtj.core.internal.MTJCorePlugin; +import org.eclipse.mtj.core.internal.utils.Utils; + +/** + * Utilities for Midlet launching + * + * @author wangf + * + */ +public class MidletLaunchConfigUtils { + /** + * Searches for Midlets from within the given scope of elements + * + * @param context + * @param elements + * - a array of IJavaElements. The search scope. + * @return - an array of ITypes of matches for java types that + * extend javax.microedition.midlet.MIDlet (directly or + * indirectly) + * @throws InvocationTargetException + * @throws InterruptedException + */ + public static IType[] findMidlets(IRunnableContext context, + final Object[] elements) throws InvocationTargetException, + InterruptedException { + final Set result = new HashSet(); + + if (elements.length > 0) { + IRunnableWithProgress runnable = new IRunnableWithProgress() { + + public void run(IProgressMonitor monitor) + throws InvocationTargetException, InterruptedException { + for (Object element : elements) { + collectTypes(element, + new SubProgressMonitor(monitor, 1), result); + } + } + + }; + context.run(true, true, runnable); + } + + IType[] types = result.toArray(new IType[result.size()]); + return types; + } + + /** + * Collect Midlet(s) from given Java element. + * + * @param element + * - a IJavaElement within which the collecting is + * performed. + * @param monitor + * @param result + * - a Set contains collected Midlets. + */ + private static void collectTypes(Object element, + SubProgressMonitor monitor, Set result) { + element = computeScope(element); + try { + // if the selected is a member(field, method) of Midlet, collect + // is't parent Midlet + while (element instanceof IMember) { + if (element instanceof IType) { + if (Utils.isMidlet((IType) element, monitor)) { + result.add((IType) element); + monitor.done(); + return; + } + } + element = ((IJavaElement) element).getParent(); + } + // if the selected is a Midlet, collect it + if (element instanceof ICompilationUnit) { + ICompilationUnit cu = (ICompilationUnit) element; + IType[] types = cu.getAllTypes(); + for (int i = 0; i < types.length; i++) { + if (Utils.isMidlet(types[i], monitor)) { + result.add(types[i]); + } + } + } + // if the selected is a Midlet class file, collect the Midlet + else if (element instanceof IClassFile) { + IType type = ((IClassFile) element).getType(); + if (Utils.isMidlet(type, monitor)) { + result.add(type); + } + } + // if the selected is a container, collect all Midlets in it + else if (element instanceof IJavaElement) { + // the container + IJavaElement parent = (IJavaElement) element; + // get all Midlets in the project + List found = collectMidletTypesInProject(monitor, parent + .getJavaProject()); + // filter within the parent element + // only collect Midlets that are located in the container + Iterator iterator = found.iterator(); + while (iterator.hasNext()) { + IJavaElement target = iterator.next(); + IJavaElement child = target; + while (child != null) { + if (child.equals(parent)) { + result.add((IType) target); + break; + } + child = child.getParent(); + } + } + } + } catch (JavaModelException e) { + MTJCorePlugin.log(IStatus.WARNING, "collectTypes", e); + } + } + + /** + * Collect Midlets from project. + * + * @param monitor + * @param project + * @return + */ + private static List collectMidletTypesInProject( + IProgressMonitor monitor, IJavaProject project) { + IType[] types; + HashSet result = new HashSet(5); + try { + IType midlet = project + .findType(IMTJCoreConstants.MIDLET_SUPERCLASS); + ITypeHierarchy hierarchy = midlet.newTypeHierarchy(project, + new SubProgressMonitor(monitor, 1)); + types = hierarchy.getAllSubtypes(midlet); + int length = types.length; + if (length != 0) { + for (int i = 0; i < length; i++) { + if (!types[i].isBinary()) { + result.add(types[i]); + } + } + } + } catch (JavaModelException jme) { + } + monitor.done(); + return new ArrayList(result); + } + + /** + * If the element is not a IJavaElement, try to get the + * IJavaElement from it. + * + * @param element + * @return + */ + private static Object computeScope(Object element) { + if (element instanceof IJavaElement) { + return element; + } + if (element instanceof IAdaptable) { + element = ((IAdaptable) element).getAdapter(IResource.class); + } + if (element instanceof IResource) { + IJavaElement javaElement = JavaCore.create((IResource) element); + if (javaElement != null && !javaElement.exists()) { + // do not consider the resource - corresponding java element + // does not exist + element = null; + } else { + element = javaElement; + } + + } + return element; + } +} Index: src/org/eclipse/mtj/ui/internal/launching/MidletLaunchShortcut.java =================================================================== --- src/org/eclipse/mtj/ui/internal/launching/MidletLaunchShortcut.java (revision 0) +++ src/org/eclipse/mtj/ui/internal/launching/MidletLaunchShortcut.java (revision 0) @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2008 Sybase 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: + * Feng Wang (Sybase) - initial implementation + *******************************************************************************/ + +package org.eclipse.mtj.ui.internal.launching; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationType; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; +import org.eclipse.jface.operation.IRunnableContext; +import org.eclipse.mtj.core.internal.MTJCorePlugin; +import org.eclipse.mtj.core.internal.utils.Utils; +import org.eclipse.mtj.core.launching.ILaunchConstants; + +/** + * Launch shortcut for Midlet. + * + * @author wangf + * + */ +public class MidletLaunchShortcut extends JavaLaunchShortcut { + /* + * (non-Javadoc) + * + * @seeorg.eclipse.jdt.debug.ui.launchConfigurations.JavaLaunchShortcut# + * createConfiguration(org.eclipse.jdt.core.IType) + */ + @Override + protected ILaunchConfiguration createConfiguration(IType type) { + ILaunchConfiguration config = null; + try { + ILaunchConfigurationType configType = getConfigurationType(); + + String launchConfigName = DebugPlugin.getDefault() + .getLaunchManager() + .generateUniqueLaunchConfigurationNameFrom( + type.getElementName()); + ILaunchConfigurationWorkingCopy wc = configType.newInstance(null, + launchConfigName); + + wc.setAttribute(ILaunchConstants.EMULATED_CLASS, Utils + .getQualifiedClassName(type)); + wc.setAttribute( + IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, type + .getJavaProject().getElementName()); + wc.setAttribute(ILaunchConstants.DO_OTA, false); + + DebugUITools.setLaunchPerspective(configType, + ILaunchManager.RUN_MODE, + IDebugUIConstants.PERSPECTIVE_DEFAULT); + DebugUITools.setLaunchPerspective(configType, + ILaunchManager.DEBUG_MODE, + IDebugUIConstants.PERSPECTIVE_DEFAULT); + + config = wc.doSave(); + + } catch (CoreException ce) { + MTJCorePlugin.log(IStatus.WARNING, "createConfiguration", ce); + } + + return config; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jdt.debug.ui.launchConfigurations.JavaLaunchShortcut#findTypes + * (java.lang.Object[], org.eclipse.jface.operation.IRunnableContext) + */ + @Override + protected IType[] findTypes(Object[] elements, IRunnableContext context) + throws InterruptedException, CoreException { + + try { + return MidletLaunchConfigUtils.findMidlets(context, elements); + } catch (InvocationTargetException e) { + throw (CoreException) e.getTargetException(); + } + + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.jdt.debug.ui.launchConfigurations.JavaLaunchShortcut# + * getConfigurationType() + */ + @Override + protected ILaunchConfigurationType getConfigurationType() { + ILaunchManager lm = DebugPlugin.getDefault().getLaunchManager(); + ILaunchConfigurationType configType = lm + .getLaunchConfigurationType(ILaunchConstants.LAUNCH_CONFIG_TYPE); + return configType; + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.jdt.debug.ui.launchConfigurations.JavaLaunchShortcut# + * getEditorEmptyMessage() + */ + @Override + protected String getEditorEmptyMessage() { + return LauncherMessages.MidletLaunching_EditorContainsNoMidlet; + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.jdt.debug.ui.launchConfigurations.JavaLaunchShortcut# + * getSelectionEmptyMessage() + */ + @Override + protected String getSelectionEmptyMessage() { + return LauncherMessages.MidletLaunching_SelectionContainsNoMidlet; + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.jdt.debug.ui.launchConfigurations.JavaLaunchShortcut# + * getTypeSelectionTitle() + */ + @Override + protected String getTypeSelectionTitle() { + return LauncherMessages.MidletLaunching_SelectionDialogTitle; + } + +} Index: src/org/eclipse/mtj/ui/internal/launching/LauncherMessages.java =================================================================== --- src/org/eclipse/mtj/ui/internal/launching/LauncherMessages.java (revision 0) +++ src/org/eclipse/mtj/ui/internal/launching/LauncherMessages.java (revision 0) @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2008 Sybase 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: + * Feng Wang (Sybase) - Initial implementation + *******************************************************************************/ +package org.eclipse.mtj.ui.internal.launching; + +import org.eclipse.osgi.util.NLS; + +public class LauncherMessages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.mtj.ui.internal.launching.messages";//$NON-NLS-1$ + public static String launch_configSelection_title; + public static String launch_configSelection_message; + public static String MidletLaunching_EditorContainsNoMidlet; + public static String MidletLaunching_SelectionContainsNoMidlet; + public static String MidletLaunching_SelectionDialogTitle; + public static String JavaLaunchShortcut_0; + public static String JavaLaunchShortcut_1; + public static String JavaLaunchShortcut_2; + public static String JavaLaunchShortcut_3; + public static String MainMethodLabelProvider_0; + public static String JavaMainTab_Choose_a_main__type_to_launch__12; + static { + // load message values from bundle file + NLS.initializeMessages(BUNDLE_NAME, LauncherMessages.class); + } +} Index: src/org/eclipse/mtj/ui/internal/launching/DebugTypeSelectionDialog.java =================================================================== --- src/org/eclipse/mtj/ui/internal/launching/DebugTypeSelectionDialog.java (revision 0) +++ src/org/eclipse/mtj/ui/internal/launching/DebugTypeSelectionDialog.java (revision 0) @@ -0,0 +1,337 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +/******************************************************************************* + * Copyright (c) 2008 Sybase 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: + * Feng Wang (Sybase) - Copy from + * org.eclipse.jdt.internal.debug.ui.launcher.DebugTypeSelectionDialog And Modified. + * This class is used by org.eclipse.mtj.ui.internal.launching.JavaLaunchShortcut + * In feature when MTJ do not need to support Eclipse 3.3, + * org.eclipse.mtj.ui.internal.launching.JavaLaunchShortcut will no + * longer useful and will be deleted. This class will be deleted too. + *******************************************************************************/ + +package org.eclipse.mtj.ui.internal.launching; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.mtj.core.internal.MTJCorePlugin; +import org.eclipse.mtj.ui.IMTJUIConstants; +import org.eclipse.mtj.ui.internal.MTJUIPlugin; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog; +import org.eclipse.ui.model.IWorkbenchAdapter; + +/** + * This is a specialization of FilteredItemsSelectionDialog used + * to present users with a listing of ITypes that contain main + * methods + * + * @since 3.3 + * + */ +public class DebugTypeSelectionDialog extends FilteredItemsSelectionDialog { + + private static final String SELECT_MAIN_METHOD_DIALOG = "org.eclipse.jdt.debug.ui.select_main_method_dialog"; + + /** + * Main list label provider + */ + public class DebugTypeLabelProvider implements ILabelProvider { + HashMap fImageMap = new HashMap(); + + public Image getImage(Object element) { + if (element instanceof IAdaptable) { + IWorkbenchAdapter adapter = (IWorkbenchAdapter) ((IAdaptable) element) + .getAdapter(IWorkbenchAdapter.class); + if (adapter != null) { + ImageDescriptor descriptor = adapter + .getImageDescriptor(element); + Image image = fImageMap.get(descriptor); + if (image == null) { + image = descriptor.createImage(); + fImageMap.put(descriptor, image); + } + return image; + } + } + return null; + } + + public String getText(Object element) { + if (element instanceof IType) { + IType type = (IType) element; + String label = type.getElementName(); + String container = getDeclaringContainerName(type); + if (container != null && !"".equals(container)) { //$NON-NLS-1$ + label += " - " + container; //$NON-NLS-1$ + } + return label; + } + return null; + } + + /** + * Returns the name of the declaring container name + * + * @param type + * the type to find the container name for + * @return the container name for the specified type + */ + protected String getDeclaringContainerName(IType type) { + IType outer = type.getDeclaringType(); + if (outer != null) { + return outer.getFullyQualifiedName('.'); + } else { + String name = type.getPackageFragment().getElementName(); + if ("".equals(name)) { //$NON-NLS-1$ + name = LauncherMessages.MainMethodLabelProvider_0; + } + return name; + } + } + + /** + * Returns the narrowest enclosing IJavaElement which is + * either an IType (enclosing) or an + * IPackageFragment (contained in) + * + * @param type + * the type to find the enclosing IJavaElement + * for. + * @return the enclosing element or null if none + */ + protected IJavaElement getDeclaringContainer(IType type) { + IJavaElement outer = type.getDeclaringType(); + if (outer == null) { + outer = type.getPackageFragment(); + } + return outer; + } + + public void dispose() { + fImageMap.clear(); + fImageMap = null; + } + + public void addListener(ILabelProviderListener listener) { + } + + public boolean isLabelProperty(Object element, String property) { + return false; + } + + public void removeListener(ILabelProviderListener listener) { + } + } + + /** + * Provides a label and image for the details area of the dialog + */ + class DebugTypeDetailsLabelProvider extends DebugTypeLabelProvider { + public String getText(Object element) { + if (element instanceof IType) { + IType type = (IType) element; + String name = getDeclaringContainerName(type); + if (name != null) { + if (name.equals(LauncherMessages.MainMethodLabelProvider_0)) { + IJavaProject project = type.getJavaProject(); + if (project != null) { + try { + return project.getOutputLocation().toOSString() + .substring(1) + + " - " + name; //$NON-NLS-1$ + } catch (JavaModelException e) { + MTJCorePlugin.log(IStatus.ERROR, e); + } + } + } else { + return name; + } + } + } + return null; + } + + public Image getImage(Object element) { + if (element instanceof IType) { + return super.getImage(getDeclaringContainer(((IType) element))); + } + return super.getImage(element); + } + } + + /** + * Simple items filter + */ + class DebugTypeItemsFilter extends ItemsFilter { + public boolean isConsistentItem(Object item) { + return item instanceof IType; + } + + public boolean matchItem(Object item) { + if (!(item instanceof IType) + || !Arrays.asList(fTypes).contains(item)) { + return false; + } + return matches(((IType) item).getElementName()); + } + } + + /** + * The selection history for the dialog + */ + class DebugTypeSelectionHistory extends SelectionHistory { + protected Object restoreItemFromMemento(IMemento memento) { + IJavaElement element = JavaCore.create(memento.getTextData()); + return (element instanceof IType ? element : null); + } + + protected void storeItemToMemento(Object item, IMemento memento) { + if (item instanceof IType) { + memento.putTextData(((IType) item).getHandleIdentifier()); + } + } + } + + private static final String SETTINGS_ID = IMTJUIConstants.PLUGIN_ID + + ".MIDLET_SELECTION_DIALOG"; //$NON-NLS-1$ + private IType[] fTypes = null; + + /** + * Constructor + * + * @param elements + * the types to display in the dialog + */ + public DebugTypeSelectionDialog(Shell shell, IType[] elements, String title) { + super(shell, false); + setTitle(title); + fTypes = elements; + setMessage(LauncherMessages.JavaMainTab_Choose_a_main__type_to_launch__12); + setInitialPattern("**"); //$NON-NLS-1$ + setListLabelProvider(new DebugTypeLabelProvider()); + setDetailsLabelProvider(new DebugTypeDetailsLabelProvider()); + setSelectionHistory(new DebugTypeSelectionHistory()); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createDialogArea(org.eclipse.swt.widgets.Composite) + */ + protected Control createDialogArea(Composite parent) { + Control ctrl = super.createDialogArea(parent); + PlatformUI.getWorkbench().getHelpSystem().setHelp(ctrl, + SELECT_MAIN_METHOD_DIALOG); + return ctrl; + } + + /** + * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getDialogSettings() + */ + protected IDialogSettings getDialogSettings() { + IDialogSettings settings = MTJUIPlugin.getDefault().getDialogSettings(); + IDialogSettings section = settings.getSection(SETTINGS_ID); + if (section == null) { + section = settings.addNewSection(SETTINGS_ID); + } + return section; + } + + /** + * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getItemsComparator() + */ + protected Comparator getItemsComparator() { + Comparator comp = new Comparator() { + + public int compare(IType o1, IType o2) { + return o1.getElementName().compareTo(o2.getElementName()); + } + }; + return comp; + } + + /** + * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#validateItem(java.lang.Object) + */ + protected IStatus validateItem(Object item) { + return Status.OK_STATUS; + } + + /** + * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createExtendedContentArea(org.eclipse.swt.widgets.Composite) + */ + protected Control createExtendedContentArea(Composite parent) { + return null; + } + + /** + * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createFilter() + */ + protected ItemsFilter createFilter() { + return new DebugTypeItemsFilter(); + } + + /** + * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#fillContentProvider(org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.AbstractContentProvider, + * org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter, + * org.eclipse.core.runtime.IProgressMonitor) + */ + protected void fillContentProvider(AbstractContentProvider contentProvider, + ItemsFilter itemsFilter, IProgressMonitor progressMonitor) + throws CoreException { + if (fTypes != null && fTypes.length > 0) { + for (int i = 0; i < fTypes.length; i++) { + if (itemsFilter.isConsistentItem(fTypes[i])) { + contentProvider.add(fTypes[i], itemsFilter); + } + } + } + } + + /** + * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getElementName(java.lang.Object) + */ + public String getElementName(Object item) { + if (item instanceof IType) { + return ((IType) item).getElementName(); + } + return null; + } +} Index: src/org/eclipse/mtj/ui/internal/launching/JavaLaunchShortcut.java =================================================================== --- src/org/eclipse/mtj/ui/internal/launching/JavaLaunchShortcut.java (revision 0) +++ src/org/eclipse/mtj/ui/internal/launching/JavaLaunchShortcut.java (revision 0) @@ -0,0 +1,318 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +/******************************************************************************* + * Copyright (c) 2008 Sybase 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: + * Feng Wang (Sybase) - Copy from + * org.eclipse.jdt.internal.debug.ui.launcher.JavaLaunchShortcut And Modified. + * In Eclipse 3.4, JavaLaunchShortcut become a non-internal class: + * org.eclipse.jdt.debug.ui.launchConfigurations.JavaLaunchShortcut, + * so we can use it directly. + * In feature when MTJ do not need to support Eclipse 3.3, this + * class will no longer useful and should be deleted. + *******************************************************************************/ + +package org.eclipse.mtj.ui.internal.launching; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationType; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.IDebugModelPresentation; +import org.eclipse.debug.ui.ILaunchShortcut; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.operation.IRunnableContext; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.window.Window; +import org.eclipse.mtj.core.internal.MTJCorePlugin; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.ElementListSelectionDialog; + +/** + * Common behavior for Java launch shortcuts + * + * @since 3.2 + */ +public abstract class JavaLaunchShortcut implements ILaunchShortcut { + + /** + * @param search + * the java elements to search for a main type + * @param mode + * the mode to launch in + * @param editor + * activated on an editor (or from a selection in a viewer) + */ + public void searchAndLaunch(Object[] search, String mode, + String selectMessage, String emptyMessage) { + IType[] types = null; + try { + types = findTypes(search, PlatformUI.getWorkbench() + .getProgressService()); + } catch (InterruptedException e) { + return; + } catch (CoreException e) { + MessageDialog.openError(getShell(), + LauncherMessages.JavaLaunchShortcut_0, e.getMessage()); + return; + } + IType type = null; + if (types.length == 0) { + MessageDialog.openError(getShell(), + LauncherMessages.JavaLaunchShortcut_1, emptyMessage); + } else if (types.length > 1) { + type = chooseType(types, selectMessage); + } else { + type = types[0]; + } + if (type != null) { + launch(type, mode); + } + } + + /** + * Finds and returns the launchable types in the given selection of + * elements. + * + * @param elements + * scope to search for launchable types + * @param context + * progress reporting context + * @return launchable types, possibly empty + * @exception InterruptedException + * if the search is canceled + * @exception org.eclipse.core.runtime.CoreException + * if the search fails + */ + protected abstract IType[] findTypes(Object[] elements, + IRunnableContext context) throws InterruptedException, + CoreException; + + /** + * Prompts the user to select a type from the given types. + * + * @param types + * the types to choose from + * @param title + * the selection dialog title + * + * @return the selected type or null if none. + */ + protected IType chooseType(IType[] types, String title) { + DebugTypeSelectionDialog mmsd = new DebugTypeSelectionDialog( + getShell(), types, title); + if (mmsd.open() == Window.OK) { + return (IType) mmsd.getResult()[0]; + } + return null; + } + + /** + * Launches a configuration for the given type + */ + protected void launch(IType type, String mode) { + ILaunchConfiguration config = findLaunchConfiguration(type, + getConfigurationType()); + if (config != null) { + DebugUITools.launch(config, mode); + } + } + + /** + * Returns the type of configuration this shortcut is applicable to. + * + * @return the type of configuration this shortcut is applicable to + */ + protected abstract ILaunchConfigurationType getConfigurationType(); + + /** + * Locate a configuration to relaunch for the given type. If one cannot be + * found, create one. + * + * @return a re-usable config or null if none + */ + protected ILaunchConfiguration findLaunchConfiguration(IType type, + ILaunchConfigurationType configType) { + List candidateConfigs = Collections.emptyList(); + try { + ILaunchConfiguration[] configs = DebugPlugin.getDefault() + .getLaunchManager().getLaunchConfigurations(configType); + candidateConfigs = new ArrayList( + configs.length); + for (int i = 0; i < configs.length; i++) { + ILaunchConfiguration config = configs[i]; + if (config.getAttribute( + IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, + "").equals(type.getFullyQualifiedName())) { //$NON-NLS-1$ + if (config + .getAttribute( + IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, + "").equals(type.getJavaProject().getElementName())) { //$NON-NLS-1$ + candidateConfigs.add(config); + } + } + } + } catch (CoreException e) { + MTJCorePlugin.log(IStatus.ERROR, e); + } + + // If there are no existing configs associated with the IType, create + // one. + // If there is exactly one config associated with the IType, return it. + // Otherwise, if there is more than one config associated with the + // IType, prompt the + // user to choose one. + int candidateCount = candidateConfigs.size(); + if (candidateCount < 1) { + return createConfiguration(type); + } else if (candidateCount == 1) { + return candidateConfigs.get(0); + } else { + // Prompt the user to choose a config. A null result means the user + // canceled the dialog, in which case this method returns null, + // since canceling the dialog should also cancel launching anything. + ILaunchConfiguration config = chooseConfiguration(candidateConfigs); + if (config != null) { + return config; + } + } + + return null; + } + + /** + * Show a selection dialog that allows the user to choose one of the + * specified launch configurations. Return the chosen config, or + * null if the user canceled the dialog. + */ + protected ILaunchConfiguration chooseConfiguration( + List configList) { + IDebugModelPresentation labelProvider = DebugUITools + .newDebugModelPresentation(); + ElementListSelectionDialog dialog = new ElementListSelectionDialog( + getShell(), labelProvider); + dialog.setElements(configList.toArray()); + dialog.setTitle(getTypeSelectionTitle()); + dialog.setMessage(LauncherMessages.JavaLaunchShortcut_2); + dialog.setMultipleSelection(false); + int result = dialog.open(); + labelProvider.dispose(); + if (result == Window.OK) { + return (ILaunchConfiguration) dialog.getFirstResult(); + } + return null; + } + + /** + * Create and returns a new configuration based on the specified + * IType. + */ + protected abstract ILaunchConfiguration createConfiguration(IType type); + + /** + * Opens an error dialog on the given exception. + * + * @param exception + */ + protected void reportErorr(CoreException exception) { + MessageDialog.openError(getShell(), + LauncherMessages.JavaLaunchShortcut_3, exception.getStatus() + .getMessage()); + } + + protected ILaunchManager getLaunchManager() { + return DebugPlugin.getDefault().getLaunchManager(); + } + + /** + * Convenience method to get the window that owns this action's Shell. + */ + private Shell getShell() { + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + if (window == null) { + IWorkbenchWindow[] windows = PlatformUI.getWorkbench() + .getWorkbenchWindows(); + if (windows.length > 0) { + return windows[0].getShell(); + } + } else { + return window.getShell(); + } + return null; + } + + /** + * @see ILaunchShortcut#launch(IEditorPart, String) + */ + public void launch(IEditorPart editor, String mode) { + IEditorInput input = editor.getEditorInput(); + IJavaElement je = (IJavaElement) input.getAdapter(IJavaElement.class); + if (je != null) { + searchAndLaunch(new Object[] { je }, mode, getTypeSelectionTitle(), + getEditorEmptyMessage()); + } + } + + /** + * @see ILaunchShortcut#launch(ISelection, String) + */ + public void launch(ISelection selection, String mode) { + if (selection instanceof IStructuredSelection) { + searchAndLaunch(((IStructuredSelection) selection).toArray(), mode, + getTypeSelectionTitle(), getSelectionEmptyMessage()); + } + } + + /** + * Returns the title for type selection dialog for this launch shortcut. + * + * @return type selection dialog title + */ + protected abstract String getTypeSelectionTitle(); + + /** + * Returns an error message to use when the editor does not contain a + * launchable type. + * + * @return error message + */ + protected abstract String getEditorEmptyMessage(); + + /** + * Returns an error message to use when the selection does not contain a + * launchable type. + * + * @return error message + */ + protected abstract String getSelectionEmptyMessage(); +} Index: src/org/eclipse/mtj/ui/internal/launching/messages.properties =================================================================== --- src/org/eclipse/mtj/ui/internal/launching/messages.properties (revision 415) +++ src/org/eclipse/mtj/ui/internal/launching/messages.properties (working copy) @@ -12,3 +12,15 @@ launch_configSelection_title = Launch configuration launch_configSelection_message = Select launch configuration + +MidletLaunching_SelectionDialogTitle = Select Java Midlet +MidletLaunching_EditorContainsNoMidlet = Editor does not contain an Midlet +MidletLaunching_SelectionContainsNoMidlet = Selection does not contain an Midlet + +JavaLaunchShortcut_0=Error +JavaLaunchShortcut_1=Launch Error +JavaLaunchShortcut_2=&Select existing configuration: +JavaLaunchShortcut_3=Error + +MainMethodLabelProvider_0=(default package) +JavaMainTab_Choose_a_main__type_to_launch__12=Select &type (? = any character, * = any String, TZ = TimeZone): Index: src/org/eclipse/mtj/ui/internal/launching/LauncherMessage.java =================================================================== --- src/org/eclipse/mtj/ui/internal/launching/LauncherMessage.java (revision 415) +++ src/org/eclipse/mtj/ui/internal/launching/LauncherMessage.java (working copy) @@ -1,24 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Sybase 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: - * Feng Wang (Sybase) - Initial implementation - *******************************************************************************/ -package org.eclipse.mtj.ui.internal.launching; - -import org.eclipse.osgi.util.NLS; - -public class LauncherMessage extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.mtj.ui.internal.launching.messages";//$NON-NLS-1$ - public static String launch_configSelection_title; - public static String launch_configSelection_message; - static { - // load message values from bundle file - NLS.initializeMessages(BUNDLE_NAME, LauncherMessage.class); - } -}