icy.icy4eclipse.core.Icy4EclipsePlugin.java Source code

Java tutorial

Introduction

Here is the source code for icy.icy4eclipse.core.Icy4EclipsePlugin.java

Source

/*
 * Copyright 2011 Nicolas Herv.
 * 
 * This file is part of Icy4Eclipse.
 * 
 * Icy4Eclipse is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Icy4Eclipse 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Icy4Eclipse. If not, see <http://www.gnu.org/licenses/>.
 */

package icy.icy4eclipse.core;

import java.io.File;
import java.io.FileFilter;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
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.Path;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.sourcelookup.ISourceContainer;
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
import org.eclipse.debug.core.sourcelookup.ISourcePathComputer;
import org.eclipse.debug.core.sourcelookup.containers.DefaultSourceContainer;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.launching.JavaSourceLookupDirector;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.sourcelookup.containers.JavaProjectSourceContainer;
import org.eclipse.jdt.launching.sourcelookup.containers.PackageFragmentRootSourceContainer;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.console.MessageConsoleStream;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;

/**
 * @author Nicolas Herv - n.herve@laposte.net
 * 
 */
public class Icy4EclipsePlugin extends AbstractUIPlugin implements Icy4EclipseCommonResources {
    private static Icy4EclipsePlugin plugin;

    public static void addIcyNature(IJavaProject project) throws CoreException {
        addNature(project.getProject(), ICY_NATURE_ID);
    }

    static void addNature(IProject proj, String nat) throws CoreException {
        IProjectDescription description = proj.getDescription();
        String[] prevNatures = description.getNatureIds();

        boolean hasNature = false;
        for (String n : prevNatures) {
            if (nat.equals(n)) {
                hasNature = true;
                break;
            }
        }

        if (!hasNature) {
            String[] newNatures = new String[prevNatures.length + 1];
            System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
            newNatures[prevNatures.length] = nat;
            description.setNatureIds(newNatures);
            proj.setDescription(description, null);
        }
    }

    static void checkIcyConfiguration() throws Icy4EclipseException {
        String hd = getIcyHomeDir();
        if ((hd == null) || (hd.length() == 0)) {
            throw new Icy4EclipseException("Check your parameters, you need to set the Icy home directory");
        }

        String dev = getIcyDeveloper();
        if ((dev == null) || (dev.length() == 0)) {
            throw new Icy4EclipseException("Check your parameters, you need to set the Icy developer login");
        }

        File setXML = new File(hd, ICY_SETTING_XML);
        File versXML = new File(hd, ICY_VERSION_XML);
        if (!(setXML.exists() && versXML.exists())) {
            throw new Icy4EclipseException("Check your parameters, unable to find standard Icy files ("
                    + ICY_SETTING_XML + ", " + ICY_VERSION_XML + ") in directory : " + hd);
        }
    }

    static IcyProject create(IJavaProject javaProject) {
        IcyProject result = null;
        try {
            result = (IcyProject) javaProject.getProject().getNature(ICY_NATURE_ID);
            if (result != null)
                result.setJavaProject(javaProject);
        } catch (CoreException ex) {
            logException(ex);
        }
        return result;
    }

    public static String fromPluginnameToClassname(String pluginname) {
        String classname = pluginname;
        int sz = classname.length();
        char[] asChar = new char[sz];
        classname.getChars(0, sz, asChar, 0);
        int idx = 0;
        boolean ucNext = true;
        classname = "";
        while (idx < sz) {
            if (asChar[idx] == ' ') {
                ucNext = true;
            } else {
                if (ucNext) {
                    classname += String.valueOf(asChar[idx]).toUpperCase();
                    ucNext = false;
                } else {
                    classname += asChar[idx];
                }
            }
            idx++;
        }
        return classname;
    }

    public static String fromPluginnameToPackagename(String pluginname) {
        String classname = pluginname;
        int sz = classname.length();
        char[] asChar = new char[sz];
        classname.getChars(0, sz, asChar, 0);
        int idx = 0;
        classname = "";
        while (idx < sz) {
            if (asChar[idx] != ' ') {
                classname += String.valueOf(asChar[idx]).toLowerCase();
            }
            idx++;
        }
        return classname;
    }

    public static String getFullPackageName(String devName, String subpackageName) {
        return ICY_PLUGINS_PACKAGE + "." + devName + "." + subpackageName;
    }

    public static Icy4EclipsePlugin getDefault() {
        return plugin;
    }

    public static IPreferenceStore getDefaultPreferenceStore() {
        return plugin.getPreferenceStore();
    }

    static String getIcyDeveloper() {
        IPreferenceStore pref = getDefaultPreferenceStore();
        return pref.getString(ICY4ECLIPSE_PREF_DEVELOPER_KEY);
    }

    static boolean loadIcyJar() {
        IPreferenceStore pref = getDefaultPreferenceStore();
        return pref.getBoolean(ICY4ECLIPSE_PREF_ICYJAR_KEY);
    }

    static String getIcyHomeDir() {
        IPath path = JavaCore.getClasspathVariable(ICY4ECLIPSE_HOME_VARIABLE);
        if (path == null) {
            return null;
        }
        return path.toOSString();
    }

    public static ImageDescriptor getImageDescriptor(String path) {
        return imageDescriptorFromPlugin(ICY4ECLIPSE_PLUGIN_ID, path);
    }

    public static void logError(String msg) {
        getDefault().log(msg, null, SWT.COLOR_RED);
    }

    public static void logException(Exception ex) {
        getDefault().log(ex.getClass().getName() + " : " + ex.getMessage(), ex, SWT.COLOR_RED);
    }

    public static void logInfo(String msg) {
        getDefault().log(msg, null, SWT.COLOR_BLACK);
    }

    static void removeIcyNature(IJavaProject project) {
        try {
            IProject proj = project.getProject();
            IProjectDescription description = proj.getDescription();
            String[] prevNatures = description.getNatureIds();

            int natureIndex = -1;
            for (int i = 0; i < prevNatures.length; i++) {
                if (prevNatures[i].equals(ICY_NATURE_ID)) {
                    natureIndex = i;
                    i = prevNatures.length;
                }
            }

            if (natureIndex != -1) {
                String[] newNatures = new String[prevNatures.length - 1];
                System.arraycopy(prevNatures, 0, newNatures, 0, natureIndex);
                System.arraycopy(prevNatures, natureIndex + 1, newNatures, natureIndex,
                        prevNatures.length - (natureIndex + 1));
                description.setNatureIds(newNatures);
                proj.setDescription(description, null);
            }
        } catch (CoreException ex) {
            logException(ex);
        }
    }

    static void setIcyHomeDir(String hd) {
        try {
            JavaCore.setClasspathVariable(ICY4ECLIPSE_HOME_VARIABLE, new Path(hd), null);
        } catch (JavaModelException e) {
            logException(e);
        }
    }

    public static void startIcy() {
        try {
            getDefault().startIcyInternal(false, true);
        } catch (CoreException e) {
            logException(e);
        }
    }

    public static void startIcyDebug() {
        try {
            getDefault().startIcyInternal(true, true);
        } catch (CoreException e) {
            logException(e);
        }
    }

    public static void startIcyUpdate() {
        try {
            getDefault().startIcyInternal(false, false);
        } catch (CoreException e) {
            logException(e);
        }
    }

    private IcyTemplateLocator templateLocator;

    public Icy4EclipsePlugin() {
        super();
    }

    private List<IcyProject> computeOpenIcyProjectsList() {
        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
        IProject[] allProjects = root.getProjects();

        ArrayList<IcyProject> tempList = new ArrayList<IcyProject>();

        for (int i = 0; i < allProjects.length; i++) {
            IProject project = allProjects[i];
            try {
                if ((project.isOpen()) && project.hasNature(ICY_NATURE_ID)) {
                    IcyProject p = create((IJavaProject) project.getNature(JavaCore.NATURE_ID));
                    tempList.add(p);
                }
            } catch (CoreException e) {
                logException(e);
            }
        }
        return tempList;

    }

    private List<File> getAllJarFiles(File root) {
        List<File> result = new ArrayList<File>();
        File[] temp = root.listFiles(new FileFilter() {
            @Override
            public boolean accept(File f) {
                return f.isDirectory() || f.getName().toUpperCase().endsWith(".JAR");
            }
        });
        for (File f : temp) {
            if (f.isDirectory()) {
                result.addAll(getAllJarFiles(f));
            } else {
                result.add(f);
            }
        }
        return result;
    }

    String getIcyMainClass() {
        IPreferenceStore pref = getPreferenceStore();
        return pref.getString(ICY4ECLIPSE_PREF_MAINCLASS_KEY);
    }

    String getIcyMemory() {
        IPreferenceStore pref = getPreferenceStore();
        return pref.getString(ICY4ECLIPSE_PREF_MEMORY_KEY);
    }

    String getOtherJVMArgs() {
        IPreferenceStore pref = getPreferenceStore();
        return pref.getString(ICY4ECLIPSE_PREF_OTHER_JVM_ARGS_KEY);
    }

    IcyTemplateLocator getTemplateLocator() {
        return templateLocator;
    }

    private void log(String msg, Exception ex, int color) {
        MessageConsole myConsole = null;
        ConsolePlugin plugin = ConsolePlugin.getDefault();
        IConsoleManager conMan = plugin.getConsoleManager();
        IConsole[] existing = conMan.getConsoles();
        for (int i = 0; i < existing.length; i++) {
            if (ICY4ECLIPSE_CONSOLE.equals(existing[i].getName())) {
                myConsole = (MessageConsole) existing[i];
            }
        }

        if (myConsole == null) {
            myConsole = new MessageConsole(ICY4ECLIPSE_CONSOLE, null);
            conMan.addConsoles(new IConsole[] { myConsole });
        }

        MessageConsoleStream out = myConsole.newMessageStream();
        out.setColor(Display.getCurrent().getSystemColor(color));
        out.println(msg);

        if (ex != null) {
            PrintStream ps = new PrintStream(out);
            ex.printStackTrace(ps);
        }

        myConsole.activate();
    }

    public void start(BundleContext context) throws Exception {
        super.start(context);

        context.registerService(IcyProjectTemplate.class.getName(), new DefaultIcyProjectTemplate(), null);

        plugin = this;
        templateLocator = new IcyTemplateLocator(context);
    }

    private void startIcyInternal(boolean debug, boolean bypassJarclassloader) throws CoreException {
        logInfo("Starting Icy - (debug = " + debug + ") (disableJCL = " + bypassJarclassloader + ")");

        // Check parameters
        try {
            checkIcyConfiguration();
        } catch (Icy4EclipseException e) {
            logException(e);
            return;
        }

        String hd = getIcyHomeDir();
        File pluginsDirectory = new File(hd, ICY_PLUGINS_DIR);
        List<IcyProject> icyProjects = computeOpenIcyProjectsList();
        List<String> classpath = new ArrayList<String>();

        // Add Icy jars to system class loader if needed
        if (loadIcyJar()) {
            for (String s : ICY_JARS) {
                classpath.add(hd + File.separator + s);
            }
        }

        if (bypassJarclassloader) {
            // Add Eclipse Icy projects to system class loader
            for (IcyProject p : icyProjects) {
                IJavaProject project = p.getJavaProject();
                for (String s : JavaRuntime.computeDefaultRuntimeClassPath(project)) {
                    classpath.add(s);
                }
            }

            // Add plugins jars to system class loader
            IPreferenceStore pref = getPreferenceStore();
            String bypassJars = pref.getString(ICY4ECLIPSE_PREF_BYPASS_JARS_KEY);
            List<Pattern> bypassRegexp = null;
            if (bypassJars != null) {
                bypassJars = bypassJars.trim();
                if (bypassJars.length() > 0) {
                    String[] bypass = bypassJars.split(":");
                    bypassRegexp = new ArrayList<Pattern>();
                    for (String r : bypass) {
                        bypassRegexp.add(Pattern.compile("^(.*)" + r + "$", Pattern.CASE_INSENSITIVE));
                    }
                }
            }

            if (pluginsDirectory.exists()) {
                List<File> jars = getAllJarFiles(pluginsDirectory);
                for (File f : jars) {
                    boolean add = true;
                    String path = f.getAbsolutePath();
                    if (bypassRegexp != null) {
                        for (Pattern p : bypassRegexp) {
                            Matcher m = p.matcher(path);
                            if (m.matches()) {
                                logInfo(" - bypassing jar : " + p.pattern() + " -> " + path);
                                add = false;
                                break;
                            }
                        }
                    }

                    if (add) {
                        classpath.add(path);
                    }
                }
            }
        }

        // Other launch arguments
        StringBuffer programArguments = new StringBuffer();
        for (String arg : ICY_PRG_ARGS) {
            programArguments.append(" " + arg);
        }
        if (bypassJarclassloader) {
            programArguments.append(" " + ICY_BYPASS_JARCLASSLOADER_ARG);
        }

        StringBuffer jvmArguments = new StringBuffer();
        for (String arg : ICY_VM_MANDATORY_ARGS) {
            jvmArguments.append(" " + arg);
        }
        jvmArguments.append(" -Xmx" + getIcyMemory() + "m");
        jvmArguments.append(" " + getOtherJVMArgs());

        // Launching the JVM
        ILaunchConfigurationType launchType = DebugPlugin.getDefault().getLaunchManager()
                .getLaunchConfigurationType("org.eclipse.jdt.launching.localJavaApplication");
        ILaunchConfigurationWorkingCopy config = launchType.newInstance(null, ICY4ECLIPSE_LABEL);
        config.setAttribute(IDebugUIConstants.ATTR_PRIVATE, false);
        config.setAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID,
                "org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector");

        if (bypassJarclassloader) {
            ISourceLookupDirector sourceLocator = new JavaSourceLookupDirector();
            ISourcePathComputer computer = DebugPlugin.getDefault().getLaunchManager()
                    .getSourcePathComputer("org.eclipse.jdt.launching.sourceLookup.javaSourcePathComputer");
            sourceLocator.setSourcePathComputer(computer);

            ArrayList<ISourceContainer> sourceContainers = new ArrayList<ISourceContainer>();

            if (!icyProjects.isEmpty()) {
                for (IcyProject ip : icyProjects) {
                    IJavaProject project = ip.getJavaProject();
                    sourceContainers.add(new JavaProjectSourceContainer(project));
                }

                Set<IPath> external = new HashSet<IPath>();

                for (IcyProject ip : icyProjects) {
                    IJavaProject project = ip.getJavaProject();

                    IPackageFragmentRoot[] roots = project.getPackageFragmentRoots();
                    for (int ri = 0; ri < roots.length; ri++) {
                        IPackageFragmentRoot root = roots[ri];
                        if (root.isExternal()) {
                            IPath location = root.getPath();
                            if (external.contains(location)) {
                                continue;
                            }
                            external.add(location);
                        }
                        sourceContainers.add(new PackageFragmentRootSourceContainer(root));
                    }
                }
            }

            sourceContainers.add(new DefaultSourceContainer());

            sourceLocator.setSourceContainers(
                    (ISourceContainer[]) sourceContainers.toArray(new ISourceContainer[sourceContainers.size()]));
            sourceLocator.initializeParticipants();
            config.setAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, sourceLocator.getMemento());
        }

        ArrayList<String> classpathMementos = new ArrayList<String>();
        for (String s : classpath) {
            IRuntimeClasspathEntry cpEntry = JavaRuntime.newArchiveRuntimeClasspathEntry(new Path(s));
            cpEntry.setClasspathProperty(IRuntimeClasspathEntry.USER_CLASSES);
            classpathMementos.add(cpEntry.getMemento());
        }

        IPath path = new Path(JavaRuntime.JRE_CONTAINER);
        try {
            IClasspathEntry cpEntry = JavaCore.newContainerEntry(path);
            IRuntimeClasspathEntry rcpEntry = JavaRuntime.newRuntimeContainerClasspathEntry(cpEntry.getPath(),
                    IRuntimeClasspathEntry.STANDARD_CLASSES);
            classpathMementos.add(rcpEntry.getMemento());
        } catch (CoreException ex) {
            logException(ex);
        }

        config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, false);
        config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH, classpathMementos);
        config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, programArguments.toString());
        config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, jvmArguments.toString());
        config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, getIcyMainClass());
        config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, getIcyHomeDir());

        logInfo(" - home dir   : " + getIcyHomeDir());
        logInfo(" - main class : " + getIcyMainClass());
        logInfo(" - prog args  : " + programArguments);
        logInfo(" - jvm args   : " + jvmArguments);
        logInfo(" - classpath  : " + classpath);

        config.launch(debug ? ILaunchManager.DEBUG_MODE : ILaunchManager.RUN_MODE, null);

    }

    public void stop(BundleContext context) throws Exception {
        plugin = null;
        super.stop(context);
    }
}