/******************************************************************************* * Copyright (c) 2012 VMWare, Inc. * 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: * VMWare, Inc. - initial API and implementation *******************************************************************************/ package org.grails.ide.eclipse.ui.internal.launch; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Set; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.jdt.core.IJavaModel; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.debug.ui.launchConfigurations.JavaLaunchTab; import org.eclipse.jdt.internal.debug.ui.launcher.LauncherMessages; import org.eclipse.jdt.internal.launching.JavaMigrationDelegate; import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; import org.eclipse.jdt.ui.JavaElementLabelProvider; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.ElementListSelectionDialog; import org.grails.ide.eclipse.core.GrailsCoreActivator; import org.grails.ide.eclipse.core.internal.GrailsNature; import org.grails.ide.eclipse.core.launch.GrailsLaunchArgumentUtils; import org.grails.ide.eclipse.core.model.GrailsBuildSettingsHelper; import org.grails.ide.eclipse.core.model.IGrailsInstall; import org.springsource.ide.eclipse.commons.core.SpringCoreUtils; import org.grails.ide.eclipse.ui.GrailsUiImages; import org.grails.ide.eclipse.ui.internal.inplace.GrailsCompletionUtils; /** * @author Christian Dupuis * @since 2.2.0 */ public class GrailsLaunchMainTab extends JavaLaunchTab { /** * A listener which handles widget change events for the controls in this tab. */ private class WidgetListener implements ModifyListener, SelectionListener { public void modifyText(ModifyEvent e) { updateLaunchConfigurationDialog(); } public void widgetDefaultSelected(SelectionEvent e) {/* do nothing */ } public void widgetSelected(SelectionEvent e) { Object source = e.getSource(); if (source == fProjButton) { handleProjectButtonSelected(); } else { updateLaunchConfigurationDialog(); } } } protected static final String EMPTY_STRING = ""; //$NON-NLS-1$ // Project UI widgets protected Text fProjText; private Button fProjButton; private WidgetListener fListener = new WidgetListener(); /** * chooses a project for the type of java launch config that it is * @return */ private IJavaProject chooseJavaProject() { ILabelProvider labelProvider = new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT); ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(), labelProvider); dialog.setTitle(""); dialog.setMessage(""); try { Set<IJavaProject> projects = new LinkedHashSet<IJavaProject>(); for (IJavaProject project : JavaCore.create(getWorkspaceRoot()).getJavaProjects()) { if (SpringCoreUtils.hasNature(project.getResource(), GrailsNature.NATURE_ID)) { projects.add(project); } } dialog.setElements((IJavaProject[]) projects.toArray(new IJavaProject[projects.size()])); } catch (JavaModelException e) { GrailsCoreActivator.log(e); } IJavaProject javaProject = getJavaProject(); if (javaProject != null) { dialog.setInitialSelections(new Object[] { javaProject }); } if (dialog.open() == Window.OK) { return (IJavaProject) dialog.getFirstResult(); } return null; } /** * Creates the widgets for specifying a main type. * * @param parent the parent composite */ protected void createProjectEditor(Composite parent) { Font font = parent.getFont(); Group group = new Group(parent, SWT.NONE); group.setText(LauncherMessages.AbstractJavaMainTab_0); GridData gd = new GridData(GridData.FILL_HORIZONTAL); group.setLayoutData(gd); GridLayout layout = new GridLayout(); layout.numColumns = 2; group.setLayout(layout); group.setFont(font); fProjText = new Text(group, SWT.SINGLE | SWT.BORDER); gd = new GridData(GridData.FILL_HORIZONTAL); fProjText.setLayoutData(gd); fProjText.setFont(font); fProjText.addModifyListener(fListener); fProjText.setEditable(false); fProjButton = createPushButton(group, LauncherMessages.AbstractJavaMainTab_1, null); fProjButton.addSelectionListener(fListener); } /** * returns the default listener from this class. For all subclasses this listener will only provide the * functionality of updating the current tab * * @return a widget listener */ protected WidgetListener getDefaultListener() { return fListener; } /** * Convenience method to get access to the java model. */ private IJavaModel getJavaModel() { return JavaCore.create(getWorkspaceRoot()); } /** * Return the IJavaProject corresponding to the project name in the project name text field, or null if the text * does not match a project name. */ protected IJavaProject getJavaProject() { String projectName = fProjText.getText().trim(); if (projectName == null || projectName.length() < 1) { setErrorMessage("No project selected"); return null; } IJavaProject javaProject = getJavaModel().getJavaProject(projectName); if (! javaProject.exists()) { setErrorMessage("Project " + projectName + " doesn't exist"); return null; } if (! javaProject.exists()) { setErrorMessage("Project " + projectName + " isn't open"); return null; } setErrorMessage(null); return javaProject; } /** * Convenience method to get the workspace root. */ protected IWorkspaceRoot getWorkspaceRoot() { return ResourcesPlugin.getWorkspace().getRoot(); } /** * Show a dialog that lets the user select a project. This in turn provides context for the main type, allowing the * user to key a main type name, or constraining the search for main types to the specified project. */ protected void handleProjectButtonSelected() { IJavaProject project = chooseJavaProject(); if (project == null) { return; } String projectName = project.getElementName(); fProjText.setText(projectName); initializeContentAssist(); } /** * updates the project text field form the configuration * @param config the configuration we are editing */ private void updateProjectFromConfig(ILaunchConfiguration config) { String projectName = EMPTY_STRING; try { projectName = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, EMPTY_STRING); script.setText(config.getAttribute(GrailsCoreActivator.PLUGIN_ID + ".SCRIPT", EMPTY_STRING)); } catch (CoreException ce) { setErrorMessage(ce.getStatus().getMessage()); } fProjText.setText(projectName); } /** * Maps the config to associated java resource * * @param config */ protected void mapResources(ILaunchConfigurationWorkingCopy config) { try { // CONTEXTLAUNCHING IJavaProject javaProject = getJavaProject(); if (javaProject != null && javaProject.exists() && javaProject.isOpen()) { JavaMigrationDelegate.updateResourceMapping(config); } } catch (CoreException ce) { setErrorMessage(ce.getStatus().getMessage()); } } private Text script; public Image getImage() { return GrailsUiImages.getImage(GrailsUiImages.IMG_OBJ_GRAILS); } public void createControl(Composite parent) { Composite mainComposite = new Composite(parent, SWT.NONE); setControl(mainComposite); GridLayout layout = new GridLayout(); layout.numColumns = 1; GridData gridData = new GridData(GridData.FILL_HORIZONTAL); mainComposite.setLayout(layout); mainComposite.setLayoutData(gridData); mainComposite.setFont(parent.getFont()); createProjectEditor(mainComposite); Group group = new Group(mainComposite, SWT.NONE); group.setText("Grails Command"); GridData gd = new GridData(GridData.FILL_HORIZONTAL); group.setLayoutData(gd); layout = new GridLayout(); layout.numColumns = 2; group.setLayout(layout); Label label = new Label(group, SWT.NONE); label.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false)); label.setText("grails> "); script = new Text(group, SWT.BORDER); script.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); script.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { setDirty(true); updateLaunchConfigurationDialog(); } }); new Label(group, SWT.NONE); Label note = new Label(group, SWT.NONE); note.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false)); note.setText("Note: type command without the 'grails' prefix"); } public void initializeFrom(ILaunchConfiguration configuration) { super.initializeFrom(configuration); updateProjectFromConfig(configuration); initializeContentAssist(); setDirty(false); } private void initializeContentAssist() { if (getJavaProject() != null) { GrailsCompletionUtils.addTypeFieldAssistToText(script, getJavaProject().getProject()); } } public void performApply(ILaunchConfigurationWorkingCopy configuration) { if (configuration == null) { return; } if (getJavaProject() != null) { IProject project = getJavaProject().getProject(); IGrailsInstall install = GrailsCoreActivator.getDefault().getInstallManager().getGrailsInstall(project); try { GrailsLaunchArgumentUtils.prepareLaunchConfiguration(project, script.getText(), install, GrailsBuildSettingsHelper.getBaseDir(project), configuration); configuration.doSave(); setDirty(false); } catch (CoreException e) { GrailsCoreActivator.log(e); } } } public String getName() { return "Grails"; } public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { configuration.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, true); configuration.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, new HashMap<String, String>()); } }