Package org.erlide.wrangler.refactoring.ui

Source Code of org.erlide.wrangler.refactoring.ui.AddRefacHandler

package org.erlide.wrangler.refactoring.ui;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.ui.PlatformUI;
import org.erlide.engine.ErlangEngine;
import org.erlide.engine.model.ErlModelException;
import org.erlide.engine.model.erlang.IErlAttribute;
import org.erlide.engine.model.erlang.IErlModule;
import org.erlide.engine.model.root.ErlElementKind;
import org.erlide.engine.model.root.IErlElement;
import org.erlide.engine.model.root.IErlProject;
import org.erlide.engine.services.parsing.ScannerService;
import org.erlide.wrangler.refactoring.Activator;
import org.erlide.wrangler.refactoring.backend.UserRefactoringsManager;
import org.erlide.wrangler.refactoring.backend.internal.WranglerBackendManager;
import org.erlide.wrangler.refactoring.ui.validator.IValidator;
import org.erlide.wrangler.refactoring.ui.validator.ModuleNameValidator;
import org.osgi.framework.Bundle;

/**
* Handler for adding user-defined refactorings to Wrangler
*
* @author Aleksandra Lipiec <aleksandra.lipiec@erlang-solutions.com>
* @version %I%, %G%
*/
public class AddRefacHandler extends AbstractHandler {

    @Override
    public Object execute(final ExecutionEvent event) throws ExecutionException {

        final InputDialog dialog = new InputDialog(PlatformUI.getWorkbench()
                .getActiveWorkbenchWindow().getShell(), "Add user-defined refactoring",
                "Please type callback module name!", "", new IInputValidator() {

                    public IValidator internalV = new ModuleNameValidator();

                    @Override
                    public String isValid(final String newText) {
                        if (internalV.isValid(newText)) {
                            return null;
                        }
                        return "Please type a correct module name!";
                    }
                });

        dialog.open();

        if (dialog.getReturnCode() == Window.CANCEL) {
            return null;
        }

        final String callbackModule = dialog.getValue();

        final RefacType type = checkType(callbackModule);
        if (type == null) {
            showErrorMesg("Callback module must implement either "
                    + "gen_refac or gen_composite_refac behaviour");
            return null;
        }

        if (!addAndLoad(callbackModule, type)) {
            showErrorMesg("Can not load callback module");
            return null;
        }
        if (type.equals(RefacType.ELEMENTARY)) {
            UserRefactoringsManager.getInstance().addMyElementary(callbackModule);
        } else {
            UserRefactoringsManager.getInstance().addMyComposite(callbackModule);
        }

        MessageDialog.openInformation(PlatformUI.getWorkbench()
                .getActiveWorkbenchWindow().getShell(), "Add user-defined refactoring",
                "Success!");

        return null;
    }

    private void showErrorMesg(final String mesg) {
        MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow()
                .getShell(), "Add user-defined refactoring  - error", mesg);
    }

    // check if the refactoring is elementary or composite
    private RefacType checkType(final String callbackModule) {

        try {
            final IErlModule module = ErlangEngine.getInstance().getModel()
                    .findModule(callbackModule);
            final ScannerService scanner = module.getScanner();
            try {
                module.resetAndCacheScannerAndParser(null);
            } finally {
                scanner.dispose();
            }

            for (final IErlElement el : module
                    .getChildrenOfKind(ErlElementKind.ATTRIBUTE)) {
                final IErlAttribute attr = (IErlAttribute) el;
                if (attr.getName().equals("behaviour")
                        || attr.getName().equals("behavior")) {
                    if (attr.getValue().toString().contains("gen_refac")) {
                        return RefacType.ELEMENTARY;
                    } else if (attr.getValue().toString().contains("gen_composite_refac")) {
                        return RefacType.COMPOSITE;
                    }
                }
            }
            return null;

        } catch (final ErlModelException e) {
            return null;
        }
    }

    // look for module path
    private boolean addAndLoad(final String callbackModule, final RefacType type) {

        final String sourcePath = getBinPath(callbackModule);

        final IPath destDir = getDestDir(type);
        final String destPath = getDestPath(callbackModule, destDir);
        String destDirStr = destDir.toOSString();
        destDirStr = destDirStr.substring(destDirStr.lastIndexOf(":") + 1);

        if (sourcePath == null || destPath == null
                || copy(sourcePath, destPath, destDirStr)) {
            load(callbackModule, destDirStr);
        } else {
            return false;
        }

        return true;
    }

    // gets original binary path
    private String getBinPath(final String callbackModule) {
        String path;

        try {
            if (ErlangEngine.getInstance().getModel().findModule(callbackModule) == null) {
                return null;
            }

            final IErlProject project = ErlangEngine
                    .getInstance()
                    .getModelUtilService()
                    .getProject(
                            ErlangEngine.getInstance().getModel()
                                    .findModule(callbackModule));
            path = project.getWorkspaceProject().getLocation()
                    .append(project.getProperties().getOutputDir())
                    .append(callbackModule + ".beam").toOSString();

            return path;

        } catch (final ErlModelException e) {
            return null;
        }
    }

    // destination directory
    private IPath getDestDir(final RefacType type) {
        final Bundle coreBundle = Platform.getBundle(Activator.CORE_ID);
        return new Path(coreBundle.getLocation()).append("wrangler").append("ebin")
                .append(type.getDirName());
    }

    // destination path
    private String getDestPath(final String callbackModule, final IPath dir) {
        String path = dir.append(callbackModule + ".beam").toOSString();
        path = path.substring(path.lastIndexOf(':') + 1);
        return path;
    }

    // copying files
    private boolean copy(final String source, final String dest, final String destDir) {

        final File dir = new File(destDir);
        if (!dir.exists()) {
            if (!dir.mkdir()) {
                return false;
            }
        }

        InputStream in = null;
        OutputStream out = null;
        try {
            in = new FileInputStream(source);
            out = new FileOutputStream(dest);
            final byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
        } catch (final IOException e) {
            return false;
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (final IOException ignore) {
            }
            try {
                if (out != null) {
                    out.close();
                }
            } catch (final IOException ignore) {
            }
        }
        return true;
    }

    // invoke loading module
    private void load(final String callbackModule, final String dir) {
        WranglerBackendManager.getRefactoringBackend().callWithoutParser(
                "load_callback_mod_eclipse", "ss", callbackModule, dir);
    }

    /**
     * enum for refactoring types - defining refactoring folders
     *
     * @author Aleksandra Lipiec <aleksandra.lipiec@erlang-solutions.com>
     * @version %I%, %G%
     */
    private enum RefacType {
        ELEMENTARY("my_gen_refac"), COMPOSITE("my_gen_composite_refac");

        private final String dir;

        private RefacType(final String dir) {
            this.dir = dir;
        }

        public String getDirName() {
            return dir;
        }
    }

}
TOP

Related Classes of org.erlide.wrangler.refactoring.ui.AddRefacHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.