blob: 27032954f9653015e1741c1c1274c4e5e2cc6916 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005-2008 Sybase, Inc.
*
* 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:
* shongxum - initial API and implementation
* Actuate Corporation - refactored to improve extensibility
******************************************************************************/
package org.eclipse.datatools.connectivity.ui.actions;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.HandlerEvent;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.IHandlerListener;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.datatools.connectivity.ICategory;
import org.eclipse.datatools.connectivity.IConnectionProfile;
import org.eclipse.datatools.connectivity.IManagedConnection;
import org.eclipse.datatools.connectivity.IProfileListener;
import org.eclipse.datatools.connectivity.ProfileManager;
import org.eclipse.datatools.connectivity.internal.Category;
import org.eclipse.datatools.connectivity.internal.repository.IConnectionProfileRepository;
import org.eclipse.datatools.connectivity.internal.repository.IConnectionProfileRepositoryConstants;
import org.eclipse.datatools.connectivity.internal.ui.ConnectivityUIPlugin;
import org.eclipse.datatools.connectivity.internal.ui.LocalRepositoryNode;
import org.eclipse.datatools.connectivity.internal.ui.wizards.CPCategoryWizardNode;
import org.eclipse.datatools.connectivity.internal.ui.wizards.CPWizardNode;
import org.eclipse.datatools.connectivity.internal.ui.wizards.CPWizardSelectionPage;
import org.eclipse.datatools.connectivity.internal.ui.wizards.NewCPWizard;
import org.eclipse.datatools.connectivity.internal.ui.wizards.NewCPWizardCategoryFilter;
import org.eclipse.datatools.connectivity.internal.ui.wizards.NewCategoryWizard;
import org.eclipse.datatools.connectivity.internal.ui.wizards.ProfileWizardProvider;
import org.eclipse.datatools.connectivity.ui.wizards.ICPWizard;
import org.eclipse.datatools.connectivity.ui.wizards.IWizardCategoryProvider;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IViewActionDelegate;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.HandlerUtil;
/**
* Ideally, this class should be split into two, one is for Action, the other
* is for View Action.
*
* @author shongxum, brianf
*/
public class AddProfileViewAction extends Action
implements IHandler, IViewActionDelegate {
protected String categoryID;
private IConnectionProfile parentProfile;
private int returnCode;
private IConnectionProfile addedProfile;
private Shell shell;
private boolean ignoreCategory = false;
private boolean useSelection = true;
private static String PROP_IGNORE_CATEGORY = "org.eclipse.datatools.connectivity.ui.ignoreCategory";//$NON-NLS-1$
private static String PROP_USE_SELECTION = "org.eclipse.datatools.connectivity.ui.useSelection";//$NON-NLS-1$
/**
* A collection of objects listening to changes to this manager. This
* collection is <code>null</code> if there are no listeners.
*/
private transient ListenerList listenerList = null;
/**
* Constructor
*/
public AddProfileViewAction() {
super();
setText(ConnectivityUIPlugin.getDefault().getResourceString(
"ServersView.action.newCP")); //$NON-NLS-1$
}
/**
* @param category
*/
public AddProfileViewAction(ICategory category) {
this(category.getId());
}
/**
* @param categoryID
*/
public AddProfileViewAction ( String categoryID ) {
this.categoryID = categoryID;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart)
*/
public void init(IViewPart viewpart) {
shell = viewpart.getSite().getShell();
}
/**
* Initialize the shell for use as the parent shell of the action's dialog.
* Use this method when the action is extended to run without being associated
* with a view.
* @param parentShell
*/
public void init( Shell parentShell )
{
shell = parentShell;
}
/* (non-Javadoc)
* @see org.eclipse.core.commands.IHandler#addHandlerListener(org.eclipse.core.commands.IHandlerListener)
*/
public final void addHandlerListener(final IHandlerListener listener) {
if (listenerList == null) {
listenerList = new ListenerList(ListenerList.IDENTITY);
}
listenerList.add(listener);
}
/* (non-Javadoc)
* @see org.eclipse.core.commands.IHandler#dispose()
*/
public final void dispose() {
listenerList = null;
}
/* (non-Javadoc)
* @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
*/
public Object execute(ExecutionEvent event) throws ExecutionException {
IWorkbenchPart part = HandlerUtil.getActivePart(event);
if (part == null && event.getApplicationContext() != null)
return null;
else if (part instanceof IViewPart)
init((IViewPart)part);
String ignoreCategoryValue = event.getParameter(PROP_IGNORE_CATEGORY);
if (ignoreCategoryValue != null && ignoreCategoryValue.trim().length() > 0) {
ignoreCategory = Boolean.valueOf(ignoreCategoryValue).booleanValue();
}
String useSelectionValue = event.getParameter(PROP_USE_SELECTION);
if (useSelectionValue != null && useSelectionValue.trim().length() > 0 ) {
useSelection = Boolean.valueOf(useSelectionValue).booleanValue();
}
if (ignoreCategory) {
categoryID = null;
}
else if (useSelection) {
ISelection selection =
part.getSite().getSelectionProvider().getSelection();
if (selection instanceof IStructuredSelection) {
Object sel = ((IStructuredSelection) selection).getFirstElement();
// update enabled state for add action on categories.
if (sel instanceof ICategory) {
setCategory((ICategory)sel);
}
else if (sel instanceof IConnectionProfile) {
setCategory(((IConnectionProfile)sel).getCategory());
}
else
categoryID = null;
}
}
IWizard wizard = getDefaultWizard(new String(), categoryID);
if (wizard == null) {
ViewerFilter[] wizardSelectionFilters = getApplicableFilters( categoryID );
wizard = new NewCPWizard(wizardSelectionFilters,parentProfile);
}
WizardDialog wizardDialog = new WizardDialog(shell, wizard);
wizardDialog.setBlockOnOpen(true);
InternalProfileListener listener = new InternalProfileListener();
ProfileManager.getInstance().addProfileListener(listener);
returnCode = wizardDialog.open();
addedProfile = listener.cachedProfile;
ProfileManager.getInstance().removeProfileListener(listener);
fireHandlerChanged(new HandlerEvent(this, false, false));
return null;
}
/* (non-Javadoc)
* @see org.eclipse.core.commands.IHandler#removeHandlerListener(org.eclipse.core.commands.IHandlerListener)
*/
public void removeHandlerListener(IHandlerListener handlerListener) {
if (listenerList != null) {
listenerList.remove(handlerListener);
if (listenerList.isEmpty()) {
listenerList = null;
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.IAction#run()
*/
public void run() {
if (shell == null) {
shell = PlatformUI.getWorkbench().getDisplay().getActiveShell();
}
IWizard wizard = getDefaultWizard(new String(), categoryID);
if (wizard == null) {
ViewerFilter[] wizardSelectionFilters = getApplicableFilters( categoryID );
wizard = new NewCPWizard(wizardSelectionFilters,parentProfile);
}
WizardDialog wizardDialog = new WizardDialog(shell, wizard);
wizardDialog.setBlockOnOpen(true);
InternalProfileListener listener = new InternalProfileListener();
ProfileManager.getInstance().addProfileListener(listener);
returnCode = wizardDialog.open();
addedProfile = listener.cachedProfile;
ProfileManager.getInstance().removeProfileListener(listener);
}
/**
* Gets all the applicable filters for the specified category id.
* The returned collection starts with the required category filter,
* followed by any additional wizard selection filters that may be provided
* by an extended implementation.
* @param categoryId category id
* @return an array of ViewerFilter instances
*/
private ViewerFilter[] getApplicableFilters( String categoryId ) {
ArrayList filters = new ArrayList();
// adds required category filter
filters.add( getCategoryFilter( categoryId ) );
// appends additional wizard selection filters, if any
ViewerFilter[] moreFilters = getWizardSelectionFilters();
if( moreFilters != null ) {
for( int i=0; i < moreFilters.length; i++ ) {
filters.add( moreFilters[i] );
}
}
return (ViewerFilter[]) filters.toArray( new ViewerFilter[ filters.size() ] );
}
/**
* Gets the category filter for the specified category id.
* @param categoryId
* @return a category ViewerFilter
* @since DTP 1.6
*/
protected ViewerFilter getCategoryFilter( String categoryId ) {
return new NewCPWizardCategoryFilter( categoryId );
}
/**
* Gets the viewer filters for filtering the display of the connection profile
* wizard selection.
* @return an array of ViewerFilter instances
* @since DTP 1.6
*/
protected ViewerFilter[] getWizardSelectionFilters() {
// this base class provides a category filter only;
// subclass may override and provide additional filter(s)
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
*/
public void run(IAction action) {
run();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
* org.eclipse.jface.viewers.ISelection)
*/
public void selectionChanged(IAction action, ISelection selection) {
if (selection instanceof IStructuredSelection && action != null) {
Object sel = ((IStructuredSelection) selection).getFirstElement();
// always enable add action on local repository node.
if (sel instanceof LocalRepositoryNode) {
action.setEnabled(true);
}
// disable add action on read-only non-local repository
if (sel instanceof IConnectionProfile) {
IManagedConnection imc = ((IConnectionProfile) sel)
.getManagedConnection(IConnectionProfileRepositoryConstants.REPOSITORY_CONNECTION_FACTORY_ID);
if (imc != null && imc.isConnected()) {
IConnectionProfileRepository repo = (IConnectionProfileRepository) imc
.getConnection().getRawConnection();
action.setEnabled(!repo.isReadOnly());
}
// update enabled state for add action on categories.
} else if (sel instanceof ICategory) {
if (sel instanceof Category) {
IConnectionProfile profile = ((Category) sel)
.getRepositoryProfile();
// disable add action on categories in read-only
// non-local repository
if (profile != null) {
IManagedConnection imc = profile
.getManagedConnection(IConnectionProfileRepositoryConstants.REPOSITORY_CONNECTION_FACTORY_ID);
if (imc != null && imc.isConnected()) {
IConnectionProfileRepository repo = (IConnectionProfileRepository) imc
.getConnection().getRawConnection();
action.setEnabled(!repo.isReadOnly());
}
// enable add action on categories in local repository.
} else {
action.setEnabled(true);
}
}
}
}
}
/**
* @param category
*/
public void setCategory ( ICategory category ) {
setCategory(category == null ? null : category.getId());
}
/**
* @param categoryID
*/
public void setCategory ( String categoryID ) {
this.categoryID = categoryID;
}
/**
* @param profile
*/
public void setParentProfile(IConnectionProfile profile) {
parentProfile = profile;
}
/**
* @return
*/
public IConnectionProfile getParentProfile() {
return parentProfile;
}
/**
* @return
*/
public int getWizardReturnCode() {
return this.returnCode;
}
/**
* @return
*/
public IConnectionProfile getAddedProfile() {
return this.addedProfile;
}
/**
* @param parentCategoryID
* @param categoryID
* @return
*/
private IWizard getDefaultWizard(String parentCategoryID, String categoryID) {
List wizardNodes = new CPWizardSelectionPage(new String())
.getCategoryItems(parentCategoryID);
// include category filter if categoryID is defined
ViewerFilter[] wizardNodeFilters = (categoryID != null) ?
getApplicableFilters( categoryID ) :
getWizardSelectionFilters();
if ( wizardNodeFilters != null && wizardNodeFilters.length > 0 ) {
for (Iterator it = wizardNodes.iterator(); it.hasNext();) {
Object wizardNode = it.next();
for ( int i = 0; i < wizardNodeFilters.length; i++ ) {
ViewerFilter filter = wizardNodeFilters[i];
if (!filter.select(null, null, wizardNode)) {
it.remove();
break; // done with checking on filters
}
}
}
}
if (wizardNodes == null || wizardNodes.size() == 0) {
return null;
}
if (wizardNodes.size() > 1) {
return null;
}
IWizard wizard;
CPWizardNode wizardNode = (CPWizardNode) wizardNodes.get(0);
if (wizardNode instanceof CPCategoryWizardNode) {
wizard = getDefaultWizard(((CPCategoryWizardNode) wizardNode)
.getProvider().getCategory(), null);
if (wizard == null) {
wizard = wizardNode.getWizard();
if (wizard instanceof NewCategoryWizard) {
((NewCategoryWizard) wizard)
.initWizardCategory((IWizardCategoryProvider) wizardNode
.getProvider());
}
}
}
else {
wizard = wizardNode.getWizard();
if (wizard instanceof ICPWizard) {
((ICPWizard) wizard)
.initProviderID(((ProfileWizardProvider) wizardNode
.getProvider()).getProfile());
((ICPWizard) wizard).setParentProfile(parentProfile);
}
}
return wizard;
}
/**
* Internal listener to listen for the new profile
* @author brianf
*
*/
private class InternalProfileListener implements IProfileListener {
protected IConnectionProfile cachedProfile;
public void profileAdded(IConnectionProfile profile) {
cachedProfile = profile;
}
public void profileChanged(IConnectionProfile profile) {
// ignore
}
public void profileDeleted(IConnectionProfile profile) {
// ignore
}
}
/* (non-Javadoc)
* @see org.eclipse.jface.action.Action#isEnabled()
*/
public boolean isEnabled() {
return true;
}
/* (non-Javadoc)
* @see org.eclipse.jface.action.Action#isHandled()
*/
public boolean isHandled() {
return true;
}
/**
* @return
*/
public boolean getIgnoreCategory() {
return this.ignoreCategory;
}
/**
* @param flag
*/
public void setIgnoreCategory( boolean flag ) {
this.ignoreCategory = flag;
}
/**
* @return
*/
public boolean getUseSelection() {
return this.useSelection;
}
/**
* @param flag
*/
public void setUseSelection( boolean flag ) {
this.useSelection = flag;
}
/**
* @param handlerEvent
*/
protected void fireHandlerChanged(final HandlerEvent handlerEvent) {
if (handlerEvent == null) {
throw new NullPointerException();
}
if (listenerList == null)
return;
final Object[] listeners = listenerList.getListeners();
for (int i = 0; i < listeners.length; i++) {
final IHandlerListener listener = (IHandlerListener) listeners[i];
listener.handlerChanged(handlerEvent);
}
}
}