/******************************************************************************* * 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.launch.ui.tabs; import com.google.gdt.eclipse.core.CorePluginLog; import com.google.gdt.eclipse.core.launch.ILaunchArgumentsContainer; import com.google.gdt.eclipse.core.launch.LaunchConfigurationAttributeUtilities; import com.google.gdt.eclipse.core.launch.LaunchConfigurationProcessorUtilities; import com.google.gdt.eclipse.core.launch.UpdateLaunchConfigurationDialogBatcher; import com.google.gdt.eclipse.core.launch.WebAppLaunchAttributes; import com.google.gdt.eclipse.core.launch.WebAppLaunchConfiguration; import com.google.gdt.eclipse.core.launch.WebAppLaunchConfigurationWorkingCopy; import com.google.gdt.eclipse.suite.GdtPlugin; import com.google.gdt.eclipse.suite.launch.processors.PortArgumentProcessor; import com.google.gdt.eclipse.suite.launch.processors.PortArgumentProcessor.PortParser; import com.google.gdt.eclipse.suite.resources.GdtImages; import com.google.gwt.eclipse.core.launch.processors.NoServerArgumentProcessor; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.debug.ui.launchConfigurations.JavaLaunchTab; import org.eclipse.jdt.internal.debug.ui.SWTFactory; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.swt.SWT; 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.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 java.util.List; /** * Main configuration tab for webapp or Speed Tracer launch preferences. */ @SuppressWarnings("restriction") public class WebAppServerTab extends JavaLaunchTab implements WebAppArgumentsTab.ArgumentsListener, UpdateLaunchConfigurationDialogBatcher.Listener { // TODO: Create a subclass that contains the run server and autoport /** * May be null. */ private Button runServerButton; /** * May be null. */ private Button autoPortSelectionButton; private Text serverPortText; private final WebAppServerTab webAppServerTab = this; /** * See javadoc on {@link com.google.gdt.eclipse.core.launch.ILaunchConfigurationProcessor} for information about why * this is required. */ private boolean blockUpdateLaunchConfigurationDialog; private final UpdateLaunchConfigurationDialogBatcher updateLaunchConfigurationDialogBatcher = new UpdateLaunchConfigurationDialogBatcher( this); private final boolean showAutoPortSelectionButton; private final boolean showRunServerButton; public WebAppServerTab(ILaunchArgumentsContainer argsContainer, boolean showAutoPortSelectionButton, boolean showRunServerButton) { this.showAutoPortSelectionButton = showAutoPortSelectionButton; this.showRunServerButton = showRunServerButton; argsContainer.registerProgramArgsListener(this); } @Override public void callSuperUpdateLaunchConfigurationDialog() { super.updateLaunchConfigurationDialog(); } @Override public void createControl(Composite parent) { Composite comp = SWTFactory.createComposite(parent, parent.getFont(), 1, 1, GridData.FILL_BOTH); ((GridLayout) comp.getLayout()).verticalSpacing = 0; setControl(comp); createServerComponent(comp); } @Override public void deactivated(ILaunchConfigurationWorkingCopy workingCopy) { updateLaunchConfigurationDialogBatcher.deactivatedCalled(workingCopy); super.deactivated(workingCopy); } @Override public void dispose() { updateLaunchConfigurationDialogBatcher.disposeCalled(); super.dispose(); } @Override public void doPerformApply(ILaunchConfigurationWorkingCopy configuration) { if (runServerButton != null) { WebAppLaunchConfigurationWorkingCopy.setRunServer(configuration, runServerButton.getSelection()); } LaunchConfigurationProcessorUtilities.updateViaProcessor(new NoServerArgumentProcessor(), configuration); // TODO remove and have folks use the CodeServerLauncher //LaunchConfigurationProcessorUtilities.updateViaProcessor(new ServerArgumentProcessor(), configuration); WebAppLaunchConfigurationWorkingCopy.setServerPort(configuration, serverPortText.getText().trim()); if (autoPortSelectionButton != null) { WebAppLaunchConfigurationWorkingCopy.setAutoPortSelection(configuration, autoPortSelectionButton.getSelection()); } LaunchConfigurationProcessorUtilities.updateViaProcessor(new PortArgumentProcessor(), configuration); } @Override public Image getImage() { return GdtPlugin.getDefault().getImage(GdtImages.GDT_ICON); } @Override public String getName() { return "Server"; } @Override public void initializeFrom(ILaunchConfiguration config) { blockUpdateLaunchConfigurationDialog = true; try { try { super.initializeFrom(config); if (runServerButton != null) { runServerButton.setSelection(WebAppLaunchConfiguration.getRunServer(config)); } if (autoPortSelectionButton != null) { boolean autoPortSelection = WebAppLaunchConfiguration.getAutoPortSelection(config); autoPortSelectionButton.setSelection(autoPortSelection); } serverPortText.setText(WebAppLaunchConfiguration.getServerPort(config)); } catch (CoreException e) { CorePluginLog.logError(e); } super.initializeFrom(config); updateEnabledState(); } finally { blockUpdateLaunchConfigurationDialog = false; } } @Override public boolean isValid(ILaunchConfiguration launchConfig) { setErrorMessage(null); setMessage(null); if (!super.isValid(launchConfig)) { return false; } IProject project; try { IJavaProject javaProject = JavaRuntime.getJavaProject(launchConfig); if (javaProject == null) { return false; } project = javaProject.getProject(); } catch (CoreException ce) { // Thrown if the Java project does not exist, which is not of concern in // this tab (the Main tab handles those error messages) return false; } return true; } @Override public void performApply(ILaunchConfigurationWorkingCopy configuration) { if (!this.equals(getLaunchConfigurationDialog().getActiveTab())) { return; } doPerformApply(configuration); } @Override public void persistFromArguments(List<String> args, ILaunchConfigurationWorkingCopy config) { boolean runServer = false; try { runServer = LaunchConfigurationAttributeUtilities.getBoolean(config, WebAppLaunchAttributes.RUN_SERVER); } catch (CoreException e) { // ignored, just use false } PortParser portParser = PortParser.parse(args); WebAppLaunchConfigurationWorkingCopy.setAutoPortSelection(config, (!portParser.isPresent || portParser.isAuto) && runServer); if (portParser.isPresent && !portParser.isAuto) { WebAppLaunchConfigurationWorkingCopy.setServerPort(config, portParser.port); } boolean shouldRunServer = !NoServerArgumentProcessor.hasNoServerArg(args); WebAppLaunchConfigurationWorkingCopy.setRunServer(config, shouldRunServer); } @Override public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { } protected void createServerComponent(Composite parent) { Group group = SWTFactory.createGroup(parent, "Embedded Jetty Server:", 3, 1, GridData.FILL_HORIZONTAL); if (showRunServerButton) { runServerButton = SWTFactory.createCheckButton(group, "Run built-in server", null, true, 3); runServerButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { updateEnabledState(); webAppServerTab.updateLaunchConfigurationDialog(); } }); } Label serverPortLabel = new Label(group, SWT.NONE); final GridData serverPortLabelGridData = new GridData(); if (showRunServerButton) { // If showing the "Run server" checkbox, this should be indented serverPortLabelGridData.horizontalIndent = 20; } serverPortLabel.setLayoutData(serverPortLabelGridData); serverPortLabel.setText("Port:"); serverPortText = new Text(group, SWT.BORDER); final GridData serverPortTextGridData = new GridData(SWT.FILL, SWT.CENTER, false, false); serverPortTextGridData.widthHint = 75; serverPortText.setLayoutData(serverPortTextGridData); serverPortText.setTextLimit(5); serverPortText.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { webAppServerTab.updateLaunchConfigurationDialog(); } }); if (showAutoPortSelectionButton) { autoPortSelectionButton = new Button(group, SWT.CHECK); autoPortSelectionButton.setText("Automatically select an unused port"); autoPortSelectionButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false)); autoPortSelectionButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { updateEnabledState(); webAppServerTab.updateLaunchConfigurationDialog(); } }); } } @Override protected void updateLaunchConfigurationDialog() { if (!blockUpdateLaunchConfigurationDialog) { updateLaunchConfigurationDialogBatcher.updateLaunchConfigurationDialogCalled(); } } private void updateEnabledState() { boolean usingAutoPort = autoPortSelectionButton != null && autoPortSelectionButton.getSelection(); boolean runningServer = runServerButton == null || runServerButton.getSelection(); serverPortText.setEnabled(!usingAutoPort && runningServer); if (autoPortSelectionButton != null) { autoPortSelectionButton.setEnabled(runServerButton.getSelection()); } } }