/*******************************************************************************
 * Copyright (c) 2004 Actuate Corporation.
 * 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:
 *  Actuate Corporation  - initial API and implementation
 *******************************************************************************/

package org.eclipse.birt.report.designer.data.ui.dataset;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.List;

import org.eclipse.birt.report.designer.data.ui.util.DTPUtil;
import org.eclipse.birt.report.designer.data.ui.util.DataSetProvider;
import org.eclipse.birt.report.designer.data.ui.util.DataUIConstants;
import org.eclipse.birt.report.designer.data.ui.util.DtpManifestExplorer;
import org.eclipse.birt.report.designer.data.ui.util.IHelpConstants;
import org.eclipse.birt.report.designer.data.ui.util.Utility;
import org.eclipse.birt.report.designer.internal.ui.util.ExceptionHandler;
import org.eclipse.birt.report.designer.nls.Messages;
import org.eclipse.birt.report.designer.ui.ReportPlugin;
import org.eclipse.birt.report.designer.ui.odadatasource.wizards.AbstractDataSetWizard;
import org.eclipse.birt.report.model.adapter.oda.ModelOdaAdapter;
import org.eclipse.birt.report.model.api.DataSetHandle;
import org.eclipse.birt.report.model.api.DataSourceHandle;
import org.eclipse.birt.report.model.api.DesignElementHandle;
import org.eclipse.birt.report.model.api.ModuleHandle;
import org.eclipse.birt.report.model.api.OdaDataSetHandle;
import org.eclipse.birt.report.model.api.OdaDataSourceHandle;
import org.eclipse.birt.report.model.api.ScriptDataSetHandle;
import org.eclipse.birt.report.model.api.ScriptDataSourceHandle;
import org.eclipse.birt.report.model.api.SlotHandle;
import org.eclipse.birt.report.model.api.activity.SemanticException;
import org.eclipse.birt.report.model.api.command.ContentException;
import org.eclipse.birt.report.model.api.command.NameException;
import org.eclipse.birt.report.model.api.elements.ReportDesignConstants;
import org.eclipse.birt.report.model.api.util.StringUtil;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.datatools.connectivity.oda.OdaException;
import org.eclipse.datatools.connectivity.oda.design.DataSourceDesign;
import org.eclipse.datatools.connectivity.oda.design.ui.designsession.DataSetDesignSession;
import org.eclipse.datatools.connectivity.oda.design.ui.designsession.DesignSessionUtil;
import org.eclipse.datatools.connectivity.oda.util.manifest.DataSetType;
import org.eclipse.datatools.connectivity.oda.util.manifest.ExtensionManifest;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

/**
 * Base information page for dataset wizards
 * 
 *  
 */

public class DataSetBasePage extends WizardPage implements
		ISelectionChangedListener
{

	private transient Text nameEditor = null;

	private transient ComboViewer dataSourceViewer = null;

	private transient ComboViewer dataSetTypeChooser = null;

	private transient boolean useTransaction = true;

	final private static String EMPTY_NAME = Messages.getString( "error.emptyName" );//$NON-NLS-1$

	final private static String DUPLICATE_NAME = Messages.getString( "error.duplicateName" );//$NON-NLS-1$

	final private static String CREATE_PROMPT = Messages.getString( "dataset.message.create" );//$NON-NLS-1$

	private String originalName;

	private transient DataSourceHandle newDataSource = null;

	private Hashtable htDataSetWizards = new Hashtable( 10 );
	
	private final static String SCRIPT_DATASET_NAME = "Scripted Data Set"; 

	// store latest selection data source
	private ISelection dataSourceSelection; 
	private ISelection dateSetTypeSelection = null;
	private transient DataSetDesignSession m_designSession = null;
	private boolean useODAV3 = false;
	
	/**
	 * Creates a new data set wizard page
	 * 
	 * @param useTransaction
	 *            the style of page
	 */
	public DataSetBasePage( boolean useTransaction )
	{
		super( "DataSet Base Page" );//$NON-NLS-1$
		setTitle( Messages.getString( "dataset.new" ) );//$NON-NLS-1$
		this.setMessage( Messages.getString( "AbstractDataSetWizard.ModelTrans.Create" ) ); //$NON-NLS-1$
		this.useTransaction = useTransaction;
		setImage( );
	}

	/**
	 * Sets the Image for the page
	 */
	private void setImage( )
	{
		URL url = null;
		try
		{
			url = new URL( ReportPlugin.getDefault( )
					.getBundle( )
					.getEntry( "/" ), //$NON-NLS-1$
					"icons/wizban/dataset_wizard.gif" );//$NON-NLS-1$
		}
		catch ( MalformedURLException e )
		{
			ExceptionHandler.handle( e );
		}
		ImageDescriptor desc = ImageDescriptor.createFromURL( url );
		this.setImageDescriptor( desc );

	}

	/**
	 * Creates the top level control for this dialog page under the given parent
	 * composite.
	 * <p>
	 * Implementors are responsible for ensuring that the created control can be
	 * accessed via <code>getControl</code>
	 * </p>
	 * 
	 * @param parent
	 *            the parent composite
	 */
	public void createControl( Composite parent )
	{
		//initialize the dialog layout
		Composite composite = new Composite( parent, SWT.NULL );
		composite.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
		GridLayout layout = new GridLayout( );
		layout.numColumns = 2;
		composite.setLayout( layout );
		//		GridData gridData;

		//initialize name editor
		new Label( composite, SWT.RIGHT ).setText( Messages.getString( "dataset.wizard.label.datasetName" ) );//$NON-NLS-1$
		nameEditor = new Text( composite, SWT.BORDER );
	//	nameEditor.setText( Utility.getUniqueDataSetName( Messages.getString( "dataset.new.defaultName" ) ) );//$NON-NLS-1$
		String name = ReportPlugin.getDefault( ).getCustomName( ReportDesignConstants.DATA_SET_ELEMENT );
		if(name != null)
		{
			nameEditor.setText( Utility.getUniqueDataSetName( name ) );
		}else // can't get defaut name
		{
			nameEditor.setText( Utility.getUniqueDataSetName( Messages.getString( "dataset.new.defaultName" ) ) );//$NON-NLS-1$			
		}
		
		nameEditor.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
		nameEditor.setToolTipText( Messages.getString( "DataSetBasePage.tooltip" ) ); //$NON-NLS-1$
		nameEditor.addModifyListener( new ModifyListener( ) {

			public void modifyText( ModifyEvent e )
			{
				if ( StringUtil.isBlank( nameEditor.getText( ).trim( ) ) )
				{
					setMessage( EMPTY_NAME, ERROR );
				}
				else if ( isDuplicateName( ) )
				{// name is duplicated
					setMessage( DUPLICATE_NAME, ERROR );
				}
				else if ( containDotCharactor( nameEditor.getText( ) ) )
				{// name contains invalid "." charactor
					String msg = Messages.getFormattedString( "error.invalidName",
							new Object[]{
							nameEditor.getText( )
							} );
					setMessage( msg, ERROR );
				}
				else
				{// everything is OK
					setMessage( CREATE_PROMPT );
				}
				setPageComplete( !hasWizard( ) && ( getMessageType( ) != ERROR ) );
			}
		} );

		// initialize data source chooser
		new Label( composite, SWT.RIGHT ).setText( Messages.getString( "dataset.wizard.label.dataSource" ) );//$NON-NLS-1$
		dataSourceViewer = new ComboViewer( composite, SWT.DROP_DOWN
				| SWT.READ_ONLY );
		dataSourceViewer.getControl( )
				.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
		DataSourceComboProvider provider = new DataSourceComboProvider( );
		dataSourceViewer.setContentProvider( provider );
		dataSourceViewer.setLabelProvider( provider );
		dataSourceViewer.addSelectionChangedListener( this );
		List dataSources = Utility.getVisibleDataSources( );
		if ( dataSources == null )
		{
			dataSources = new ArrayList( 10 );
		}
		if ( newDataSource != null )
		{
			dataSources.add( 0, newDataSource );
		}
		Object[] objs = dataSources.toArray( );
		Arrays.sort( objs, new Comparator( ) {

			public int compare( Object o1, Object o2 )
			{
				return ( (DataSourceHandle) o1 ).getName( )
						.compareTo( ( (DataSourceHandle) o2 ).getName( ) );
			}
		} );
		dataSources.clear( );
		for ( int i = 0; i < objs.length; i++ )
		{
			dataSources.add( objs[i] );
		}
		// create the data set type chooser combo
		new Label( composite, SWT.RIGHT ).setText( Messages.getString( "dataset.wizard.label.datasetType" ) );//$NON-NLS-1$
		dataSetTypeChooser = new ComboViewer( composite, SWT.DROP_DOWN
				| SWT.READ_ONLY );
		dataSetTypeChooser.getControl( )
				.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
		DataSetTypesProvider dataSetTypes = new DataSetTypesProvider( );
		dataSetTypeChooser.setContentProvider( dataSetTypes );
		dataSetTypeChooser.setLabelProvider( dataSetTypes );
		dataSetTypeChooser.addSelectionChangedListener( new ISelectionChangedListener( ) {

			public void selectionChanged( SelectionChangedEvent event )
			{
				if ( dataSetTypeChooser.getCombo( ).isEnabled( ) )
				{
					dateSetTypeSelection = dataSetTypeChooser.getSelection( );
					setPageComplete( !hasWizard( )
							&& ( getMessageType( ) != ERROR ) );
				}
			}
		} );

		dataSourceViewer.setInput( dataSources );
		setControl( composite );
		refreshFocus( );
		
		Utility.setSystemHelp( getControl( ),
				IHelpConstants.CONEXT_ID_DATASET_NEW );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.IDialogPage#setVisible(boolean)
	 */
	public void setVisible( boolean visible )
	{
		super.setVisible( visible );
		getControl( ).setFocus( );
		if ( visible )
		{
			List dataSourceList = (List) dataSourceViewer.getInput( );
			if ( dataSourceList.size( ) > 0 )
			{
				if ( dataSourceSelection == null )
					dataSourceSelection = new StructuredSelection( dataSourceList.get( 0 ) );
				dataSourceViewer.setSelection( dataSourceSelection );
			}
			refreshFocus( );
		}
	}

	/**
	 * Refreshes focus of current page.
	 *  
	 */
	protected void refreshFocus( )
	{
		nameEditor.setFocus( );
	}

	/**
	 * checks if the name is duplicate
	 * 
	 * @return Returns true if the name is duplicate,and false if it is
	 *         duplicate
	 */
	private boolean isDuplicateName( )
	{
		String name = nameEditor.getText( ).trim( );
		return !name.equals( originalName ) && Utility.checkDataSetName( name );
	}

	public String getDataSetName( )
	{
		return ( nameEditor.getText( ) );
	}

	/**
	 * whether name contains '.' charactor
	 * @param name
	 * @return
	 */
	private boolean containDotCharactor( String name )
	{
		if ( name == null )
			return false;
		else if ( name.indexOf( "." ) >= 0 )
			return true;
		else
			return false;
	}
	
	protected final DataSourceHandle getSelectedDataSource( )
	{
		return (DataSourceHandle) ( (IStructuredSelection) dataSourceViewer.getSelection( ) ).getFirstElement( );
	}

	/**
	 * @return Returns the newDataSource.
	 */
	final DataSourceHandle getNewDataSource( )
	{
		return newDataSource;
	}

	/**
	 * @param newDataSourceHandle
	 *            The newDataSource to set.
	 */
	final void setNewDataSource( DataSourceHandle newDataSourceHandle )
	{
		this.newDataSource = newDataSourceHandle;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.wizard.IWizardPage#getNextPage()
	 */
	public IWizardPage getNextPage( )
	{
		if ( dataSetTypeChooser.getCombo( ).isEnabled( ) )
		{
			if ( useODAV3 )
			{
				return getNextPageODAV3( );
			}
			else
			{
				return getNextPageODAV2( );
			}
		}
		{
			// switch to script data set page
			setPageComplete( true );
			return super.getNextPage( );
		}
	}

	/**
	 * 
	 * @param dataSourceDesign
	 * @return
	 */
	private IWizardPage getNextPageODAV3( )
	{
		DataSourceDesign dataSourceDesign = new ModelOdaAdapter( ).createDataSourceDesign( (OdaDataSourceHandle) getSelectedDataSource( ) );
		DataSetType dataSetElement = (DataSetType) ( (Object[]) getSelectedDataSet( ) )[0];
		String dataSetTypeName = dataSetElement.getID( );
		try
		{
			if ( m_designSession == null )
				m_designSession = DataSetDesignSession.startNewDesign( nameEditor.getText( )
						.trim( ),
						dataSetTypeName,
						dataSourceDesign );
			else
				m_designSession.restartNewDesign( nameEditor.getText( ).trim( ),
						dataSetTypeName,
						dataSourceDesign );

			setPageComplete( true );

			return m_designSession.getWizardStartingPage( );
		}
		catch ( OdaException e )
		{
			// TODO Auto-generated catch block
			return null;
		}
	}
	
	/**
	 * 
	 * @return
	 */
	private IWizardPage getNextPageODAV2( )
	{
		// Get the currently selected Data Set type and invoke its wizard
		// class
		IConfigurationElement element = (IConfigurationElement) ( (Object[]) ( (IStructuredSelection) dataSetTypeChooser.getSelection( ) ).getFirstElement( ) )[1];
		if ( element != null )
		{
			AbstractDataSetWizard newWizard = (AbstractDataSetWizard) htDataSetWizards.get( element.getAttribute( "id" ) );//$NON-NLS-1$
			if ( newWizard == null )
			{
				// Get the new wizard from this element
				IConfigurationElement[] elements = element.getChildren( "newDataSetWizard" );//$NON-NLS-1$
				if ( elements.length > 0 )
				{
					// Use only the first one.
					// There can only be one data set wizard for a data set
					try
					{
						Object wizard = elements[0].createExecutableExtension( "class" );//$NON-NLS-1$
						if ( wizard instanceof AbstractDataSetWizard )
						{
							newWizard = (AbstractDataSetWizard) wizard;
							newWizard.setConfigurationElement( element );
							// Allow the wizard to create its pages
							newWizard.addPages( );
							newWizard.setUseTransaction( useTransaction );
							htDataSetWizards.put( element.getAttribute( "id" ),//$NON-NLS-1$
									newWizard );
						}
					}
					catch ( CoreException e )
					{
						ExceptionHandler.handle( e );
					}
				}
			}

			if ( newWizard != null )
			{
				newWizard.setDataSource( getSelectedDataSource( ) );
				newWizard.setDataSetName( nameEditor.getText( ).trim( ) );

				// if the data set has been created
				// update it in the data set as well
				if ( newWizard.getDataSet( ) != null )
				{
					try
					{
						newWizard.getDataSet( )
								.setDataSource( newWizard.getDataSource( )
										.getName( ) );
						newWizard.getDataSet( )
								.setName( newWizard.getDataSetName( ) );
					}
					catch ( SemanticException e )
					{
						ExceptionHandler.handle( e );
					}
				}
				return newWizard.getStartingPage( );
			}
		}

		return super.getNextPage( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.wizard.IWizardPage#canFlipToNextPage()
	 */
	public boolean canFlipToNextPage( )
	{
		return !isPageComplete( )
				&& this.getMessageType( ) != ERROR
				&& !StringUtil.isBlank( nameEditor.getText( ) )
				&& ( !dataSetTypeChooser.getCombo( ).isEnabled( ) || ( ( dataSetTypeChooser.getSelection( ) != null ) && ( ( (IStructuredSelection) dataSetTypeChooser.getSelection( ) ).getFirstElement( ) != null ) ) );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
	 */
	public void selectionChanged( SelectionChangedEvent event )
	{
		// save it
		dataSourceSelection = this.dataSourceViewer.getSelection( );
		
		DataSourceHandle handle = (DataSourceHandle) ( (IStructuredSelection) event.getSelection( ) ).getFirstElement( );
		//DataSetType[] dataSets = null;
		Object[] dataSets = null; //Each element in this array contain another
		// array, the first element of which is the
		// oda element and the second is the ui if any

		if ( handle instanceof OdaDataSourceHandle )
		{
			String type = ( (OdaDataSourceHandle) handle ).getExtensionID( );
			useODAV3 = DesignSessionUtil.hasValidOdaDesignUIExtension( type );
			try
			{
				//Find the data source
				ExtensionManifest extMF = DtpManifestExplorer.getInstance( )
						.getExtensionManifest( type );
				if ( extMF != null )
				{
					//Find the data sets for this data source.
					DataSetType[] dataSetTypes = extMF.getDataSetTypes( );
					dataSets = new Object[dataSetTypes.length];
					for ( int n = 0; n < dataSetTypes.length; n++ )
					{
						dataSets[n] = new Object[2];
						( (Object[]) dataSets[n] )[0] = dataSetTypes[n];
						( (Object[]) dataSets[n] )[1] = DataSetProvider.findDataSetElement( dataSetTypes[n].getID( ),
								type );
					}
				}
			}
			catch ( Exception ex )
			{
				ExceptionHandler.handle( ex );
			}
		}
		else if ( handle instanceof ScriptDataSourceHandle )
		{
			useODAV3 = false;
			dataSets = new Object[]{
				SCRIPT_DATASET_NAME
			}; // type chooser is disabled
		}

		//populate the data set type combo box;
		dataSetTypeChooser.setInput( dataSets );
		if ( handle instanceof ScriptDataSourceHandle )
		{
			dataSetTypeChooser.getCombo( ).setEnabled( false );
			setPageComplete( false );
		}
		else
		{
			dataSetTypeChooser.getCombo( ).setEnabled( true );
			setPageComplete( !hasWizard( ) && ( getMessageType( ) != ERROR ) );
		}

		if ( dataSets != null && dataSets.length > 0 )
		{
			if ( dataSets.length > 1 && dateSetTypeSelection != null )
			{
				int index = getSelectedDateSetTypeIndex( dataSets,
						(StructuredSelection) dateSetTypeSelection );
				dataSetTypeChooser.setSelection( new StructuredSelection( dataSets[index] ) );
			}
			else
				dataSetTypeChooser.setSelection( new StructuredSelection( dataSets[0] ) );
		}
	}
	
	private int getSelectedDateSetTypeIndex( Object[] dataSets,
			StructuredSelection dateSetTypeSelection )
	{
		int index = 0;
		for ( int i = 0; i < dataSets.length; i++ )
		{
			if ( ( (DataSetType) ( (Object[]) dataSets[i] )[0] ).getID( )
					.equals( ( (DataSetType) ( (Object[]) dateSetTypeSelection.getFirstElement( ) )[0] ).getID( ) ) )
			{
				index = i;
				break;
			}
		}

		return index;
	}

	private Object getSelectedDataSet( )
	{
		return ( (IStructuredSelection) dataSetTypeChooser.getSelection( ) ).getFirstElement( );
	}

	private boolean hasWizard( )
	{
		if ( getSelectedDataSet( ) instanceof Object[] )
		{
			//Get the currently selected Data Set type and invoke its wizard
			// class
			IConfigurationElement element = (IConfigurationElement) ( (Object[]) getSelectedDataSet( ) )[1];
			if ( element != null )
			{
				AbstractDataSetWizard newWizard = (AbstractDataSetWizard) htDataSetWizards.get( element.getAttribute( "id" ) );//$NON-NLS-1$
				if ( newWizard != null )
				{
					return true;
				}
				//Get the new wizard from this element
				IConfigurationElement[] v3elements = element.getChildren( "dataSetWizard" );//$NON-NLS-1$
				IConfigurationElement[] v2elements = element.getChildren( "newDataSetWizard" );//$NON-NLS-1$
				if ( v3elements.length > 0 || v2elements.length > 0 )
				{
					return true;
				}
			}
		}
		else if ( getSelectedDataSet( ) != null
				&& getSelectedDataSet( ).toString( )
						.equals( SCRIPT_DATASET_NAME ) )
			return true;
		return false;
	}

	DataSetHandle createSelectedDataSet( )
	{
		DataSetHandle dataSetHandle = null;

		try
		{
			if ( useODAV3 )
			{
				dataSetHandle = createDataSetODAV3( );
			}
			else
			{
				dataSetHandle = createDataSetODAV2( );
			}

			return dataSetHandle;
		}
		catch ( SemanticException e )
		{
			ExceptionHandler.handle( e );
			return null;
		}
		catch ( IllegalStateException e )
		{
			ExceptionHandler.handle( e );
			return null;
		}
		catch ( OdaException e )
		{
			ExceptionHandler.handle( e );
			return null;
		}
	}
	
	/**
	 * 
	 * @return
	 * @throws OdaException
	 * @throws SemanticException
	 * @throws IllegalStateException
	 */
	private DataSetHandle createDataSetODAV3( ) throws OdaException, SemanticException, IllegalStateException
	{
		DesignElementHandle parentHandle = Utility.getReportModuleHandle( );

		DataSetHandle dataSetHandle = DTPUtil.getInstance( )
				.createOdaDataSetHandle( m_designSession.finish( )
						.getResponse( ),
						(ModuleHandle) parentHandle );
		m_designSession = null; // reset

		return dataSetHandle;
	}	
	
	/**
	 * 
	 * @return
	 * @throws SemanticException
	 */
	private DataSetHandle createDataSetODAV2( ) throws SemanticException
	{
		String dataSetTypeName = null;
		if ( getSelectedDataSet( ) instanceof Object[] )
		{
			DataSetType dataSetElement = (DataSetType) ( (Object[]) getSelectedDataSet( ) )[0];
			dataSetTypeName = dataSetElement.getID( );
		}
		else
		{
			dataSetTypeName = DataUIConstants.DATA_SET_SCRIPT;
		}

		return createDataSet( dataSetTypeName );
	}

	private DataSetHandle createDataSet( String dataSetType )
			throws SemanticException
	{
		DataSourceHandle source = getSelectedDataSource( );
		if ( source instanceof OdaDataSourceHandle )
		{
			OdaDataSetHandle dsHandle = Utility.newOdaDataSet( getDataSetName( ).trim( ),
					dataSetType );
			dsHandle.setDataSource( source.getQualifiedName() );
			dsHandle.setQueryText( "" ); //$NON-NLS-1$ //Need a empty query in the dataset.
			return dsHandle;
		}
		if ( source instanceof ScriptDataSourceHandle )
		{
			ScriptDataSetHandle dsHandle = Utility.newScriptDataSet( getDataSetName( ) );
			dsHandle.setDataSource( source.getName( ) );
			return dsHandle;
		}
		return null;
	}

}

class DataSourceComboProvider implements
		IStructuredContentProvider,
		ILabelProvider
{

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
	 */
	public Object[] getElements( Object inputElement )
	{
		return ( (List) inputElement ).toArray( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
	 */
	public void dispose( )
	{
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
	 *      java.lang.Object, java.lang.Object)
	 */
	public void inputChanged( Viewer viewer, Object oldInput, Object newInput )
	{
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
	 */
	public Image getImage( Object element )
	{
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
	 */
	public String getText( Object element )
	{
		return ( (DataSourceHandle) element ).getQualifiedName();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
	 */
	public void addListener( ILabelProviderListener listener )
	{
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object,
	 *      java.lang.String)
	 */
	public boolean isLabelProperty( Object element, String property )
	{
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
	 */
	public void removeListener( ILabelProviderListener listener )
	{
	}

}

class DataSetTypesProvider implements
		IStructuredContentProvider,
		ILabelProvider
{

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
	 */
	public Object[] getElements( Object inputElement )
	{
		if ( inputElement != null )
		{
			return (Object[]) inputElement;
		}
		return new Object[]{};
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
	 */
	public void dispose( )
	{
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
	 *      java.lang.Object, java.lang.Object)
	 */
	public void inputChanged( Viewer viewer, Object oldInput, Object newInput )
	{
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
	 */
	public Image getImage( Object element )
	{
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
	 */
	public String getText( Object element )
	{
		if ( element instanceof Object[] )
		{
			DataSetType type = (DataSetType) ( (Object[]) element )[0];
			return type.getDisplayName( );
		}
		return element.toString( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
	 */
	public void addListener( ILabelProviderListener listener )
	{
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object,
	 *      java.lang.String)
	 */
	public boolean isLabelProperty( Object element, String property )
	{
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
	 */
	public void removeListener( ILabelProviderListener listener )
	{
	}
}