/*******************************************************************************
* Copyright (c) 2007-2009 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is 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
*
* Contributor:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.hibernate.eclipse.console;
import java.io.File;
import java.text.MessageFormat;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.ControlContribution;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IShowEditorInput;
import org.eclipse.ui.IURIEditorInput;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.dialogs.SaveAsDialog;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.ide.FileStoreEditorInput;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.hibernate.console.ConsoleConfiguration;
import org.hibernate.console.KnownConfigurations;
import org.hibernate.console.QueryInputModel;
import org.hibernate.eclipse.console.actions.ClearAction;
import org.hibernate.eclipse.console.actions.ExecuteQueryAction;
import org.hibernate.eclipse.console.actions.StickResTabAction;
import org.jboss.tools.hibernate.runtime.spi.IService;
public abstract class AbstractQueryEditor extends TextEditor implements
QueryEditor, IShowEditorInput {
private ToolBarManager tbm;
private ExecuteQueryAction execAction = null;
private ClearAction clearAction = null;
private StickResTabAction stickResTabAction = null;
private QueryInputModel queryInputModel;
private String defPartName;
private Image defTitleImage;
private Image connectedTitleImage;
// to enable execution of queries from files - hack for HBX-744
private String consoleConfigurationName;
protected boolean pinToOneResTab = false;
final public boolean askUserForConfiguration(String name) {
String out = NLS.bind(HibernateConsoleMessages.AbstractQueryEditor_do_you_want_open_session_factory, name);
return MessageDialog.openQuestion( HibernateConsolePlugin.getDefault()
.getWorkbench().getActiveWorkbenchWindow().getShell(),
HibernateConsoleMessages.AbstractQueryEditor_open_session_factory, out );
}
final public ConsoleConfiguration getConsoleConfiguration() {
return KnownConfigurations.getInstance().find(
getConsoleConfigurationName() );
}
final public String getConsoleConfigurationName() {
//TODO: these should be stored as resource info
if(getEditorInput() instanceof QueryEditorInput) {
QueryEditorInput hei = (QueryEditorInput) getEditorInput();
return hei.getConsoleConfigurationName();
} else {
return consoleConfigurationName;
}
}
final public void setConsoleConfigurationName(String name) {
if(getEditorInput() instanceof QueryEditorInput) {
QueryEditorInput hei = (QueryEditorInput) getEditorInput();
hei.setConsoleConfigurationName( name );
hei.setQuery( getEditorText() );
hei.resetName();
}
this.consoleConfigurationName = name;
showEditorInput( getEditorInput() );
}
protected void updateExecButton(){
/*if (getSourceViewer() != null ){
execAction.setEnabled(getConsoleConfigurationName().trim().length() != 0
&& getSourceViewer().getDocument().get().trim().length() > 0);
} else {
execAction.setEnabled(false);
}*/
execAction.setEnabled(getQueryString().trim().length() > 0
&& getConsoleConfigurationName().length() != 0);
}
public void showEditorInput(IEditorInput editorInput) {
try {
doSetInput( editorInput );
updateExecButton();
}
catch (CoreException e) {
HibernateConsolePlugin.getDefault().logErrorMessage(
HibernateConsoleMessages.AbstractQueryEditor_could_not_show_query_editor_input, e );
}
}
final public void doSave(IProgressMonitor progressMonitor) {
// super.doSave(progressMonitor);
QueryEditorInput hei = null;
if (getEditorInput() instanceof QueryEditorInput) {
hei = (QueryEditorInput) getEditorInput();
hei.setQuery( getEditorText() );
}
IDocumentProvider p = getDocumentProvider();
if (p != null && p.isDeleted(getEditorInput())) {
if (isSaveAsAllowed()) {
// 1GEUSSR: ITPUI:ALL - User should never loose changes made in the editors.
// Changed Behavior to make sure that if called inside a regular save (because
// of deletion of input element) there is a way to report back to the caller.
performSaveAs(progressMonitor);
} else {
Shell shell = getSite().getShell();
String title = HibernateConsoleMessages.AbstractQueryEditor_cannot_save;
String msg = HibernateConsoleMessages.AbstractQueryEditor_the_file_has_been_deleted_or_is_not_accessible;
MessageDialog.openError(shell, title, msg);
}
} else {
performSave( false, progressMonitor );
}
}
protected void doSetInput(IEditorInput input) throws CoreException {
super.doSetInput(input);
}
final public String getEditorText() {
IEditorInput editorInput = getEditorInput();
IDocumentProvider docProvider = getDocumentProvider();
IDocument doc = docProvider.getDocument( editorInput );
return doc.get();
}
public String getQueryString() {
return getEditorText();
}
/**
* Dispose of resources held by this editor.
*
* @see IWorkbenchPart#dispose()
*/
final public void dispose() {
super.dispose();
if ( tbm != null )
tbm.dispose();
}
final protected void createToolbar(Composite parent) {
ToolBar bar = new ToolBar( parent, SWT.HORIZONTAL );
bar.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
tbm = new ToolBarManager( bar );
execAction = new ExecuteQueryAction( this );
clearAction = new ClearAction( this );
stickResTabAction = new StickResTabAction( this );
ActionContributionItem item = new ActionContributionItem( execAction );
tbm.add( item );
item = new ActionContributionItem( clearAction );
tbm.add( item );
ControlContribution cc = new ConfigurationCombo( "hql-target", this ); //$NON-NLS-1$
tbm.add( cc );
tbm.add( new Separator() );
cc = new ComboContribution("maxResults") { //$NON-NLS-1$
SelectionAdapter selectionAdapter = new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
Integer maxResults = null;
try {
maxResults = new Integer(getText());
}
catch (NumberFormatException e1) {
maxResults = null;
}
getQueryInputModel().setMaxResults( maxResults );
}
};
protected Control createControl(Composite parent) {
Control control = super.createControl( parent );
comboControl.addModifyListener( new ModifyListener() {
public void modifyText(ModifyEvent e) {
Integer maxResults = null;
try {
maxResults = new Integer(getText());
}
catch (NumberFormatException e1) {
maxResults = null;
}
getQueryInputModel().setMaxResults( maxResults );
}
} );
return control;
}
protected int getComboWidth() {
return 75;
}
protected String getLabelText() {
return HibernateConsoleMessages.AbstractQueryEditor_max_results;
}
protected boolean isReadOnly() {
return false;
}
protected SelectionListener getSelectionAdapter() {
return selectionAdapter;
}
void populateComboBox() {
comboControl.getDisplay().syncExec( new Runnable() {
public void run() {
String[] items = new String[] { "", "10", "20", "30", "50"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
comboControl.setItems( items );
}
} );
}
};
tbm.add(cc);
tbm.add( new Separator() );
item = new ActionContributionItem( stickResTabAction );
tbm.add( item );
tbm.update( true );
}
protected void initializeKeyBindingScopes() {
setKeyBindingScopes(new String[] { "org.hibernate.eclipse.console.hql" }); //$NON-NLS-1$
}
public QueryInputModel getQueryInputModel() {
if (queryInputModel == null) {
IService service = getConsoleConfiguration().getHibernateExtension().getHibernateService();
queryInputModel = new QueryInputModel(service);
}
return queryInputModel;
}
public void showConnected(IEditorPart editor){
defPartName = getPartName();
defTitleImage = getTitleImage();
setPartName(defPartName + "->" + editor.getTitle()); //$NON-NLS-1$
if (connectedTitleImage == null){
connectedTitleImage = HibernateConsolePlugin.getImageDescriptor(getConnectedImageFilePath()).createImage();
}
setTitleImage(connectedTitleImage);
}
public void showDisconnected(){
setPartName(defPartName);
if (defTitleImage != null && !defTitleImage.isDisposed()){
setTitleImage(defTitleImage);
} else {
setTitleImage(null);
}
connectedTitleImage.dispose();
}
protected abstract String getConnectedImageFilePath();
/**
* returns file extension for "Save As" dialog
*/
protected abstract String getSaveAsFileExtension();
/**
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#performSaveAs(IProgressMonitor)
* the same method except line: "dialog.setOriginalName(getSaveAsFileExtension());"
*/
protected void performSaveAs(IProgressMonitor progressMonitor) {
Shell shell= getSite().getShell();
final IEditorInput input= getEditorInput();
IDocumentProvider provider= getDocumentProvider();
final IEditorInput newInput;
if (input instanceof IURIEditorInput && !(input instanceof IFileEditorInput)) {
FileDialog dialog= new FileDialog(shell, SWT.SAVE);
IPath oldPath= URIUtil.toPath(((IURIEditorInput)input).getURI());
if (oldPath != null) {
dialog.setFileName(oldPath.lastSegment());
dialog.setFilterPath(oldPath.toOSString());
}
String path= dialog.open();
if (path == null) {
if (progressMonitor != null)
progressMonitor.setCanceled(true);
return;
}
// Check whether file exists and if so, confirm overwrite
final File localFile= new File(path);
if (localFile.exists()) {
MessageDialog overwriteDialog= new MessageDialog(
shell,
HibernateConsoleMessages.AbstractQueryEditor_save_as,
null,
MessageFormat.format(HibernateConsoleMessages.AbstractQueryEditor_already_exists_do_you_want_to_replace_it, path),
MessageDialog.WARNING,
new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL },
1); // 'No' is the default
if (overwriteDialog.open() != Window.OK) {
if (progressMonitor != null) {
progressMonitor.setCanceled(true);
return;
}
}
}
IFileStore fileStore;
try {
fileStore= EFS.getStore(localFile.toURI());
} catch (CoreException ex) {
HibernateConsolePlugin.getDefault().log(ex.getStatus());
String title= HibernateConsoleMessages.AbstractQueryEditor_problems_during_save_as;
String msg= MessageFormat.format(HibernateConsoleMessages.AbstractQueryEditor_save_could_not_be_completed, ex.getMessage());
MessageDialog.openError(shell, title, msg);
return;
}
IFile file= getWorkspaceFile(fileStore);
if (file != null)
newInput= new FileEditorInput(file);
else
newInput= new FileStoreEditorInput(fileStore);
} else {
SaveAsDialog dialog= new SaveAsDialog(shell);
IFile original= (input instanceof IFileEditorInput) ? ((IFileEditorInput) input).getFile() : null;
if (original != null) {
dialog.setOriginalFile(original);
}
else {
dialog.setOriginalName(getSaveAsFileExtension());
}
dialog.create();
if (provider.isDeleted(input) && original != null) {
String message= MessageFormat.format(HibernateConsoleMessages.AbstractQueryEditor_the_original_file_has_been_deleted_or_is_not_accessible, original.getName());
dialog.setErrorMessage(null);
dialog.setMessage(message, IMessageProvider.WARNING);
}
if (dialog.open() == Window.CANCEL) {
if (progressMonitor != null)
progressMonitor.setCanceled(true);
return;
}
IPath filePath= dialog.getResult();
if (filePath == null) {
if (progressMonitor != null)
progressMonitor.setCanceled(true);
return;
}
IWorkspace workspace= ResourcesPlugin.getWorkspace();
IFile file= workspace.getRoot().getFile(filePath);
newInput= new FileEditorInput(file);
}
if (provider == null) {
// editor has programmatically been closed while the dialog was open
return;
}
boolean success= false;
try {
provider.aboutToChange(newInput);
provider.saveDocument(progressMonitor, newInput, provider.getDocument(input), true);
success= true;
} catch (CoreException x) {
final IStatus status= x.getStatus();
if (status == null || status.getSeverity() != IStatus.CANCEL) {
String title= HibernateConsoleMessages.AbstractQueryEditor_problems_during_save_as;
String msg= MessageFormat.format(HibernateConsoleMessages.AbstractQueryEditor_save_could_not_be_completed, x.getMessage());
MessageDialog.openError(shell, title, msg);
}
} finally {
provider.changed(newInput);
if (success)
setInput(newInput);
}
if (progressMonitor != null)
progressMonitor.setCanceled(!success);
}
/**
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#getWorkspaceFile(IFileStore)
* the same PROTECTED method instead of PRIVATE
*/
protected IFile getWorkspaceFile(IFileStore fileStore) {
IWorkspaceRoot workspaceRoot= ResourcesPlugin.getWorkspace().getRoot();
IFile[] files= workspaceRoot.findFilesForLocationURI(fileStore.toURI());
if (files != null && files.length == 1)
return files[0];
return null;
}
public boolean initTextAndToolTip(String text) {
if (execAction != null) {
execAction.initTextAndToolTip(text);
return true;
}
return false;
}
public boolean getPinToOneResTab() {
return pinToOneResTab;
}
public void setPinToOneResTab(boolean pinToOneResTab) {
this.pinToOneResTab = pinToOneResTab;
}
}