Package org.apache.felix.sigil.eclipse

Source Code of org.apache.felix.sigil.eclipse.SigilCore

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.felix.sigil.eclipse;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.felix.sigil.common.config.IBldProject;
import org.apache.felix.sigil.common.core.BldCore;
import org.apache.felix.sigil.common.model.ICapabilityModelElement;
import org.apache.felix.sigil.common.model.eclipse.ISigilBundle;
import org.apache.felix.sigil.common.repository.IBundleRepository;
import org.apache.felix.sigil.common.repository.IRepositoryManager;
import org.apache.felix.sigil.common.repository.IRepositoryVisitor;
import org.apache.felix.sigil.common.repository.ResolutionConfig;
import org.apache.felix.sigil.eclipse.install.IOSGiInstallManager;
import org.apache.felix.sigil.eclipse.internal.install.OSGiInstallManager;
import org.apache.felix.sigil.eclipse.internal.model.project.SigilModelRoot;
import org.apache.felix.sigil.eclipse.internal.model.repository.RepositoryPreferences;
import org.apache.felix.sigil.eclipse.internal.repository.manager.GlobalRepositoryManager;
import org.apache.felix.sigil.eclipse.internal.repository.manager.IEclipseBundleRepository;
import org.apache.felix.sigil.eclipse.internal.repository.manager.RepositoryCache;
import org.apache.felix.sigil.eclipse.internal.resources.ProjectResourceListener;
import org.apache.felix.sigil.eclipse.internal.resources.SigilProjectManager;
import org.apache.felix.sigil.eclipse.model.project.ISigilModelRoot;
import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
import org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel;
import org.apache.felix.sigil.eclipse.model.repository.IRepositoryPreferences;
import org.apache.felix.sigil.eclipse.model.util.JavaHelper;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IncrementalProjectBuilder;
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.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;

/**
* The activator class controls the plug-in life cycle
*/
public class SigilCore extends AbstractUIPlugin
{

    private static final String BASE = "org.apache.felix.sigil";
    // The plug-in ID
    public static final String PLUGIN_ID = BASE + ".eclipse.core";
    public static final String NATURE_ID = BASE + ".sigilnature";
    public static final String PREFERENCES_ID = BASE
        + ".ui.preferences.SigilPreferencePage";
    public static final String OSGI_INSTALLS_PREFERENCES_ID = BASE
        + ".ui.preferences.osgiInstalls";
    public static final String EXCLUDED_RESOURCES_PREFERENCES_ID = BASE
        + ".ui.preferences.excludedResources";
    public static final String REPOSITORIES_PREFERENCES_ID = BASE
        + ".ui.preferences.repositoriesPreferencePage";
    public static final String SIGIL_PROJECT_FILE = IBldProject.PROJECT_FILE;
    public static final String BUILDER_ID = PLUGIN_ID + ".sigilBuilder";
    public static final String CLASSPATH_CONTAINER_PATH = BASE + ".classpathContainer";

    public static final String OSGI_INSTALLS = BASE + ".osgi.installs";
    public static final String OSGI_DEFAULT_INSTALL_ID = BASE
        + ".osgi.default.install.id";
    public static final String OSGI_INSTALL_PREFIX = BASE + ".osgi.install.";
    public static final String OSGI_SOURCE_LOCATION = BASE + ".osgi.source.location";
    public static final String OSGI_INSTALL_CHECK_PREFERENCE = BASE
        + ".osgi.install.check";
    public static final String LIBRARY_KEYS_PREF = BASE + ".library.keys";
    public static final String PREFERENCES_REBUILD_PROJECTS = BASE + ".rebuild.projects";
    public static final String QUALIFY_VERSIONS = BASE + ".qualify.versions";

    public static final String DEFAULT_VERSION_LOWER_BOUND = BASE + ".versionLowerBound";
    public static final String DEFAULT_VERSION_UPPER_BOUND = BASE + ".versionUpperBound";

    public static final String DEFAULT_EXCLUDED_RESOURCES = BASE + ".excludedResources";
    public static final String INCLUDE_OPTIONAL_DEPENDENCIES = BASE
        + ".includeOptionalDependencies";

    public static final String INSTALL_BUILDER_EXTENSION_POINT_ID = BASE
        + ".installbuilder";
    public static final String REPOSITORY_PROVIDER_EXTENSION_POINT_ID = BASE
        + ".repositoryprovider";

    public static final String MARKER_UNRESOLVED_DEPENDENCY = BASE
        + ".unresolvedDependencyMarker";
    public static final String MARKER_UNRESOLVED_IMPORT_PACKAGE = BASE
        + ".unresolvedDependencyMarker.importPackage";
    public static final String MARKER_UNRESOLVED_REQUIRE_BUNDLE = BASE
        + ".unresolvedDependencyMarker.requireBundle";
    public static final String REPOSITORY_SET = PLUGIN_ID + ".repository.set";

    public static final String PREFERENCES_NOASK_OSGI_INSTALL = BASE + ".noAskOSGIHome";
    public static final String PREFERENCES_ADD_IMPORT_FOR_EXPORT = BASE
        + ".addImportForExport";
    public static final String PREFERENCES_INCLUDE_OPTIONAL = PLUGIN_ID
        + ".include.optional";
    public static final String PREFERENCES_REMOVE_IMPORT_FOR_EXPORT = BASE
        + ".removeImportForExport";

    // The shared instance
    private static SigilCore plugin;

    private static RepositoryPreferences repositoryPrefs;
    private static SigilProjectManager projectManager;
    private static OSGiInstallManager installs;
    private static ISigilModelRoot modelRoot;
    private static GlobalRepositoryManager globalRepositoryManager;

    /**
     * Returns the shared instance
     *
     * @return the shared instance
     */
    public static SigilCore getDefault()
    {
        return plugin;
    }

    public static CoreException newCoreException(String msg, Throwable t)
    {
        return new CoreException(makeStatus(msg, t, IStatus.ERROR));
    }

    public static void log(String msg)
    {
        DebugPlugin.log(makeStatus(msg, null, IStatus.INFO));
    }

    public static void error(String msg)
    {
        DebugPlugin.log(makeStatus(msg, null, IStatus.ERROR));
    }

    public static void error(String msg, Throwable t)
    {
        DebugPlugin.log(makeStatus(msg, t, IStatus.ERROR));
    }

    public static void warn(String msg)
    {
        DebugPlugin.log(makeStatus(msg, null, IStatus.WARNING));
    }

    public static void warn(String msg, Throwable t)
    {
        DebugPlugin.log(makeStatus(msg, t, IStatus.WARNING));
    }

    private static IStatus makeStatus(String msg, Throwable t, int status)
    {
        if (t instanceof CoreException)
        {
            CoreException c = (CoreException) t;
            return c.getStatus();
        }
        else
        {
            return new Status(status, SigilCore.PLUGIN_ID, status, msg, t);
        }
    }

    public static boolean isSigilProject(IProject resource)
    {
        if (resource == null)
            return false;

        if (resource.isAccessible() && resource instanceof IProject)
        {
            IProject project = (IProject) resource;
            try
            {
                return project.hasNature(NATURE_ID);
            }
            catch (CoreException e)
            {
                error(e.getMessage(), e);
                return false;
            }
        }
        else
        {
            return false;
        }
    }

    public static boolean hasProjectNature(IProject project) throws CoreException
    {
        return project.getNature(NATURE_ID) != null;
    }

    public static ResourceBundle getResourceBundle()
    {
        return ResourceBundle.getBundle("resources." + SigilCore.class.getName(),
            Locale.getDefault(), SigilCore.class.getClassLoader());
    }

    public static ISigilProjectModel create(IProject project) throws CoreException
    {
        return projectManager.getSigilProject(project);
    }

    /**
     * The constructor
     */
    public SigilCore()
    {
        plugin = this;
    }

    public void earlyStartup()
    {
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
     * )
     */
    public void start(final BundleContext context) throws Exception
    {
        super.start(context);

        RepositoryCache repositoryCache = new RepositoryCache();
        projectManager = new SigilProjectManager(repositoryCache);

        modelRoot = new SigilModelRoot();

        installs = new OSGiInstallManager();

        repositoryPrefs = new RepositoryPreferences();
        globalRepositoryManager = new GlobalRepositoryManager(repositoryCache);
        globalRepositoryManager.initialise();

        registerModelElements(context);
        registerResourceListeners();
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
     * )
     */
    public void stop(BundleContext context) throws Exception
    {
        globalRepositoryManager.destroy();
        globalRepositoryManager = null;
       
        projectManager.destroy();
        projectManager = null;

        plugin = null;

        super.stop(context);
    }

    public static boolean isBundledPath(String bp) throws CoreException
    {
        boolean bundle = JavaHelper.isCachedBundle(bp);

        if (!bundle)
        {
            bundle = isProjectPath(bp);

            if (!bundle)
            {
                for (IBundleRepository r : getGlobalRepositoryManager().getRepositories())
                {
                    bundle = isBundlePath(bp, r);
                    if (bundle)
                        break;
                }
            }
        }

        return bundle;
    }

    private static boolean isBundlePath(final String bp, IBundleRepository r)
    {
        final AtomicBoolean flag = new AtomicBoolean();

        IRepositoryVisitor visitor = new IRepositoryVisitor()
        {
            public boolean visit(ISigilBundle b)
            {
                File path = b.getLocation();
                if (path != null && path.getAbsolutePath().equals(bp))
                {
                    flag.set(true);
                    return false;
                }
                else
                {
                    return true;
                }
            }

        };

        r.accept(visitor, ResolutionConfig.INDEXED_ONLY | ResolutionConfig.LOCAL_ONLY);

        return flag.get();
    }

    private static boolean isProjectPath(String bp) throws CoreException
    {
        for (ISigilProjectModel p : SigilCore.getRoot().getProjects())
        {
            IPath path = p.findOutputLocation();

            if (path.toOSString().equals(bp))
            {
                return true;
            }
        }

        return false;
    }

    private void registerResourceListeners()
    {
        Job job = new Job("Initialising sigil resource listeners")
        {
            @Override
            protected IStatus run(IProgressMonitor monitor)
            {
                ResourcesPlugin.getWorkspace().addResourceChangeListener(
                    new ProjectResourceListener(projectManager),
                    ProjectResourceListener.EVENT_MASKS);
                return Status.OK_STATUS;
            }
        };
        job.setSystem(true);
        job.schedule();
    }

    private void registerModelElements(BundleContext context)
    {
        // trick to get eclipse to lazy load BldCore for model elements
        BldCore.getLicenseManager();
    }

    public static IOSGiInstallManager getInstallManager()
    {
        return installs;
    }

    public static ISigilModelRoot getRoot()
    {
        return modelRoot;
    }

    public static IRepositoryManager getGlobalRepositoryManager()
    {
        return globalRepositoryManager;
    }

    public static IRepositoryManager getRepositoryManager(ISigilProjectModel model)
    {
        if ( model == null ) return globalRepositoryManager;
        try
        {
            return projectManager.getRepositoryManager(model);
        }
        catch (CoreException e)
        {
            SigilCore.error("Failed to read repository config", e);
            return globalRepositoryManager;
        }       
    }
   
    /**
     * @param rep
     * @return
     */
    public static IRepositoryModel getRepositoryModel(IBundleRepository rep)
    {
        IEclipseBundleRepository cast = (IEclipseBundleRepository) rep;
        return cast.getModel();
    }   

    public static IRepositoryPreferences getRepositoryPreferences()
    {
        return repositoryPrefs;
    }

    public static void rebuildAllBundleDependencies(IProgressMonitor monitor)
    {
        Collection<ISigilProjectModel> projects = getRoot().getProjects();
       
        if (!projects.isEmpty())
        {
            SubMonitor progress = SubMonitor.convert(monitor, projects.size() * 20);
            for (ISigilProjectModel p : projects)
            {
                rebuild(p, progress);
            }
        }

        monitor.done();
    }

    public static void rebuildBundleDependencies(ISigilProjectModel project,
        Collection<ICapabilityModelElement> caps, IProgressMonitor monitor)
    {
        Set<ISigilProjectModel> affected = SigilCore.getRoot().resolveDependentProjects(
            caps, monitor);

        if (project != null)
        {
            affected.remove(project);
        }

        SubMonitor progress = SubMonitor.convert(monitor, affected.size() * 20);
        for (ISigilProjectModel dependent : affected)
        {
            //dependent.flushDependencyState();
            rebuild(dependent, progress);
        }
    }

    public static void rebuild(ISigilProjectModel dependent, SubMonitor progress)
    {
        try
        {
            dependent.resetClasspath(progress.newChild(10), false);
            dependent.getProject().build(IncrementalProjectBuilder.FULL_BUILD,
                progress.newChild(10));
        }
        catch (CoreException e)
        {
            SigilCore.error("Failed to rebuild " + dependent, e);
        }
    }

    public IPath findDefaultBundleLocation(ISigilProjectModel m) throws CoreException
    {
        IPath loc = m.getProject().getLocation();
        loc = loc.append(m.getJavaModel().getOutputLocation().removeFirstSegments(1));
        loc = loc.removeLastSegments(1).append("lib");
        return loc.append(m.getSymbolicName() + ".jar");
    }

    public static void makeSigilProject(IProject project, IProgressMonitor monitor)
        throws CoreException
    {
        IProjectDescription description = project.getDescription();

        String[] natures = description.getNatureIds();
        String[] newNatures = new String[natures.length + 1];
        System.arraycopy(natures, 0, newNatures, 0, natures.length);
        newNatures[natures.length] = SigilCore.NATURE_ID;
        description.setNatureIds(newNatures);

        ICommand sigilBuild = description.newCommand();
        sigilBuild.setBuilderName(SigilCore.BUILDER_ID);

        ICommand javaBuild = description.newCommand();
        javaBuild.setBuilderName(JavaCore.BUILDER_ID);

        description.setBuildSpec(new ICommand[] { javaBuild, sigilBuild });

        project.setDescription(description, new SubProgressMonitor(monitor, 2));

        IJavaProject java = JavaCore.create(project);
        if (java.exists())
        {
            IClasspathEntry[] cp = java.getRawClasspath();
            // check if sigil container is already on classpath - if not add it
            if (!isSigilOnClasspath(cp))
            {
                ArrayList<IClasspathEntry> entries = new ArrayList<IClasspathEntry>(
                    Arrays.asList(cp));
                entries.add(JavaCore.newContainerEntry(new Path(
                    SigilCore.CLASSPATH_CONTAINER_PATH)));
                java.setRawClasspath(
                    entries.toArray(new IClasspathEntry[entries.size()]), monitor);
            }
        }
    }

    /**
     * @param cp
     * @return
     */
    private static boolean isSigilOnClasspath(IClasspathEntry[] cp)
    {
        for (IClasspathEntry e : cp)
        {
            if (e.getEntryKind() == IClasspathEntry.CPE_CONTAINER
                && e.getPath().segment(0).equals(SigilCore.CLASSPATH_CONTAINER_PATH))
            {
                return true;
            }
        }
        return false;
    }

    public static Image loadImage(URL url) throws IOException
    {
        ImageRegistry registry = getDefault().getImageRegistry();

        String key = url.toExternalForm();
        Image img = registry.get(key);

        if (img == null)
        {
            img = openImage(url);
            registry.put(key, img);
        }

        return img;
    }

    private static Image openImage(URL url) throws IOException
    {
        Display display = Display.getCurrent();
        if (display == null)
        {
            display = Display.getDefault();
        }

        InputStream in = null;
        try
        {
            in = url.openStream();
            return new Image(display, in);
        }
        finally
        {
            if (in != null)
            {
                try
                {
                    in.close();
                }
                catch (IOException e)
                {
                    error("Failed to close stream", e);
                }
            }
        }
    }
}
TOP

Related Classes of org.apache.felix.sigil.eclipse.SigilCore

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.