/******************************************************************************* * Copyright 2011 Google Inc. All Rights Reserved. * * 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 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ package com.google.gdt.eclipse.suite.wizards; import com.google.gdt.eclipse.core.sdk.Sdk; import com.google.gdt.eclipse.core.sdk.SdkClasspathContainer; import com.google.gdt.eclipse.core.ui.SdkSelectionBlock; import com.google.gdt.eclipse.core.ui.SdkSelectionBlock.SdkSelection; import com.google.gdt.eclipse.platform.ui.PixelConverterFactory; import com.google.gwt.eclipse.core.preferences.GWTPreferences; import com.google.gwt.eclipse.core.preferences.ui.GwtPreferencePage; import com.google.gwt.eclipse.core.runtime.GWTRuntimeContainer; import com.google.gwt.eclipse.core.runtime.GwtSdk; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.JavaConventions; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jface.window.Window; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; 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.DirectoryDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.PreferencesUtil; import java.io.File; import java.net.URI; import java.util.ArrayList; import java.util.List; /** * Wizard page where the user specifies the parameters for a new GWT project. */ public class NewWebAppProjectWizardPage extends WizardPage { /** * Select a GWT {@link Sdk} based on the set of {@link Sdk} known to the workspace. */ private final class GwtWorkspaceSdkSelectionBlock extends SdkSelectionBlock<GwtSdk> { private GwtWorkspaceSdkSelectionBlock(Composite parent, int style) { super(parent, style); updateSdkBlockControls(); initializeSdkComboBox(); setSelection(-1); } @Override protected void doConfigure() { if (Window.OK == PreferencesUtil .createPreferenceDialogOn(getShell(), GwtPreferencePage.ID, new String[] { GwtPreferencePage.ID }, null) .open()) { NewWebAppProjectWizardPage.this.updateControls(); } } @Override protected GwtSdk doGetDefaultSdk() { return GWTPreferences.getDefaultRuntime(); } @Override protected List<GwtSdk> doGetSpecificSdks() { return new ArrayList<GwtSdk>(GWTPreferences.getSdks()); } } private final List<String> existingProjectNames = new ArrayList<String>(); private SdkSelectionBlock<GwtSdk> gwtSelectionBlock; private Button outDirBrowseButton; private String outDirCustom = ""; private Button outDirCustomButton; private Label outDirLabel; private Text outDirText; private Button outDirWorkspaceButton; private Text packageText; private Text projectNameText; private Button useGwtCheckbox; private final String workspaceDirectory; private Button generateSampleCodeCheckbox; private Button generateMavenCodeCheckbox; private Button generateAntCodeCheckbox; private Group otherOptionsGroup; public NewWebAppProjectWizardPage() { super("createProject"); setTitle("Create a Web Application Project"); setDescription("Create a Web Application project in the workspace or in an external location"); IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); workspaceDirectory = workspaceRoot.getLocation().toOSString(); for (IProject project : workspaceRoot.getProjects()) { existingProjectNames.add(project.getName()); } } @Override public void createControl(Composite parent) { final ScrolledComposite scroller = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL); final GridLayout gridLayout = new GridLayout(); Composite containerOfComponents = new Composite(scroller, SWT.NULL); containerOfComponents.setLayout(gridLayout); setControl(containerOfComponents); // TODO: convert these fields to use StringDialogField instead? // Project name final Label projectNameLabel = new Label(containerOfComponents, SWT.NONE); projectNameLabel.setText("Project name:"); projectNameText = new Text(containerOfComponents, SWT.BORDER); final GridData gd1 = new GridData(GridData.FILL_HORIZONTAL); gd1.horizontalSpan = 2; projectNameText.setLayoutData(gd1); projectNameText.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { updateControls(); } }); // Package final Label packageLabel = new Label(containerOfComponents, SWT.NONE); packageLabel.setText("Package: (e.g. com.example.myproject)"); packageText = new Text(containerOfComponents, SWT.BORDER); final GridData gd2 = new GridData(GridData.FILL_HORIZONTAL); gd2.horizontalSpan = 2; packageText.setLayoutData(gd2); packageText.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { updateControls(); } }); createLocationGroup(containerOfComponents); createSdkGroup(containerOfComponents); createOtherOptionsGroup(containerOfComponents); scroller.setExpandHorizontal(true); scroller.setExpandVertical(true); scroller.setContent(containerOfComponents); scroller.setMinSize(containerOfComponents.computeSize(SWT.DEFAULT, SWT.DEFAULT)); updateControls(); projectNameText.forceFocus(); } public String getCreationLocation() { if (outDirWorkspaceButton.getSelection()) { // Use the default location. return null; } return getOutputDirectory(); } public URI getCreationLocationURI() { if (outDirWorkspaceButton.getSelection()) { // Default location is the workspace URI return ResourcesPlugin.getWorkspace().getRoot().getLocationURI(); } return new Path(getOutputDirectory()).toFile().toURI(); } public String getPackage() { return packageText.getText().trim(); } public String getProjectName() { return projectNameText.getText().trim(); } public GwtSdk getSelectedGwtSdk() { if (useGwtCheckbox.getSelection()) { SdkSelection<GwtSdk> sdkSelection = gwtSelectionBlock.getSdkSelection(); if (sdkSelection != null) { return sdkSelection.getSelectedSdk(); } } return null; } public boolean isGenerateEmptyProject() { return !generateSampleCodeCheckbox.getSelection(); } IPath getGWTSdkContainerPath() { return getSdkContainerPath(gwtSelectionBlock.getSdkSelection(), GWTRuntimeContainer.CONTAINER_ID); } IPath getSdkContainerPath(SdkSelection<? extends Sdk> sdkSelection, String containerId) { if (sdkSelection != null) { return SdkClasspathContainer.computeContainerPath(containerId, sdkSelection.getSelectedSdk(), sdkSelection.isDefault() ? SdkClasspathContainer.Type.DEFAULT : SdkClasspathContainer.Type.NAMED); } return null; } boolean useGWT() { return useGwtCheckbox.getSelection(); } private String browseForOutputDirectory() { DirectoryDialog dlg = new DirectoryDialog(getShell(), SWT.OPEN); dlg.setFilterPath(getOutputDirectory()); dlg.setMessage("Choose a directory for the project contents:"); return dlg.open(); } private int convertValidationSeverity(int severity) { switch (severity) { case IStatus.ERROR: return ERROR; case IStatus.WARNING: return WARNING; case IStatus.INFO: default: return NONE; } } private void createSdkGroup(Composite container) { int widthIndent = PixelConverterFactory.createPixelConverter(this.getControl()).convertWidthInCharsToPixels(2); Group sdkGroup = new Group(container, SWT.NONE); sdkGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); final GridLayout sdkGroupLayout = new GridLayout(); sdkGroupLayout.verticalSpacing = 0; sdkGroupLayout.numColumns = 1; sdkGroup.setLayout(sdkGroupLayout); sdkGroup.setText("SDKs"); SelectionListener useSdkCheckboxSelectionListener = new SelectionListener() { @Override public void widgetDefaultSelected(SelectionEvent e) { updateControls(); } @Override public void widgetSelected(SelectionEvent e) { updateControls(); } }; createGwtSdkGroup(sdkGroup, useSdkCheckboxSelectionListener, widthIndent); // Add a horizontal spacer new Label(sdkGroup, SWT.HORIZONTAL); } private void createGwtSdkGroup(Group sdkGroup, SelectionListener useSdkCheckboxSelectionListener, int widthIndent) { useGwtCheckbox = new Button(sdkGroup, SWT.CHECK); useGwtCheckbox.addSelectionListener(useSdkCheckboxSelectionListener); useGwtCheckbox.setText("Use GWT"); useGwtCheckbox.setSelection(true); gwtSelectionBlock = new GwtWorkspaceSdkSelectionBlock(sdkGroup, SWT.NONE); gwtSelectionBlock.addSdkSelectionListener(new SdkSelectionBlock.SdkSelectionListener() { @Override public void onSdkSelection(SdkSelectionEvent e) { updateControls(); } }); ((GridData) gwtSelectionBlock.getLayoutData()).horizontalIndent = widthIndent; } private void createLocationGroup(Composite container) { // Output directory (defaults to subdirectory under workspace) final Group outDirGroup = new Group(container, SWT.NULL); outDirGroup.setText("Location"); final GridData gd3 = new GridData(GridData.FILL_HORIZONTAL); gd3.horizontalSpan = 2; outDirGroup.setLayoutData(gd3); final GridLayout outDirGridLayout = new GridLayout(); outDirGridLayout.numColumns = 3; outDirGroup.setLayout(outDirGridLayout); outDirWorkspaceButton = new Button(outDirGroup, SWT.RADIO); outDirWorkspaceButton.setText("Create new project in workspace"); outDirWorkspaceButton.setSelection(true); final GridData gd4 = new GridData(); gd4.horizontalAlignment = GridData.FILL; gd4.grabExcessHorizontalSpace = true; gd4.horizontalSpan = 3; outDirWorkspaceButton.setLayoutData(gd4); outDirWorkspaceButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { updateControls(); } }); outDirCustomButton = new Button(outDirGroup, SWT.RADIO); outDirCustomButton.setText("Create new project in:"); final GridData gd5 = new GridData(); gd5.horizontalAlignment = GridData.FILL; gd5.grabExcessHorizontalSpace = true; gd5.horizontalSpan = 3; outDirCustomButton.setLayoutData(gd5); outDirCustomButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { outDirText.setText(outDirCustom); updateControls(); } }); outDirLabel = new Label(outDirGroup, SWT.NONE); outDirLabel.setText("Directory:"); outDirText = new Text(outDirGroup, SWT.BORDER); final GridData gd6 = new GridData(); gd6.horizontalAlignment = GridData.FILL; gd6.grabExcessHorizontalSpace = true; outDirText.setLayoutData(gd6); outDirText.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { if (outDirCustomButton.getSelection()) { outDirCustom = getOutputDirectory(); validatePageAndSetCompletionStatus(); } } }); outDirBrowseButton = new Button(outDirGroup, SWT.NONE); outDirBrowseButton.setText("Browse..."); outDirBrowseButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { String outDir = browseForOutputDirectory(); if (outDir != null) { outDirText.setText(outDir); } } }); } private void createOtherOptionsGroup(Composite container) { // Other-options group otherOptionsGroup = new Group(container, SWT.NULL); otherOptionsGroup.setText("Sample Code"); final GridData gd_otherOptionsGroup_1 = new GridData(GridData.FILL_HORIZONTAL); gd_otherOptionsGroup_1.horizontalSpan = 2; otherOptionsGroup.setLayoutData(gd_otherOptionsGroup_1); final GridLayout gl_otherOptionsGroup_1 = new GridLayout(); gl_otherOptionsGroup_1.numColumns = 2; otherOptionsGroup.setLayout(gl_otherOptionsGroup_1); generateSampleCodeCheckbox = new Button(otherOptionsGroup, SWT.CHECK); generateSampleCodeCheckbox.setText("Generate project sample code"); generateSampleCodeCheckbox.addSelectionListener(new SelectionListener() { @Override public void widgetDefaultSelected(SelectionEvent e) { updateControls(); } @Override public void widgetSelected(SelectionEvent e) { if (!generateSampleCodeCheckbox.getSelection()) { generateAntCodeCheckbox.setSelection(false); generateMavenCodeCheckbox.setSelection(false); } updateControls(); } }); generateSampleCodeCheckbox.setSelection(true); new Label(otherOptionsGroup, SWT.NONE); generateAntCodeCheckbox = new Button(otherOptionsGroup, SWT.CHECK); generateAntCodeCheckbox.setText("Generate an Ant Project"); generateAntCodeCheckbox.addSelectionListener(new SelectionListener() { @Override public void widgetDefaultSelected(SelectionEvent e) { updateControls(); } @Override public void widgetSelected(SelectionEvent e) { if (generateAntCodeCheckbox.getSelection()) { generateSampleCodeCheckbox.setSelection(true); generateMavenCodeCheckbox.setSelection(false); } updateControls(); } }); generateAntCodeCheckbox.setSelection(false); generateMavenCodeCheckbox = new Button(otherOptionsGroup, SWT.CHECK); generateMavenCodeCheckbox.setText("Generate a Maven Project"); generateMavenCodeCheckbox.addSelectionListener(new SelectionListener() { @Override public void widgetDefaultSelected(SelectionEvent e) { updateControls(); } @Override public void widgetSelected(SelectionEvent e) { if (generateMavenCodeCheckbox.getSelection()) { generateSampleCodeCheckbox.setSelection(true); generateAntCodeCheckbox.setSelection(false); } updateControls(); } }); generateMavenCodeCheckbox.setSelection(false); } private String getOutputDirectory() { return outDirText.getText().trim(); } private void updateControls() { // Set the output directory to the workspace if (outDirWorkspaceButton.getSelection()) { outDirLabel.setEnabled(false); outDirText.setEnabled(false); outDirBrowseButton.setEnabled(true); String outDir = workspaceDirectory; if (getProjectName().length() > 0) { outDir += (System.getProperty("file.separator") + getProjectName()); } outDirText.setText(outDir); } else { outDirLabel.setEnabled(true); outDirText.setEnabled(true); outDirBrowseButton.setEnabled(true); } gwtSelectionBlock.setEnabled(useGwtCheckbox.getSelection()); validatePageAndSetCompletionStatus(); } private boolean validateFromStatus(IStatus status) { if (!status.isOK()) { setMessage(status.getMessage(), convertValidationSeverity(status.getSeverity())); return false; } return true; } private void validatePageAndSetCompletionStatus() { IStatus status; boolean pageComplete = false; try { // Project name cannot be blank if (getProjectName().length() == 0) { setMessage("Enter a name for the project"); return; } // Verify that project name is valid status = ResourcesPlugin.getWorkspace().validateName(getProjectName(), IResource.PROJECT); if (!validateFromStatus(status)) { return; } // Make sure project doesn't already exist in workspace if (existingProjectNames.contains(getProjectName())) { setMessage("A project with this name already exists.", ERROR); return; } // Output directory cannot be blank if (getOutputDirectory().length() == 0) { setMessage("Enter the output directory"); return; } // If the user wants to use a custom output directory, // verify that the directory exists if (outDirCustomButton.getSelection()) { File outDir = new Path(getOutputDirectory()).toFile(); if (!outDir.isDirectory()) { setMessage("The output directory does not exist", ERROR); return; } } // Make sure resource with project's name doesn't already exist in output // directory IPath outPath = new Path(getOutputDirectory()); if (outDirWorkspaceButton.getSelection()) { if (outPath.toFile().exists()) { setMessage("A resource with the project name already exists in the workspace root", ERROR); return; } } // Make sure output directory doesn't already contain an Eclipse project if (outDirCustomButton.getSelection()) { outPath = outPath.append(IProjectDescription.DESCRIPTION_FILE_NAME); if (outPath.toFile().exists()) { setMessage("The output directory already contains a project file", ERROR); return; } } // Package name cannot be blank if (getPackage().length() == 0) { setMessage("Enter a package name"); return; } String complianceLevel = JavaCore.getOption("org.eclipse.jdt.core.compiler.compliance"); String sourceLevel = JavaCore.getOption("org.eclipse.jdt.core.compiler.source"); // Verify that package name is valid status = JavaConventions.validatePackageName(getPackage(), complianceLevel, sourceLevel); if (!validateFromStatus(status)) { return; } // If we are using GWT then an SDK must be selected if (useGwtCheckbox.getSelection()) { IStatus gwtRuntimeValidationStatus; GwtSdk selectedGwtRuntime = getSelectedGwtSdk(); if (selectedGwtRuntime == null) { setMessage("Please configure a GWT SDK.", ERROR); return; } else if (!(gwtRuntimeValidationStatus = selectedGwtRuntime.validate()).isOK()) { setMessage("The selected GWT SDK is not valid: " + gwtRuntimeValidationStatus.getMessage(), ERROR); return; } } pageComplete = true; setMessage(null); } finally { setPageComplete(pageComplete); } } public boolean getBuildAnt() { return generateAntCodeCheckbox.getSelection(); } public boolean getBuildMaven() { return generateMavenCodeCheckbox.getSelection(); } }