/*
* Copyright (C) 2007 SQL Explorer Development Team http://sourceforge.net/projects/eclipsesql
*
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package net.sourceforge.sqlexplorer.connections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import net.sourceforge.sqlexplorer.Messages;
import net.sourceforge.sqlexplorer.SQLCannotConnectException;
import net.sourceforge.sqlexplorer.connections.actions.AbstractConnectionTreeAction;
import net.sourceforge.sqlexplorer.dbproduct.Alias;
import net.sourceforge.sqlexplorer.dbproduct.ConnectionListener;
import net.sourceforge.sqlexplorer.dbproduct.SQLConnection;
import net.sourceforge.sqlexplorer.dbproduct.Session;
import net.sourceforge.sqlexplorer.dbproduct.User;
import net.sourceforge.sqlexplorer.plugin.SQLExplorerPlugin;
import net.sourceforge.sqlexplorer.plugin.editors.SQLEditor;
import net.sourceforge.sqlexplorer.plugin.editors.SQLEditorInput;
import net.sourceforge.sqlexplorer.plugin.views.DatabaseStructureView;
import org.apache.commons.io.FileUtils;
import org.eclipse.core.resources.IFile;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.talend.core.GlobalServiceRegister;
import org.talend.core.ITDQRepositoryService;
public class ConnectionsView extends ViewPart implements ConnectionListener {
private static final HashSet<SQLConnection> EMPTY_CONNECTIONS = new HashSet<SQLConnection>();
private static final HashSet<Alias> EMPTY_ALIASES = new HashSet<Alias>();
private static final HashSet<User> EMPTY_USERS = new HashSet<User>();
// Tree viewer for connections
private TreeViewer _treeViewer;
// Last User that was selected
private User defaultUser;
private Clipboard clipboard;
public ConnectionsView() {
super();
SQLExplorerPlugin.getDefault().setConnectionsView(this);
}
/**
* @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
@Override
public void createPartControl(Composite parent) {
PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, SQLExplorerPlugin.PLUGIN_ID + ".AliasView");//$NON-NLS-1$
SQLExplorerPlugin.getDefault().getAliasManager().addListener(this);
// create outline
_treeViewer = new TreeViewer(parent, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI);
getSite().setSelectionProvider(_treeViewer);
// create action bar
IToolBarManager toolBarMgr = getViewSite().getActionBars().getToolBarManager();
// PTODO qzhang delete the Context meun in the Connections View for feature 3519.
// toolBarMgr.add(new NewAliasAction());
// toolBarMgr.add(new NewEditorAction());
// toolBarMgr.add(new NewDatabaseStructureViewAction());
// toolBarMgr.add(new CloseAllConnectionsAction());
// toolBarMgr.add(new CloseConnectionAction());
// use hash lookup to improve performance
_treeViewer.setUseHashlookup(true);
// add content and label provider
_treeViewer.setContentProvider(new ConnectionTreeContentProvider());
_treeViewer.setLabelProvider(new ConnectionTreeLabelProvider());
// Add yyi 2010-09-15 14549: hide connections in SQL Explorer when a connection is moved to the trash bin
_treeViewer.addFilter(new ViewerFilter() {
@Override
public boolean select(Viewer viewer, Object parentElement, Object element) {
try {
IFile file = SQLExplorerPlugin.getDefault().getPropertyFile().get(element);
if (null != file && file.exists()) {
// FIXME: Not recommended to judge delete status like this.
return !FileUtils.readFileToString(file.getLocation().toFile()).contains("deleted=\"true\"");//$NON-NLS-1$
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
});
// ~
// set input session
_treeViewer.setInput(SQLExplorerPlugin.getDefault().getAliasManager());
// doubleclick on alias opens session
_treeViewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
IStructuredSelection selection = (IStructuredSelection) event.getSelection();
if (selection != null) {
User user = null;
Object selected = selection.getFirstElement();
if (selected instanceof Alias) {
Alias alias = (Alias) selection.getFirstElement();
user = alias.getDefaultUser();
} else if (selected instanceof User) {
user = (User) selected;
} else if (selected instanceof SQLConnection) {
user = ((SQLConnection) selected).getUser();
}
if (user != null) {
openNewEditor(user);
}
}
}
});
_treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
refreshToolbar();
}
});
// add context menu
final ConnectionTreeActionGroup actionGroup = new ConnectionTreeActionGroup();
MenuManager menuManager = new MenuManager("ConnectionTreeContextMenu");//$NON-NLS-1$
menuManager.setRemoveAllWhenShown(true);
Menu contextMenu = menuManager.createContextMenu(_treeViewer.getTree());
_treeViewer.getTree().setMenu(contextMenu);
menuManager.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
actionGroup.fillContextMenu(manager);
}
});
_treeViewer.expandToLevel(2);
parent.layout();
SQLExplorerPlugin.getDefault().startDefaultConnections(this);
}
public void openNewEditor(User user) {
try {
// First time we connect, get the database structure view up too
if (!user.hasAuthenticated()) {
DatabaseStructureView dsView = SQLExplorerPlugin.getDefault().getDatabaseStructureView();
dsView.addUser(user);
}
SQLEditorInput input = new SQLEditorInput("SQL Editor (" + SQLExplorerPlugin.getDefault().getEditorSerialNo()
+ ").sql");//$NON-NLS-1$ $NON-NLS-2$
input.setUser(user);
IWorkbenchPage page = SQLExplorerPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage();
page.openEditor(input, SQLEditor.class.getName());
} catch (SQLCannotConnectException e) {
MessageDialog.openError(Display.getDefault().getActiveShell(), Messages.getString("ConnectionsView.cannotConnect"),
e.getMessage());
} catch (Throwable e) {
SQLExplorerPlugin.error(Messages.getString("ConnectionsView.errCreateSql"), e);
}
}
public void connectionClosed(Session session) {
modelChanged();
}
public void connectionOpened(Session session) {
modelChanged();
}
public void modelChanged() {
getSite().getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
if (!_treeViewer.getTree().isDisposed()) {
_treeViewer.refresh();
refreshToolbar();
}
}
});
}
@Override
public void dispose() {
if (clipboard != null) {
clipboard.dispose();
clipboard = null;
}
SQLExplorerPlugin.getDefault().getAliasManager().removeListener(this);
super.dispose();
}
public TreeViewer getTreeViewer() {
return _treeViewer;
}
public void refresh() {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (!_treeViewer.getTree().isDisposed()) {
_treeViewer.refresh();
}
}
});
}
private void refreshToolbar() {
IToolBarManager toolbar = getViewSite().getActionBars().getToolBarManager();
IContributionItem[] items = toolbar.getItems();
for (IContributionItem item : items) {
if (item instanceof ActionContributionItem) {
ActionContributionItem contrib = (ActionContributionItem) item;
// MOD mzhao bug 12938, Avoid a ClassCastException. 2010-05-06.
AbstractConnectionTreeAction contibAction = null;
IAction action = contrib.getAction();
if (action instanceof AbstractConnectionTreeAction) {
contibAction = (AbstractConnectionTreeAction) action;
action.setEnabled(contibAction.isAvailable());
}
// ~
}
}
}
/**
* Returns the objects which are currently selected. NOTE this is package private and should remain that way - the
* implementation of the ConnectionsView is now hidden from the rest of the application (see the getSelectedXxxx()
* methods below for a structured API)
*
* @return
*/
/* package */Object[] getSelected() {
IStructuredSelection selection = (IStructuredSelection) _treeViewer.getSelection();
if (selection == null) {
return null;
}
Object[] result = selection.toArray();
if (result.length == 0) {
return null;
}
return result;
}
/**
* Returns a list of the selected Aliases. If recurse is true then the result will include any aliases associated
* with other objects; eg, if a connection is selected and recurse is true, then the connection's alias will also be
* returned
*
* @param recurse
* @return Set of Aliases, never returns null
*/
public Set<Alias> getSelectedAliases(boolean recurse) {
IStructuredSelection selection = (IStructuredSelection) _treeViewer.getSelection();
if (selection == null) {
return EMPTY_ALIASES;
}
LinkedHashSet<Alias> result = new LinkedHashSet<Alias>();
Iterator iter = selection.iterator();
while (iter.hasNext()) {
Object obj = iter.next();
if (obj instanceof Alias) {
result.add((Alias) obj);
} else if (recurse) {
if (obj instanceof User) {
User user = (User) obj;
result.add(user.getAlias());
} else if (obj instanceof SQLConnection) {
SQLConnection connection = (SQLConnection) obj;
result.add(connection.getUser().getAlias());
}
}
}
return result;
}
/**
* Returns the first available selected alias; if recurse is true, then indirectly selected aliases are included (eg
* a selected connection's alias)
*
* @param recurse
* @return
*/
public Alias getSelectedAlias(boolean recurse) {
return (Alias) getFirstOf(getSelectedAliases(recurse));
}
/**
* Returns a list of selected Users; if recurse is true, indirectly selected users are included also (eg a session's
* user)
*
* @param recurse
* @return Set of Users, never returns null
*/
public Set<User> getSelectedUsers(boolean recurse) {
IStructuredSelection selection = (IStructuredSelection) _treeViewer.getSelection();
if (selection == null) {
return EMPTY_USERS;
}
LinkedHashSet<User> result = new LinkedHashSet<User>();
Iterator iter = selection.iterator();
while (iter.hasNext()) {
Object obj = iter.next();
if (obj instanceof User) {
result.add((User) obj);
} else if (recurse) {
if (obj instanceof Alias) {
Alias alias = (Alias) obj;
result.addAll(alias.getUsers());
} else if (obj instanceof SQLConnection) {
SQLConnection connection = (SQLConnection) obj;
result.add(connection.getUser());
}
}
}
return result;
}
/**
* Returns the first selected user; if recurse is true, this includes indirectly selected users (eg an Alias' user)
*
* @param recurse
* @return
*/
public User getSelectedUser(boolean recurse) {
return (User) getFirstOf(getSelectedUsers(recurse));
}
/**
* Returns a list of selected sessions; if recurse is true, then it includes indirectly selected sessions (eg a
* selected user's sessions)
*
* @param recurse
* @return Set of Sessions, never returns null
*/
public Set<SQLConnection> getSelectedConnections(boolean recurse) {
IStructuredSelection selection = (IStructuredSelection) _treeViewer.getSelection();
if (selection == null) {
return EMPTY_CONNECTIONS;
}
LinkedHashSet<SQLConnection> result = new LinkedHashSet<SQLConnection>();
Iterator iter = selection.iterator();
while (iter.hasNext()) {
Object obj = iter.next();
if (obj instanceof SQLConnection) {
result.add((SQLConnection) obj);
} else if (recurse) {
if (obj instanceof Alias) {
Alias alias = (Alias) obj;
for (User user : alias.getUsers()) {
result.addAll(user.getConnections());
}
} else if (obj instanceof User) {
User user = (User) obj;
result.addAll(user.getConnections());
}
}
}
return result;
}
/**
* Returns the first selected connection; if recurse is true, then includes indirectly selected sessions
*
* @param recurse
* @return
*/
public SQLConnection getSelectedConnection(boolean recurse) {
return (SQLConnection) getFirstOf(getSelectedConnections(recurse));
}
/**
* @see org.eclipse.ui.IWorkbenchPart#setFocus()
*/
@Override
public void setFocus() {
}
/**
* Helper method which returns the first element of a set, or null if the set is empty (or if the set is null)
*
* @param set the set to look into (may be null)
* @return
*/
private Object getFirstOf(Set set) {
if (set == null) {
return null;
}
Iterator iter = set.iterator();
if (iter.hasNext()) {
return iter.next();
}
return null;
}
/**
* @return the defaultUser
*/
public User getDefaultUser() {
if (defaultUser == null) {
Alias alias = getDefaultAlias();
if (alias != null) {
return alias.getDefaultUser();
}
}
return defaultUser;
}
/**
* @param defaultUser the defaultUser to set
*/
public void setDefaultUser(User lastSelectedUser) {
this.defaultUser = lastSelectedUser;
}
private Alias getDefaultAlias() {
IStructuredSelection selection = (IStructuredSelection) _treeViewer.getSelection();
if (selection == null) {
return null;
}
Object element = selection.getFirstElement();
if (element instanceof Alias) {
return (Alias) element;
} else if (element instanceof Session) {
ITreeContentProvider provider = (ITreeContentProvider) _treeViewer.getContentProvider();
return (Alias) provider.getParent(element);
}
return null;
}
/**
* @return the clipboard
*/
public Clipboard getClipboard() {
if (clipboard == null) {
clipboard = new Clipboard(getSite().getShell().getDisplay());
}
return clipboard;
}
/**
* @param clipboard the clipboard to set
*/
public void setClipboard(Clipboard clipboard) {
this.clipboard = clipboard;
}
@Override
public void init(IViewSite site, IMemento memento) throws PartInitException {
super.init(site, memento);
// MOD qiongli 2012-11-9 TDQ-6166,init the propertyFileMap when this view init and the map is empty.
ITDQRepositoryService tdqRepService = null;
if (GlobalServiceRegister.getDefault().isServiceRegistered(ITDQRepositoryService.class)) {
tdqRepService = (ITDQRepositoryService) GlobalServiceRegister.getDefault().getService(ITDQRepositoryService.class);
if (tdqRepService != null) {
tdqRepService.initAllConnectionsToSQLExplorer();
}
}
}
}