org.xmind.cathy.internal.CathyWorkbenchAdvisor.java Source code

Java tutorial

Introduction

Here is the source code for org.xmind.cathy.internal.CathyWorkbenchAdvisor.java

Source

/* ******************************************************************************
 * Copyright (c) 2006-2012 XMind Ltd. and others.
 *
 * This file is a part of XMind 3. XMind releases 3 and
 * above are dual-licensed under the Eclipse Public License (EPL),
 * which is available at http://www.eclipse.org/legal/epl-v10.html
 * and the GNU Lesser General Public License (LGPL),
 * which is available at http://www.gnu.org/licenses/lgpl.html
 * See http://www.xmind.net/license.html for details.
 *
 * Contributors:
 *     XMind Ltd. - initial API and implementation
 *******************************************************************************/
package org.xmind.cathy.internal;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPersistable;
import org.eclipse.ui.IPersistableElement;
import org.eclipse.ui.ISaveablePart2;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.XMLMemento;
import org.eclipse.ui.application.IWorkbenchConfigurer;
import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
import org.eclipse.ui.application.WorkbenchAdvisor;
import org.eclipse.ui.application.WorkbenchWindowAdvisor;
import org.eclipse.ui.internal.IWorkbenchConstants;
import org.eclipse.ui.internal.UIPlugin;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.xmind.cathy.internal.jobs.OpenFilesJob;
import org.xmind.core.internal.InternalCore;
import org.xmind.core.licensing.ILicenseAgent;
import org.xmind.core.licensing.ILicenseChangedListener;
import org.xmind.core.licensing.ILicenseKeyHeader;
import org.xmind.gef.ui.editor.IEditingContext;
import org.xmind.ui.internal.PasswordProvider;
import org.xmind.ui.internal.dialogs.DialogMessages;
import org.xmind.ui.internal.editor.AbstractWorkbookRef;
import org.xmind.ui.internal.editor.DefaultMindMapPreviewGenerator;
import org.xmind.ui.internal.editor.IMindMapPreviewGenerator;
import org.xmind.ui.internal.editor.IPasswordProvider;
import org.xmind.ui.mindmap.MindMapUI;

public class CathyWorkbenchAdvisor extends WorkbenchAdvisor implements ILicenseChangedListener {

    public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
        return new CathyWorkbenchWindowAdvisor(configurer);
    }

    public String getInitialWindowPerspectiveId() {
        return MindMapUI.PERSPECTIVE_ID;
    }

    @Override
    public String getMainPreferencePageId() {
        return "org.xmind.ui.prefPage.General"; //$NON-NLS-1$
    }

    public void initialize(IWorkbenchConfigurer configurer) {
        super.initialize(configurer);
        configurer.setSaveAndRestore(true);
        configurer.setExitOnLastWindowClose(true);
    }

    @Override
    public void preStartup() {
        super.preStartup();

        CathyPlugin.getDefault().getLicenseAgent().addLicenseChangedListener(this);
        licenseChanged(CathyPlugin.getDefault().getLicenseAgent());

        /**
         * This hack requires workbench to exist. See
         * {@link org.eclipse.ui.internal.PlatformUIPreferenceListener}.
         */
        UIPlugin.getDefault().getPreferenceStore()
                .setValue(IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS, true);
    }

    @Override
    public void postStartup() {
        super.postStartup();

        IWorkbench workbench = getWorkbenchConfigurer().getWorkbench();

        AbstractWorkbookRef.setDefaultEditingContext(createDefaultEditingContext(workbench));

        new StartUpProcess(workbench).startUp();
    }

    private IEditingContext createDefaultEditingContext(final IWorkbench workbench) {
        final IMindMapPreviewGenerator previewGenerator = new DefaultMindMapPreviewGenerator(
                workbench.getDisplay());

        final IPasswordProvider passwordProvider = new PasswordProvider();

        return new IEditingContext() {
            public <T> T getAdapter(Class<T> adapter) {

                if (IMindMapPreviewGenerator.class.equals(adapter))
                    return adapter.cast(previewGenerator);

                if (IPasswordProvider.class.equals(adapter))
                    return adapter.cast(passwordProvider);

                T result;

                result = workbench.getService(adapter);
                if (result != null)
                    return result;

                result = workbench.getAdapter(adapter);
                if (result != null)
                    return result;

                return result;
            }
        };
    }

    @Override
    public void postShutdown() {
        CathyPlugin.getDefault().getLicenseAgent().removeLicenseChangedListener(this);

        AbstractWorkbookRef.setDefaultEditingContext(null);
        super.postShutdown();
    }

    public boolean preShutdown() {
        boolean readyToShutdown = super.preShutdown();
        if (readyToShutdown) {
            readyToShutdown = saveAllEditorsOnClose();
        }
        return readyToShutdown;
    }

    private boolean saveAllEditorsOnClose() {
        IWorkbench workbench = getWorkbenchConfigurer().getWorkbench();
        final ArrayList<IEditorReference> unClosedEditorRefs = new ArrayList<IEditorReference>();
        IWorkbenchWindow[] windows = workbench.getWorkbenchWindows();
        for (IWorkbenchWindow window : windows) {
            IWorkbenchPage page = window.getActivePage();
            for (IEditorReference editorRef : page.getEditorReferences()) {
                unClosedEditorRefs.add(editorRef);
                final IEditorPart editor = editorRef.getEditor(false);
                if (editor != null && editor.isDirty()) {
                    int answer = promptToSaveOnClose(window, page, editor);
                    if (answer == ISaveablePart2.CANCEL)
                        return false;
                    if (answer == ISaveablePart2.YES) {
                        if (!doSaveEditor(window, editor)) {
                            return false;
                        }
                    }
                }
            }
        }
        SafeRunner.run(new SafeRunnable() {
            public void run() {
                XMLMemento mem = recordEditorsState(unClosedEditorRefs);
                saveMementoToFile(mem);
            }
        });
        return closeAllEditors();
    }

    private XMLMemento recordEditorsState(ArrayList<IEditorReference> editorRefs) {
        XMLMemento memento = XMLMemento.createWriteRoot("xmind"); //$NON-NLS-1$
        saveEditorsState(memento, editorRefs);
        return memento;
    }

    private void saveEditorsState(IMemento memento, ArrayList<IEditorReference> editorRefs) {
        IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
        IEditorPart activeEditor = activePage.getActiveEditor();

        IMemento childrenMemento = memento.createChild(IWorkbenchConstants.TAG_EDITORS);
        if (!editorRefs.isEmpty())
            for (IEditorReference ref : editorRefs) {
                IEditorPart editor = ref.getEditor(false);
                IMemento editorMemento = childrenMemento.createChild(IWorkbenchConstants.TAG_EDITOR);
                editorMemento.putBoolean(IWorkbenchConstants.TAG_ACTIVE_PART, editor == activeEditor);
                IPersistable editorPersistable = CathyPlugin.getAdapter(editor, IPersistable.class);
                if (editorPersistable != null) {
                    editorPersistable.saveState(editorMemento);
                }

                IEditorInput input = editor.getEditorInput();
                IMemento inputMemento = editorMemento.createChild(IWorkbenchConstants.TAG_INPUT);
                IPersistableElement inputPersistable = CathyPlugin.getAdapter(input, IPersistableElement.class);
                if (inputPersistable != null) {
                    inputMemento.putString(IWorkbenchConstants.TAG_FACTORY_ID, inputPersistable.getFactoryId());
                    inputPersistable.saveState(inputMemento);
                }
            }
    }

    private boolean saveMementoToFile(XMLMemento memento) {
        // Save it to a file.
        File stateFile = getEditorsStateFile();
        if (stateFile == null) {
            return false;
        }
        try {
            FileOutputStream stream = new FileOutputStream(stateFile);
            OutputStreamWriter writer = new OutputStreamWriter(stream, "utf-8"); //$NON-NLS-1$
            memento.save(writer);
            writer.close();
        } catch (IOException e) {
            stateFile.delete();
            return false;
        }

        // Success !
        return true;
    }

    private File getEditorsStateFile() {
        IPath path = WorkbenchPlugin.getDefault().getDataLocation();
        if (path == null) {
            return null;
        }
        path = path.append("XMind_Editors.xml"); //$NON-NLS-1$
        return path.toFile();
    }

    private int promptToSaveOnClose(IWorkbenchWindow window, IWorkbenchPage page, IEditorPart editor) {
        if (editor instanceof ISaveablePart2) {
            int answer = ((ISaveablePart2) editor).promptToSaveOnClose();
            if (answer != ISaveablePart2.DEFAULT)
                return answer;
        }
        page.activate(editor);
        MessageDialog dialog = new MessageDialog(window.getShell(), DialogMessages.Save_title, null,
                NLS.bind(WorkbenchMessages.PromptSaveEditorOnClosing_message, editor.getTitle()),
                MessageDialog.QUESTION, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL,
                        IDialogConstants.CANCEL_LABEL },
                0);
        int answerIndex = dialog.open();
        switch (answerIndex) {
        case 0:
            return ISaveablePart2.YES;
        case 1:
            return ISaveablePart2.NO;
        default:
            return ISaveablePart2.CANCEL;
        }
    }

    private boolean doSaveEditor(final IWorkbenchWindow window, final IEditorPart editor) {
        final boolean[] saved = new boolean[1];
        saved[0] = false;
        window.getShell().getDisplay().syncExec(new Runnable() {
            public void run() {
                SafeRunner.run(new SafeRunnable() {
                    public void run() throws Exception {
                        final IProgressMonitor monitor = new NullProgressMonitor();
                        if (InternalCore.DEBUG_WORKBOOK_SAVE)
                            CathyPlugin.log("CathyWorkbenchAdvisor: About to save workbook on workbench close: " //$NON-NLS-1$
                                    + editor.getEditorInput().toString());
                        editor.doSave(monitor);
                        if (!monitor.isCanceled()) {
                            saved[0] = true;
                        } else {
                            if (InternalCore.DEBUG_WORKBOOK_SAVE)
                                CathyPlugin
                                        .log("CathyWorkbenchAdvisor: Finished saving workbook on workbench close: " //$NON-NLS-1$
                                                + editor.getEditorInput().toString());
                        }
                    }
                });
            }
        });
        return saved[0];
    }

    private boolean closeAllEditors() {
        boolean closed = false;
        IWorkbench workbench = getWorkbenchConfigurer().getWorkbench();
        for (IWorkbenchWindow window : workbench.getWorkbenchWindows()) {
            closed |= window.getActivePage().closeAllEditors(false);
        }
        return closed;
    }

    public void licenseChanged(ILicenseAgent agent) {
        int type = agent.getLicenseType();
        ILicenseKeyHeader header = agent.getLicenseKeyHeader();
        String brandingVersion = System.getProperty("org.xmind.product.brandingVersion", ""); //$NON-NLS-1$ //$NON-NLS-2$
        String licenseType;
        if ((type & ILicenseAgent.PRO_LICENSE_KEY) != 0) {
            licenseType = NLS.bind(WorkbenchMessages.About_ProTitle, brandingVersion);
        } else if ((type & ILicenseAgent.PLUS_LICENSE_KEY) != 0) {
            licenseType = NLS.bind(WorkbenchMessages.About_PlusTitle, brandingVersion);
        } else if ((type & ILicenseAgent.PRO_SUBSCRIPTION) != 0) {
            licenseType = WorkbenchMessages.About_ProSubscriptionTitle;
        } else {
            licenseType = null;
        }

        if (header != null
                && ((type & ILicenseAgent.PLUS_LICENSE_KEY) != 0 || (type & ILicenseAgent.PRO_LICENSE_KEY) != 0)) {
            String licenseeType = header.getLicenseeType();
            if (ILicenseKeyHeader.LICENSEE_FAMILY.equals(licenseeType)) {
                licenseType = NLS.bind("{0} (Family License)", licenseType); //$NON-NLS-1$
            } else if (ILicenseKeyHeader.LICENSEE_EDU.equals(licenseeType)) {
                licenseType = NLS.bind("{0} (Academia License)", licenseType); //$NON-NLS-1$
            } else if (ILicenseKeyHeader.LICENSEE_GOV.equals(licenseeType)) {
                licenseType = NLS.bind("{0} (Gov/NPO License)", licenseType); //$NON-NLS-1$
            } else if (ILicenseKeyHeader.LICENSEE_TEAM_5U.equals(licenseeType)
                    || ILicenseKeyHeader.LICENSEE_TEAM_10U.equals(licenseeType)
                    || ILicenseKeyHeader.LICENSEE_TEAM_20U.equals(licenseeType)) {
                licenseType = NLS.bind("{0} (Team License)", licenseType); //$NON-NLS-1$
            } else if (ILicenseKeyHeader.LICENSEE_VLE.equals(licenseeType)) {
                licenseType = NLS.bind("{0} (Volume License)", licenseType); //$NON-NLS-1$
            }
        }
        if (licenseType == null) {
            licenseType = WorkbenchMessages.About_LicenseType_Unactivated;
        } else {
            licenseType = NLS.bind(WorkbenchMessages.About_LicenseTypePattern, licenseType);
        }
        System.setProperty("org.xmind.product.license.type", //$NON-NLS-1$
                licenseType);

        String name = agent.getLicenseeName();
        if (name != null && !"".equals(name)) { //$NON-NLS-1$
            name = NLS.bind(WorkbenchMessages.About_LicensedTo, name);
        } else {
            name = ""; //$NON-NLS-1$
        }
        System.setProperty("org.xmind.product.license.licensee", name); //$NON-NLS-1$
    }

    @Override
    public void eventLoopIdle(Display display) {
        String[] paths = OpenDocumentQueue.getInstance().drain();
        if (paths.length > 0) {
            CathyPlugin.log("Ready to open files: " + Arrays.toString(paths)); //$NON-NLS-1$
            openFiles(paths);
            IWorkbenchWindow window = getWorkbenchConfigurer().getWorkbench().getActiveWorkbenchWindow();
            if (window != null) {
                Shell shell = window.getShell();
                if (shell != null && !shell.isDisposed()) {
                    shell.forceActive();
                }
            }
        } else {
            super.eventLoopIdle(display);
        }
    }

    private void openFiles(String[] paths) {
        OpenFilesJob job = new OpenFilesJob(getWorkbenchConfigurer().getWorkbench(),
                WorkbenchMessages.CheckOpenFilesJob_CheckFiles_name, Arrays.asList(paths));
        job.setRule(Log.get(Log.OPENING));
        job.schedule();
    }

}