/******************************************************************************* * 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.wizard; import java.util.Collection; import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IType; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.IWizardPage; import org.eclipse.ui.IWorkbench; import org.grails.ide.eclipse.commands.GrailsCommand; import org.grails.ide.eclipse.commands.GrailsCommandFactory; import org.grails.ide.eclipse.core.GrailsCoreActivator; import org.grails.ide.eclipse.core.internal.GrailsResourceUtil; import org.grails.ide.eclipse.core.model.GrailsCommandAdapter; import org.springsource.ide.eclipse.commons.frameworks.core.internal.commands.ICommandParameter; import org.springsource.ide.eclipse.commons.frameworks.core.internal.commands.ICommandParameterDescriptor; import org.springsource.ide.eclipse.commons.frameworks.core.internal.commands.IFrameworkCommand; import org.springsource.ide.eclipse.commons.frameworks.core.internal.commands.IFrameworkCommandDescriptor; import org.springsource.ide.eclipse.commons.frameworks.core.internal.commands.ParameterFactory; import org.springsource.ide.eclipse.commons.frameworks.core.internal.commands.ParameterKind; import org.springsource.ide.eclipse.commons.frameworks.ui.internal.utils.ProjectFilter; import org.springsource.ide.eclipse.commons.frameworks.ui.internal.utils.SelectionUtils; import org.springsource.ide.eclipse.commons.frameworks.ui.internal.wizard.GenericCommandWizard; import org.springsource.ide.eclipse.commons.frameworks.ui.internal.wizard.GenericWizardCommandListPage; import org.grails.ide.eclipse.ui.internal.utils.OpenNewResourcesCommandListener; /** * Grails-specific command wizard with support for Grails environment variable. * @author Nieraj Singh * @author Kris De Volder */ public class GrailsCommandWizard extends GenericCommandWizard { public static final String WIZARD_TITLE = "Grails Command Wizard"; public static final String WIZARD_IMAGE_LOCATION = "platform:/plugin/org.grails.ide.eclipse.ui/icons/full/wizban/grails_wizban.png"; public GrailsCommandWizard(IFrameworkCommand command) { this(GrailsResourceUtil.getAllGrailsProjects(), command); } public GrailsCommandWizard(Collection<IProject> projects, IFrameworkCommand command) { super(command, WIZARD_TITLE, null, WIZARD_IMAGE_LOCATION, projects, false); } protected GenericWizardCommandListPage createCommandListPage() { return new GrailsCommandListPage(getWindowTitle()); } @Override public void init(IWorkbench workbench, IStructuredSelection selection) { super.init(workbench, selection); customizeCommand(selection); } /** * Behaviour: * * <p> * * Create a parameters page ONLY under these conditions: * <li>A command has been selected and a parameter page doesn't currently * exist</li> * <li>a parameter page exists but corresponds to a command different than * what is currently selected in the wizard</li> * <li>a parameter page exists, and it corresponds to the selected command, * but a user has requested that the Grails environment variable be added or * removed, in which case the parameter page controls have to be recreated</li> * </p> * <p> * Otherwise, use the existing parameters page as to preserve the current * control values. * </p> */ public IWizardPage getNextPage(IWizardPage page) { IFrameworkCommand commandInstance = getCommandInstance(); if (page == commandListPage) { boolean hasSystemEnv = hasGrailsSystemEnv(); boolean hasCommandChanged = false; if (shouldAddGrailsSystemEnv() && !hasSystemEnv) { addGrailsSystemEnv(); hasCommandChanged = true; } else if (!shouldAddGrailsSystemEnv() && hasSystemEnv) { removeGrailsSystemEnv(); hasCommandChanged = true; } if (parameterPage != null && (parameterPage.getCommand() == commandInstance) && !hasCommandChanged) { // If no changes, use the existing page. return parameterPage; } else if (commandInstance != null) { parameterPage = createParameterPage(commandInstance); return parameterPage; } } return super.getNextPage(page); } /** * If displaying the command list page (first page), update the Grails env * variable check box. */ public IWizardPage getPreviousPage(IWizardPage page) { IWizardPage previousPage = super.getPreviousPage(page); if (previousPage instanceof GrailsCommandListPage) { GrailsCommandListPage grailsListPage = (GrailsCommandListPage) previousPage; grailsListPage.setGrailsSystemEnv(hasGrailsSystemEnv()); } return previousPage; } /** * * @return true if the UI control in the command list page indicates that * the user would like to configure the Grails env variable. False * otherwise */ protected boolean shouldAddGrailsSystemEnv() { if (commandListPage instanceof GrailsCommandListPage) { return ((GrailsCommandListPage) commandListPage) .shouldAddGrailsSystemEnv(); } return false; } /** * * @return true if the command instance already has a Grails env parameter * present as the first entry of its parameter list. False * otherwise. */ protected boolean hasGrailsSystemEnv() { IFrameworkCommand command = getCommandInstance(); if (command != null) { List<ICommandParameter> parameterInstances = command .getParameters(); if (parameterInstances != null && parameterInstances.size() > 0) { // If it has a system env it should be the first parameter ICommandParameter potentialSystemEnvParameter = parameterInstances .get(0); if (GrailsCommandFactory.GRAILS_SYSTEM_ENV_PARAMETER_DESCRIPTOR .equals(potentialSystemEnvParameter .getParameterDescriptor())) { return true; } } } return false; } /** * Adds a Grails env parameter as the first parameter in a command's list. * If successfully added return true. If not added, because the command * already contains a Grails env parameter, return false; * * @return true if a Grails environment variable was added as the first * parameter in a command instance's parameter list. False otherwise */ protected boolean addGrailsSystemEnv() { IFrameworkCommand command = getCommandInstance(); if (command == null) { return false; } List<ICommandParameter> parameterInstances = command.getParameters(); ICommandParameter possibleEnvParameter = null; if (parameterInstances.size() > 0) { // If it has a system env it should be the first parameter ICommandParameter potentialSystemEnvParameter = parameterInstances .get(0); if (GrailsCommandFactory.GRAILS_SYSTEM_ENV_PARAMETER_DESCRIPTOR .equals(potentialSystemEnvParameter .getParameterDescriptor())) { possibleEnvParameter = potentialSystemEnvParameter; } } if (possibleEnvParameter == null) { ICommandParameter systemParameter = ParameterFactory .getParameterInstance(GrailsCommandFactory.GRAILS_SYSTEM_ENV_PARAMETER_DESCRIPTOR); parameterInstances.add(0, systemParameter); return true; } else { return false; } } protected boolean removeGrailsSystemEnv() { IFrameworkCommand command = getCommandInstance(); if (command == null) { return false; } List<ICommandParameter> parameterInstances = command.getParameters(); if (parameterInstances != null && parameterInstances.size() > 0) { // If it has a system env it should be the first parameter ICommandParameter potentialSystemEnvParameter = parameterInstances .get(0); if (GrailsCommandFactory.GRAILS_SYSTEM_ENV_PARAMETER_DESCRIPTOR .equals(potentialSystemEnvParameter .getParameterDescriptor())) { parameterInstances.remove(0); return true; } } return false; } @Override public boolean canFinish() { return getSelectedProject()!=null && super.canFinish(); } @Override protected void executeCommand(final IFrameworkCommand command) { final IProject project = getSelectedProject(); if (project != null) { if (command != null) { Job worker = new Job(command.getCommandDescriptor().getName()) { protected IStatus run(IProgressMonitor monitor) { GrailsCommandAdapter newRsrcListener = null; try { GrailsCommand grailsCommand = GrailsCommandFactory .getExecutableCommand(command, project); newRsrcListener = getNewResourceListener(project); GrailsCoreActivator.getDefault().addGrailsCommandResourceListener(newRsrcListener); grailsCommand.synchExec(); /** * FIXADE don't always refresh everything. * this should be put into a post op and maybe be able to * refresh only a selected set of resources */ project.refreshLocal(IResource.DEPTH_INFINITE, monitor); } catch (CoreException e) { return e.getStatus(); } finally { if (newRsrcListener != null) { newRsrcListener.finish(); GrailsCoreActivator.getDefault() .removeGrailsCommandResourceListener( newRsrcListener); } } return Status.OK_STATUS; } }; worker.setPriority(Job.INTERACTIVE); worker.schedule(); } } } @Override protected ProjectFilter getProjectFilter() { // TODO Auto-generated method stub return super.getProjectFilter(); } /** * The OpenNewResourceCommandListener determines which new resources will automatically open after * the command completes. The default will open any resource that is in a source folder, except * for resources who's name ends with 'Tests.groovy'. * <p> * Subclass may override to change this behavior (e.g. for create-unit-test it is desirable that the * created test resource be opened. */ protected GrailsCommandAdapter getNewResourceListener( final IProject project) { return new OpenNewResourcesCommandListener( project); } protected void customizeCommand(IStructuredSelection selection) { IFrameworkCommand command = getCommandInstance(); if (command!=null) { IFrameworkCommandDescriptor desc = command.getCommandDescriptor(); ICommandParameterDescriptor[] paramDescs = desc.getParameters(); List<ICommandParameter> params = command.getParameters(); for (int i = 0; i < paramDescs.length; i++) { ParameterKind paramType = paramDescs[i].getParameterKind(); ICommandParameter param = params.get(i); if (paramType==ParameterKind.JAVA_TYPE) { IType type = SelectionUtils.getType(selection); if (type!=null) { param.setValue(type.getFullyQualifiedName()); } else { //Try to get a package at least IPackageFragment pkg = SelectionUtils.getPackage(selection); if (pkg!=null) { param.setValue(pkg.getElementName()); } } } } } } }