blob: 9285f39555e0d0debc56fceb217d54a60d2be82e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004 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
* -------- -------- -----------------------------------------------------------
* 20060313 130958 pmoogk@ca.ibm.com - Peter Moogk
*******************************************************************************/
package org.eclipse.wst.command.internal.env.ui.widgets;
import java.util.Hashtable;
import java.util.Stack;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.IWizardContainer;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.wst.command.internal.env.core.data.DataFlowManager;
import org.eclipse.wst.command.internal.env.core.fragment.CommandFragment;
import org.eclipse.wst.command.internal.env.eclipse.EclipseEnvironment;
import org.eclipse.wst.command.internal.env.ui.registry.WidgetRegistry;
public class WizardPageManager extends SimpleCommandEngineManager
{
private WizardPageFactory pageFactory_;
private Hashtable pageTable_;
private IWizard wizard_;
protected SimpleWidgetRegistry registry_;
// These variables are used and set by our methods which is
// why they are not initialized in the constructor.
private PageWizardDataEvents currentPage_;
private PageWizardDataEvents nextPage_;
private PageWizardDataEvents nextPeekPage_;
private PageWizardDataEvents firstPage_;
private CommandFragment lastUndoFragment_;
private boolean firstFragment_;
private INamedWidgetContributorFactory widgetFactory_;
private Stack widgetStack_;
private Stack widgetStackStack_;
private Hashtable widgetTable_;
private WidgetRegistry widgetRegistry_;
private Hashtable widgetFactoryTable_;
public WizardPageManager( SimpleWidgetRegistry registry,
WizardPageFactory pageFactory,
IWizard wizard,
DataFlowManager dataManager,
EclipseEnvironment environment )
{
super( environment, dataManager );
pageFactory_ = pageFactory;
pageTable_ = new Hashtable();
registry_ = registry;
wizard_ = wizard;
widgetTable_ = new Hashtable();
widgetFactoryTable_ = new Hashtable();
widgetRegistry_ = WidgetRegistry.instance();
widgetStackStack_ = new Stack();
}
public IStatus runForwardToNextStop()
{
firstFragment_ = true;
nextPage_ = null;
IWizardContainer container = wizard_.getContainer();
if( container == null || container.getCurrentPage() == null )
{
container = null;
}
return super.runForwardToNextStop( container );
}
public IWizardPage getCurrentPage()
{
return currentPage_;
}
public boolean hasNextPage()
{
nextPeekPage_ = null;
try
{
nextPeekPage_ = getNextPageInGroup( widgetFactory_, false );
if( nextPeekPage_ == null )
{
// If a page is found nextPage_ will be set to its value in the method below.
engine_.peekForwardToNextStop();
}
}
catch( Throwable exc )
{
exc.printStackTrace();
}
return nextPeekPage_ != null;
}
public IWizardPage getNextPage()
{
try
{
// Need to externalize the data for the current page so that
// when we move forward below the data is available.
if( currentPage_ != null ) currentPage_.getDataEvents().externalize();
nextPage_ = getNextPageInGroup( widgetFactory_, true );
if( nextPage_ == null )
{
widgetFactory_ = null;
widgetStack_ = null;
IStatus status = runForwardToNextStop();
if( status.getSeverity() == IStatus.ERROR )
{
// An error has occured so we need undo to the previous stop point.
undoToLastPage();
}
}
if( nextPage_ != null ) nextPage_.setWizard( wizard_ );
return nextPage_;
}
catch( Throwable exc )
{
exc.printStackTrace();
}
return null;
}
public void handlePageVisible( PageWizardDataEvents page, boolean isPageVisible )
{
if( !isPageVisible && page == firstPage_ && page == currentPage_ )
{
// We are moving back one page from the first page. This can't happen with popup wizards
// since the previous button would be greyed out. But when the new wizard launches this wizard
// the previous button is not greyed out and brings the user back to the list wizards to select.
// Therefore, we must unwind the command engine and get ready for the user to invoke this wizard
// again. We are assuming here that the first page is never part of a widget group!
undoToLastPage();
currentPage_ = null;
firstPage_ = null;
}
if( currentPage_ != null && page == currentPage_.getPreviousPage() && isPageVisible )
{
// We are moving back one page.
// Note: we don't internalize the previous page and we do not externalize the current page.
// we are basically just leaving the current page without retrieving its state and
// moving to the previous page which already has its state set.
if( widgetFactory_ != null )
{
if( widgetStack_.size() > 0 )
{
widgetStack_.pop();
}
if( widgetStack_.size() == 0 )
{
widgetFactory_ = null;
widgetStack_ = null;
widgetStackStack_.pop();
}
}
if( widgetFactory_ == null )
{
undoToLastPage();
}
// Since we are moving backwards we need to remove the
// current page object from the mapping table.
dataManager_.unprocess( currentPage_.getDataEvents() );
currentPage_ = page;
}
else if( isPageVisible )
{
try
{
// We are moving forward one page.
WidgetDataEvents dataEvents = page.getDataEvents();
dataManager_.process( dataEvents ); // Push model data into the new page.
dataEvents.internalize();
page.validatePageToStatus();
}
catch( Throwable exc )
{
exc.printStackTrace();
}
finally
{
if( currentPage_ != null ) page.setPreviousPage( currentPage_ );
if( firstPage_ == null ) firstPage_ = page;
currentPage_ = page;
}
}
}
public boolean performFinish()
{
// We need to simulate the next button being pressed until there are no more pages.
// If an error occurs we will return false and reset the command stack back our original state.
boolean doneOk = true;
PageWizardDataEvents startPage = currentPage_;
// Externalize the current page.
currentPage_.getDataEvents().externalize();
// Loop through subsequent pages.
do
{
IStatus status = runForwardToNextStop();
if( status.getSeverity() == IStatus.ERROR )
{
// An error occured in one of the commands.
doneOk = false;
}
else
{
currentPage_ = nextPage_;
}
}
while( nextPage_ != null && doneOk);
if( !doneOk )
{
// An error occured, so we need to return the command stack to it's
// orginal state.
PageWizardDataEvents page = null;
boolean done = false;
do
{
done = engine_.undoToLastStop();
page = getPage( lastUndoFragment_ );
}
while( page != startPage && !done );
currentPage_ = page;
}
return doneOk;
}
public boolean performCancel()
{
while( !engine_.undoToLastStop() ){}
return true;
}
protected boolean peekFragment( CommandFragment fragment )
{
// Check to see if this fragment is in our page table.
nextPeekPage_ = getPage( fragment );
if( nextPeekPage_ == null )
{
INamedWidgetContributorFactory factory = getWidgetFactory( fragment.getId() );
if( factory != null )
{
nextPeekPage_ = getNextPageInGroup( factory, false );
}
}
return nextPeekPage_ == null;
}
protected boolean nextFragment( CommandFragment fragment )
{
// If the super class nextFragment want us to stop then we will stop right away.
if( !super.nextFragment( fragment ) ) return false;
// The first fragment is either at the start of the wizard
// or it is on a wizard page. In either case we do not want
// to stop if a page is found.
if( firstFragment_ )
{
firstFragment_ = false;
}
else
{
widgetFactory_ = getWidgetFactory( fragment.getId() );
if( widgetFactory_ != null )
{
widgetStack_ = new Stack();
nextPage_ = getNextPageInGroup( widgetFactory_, true );
if( nextPage_ == null )
{
// We found a widget contributor for this fragment, but no page was delivered for it.
// We will therefore, not put it on our stack of widget stacks.
widgetStack_ = null;
widgetFactory_ = null;
}
else
{
StackEntry entry = new StackEntry();
entry.factory_ = widgetFactory_;
entry.stack_ = widgetStack_;
widgetStackStack_.push( entry );
}
}
else
{
nextPage_ = getPage( fragment );
}
}
return nextPage_ == null;
}
protected boolean undoFragment( CommandFragment fragment )
{
lastUndoFragment_ = fragment;
return true;
}
private PageWizardDataEvents getNextPageInGroup( INamedWidgetContributorFactory factory, boolean pushNewWidget )
{
PageWizardDataEvents page = null;
if( factory != null )
{
INamedWidgetContributor newWidget = null;
if( widgetStack_ == null || widgetStack_.size() == 0 )
{
newWidget = factory.getFirstNamedWidget();
}
else
{
INamedWidgetContributor currentWidget = (INamedWidgetContributor)widgetStack_.peek();
newWidget = factory.getNextNamedWidget( currentWidget );
}
if( newWidget != null )
{
page = getPage( newWidget );
if( pushNewWidget )
{
widgetStack_.push( newWidget );
}
}
}
return page;
}
private void undoToLastPage()
{
boolean stackEmpty = false;
boolean doneUndoing = false;
while( !doneUndoing )
{
stackEmpty = engine_.undoToLastStop();
IWizardPage page = null;
if( lastUndoFragment_ != null )
{
page = getPage( lastUndoFragment_ );
if( page == null )
{
// Check to see if a group page fragment was found.
INamedWidgetContributorFactory factory = getWidgetFactory( lastUndoFragment_.getId() );
if( factory != null )
{
StackEntry entry = (StackEntry)widgetStackStack_.peek();
widgetFactory_ = entry.factory_;
widgetStack_ = entry.stack_;
if( widgetStack_ != null && !widgetStack_.empty() )
{
INamedWidgetContributor currentWidget = (INamedWidgetContributor)widgetStack_.peek();
page = getPage( currentWidget );
}
}
}
}
doneUndoing = page != null || stackEmpty;
}
}
private PageWizardDataEvents getPage( CommandFragment fragment )
{
// Check to see if this fragment is in our page table.
PageWizardDataEvents page = (PageWizardDataEvents)pageTable_.get( fragment );
String id = fragment.getId();
if( page == null && id != null )
{
// Check to see if this fragment id is in the registry.
PageInfo pageInfo = registry_.getPageInfo( id );
if( pageInfo != null )
{
page = pageFactory_.getPage( pageInfo, this );
pageTable_.put( fragment, page );
}
}
return page;
}
private PageWizardDataEvents getPage( INamedWidgetContributor widget )
{
PageWizardDataEvents page = (PageWizardDataEvents)widgetTable_.get( widget );
if( page == null )
{
PageInfo pageInfo = new PageInfo(widget.getTitle(), widget.getDescription(), widget.getWidgetContributorFactory() );
page = pageFactory_.getPage( pageInfo, this );
widgetTable_.put( widget, page );
}
return page;
}
private INamedWidgetContributorFactory getWidgetFactory( String id )
{
INamedWidgetContributorFactory factory = (INamedWidgetContributorFactory)widgetFactoryTable_.get( id );
if( factory == null )
{
// The factory is not in our table so we will try the registry.
factory = widgetRegistry_.getFactory( id );
if( factory != null )
{
widgetFactoryTable_.put( id, factory );
factory.registerDataMappings( dataManager_.getMappingRegistry() );
dataManager_.process( factory );
}
}
else
{
dataManager_.process( factory );
}
return factory;
}
private class StackEntry
{
INamedWidgetContributorFactory factory_;
Stack stack_;
}
}