net.sourceforge.sqlexplorer.plugin.editors.SQLTextEditor.java Source code

Java tutorial

Introduction

Here is the source code for net.sourceforge.sqlexplorer.plugin.editors.SQLTextEditor.java

Source

/*
 * 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.plugin.editors;

import net.sourceforge.sqlexplorer.IConstants;
import net.sourceforge.sqlexplorer.dbproduct.Session;
import net.sourceforge.sqlexplorer.plugin.SQLExplorerPlugin;
import net.sourceforge.sqlexplorer.sessiontree.model.utility.Dictionary;
import net.sourceforge.sqlexplorer.sqleditor.SQLTextViewer;
import net.sourceforge.sqlexplorer.sqleditor.actions.ExecSQLAction;

import org.apache.commons.lang.StringUtils;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
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.core.runtime.Path;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IURIEditorInput;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
import org.talend.core.GlobalServiceRegister;
import org.talend.core.ITDQRepositoryService;
import org.talend.core.model.properties.Item;

/**
 * TextEditor specialisation; encapsulates functionality specific to editing SQL.
 * 
 * Virtually all of this code came from SQLEditor, which used to be derived directly from TextEditor; SQLEditor now
 * combines the text editor (here, SQLTextEditor) and the result and messages panes in a single editor, hence this was
 * separated out for clarity
 * 
 * Note that MouseClickListener was also moved to a top-level, package-private class for readability
 * 
 * @modified John Spackman
 * 
 */
public class SQLTextEditor extends TextEditor {

    static int i = 0;

    private SQLEditor editor;

    private MouseClickListener mcl;

    private IPartListener partListener;

    /* package */SQLTextViewer sqlTextViewer;

    private boolean _enableContentAssist = SQLExplorerPlugin.getDefault().getPluginPreferences()
            .getBoolean(IConstants.SQL_ASSIST);

    private IPreferenceStore store;

    // ADD xqliu 2010-03-23 feature 10675
    private static final String DEFAULT_FILE_EXTENSION = ".sql";

    // TODO should use the file version property
    private static final String DEFAULT_VERSION_STRING = "_0.1";

    public SQLTextEditor(SQLEditor editor) {
        super();
        this.editor = editor;
        mcl = new MouseClickListener(editor);
        store = SQLExplorerPlugin.getDefault().getPreferenceStore();
        setPreferenceStore(SQLExplorerPlugin.getDefault().getPreferenceStore());
    }

    @Override
    protected boolean isLineNumberRulerVisible() {
        return true;
    }

    @Override
    protected boolean isOverviewRulerVisible() {
        return true;
    }

    @Override
    protected boolean isPrefQuickDiffAlwaysOn() {
        return true;
    }

    @Override
    public boolean isChangeInformationShowing() {
        return true;
    }

    @Override
    public IProgressMonitor getProgressMonitor() {
        return super.getProgressMonitor();
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#performSaveAs(org.eclipse.core.runtime.IProgressMonitor)
     */
    @Override
    protected void performSaveAs(IProgressMonitor progressMonitor) {
        // PTODO qzhang correct save the sql file. for bug 3860.
        Shell shell = getSite().getShell();
        final IEditorInput input = getEditorInput();
        IDocumentProvider provider = getDocumentProvider();
        IEditorInput newInput;
        if (input instanceof IURIEditorInput && !(input instanceof IFileEditorInput)) {
            super.performSaveAs(progressMonitor);
            return;
        }

        ILabelProvider lp = new WorkbenchLabelProvider();
        ITreeContentProvider cp = new WorkbenchContentProvider();
        FolderSelectionDialog dialog = new FolderSelectionDialog(shell, lp, cp);
        if (dialog.open() == Window.CANCEL) {
            if (progressMonitor != null) {
                progressMonitor.setCanceled(true);
            }
            return;
        }

        Object elements = dialog.getResult()[0];
        // ADD xqliu 2010-03-08 feature 10675
        IResource elem = (IResource) elements;
        if (elem instanceof IFolder) {
            IPath filePath = ((IFolder) elem).getFullPath();
            filePath = filePath.append(dialog.getFileName() + DEFAULT_FILE_EXTENSION);
            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);
                // MOD qiongli 2011-4-21 bug 20205.after creating property file,file name is changed(contain version
                // info),so reset'newInput'.
                file = createIFile(file, getViewer().getDocument().get());
                newInput = new FileEditorInput(file);
                success = true;

            } catch (CoreException x) {
                final IStatus status = x.getStatus();
                if (status == null || status.getSeverity() != IStatus.CANCEL) {
                    String title = "The file save failure.";
                    String msg = "The file save failure.";
                    MessageDialog.openError(shell, title, msg);
                }
            } finally {
                provider.changed(newInput);
                if (success) {
                    setInput(newInput);
                }
            }

            if (progressMonitor != null) {
                progressMonitor.setCanceled(!success);
            }
        }
    }

    /**
     * DOC qzhang Comment method "createIFile".
     * 
     * @param monitor
     * @param file
     * @param content
     * @throws CoreException
     */
    private IFile createIFile(IFile file, String content) throws CoreException {
        // MOD qiongli 2011-4-21.bug 20205 .should create sql file and property.use extension of service mechanism.
        if (GlobalServiceRegister.getDefault().isServiceRegistered(ITDQRepositoryService.class)) {
            ITDQRepositoryService service = (ITDQRepositoryService) GlobalServiceRegister.getDefault()
                    .getService(ITDQRepositoryService.class);
            if (service != null) {
                String fName = StringUtils.removeEnd(StringUtils.removeEnd(file.getName(), DEFAULT_FILE_EXTENSION),
                        DEFAULT_VERSION_STRING);
                IWorkspace workspace = ResourcesPlugin.getWorkspace();
                IPath rootPath = new Path("TDQ_Libraries/Source Files");
                Item item = service.createFile(content,
                        file.getProjectRelativePath().removeLastSegments(1).makeRelativeTo(rootPath), fName,
                        file.getFileExtension());
                // get the correct path(contain version info) for newInput file in editor.
                IPath location = file.getLocation();
                if (item != null && item.getProperty() != null && location != null) {

                    location = location.removeLastSegments(1);
                    StringBuffer strb = new StringBuffer();
                    strb.append(location.toString());
                    String version = item.getProperty().getVersion() == null ? ""
                            : "_" + item.getProperty().getVersion();
                    strb.append(Path.SEPARATOR).append(fName).append(version).append(DEFAULT_FILE_EXTENSION);
                    location = Path.fromOSString(strb.toString());
                    file = workspace.getRoot().getFileForLocation(location);
                }
            }
        }
        return file;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.texteditor.AbstractTextEditor#createActions()
     */
    @Override
    protected void createActions() {

        super.createActions();

        if (!_enableContentAssist) {
            return;
        }

        Action action = new Action("Auto-Completion") {

            @Override
            public void run() {
                sqlTextViewer.showAssistance();
            }
        };

        // This action definition is associated with the accelerator Ctrl+Space
        action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
        setAction("ContentAssistProposal", action);

    }

    @Override
    public void createPartControl(Composite parent) {

        super.createPartControl(parent);

        PlatformUI.getWorkbench().getHelpSystem().setHelp(getSourceViewer().getTextWidget(),
                SQLExplorerPlugin.PLUGIN_ID + ".SQLEditor");

        Object adapter = getAdapter(org.eclipse.swt.widgets.Control.class);
        if (adapter instanceof StyledText) {
            StyledText text = (StyledText) adapter;
            text.setWordWrap(
                    SQLExplorerPlugin.getDefault().getPluginPreferences().getBoolean(IConstants.WORD_WRAP));

            FontData[] fData = PreferenceConverter.getFontDataArray(store, IConstants.FONT);
            if (fData.length > 0) {
                JFaceResources.getFontRegistry().put(fData[0].toString(), fData);
                text.setFont(JFaceResources.getFontRegistry().get(fData[0].toString()));
            }
        }
    }

    @Override
    protected ISourceViewer createSourceViewer(final Composite parent, IVerticalRuler ruler, int style) {

        parent.setLayout(new FillLayout());
        final Composite myParent = new Composite(parent, SWT.NONE);

        GridLayout layout = new GridLayout();
        layout.marginHeight = layout.marginWidth = layout.horizontalSpacing = layout.verticalSpacing = 0;
        myParent.setLayout(layout);

        // create divider line

        Composite div1 = new Composite(myParent, SWT.NONE);
        GridData lgid = new GridData();
        lgid.grabExcessHorizontalSpace = true;
        lgid.horizontalAlignment = GridData.FILL;
        lgid.heightHint = 1;
        lgid.verticalIndent = 1;
        div1.setLayoutData(lgid);
        div1.setBackground(editor.getSite().getShell().getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));

        // create text viewer

        GridData gid = new GridData();
        gid.grabExcessHorizontalSpace = gid.grabExcessVerticalSpace = true;
        gid.horizontalAlignment = gid.verticalAlignment = GridData.FILL;

        Dictionary dictionary = null;
        if (editor.getSession() != null && _enableContentAssist) {
            dictionary = editor.getSession().getUser().getMetaDataSession().getDictionary();
        }
        sqlTextViewer = new SQLTextViewer(myParent, style, store, dictionary, ruler);
        sqlTextViewer.getControl().setLayoutData(gid);

        // create bottom divider line

        Composite div2 = new Composite(myParent, SWT.NONE);
        lgid = new GridData();
        lgid.grabExcessHorizontalSpace = true;
        lgid.horizontalAlignment = GridData.FILL;
        lgid.heightHint = 1;
        lgid.verticalIndent = 0;
        div2.setLayoutData(lgid);
        div2.setBackground(editor.getSite().getShell().getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));

        final SQLEditor thisEditor = editor;
        sqlTextViewer.getTextWidget().addVerifyKeyListener(new VerifyKeyListener() {

            private ExecSQLAction _execSQLAction = new ExecSQLAction(thisEditor);

            @Override
            public void verifyKey(VerifyEvent event) {

                if (event.stateMask == SWT.CTRL && event.keyCode == 13) {
                    event.doit = false;
                    _execSQLAction.run();
                }
            }
        });

        sqlTextViewer.getTextWidget().addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {

                SQLTextEditor.this.editor.getEditorSite().getPage()
                        .activate(SQLTextEditor.this.editor.getEditorSite().getPart());
            }
        });

        myParent.layout();

        IDocument dc = new Document();
        sqlTextViewer.setDocument(dc);

        mcl.install(sqlTextViewer);

        return sqlTextViewer;
    }

    public void setNewDictionary(final Dictionary dictionary) {
        if (editor.getSite() != null && editor.getSite().getShell() != null
                && editor.getSite().getShell().getDisplay() != null) {
            editor.getSite().getShell().getDisplay().asyncExec(new Runnable() {

                @Override
                public void run() {

                    if (sqlTextViewer != null && !editor.getTitleImage().isDisposed()) {
                        sqlTextViewer.setNewDictionary(dictionary);
                    }

                }
            });
        }
    }

    public void onEditorSessionChanged(Session session) {
        if (session != null && _enableContentAssist) {
            setNewDictionary(editor.getSession().getUser().getMetaDataSession().getDictionary());
        } else {
            setNewDictionary(null);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.IWorkbenchPart#dispose()
     */
    @Override
    public void dispose() {
        if (partListener != null) {
            editor.getEditorSite().getPage().removePartListener(partListener);
        }
        mcl.uninstall();
        super.dispose();
    }

    ISourceViewer getViewer() {
        return getSourceViewer();
    }
}