ccw.editors.clojure.LoadFileAction.java Source code

Java tutorial

Introduction

Here is the source code for ccw.editors.clojure.LoadFileAction.java

Source

/*******************************************************************************
 * Copyright (c) 2009 Laurent Petit.
 * 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: 
 *    Laurent PETIT - initial API and implementation
 *******************************************************************************/
package ccw.editors.clojure;

import org.apache.commons.io.FilenameUtils;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.action.Action;
import org.eclipse.ui.ide.FileStoreEditorInput;

import ccw.CCWPlugin;
import ccw.ClojureCore;
import ccw.ClojureProject;
import ccw.TraceOptions;
import ccw.launching.ClojureLaunchShortcut;
import ccw.launching.ClojureLaunchShortcut.IWithREPLView;
import ccw.repl.Actions;
import ccw.repl.REPLView;
import ccw.util.ClojureInvoker;

public class LoadFileAction extends Action {

    private static ClojureInvoker nreplHelpers = ClojureInvoker.newInvoker(CCWPlugin.getDefault(),
            "clojure.tools.nrepl.helpers");

    public final static String ID = "LoadFileAction"; //$NON-NLS-1$

    private final ClojureEditor editor;

    public LoadFileAction(ClojureEditor editor) {
        super(ClojureEditorMessages.LoadFileAction_label);
        Assert.isNotNull(editor);
        this.editor = editor;
        setEnabled(true);
    }

    public void run() {
        run(editor, null /* default run mode */, false);
    }

    /**
     * @param editor the clojure editor
     * @param mode the "run" or "debug" launch mode
     */
    public static void run(final ClojureEditor editor, final String mode, boolean forceLeinLaunchWhenPossible) {
        final IFile editorFile = (IFile) editor.getEditorInput().getAdapter(IFile.class);

        final String filePath = computeFilePath(editor, editorFile);
        final String fileName = FilenameUtils.getName(filePath);

        if (filePath == null) {
            editor.setStatusLineErrorMessage("Unable to create a Clojure Application for this editor's content");
            return;
        }

        final String sourcePath = computeSourcePath(editor, editorFile, filePath);

        final REPLView repl = REPLView.activeREPL.get();
        if (repl != null && !repl.isDisposed()) {
            try {
                evaluateFileText(repl, editor.getDocument().get(), filePath, sourcePath, fileName);
            } catch (Exception e) {
                CCWPlugin.logError("Could not start a REPL for loading file " + filePath, e);
            }
        } else if (editorFile != null) {
            CCWPlugin.getTracer().trace(TraceOptions.LAUNCHER, "No active REPL found (",
                    (repl == null) ? "active repl is null" : "active repl is disposed",
                    "), so launching a new one");
            final IProject project = editorFile.getProject();
            new ClojureLaunchShortcut().launchProject(project, mode, forceLeinLaunchWhenPossible,
                    new IWithREPLView() {
                        @Override
                        public void run(final REPLView repl) {
                            if (repl != null && !repl.isDisposed()) {
                                try {
                                    evaluateFileText(repl, editor.getDocument().get(), filePath, sourcePath,
                                            fileName);
                                } catch (Exception e) {
                                    CCWPlugin.logError("Could not start a REPL for loading file " + filePath, e);
                                }
                                SwitchNamespaceAction.run(repl, editor, false);
                            } else {
                                CCWPlugin.logError("Could not start a REPL for loading file " + filePath);
                            }
                        }
                    });
        } else {
            editor.setStatusLineErrorMessage("Cannot start a REPL for loading " + fileName);
        }
    }

    private static String computeFilePath(final ClojureEditor editor, final IFile editorFile) {
        String filePath;
        if (editorFile != null) {
            filePath = editorFile.getLocation().toOSString();
        } else {
            FileStoreEditorInput fei = (FileStoreEditorInput) editor.getEditorInput();
            IPath path = URIUtil.toPath(fei.getURI());
            if (path != null) {
                filePath = path.toOSString();
            } else {
                filePath = null;
            }
        }
        return filePath;
    }

    // FIXME similar code in ClojureCore for finding classpath root related path
    private static String computeSourcePath(final ClojureEditor editor, final IFile editorFile, String filePath) {
        String sourcePath;
        if (editorFile != null) {
            ClojureProject proj = ClojureCore.getClojureProject(editor.getProject());
            String tempSourcePath = null;
            if (proj != null) {
                for (IFolder f : proj.sourceFolders()) {
                    if (f.getProjectRelativePath().isPrefixOf(editorFile.getProjectRelativePath())) {
                        tempSourcePath = editorFile.getProjectRelativePath()
                                .makeRelativeTo(f.getProjectRelativePath()).toOSString();
                        break;
                    }
                }
            }
            sourcePath = tempSourcePath != null ? tempSourcePath : filePath;
        } else { // (filesystemFile != null)
            // We cannot determine the source path, so let it be the full path
            sourcePath = filePath;
        }
        return sourcePath;
    }

    private static void evaluateFileText(REPLView repl, String text, String filePath, String sourcePath,
            String fileName) throws Exception {
        if (repl.getAvailableOperations().contains("load-file")) {
            repl.getConnection().sendSession(repl.getSessionId(), "op", "load-file", "file", text, "file-path",
                    sourcePath, "file-name", fileName);
        } else {
            String loadFileText = (String) nreplHelpers.__("load-file-command", text, sourcePath, fileName);
            EvaluateTextUtil.evaluateText(repl, ";; Loading file " + filePath, false);
            EvaluateTextUtil.evaluateText(repl, loadFileText, true);
        }
        Actions.ShowActiveREPL.execute(false);
    }
}