| /******************************************************************************* |
| * 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 |
| * yyyymmdd bug Email and other contact information |
| * -------- -------- ----------------------------------------------------------- |
| * 20070314 176886 pmoogk@ca.ibm.com - Peter Moogk |
| *******************************************************************************/ |
| |
| package org.eclipse.jst.ws.internal.consumption.ui.server; |
| |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.jobs.IJobChangeEvent; |
| import org.eclipse.core.runtime.jobs.IJobManager; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.core.runtime.jobs.JobChangeAdapter; |
| import org.eclipse.jface.wizard.ProgressMonitorPart; |
| import org.eclipse.jst.ws.internal.consumption.ui.ConsumptionUIMessages; |
| import org.eclipse.jst.ws.internal.consumption.ui.command.StartServerCommand; |
| import org.eclipse.jst.ws.internal.ui.common.UIUtils; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| 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.Display; |
| import org.eclipse.swt.widgets.Listener; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.wst.command.internal.env.core.common.StatusUtils; |
| import org.eclipse.wst.command.internal.env.core.context.TransientResourceContext; |
| import org.eclipse.wst.command.internal.env.eclipse.BaseStatusHandler; |
| import org.eclipse.wst.command.internal.env.eclipse.EclipseEnvironment; |
| import org.eclipse.wst.command.internal.env.ui.eclipse.EclipseStatusHandler; |
| import org.eclipse.wst.command.internal.env.ui.widgets.SimpleWidgetDataContributor; |
| import org.eclipse.wst.command.internal.env.ui.widgets.WidgetDataEvents; |
| import org.eclipse.wst.server.core.IServer; |
| |
| public class StartServerWidget extends SimpleWidgetDataContributor |
| { |
| private IServer server_; |
| private IStatus status_; |
| private Listener statusListener_; |
| private Button button_; |
| private JobChangeAdapter jobChangeAdapter_; |
| private Text serverStateText_; |
| private ProgressMonitorPart progressMonitor_; |
| private String pluginId_; |
| private Composite buttonGroup_; |
| |
| /*CONTEXT_ID SSWP0001 Start the server button. */ |
| private String INFOPOP_SSWP_SERVER_BUTTON = "SSWP0001"; |
| |
| public StartServerWidget( IServer server ) |
| { |
| pluginId_ = "org.eclipse.jst.ws.consumption.ui"; |
| |
| server_ = server; |
| |
| jobChangeAdapter_ = new JobChangeAdapter() |
| { |
| public void done(final IJobChangeEvent event) |
| { |
| Display.getDefault().asyncExec( new Runnable() |
| { |
| public void run() |
| { |
| if( !progressMonitor_.isDisposed() ) |
| { |
| setServerState(); |
| progressMonitor_.done(); |
| reportErrorIfRequired( (StartServerJob)event.getJob() ); |
| } |
| } |
| }); |
| } |
| }; |
| } |
| |
| public WidgetDataEvents addControls(Composite parent, Listener statusListener) |
| { |
| statusListener_ = statusListener; |
| |
| UIUtils uiUtils = new UIUtils( pluginId_ ); |
| Composite group = uiUtils.createComposite( parent, 1 ); |
| |
| Text text1 = uiUtils.createText( group, null, null, null, SWT.READ_ONLY ); |
| text1.setText( NLS.bind(ConsumptionUIMessages.LABEL_START_SERVER_TEXT1, new String[]{ server_.getName() } )); |
| |
| Text text2 = uiUtils.createText( group, null, null, null, SWT.READ_ONLY ); |
| text2.setText( NLS.bind(ConsumptionUIMessages.LABEL_START_SERVER_TEXT2, new String[]{ server_.getName() } )); |
| |
| Text text3 = uiUtils.createText( group, null, null, null, SWT.READ_ONLY ); |
| text3.setText( NLS.bind(ConsumptionUIMessages.LABEL_START_SERVER_TEXT3, new String[]{ server_.getName() } )); |
| |
| Text text4 = uiUtils.createText( group, null, null, null, SWT.READ_ONLY ); |
| text4.setText( NLS.bind(ConsumptionUIMessages.LABEL_START_SERVER_TEXT4, new String[]{ server_.getName() } )); |
| |
| buttonGroup_ = uiUtils.createComposite( group, 2,-1, 0 ); |
| serverStateText_ = uiUtils.createText( buttonGroup_, null, null, null, SWT.READ_ONLY ); |
| serverStateText_.setLayoutData( new GridData() ); |
| |
| button_ = uiUtils.createPushButton( buttonGroup_, |
| ConsumptionUIMessages.LABEL_START_SERVER_BUTTON, |
| ConsumptionUIMessages.TOOLTIP_START_SERVER_BUTTON, |
| INFOPOP_SSWP_SERVER_BUTTON ); |
| |
| button_.addSelectionListener( new SelectionAdapter() |
| { |
| public void widgetSelected( SelectionEvent evt ) |
| { |
| serverStateText_.setText( getStateMessage( ConsumptionUIMessages.TEXT_SERVER_STATUS, ConsumptionUIMessages.TEXT_SERVER_STARTING ) ); |
| progressMonitor_.beginTask( getStateMessage( ConsumptionUIMessages.TEXT_SERVER_MSG, ConsumptionUIMessages.TEXT_SERVER_STARTING ), IProgressMonitor.UNKNOWN ); |
| button_.setEnabled( false ); |
| buttonGroup_.pack(); |
| startServerJob(); |
| } |
| } ); |
| |
| progressMonitor_ = new ProgressMonitorPart( group, new GridLayout() ); |
| progressMonitor_.setLayoutData( new GridData( GridData.FILL_HORIZONTAL )); |
| |
| setServerState(); |
| return this; |
| } |
| |
| public IStatus getStatus() |
| { |
| return status_; |
| } |
| |
| private void setServerState() |
| { |
| int state = server_.getServerState(); |
| |
| switch( state ) |
| { |
| case IServer.STATE_STARTED: |
| { |
| status_ = Status.OK_STATUS; |
| button_.setEnabled( false ); |
| serverStateText_.setText( getStateMessage( ConsumptionUIMessages.TEXT_SERVER_STATUS, ConsumptionUIMessages.TEXT_SERVER_STARTED ) ); |
| |
| break; |
| } |
| |
| case IServer.STATE_STARTING: |
| { |
| status_ = StatusUtils.errorStatus( "" ); |
| button_.setEnabled( false ); |
| serverStateText_.setText( getStateMessage( ConsumptionUIMessages.TEXT_SERVER_STATUS, ConsumptionUIMessages.TEXT_SERVER_STARTING ) ); |
| progressMonitor_.beginTask( getStateMessage( ConsumptionUIMessages.TEXT_SERVER_MSG, ConsumptionUIMessages.TEXT_SERVER_STARTING ), IProgressMonitor.UNKNOWN ); |
| |
| // The server is still starting so we need to reconnect to the job |
| // that is starting it. |
| startServerJob(); |
| break; |
| } |
| |
| default: |
| { |
| status_ = StatusUtils.errorStatus( "" ); |
| button_.setEnabled( true ); |
| serverStateText_.setText( getStateMessage( ConsumptionUIMessages.TEXT_SERVER_STATUS, ConsumptionUIMessages.TEXT_SERVER_STOPPED ) ); |
| break; |
| } |
| }; |
| |
| statusListener_.handleEvent( null ); |
| buttonGroup_.pack(); |
| } |
| |
| private String getStateMessage( String mainKey, String subKey ) |
| { |
| return NLS.bind( mainKey, new String[]{ subKey } ); |
| } |
| |
| // Connect to an existing server thread otherwise start a new one. |
| private void startServerJob() |
| { |
| IJobManager jobManager = Platform.getJobManager(); |
| Job[] jobs = jobManager.find( StartServerFamily ); |
| StartServerJob startServerJob = null; |
| |
| // There may be more than one job starting for different servers. |
| // Therefore, we need to find the one for our server if it is available. |
| for( int index = 0; index < jobs.length; index++ ) |
| { |
| StartServerJob jobFound = (StartServerJob)jobs[index]; |
| |
| if( jobFound.getServer() == server_ ) |
| { |
| startServerJob = jobFound; |
| break; |
| } |
| } |
| |
| if( startServerJob != null ) |
| { |
| synchronized( StartServerFamily ) |
| { |
| IStatus status = startServerJob.getStatus(); |
| |
| // We are using status to determine if the job has completed or not. |
| // Normally, we would not get here if the job had already completed, |
| // but there is a slim window where the job manager gives us the job |
| // and then it immediately completes. |
| if( status == null ) |
| { |
| // The job had not completed yet so we will add a job change listener. |
| // We are adding the job listener here so that we don't have to assume |
| // that this instance of this widget is the same as the previous instance. |
| // If startServerJob already has "jobChangeAdapter_" added to it this |
| // method call will not have an effect.(Which is what we want.) |
| startServerJob.addJobChangeListener( jobChangeAdapter_ ); |
| |
| // Note: this job was reporting progress to different progressMonitor_ |
| // control. We need to tell the job that it should report progress |
| // to our new progressMonitor_ control on this wizard page. |
| ProgressMonitorWrapper monitor = (ProgressMonitorWrapper)startServerJob.getMonitor(); |
| monitor.setMonitor( progressMonitor_ ); |
| } |
| else |
| { |
| // The job completed before we had a chance to add the job change listener |
| // Therefore, we will just call jobChangeAdapter_ directly to notify |
| // the UI that the job has completed. |
| jobChangeAdapter_.done( null ); |
| } |
| } |
| } |
| else |
| { |
| startServerJob = new StartServerJob(); |
| startServerJob.addJobChangeListener( jobChangeAdapter_ ); |
| startServerJob.schedule(); |
| } |
| } |
| |
| private void reportErrorIfRequired( StartServerJob serverJob ) |
| { |
| IStatus status = serverJob.getStatus(); |
| |
| if( status.getSeverity() == Status.ERROR ) |
| { |
| Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); |
| EclipseStatusHandler handler = new EclipseStatusHandler( shell ); |
| |
| handler.reportError( status ); |
| } |
| } |
| |
| final private static String StartServerFamily = "StartServerFamily"; |
| |
| // This class is used to start up the server in an Eclipse job. |
| private class StartServerJob extends Job |
| { |
| private IStatus status_ = null; |
| private ProgressMonitorWrapper envMonitor_; |
| |
| public StartServerJob() |
| { |
| super( "StartServerJob" ); |
| |
| envMonitor_ = new ProgressMonitorWrapper( progressMonitor_ ); |
| } |
| |
| public IServer getServer() |
| { |
| return server_; |
| } |
| |
| public ProgressMonitorWrapper getMonitor() |
| { |
| return envMonitor_; |
| } |
| |
| public boolean belongsTo(Object family) |
| { |
| return family == StartServerFamily; |
| } |
| |
| protected IStatus run(IProgressMonitor monitor) |
| { |
| BaseStatusHandler handler = new BaseStatusHandler(); |
| TransientResourceContext resourceContext = new TransientResourceContext(); |
| EclipseEnvironment environment = new EclipseEnvironment( null,resourceContext, handler ); |
| StartServerCommand serverCommand = new StartServerCommand( false ); |
| |
| serverCommand.setServerInstanceId( server_.getId() ); |
| serverCommand.setEnvironment( environment ); |
| |
| try |
| { |
| setStatus( serverCommand.execute( envMonitor_, null ) ); |
| } |
| catch( Throwable exc ) |
| { |
| exc.printStackTrace(); |
| setStatus( StatusUtils.errorStatus( exc ) ); |
| } |
| |
| return Status.OK_STATUS; |
| } |
| |
| // Calls to this method need to first synchronize on the |
| // StartServerFamily object. |
| public IStatus getStatus() |
| { |
| return status_; |
| } |
| |
| private void setStatus( IStatus status ) |
| { |
| synchronized( StartServerFamily ) |
| { |
| status_ = status; |
| } |
| } |
| } |
| |
| private class ProgressMonitorWrapper implements IProgressMonitor |
| { |
| private IProgressMonitor monitor_ = new NullProgressMonitor(); |
| |
| public ProgressMonitorWrapper( IProgressMonitor monitor ) |
| { |
| monitor_ = monitor; |
| } |
| |
| public void setMonitor( IProgressMonitor monitor ) |
| { |
| monitor_ = monitor; |
| } |
| |
| public void beginTask(final String name, final int totalWork) |
| { |
| Display.getDefault().asyncExec( new Runnable() |
| { |
| public void run() |
| { |
| if( !progressMonitor_.isDisposed() ) |
| { |
| monitor_.beginTask( name, totalWork ); |
| } |
| } |
| } ); |
| } |
| |
| public void done() |
| { |
| Display.getDefault().asyncExec( new Runnable() |
| { |
| public void run() |
| { |
| if( !progressMonitor_.isDisposed() ) |
| { |
| monitor_.done(); |
| } |
| } |
| } ); |
| } |
| |
| public void internalWorked(final double work) |
| { |
| Display.getDefault().asyncExec( new Runnable() |
| { |
| public void run() |
| { |
| if( !progressMonitor_.isDisposed() ) |
| { |
| monitor_.internalWorked( work ); |
| } |
| } |
| } ); |
| } |
| |
| public boolean isCanceled() |
| { |
| return progressMonitor_.isDisposed() ? false : monitor_.isCanceled(); |
| } |
| |
| public void setCanceled(boolean value) |
| { |
| if( !progressMonitor_.isDisposed() ) |
| { |
| monitor_.setCanceled( value ); |
| } |
| } |
| |
| public void setTaskName(final String name) |
| { |
| Display.getDefault().asyncExec( new Runnable() |
| { |
| public void run() |
| { |
| if( !progressMonitor_.isDisposed() ) |
| { |
| monitor_.setTaskName( name ); |
| } |
| } |
| } ); |
| } |
| |
| public void subTask( final String name) |
| { |
| Display.getDefault().asyncExec( new Runnable() |
| { |
| public void run() |
| { |
| if( !progressMonitor_.isDisposed() ) |
| { |
| monitor_.subTask( name ); |
| } |
| } |
| } ); |
| } |
| |
| public void worked(final int work) |
| { |
| Display.getDefault().asyncExec( new Runnable() |
| { |
| public void run() |
| { |
| if( !progressMonitor_.isDisposed() ) |
| { |
| monitor_.worked( work ); |
| } |
| } |
| } ); |
| } |
| } |
| } |