com.aptana.ide.update.eclipse36.P2Eclipse36PluginManager.java Source code

Java tutorial

Introduction

Here is the source code for com.aptana.ide.update.eclipse36.P2Eclipse36PluginManager.java

Source

/**
 * This file Copyright (c) 2005-2010 Aptana, Inc. This program is
 * dual-licensed under both the Aptana Public License and the GNU General
 * Public license. You may elect to use one or the other of these licenses.
 * 
 * This program is distributed in the hope that it will be useful, but
 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
 * NONINFRINGEMENT. Redistribution, except as permitted by whichever of
 * the GPL or APL you select, is prohibited.
 *
 * 1. For the GPL license (GPL), you can redistribute and/or modify this
 * program under the terms of the GNU General Public License,
 * Version 3, as published by the Free Software Foundation.  You should
 * have received a copy of the GNU General Public License, Version 3 along
 * with this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 * 
 * Aptana provides a special exception to allow redistribution of this file
 * with certain Eclipse Public Licensed code and certain additional terms
 * pursuant to Section 7 of the GPL. You may view the exception and these
 * terms on the web at http://www.aptana.com/legal/gpl/.
 * 
 * 2. For the Aptana Public License (APL), this program and the
 * accompanying materials are made available under the terms of the APL
 * v1.0 which accompanies this distribution, and is available at
 * http://www.aptana.com/legal/apl/.
 * 
 * You may view the GPL, Aptana's exception and additional terms, and the
 * APL in the file titled license.html at the root of the corresponding
 * plugin containing this source file.
 * 
 * Any modifications to this file must keep this entire header intact.
 */
package com.aptana.ide.update.eclipse36;

import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
import org.eclipse.equinox.internal.p2.ui.ProvUIActivator;
import org.eclipse.equinox.internal.p2.ui.sdk.scheduler.AutomaticUpdatePlugin;
import org.eclipse.equinox.internal.p2.ui.sdk.scheduler.PreferenceConstants;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.engine.IProfile;
import org.eclipse.equinox.p2.engine.IProfileRegistry;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.operations.InstallOperation;
import org.eclipse.equinox.p2.operations.UninstallOperation;
import org.eclipse.equinox.p2.query.IQuery;
import org.eclipse.equinox.p2.query.IQueryResult;
import org.eclipse.equinox.p2.query.QueryUtil;
import org.eclipse.equinox.p2.repository.IRepositoryManager;
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository;
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
import org.eclipse.equinox.p2.ui.ProvisioningUI;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.widgets.Display;

import com.aptana.ide.core.IdeLog;
import com.aptana.ide.internal.update.manager.AbstractPluginManager;
import com.aptana.ide.update.manager.IPlugin;
import com.aptana.ide.update.manager.Plugin;
import com.aptana.ide.update.manager.PluginManagerException;

@SuppressWarnings("restriction")
public class P2Eclipse36PluginManager extends AbstractPluginManager {
    public P2Eclipse36PluginManager() {
    }

    /**
     * @see com.aptana.ide.update.manager.IPluginManager#addUpdateSite(java.net.URL)
     */
    public boolean addUpdateSite(URL siteURL) {
        try {
            URI siteURI = siteURL.toURI();

            ProvisioningUI ui = ProvUIActivator.getDefault().getProvisioningUI();
            URI[] existingMetaRepos = ui.getRepositoryTracker().getKnownRepositories(null);
            if (contains(existingMetaRepos, siteURI)) {
                return false;
            }
            ui.getRepositoryTracker().addRepository(siteURI, null, null);
            return true;
        } catch (Exception e) {
            // ignores the exception
        }
        return false;
    }

    /**
     * @see com.aptana.ide.update.manager.IPluginManager#removeUpdateSite(java.net.URL)
     */
    public void removeUpdateSite(URL siteURL) {
        try {
            URI siteURI = siteURL.toURI();

            ProvisioningUI ui = ProvUIActivator.getDefault().getProvisioningUI();
            ui.getRepositoryTracker().removeRepositories(new URI[] { siteURI }, null);
        } catch (Exception e) {
            // ignores the exception
        }
    }

    /**
     * @see com.aptana.ide.update.manager.IPluginManager#checkForUpdates(boolean)
     */
    public void checkForUpdates(boolean immediate) {
        if (!immediate) {
            AutomaticUpdatePlugin.getDefault().getScheduler().earlyStartup();
            return;
        }
        // Force the P2 automatic update check pref to be turned on, and force a
        // reschedule of the update check
        IPreferenceStore prefs = AutomaticUpdatePlugin.getDefault().getPreferenceStore();
        // Grab existing values
        boolean wasEnabled = prefs.getBoolean(PreferenceConstants.PREF_AUTO_UPDATE_ENABLED);
        String oldSchedule = prefs.getString(PreferenceConstants.PREF_AUTO_UPDATE_SCHEDULE);
        // Force new ones temporarily
        prefs.setValue(PreferenceConstants.PREF_AUTO_UPDATE_ENABLED, true);
        prefs.setValue(PreferenceConstants.PREF_AUTO_UPDATE_SCHEDULE, PreferenceConstants.PREF_UPDATE_ON_STARTUP);
        AutomaticUpdatePlugin.getDefault().savePreferences();
        // now check for updates
        AutomaticUpdatePlugin.getDefault().getScheduler().earlyStartup();
        // Now revert prefs
        prefs.setValue(PreferenceConstants.PREF_AUTO_UPDATE_ENABLED, wasEnabled);
        prefs.setValue(PreferenceConstants.PREF_AUTO_UPDATE_SCHEDULE, oldSchedule);
        AutomaticUpdatePlugin.getDefault().savePreferences();
    }

    /**
     * @see com.aptana.ide.update.manager.IPluginManager#install(Plugin[], IProgressMonitor)
     */
    public IStatus install(final IPlugin[] plugins, IProgressMonitor monitor) throws PluginManagerException {
        if (monitor == null) {
            monitor = new NullProgressMonitor();
        }
        if (monitor.isCanceled()) {
            return Status.CANCEL_STATUS;
        }

        String profileId = IProfileRegistry.SELF;
        IInstallableUnit[] toInstall = getInstallationUnits(plugins, profileId);
        if (toInstall.length <= 0) {
            throw new PluginManagerException(
                    P2Eclipse36Messages.P2PluginManager_ERR_MSG_No_installable_units_found);
        }

        if (monitor.isCanceled()) {
            return Status.CANCEL_STATUS;
        }

        Collection<IInstallableUnit> units = Arrays.asList(toInstall);
        ProvisioningUI ui = ProvUIActivator.getDefault().getProvisioningUI();
        InstallOperation op = ui.getInstallOperation(units, getURIs(plugins));
        ui.openInstallWizard(units, op, null);

        return Status.OK_STATUS;
    }

    private URI[] getURIs(IPlugin[] plugins) {
        List<URI> uris = new ArrayList<URI>();
        for (IPlugin plugin : plugins) {
            try {
                uris.add(plugin.getURL().toURI());
            } catch (URISyntaxException e) {
                IdeLog.logError(Activator.getDefault(), e.getMessage(), e);
            }
        }
        return uris.toArray(new URI[0]);
    }

    /**
     * @see com.aptana.ide.update.manager.IPluginManager#uninstall(IPlugin, IProgressMonitor)
     */
    public IStatus uninstall(IPlugin plugin, IProgressMonitor monitor) throws PluginManagerException {
        if (monitor.isCanceled()) {
            return Status.CANCEL_STATUS;
        }

        IQueryResult<IInstallableUnit> result = null;
        try {
            IQuery<IInstallableUnit> query = QueryUtil.createIUQuery(getFeatureGroupName(plugin),
                    Version.parseVersion(plugin.getVersion()));
            IProfile profile = getProfile(IProfileRegistry.SELF);
            result = profile.query(query, monitor);
        } catch (CoreException e) {
            IdeLog.logError(Activator.getDefault(), e.getMessage(), e);
        }

        if (result == null || result.isEmpty()) {
            throw new PluginManagerException(
                    P2Eclipse36Messages.P2PluginManager_ERR_MSG_No_installable_units_found);
        }
        final IInstallableUnit[] ius = result.toArray(IInstallableUnit.class);

        if (monitor.isCanceled()) {
            return Status.CANCEL_STATUS;
        }

        ProvisioningUI ui = ProvUIActivator.getDefault().getProvisioningUI();
        Collection<IInstallableUnit> units = Arrays.asList(ius);
        UninstallOperation op = ui.getUninstallOperation(units, null);
        ui.openUninstallWizard(units, op, null);

        return Status.OK_STATUS;
    }

    protected static IProfile getProfile(String self) {
        IProfileRegistry profileRegistry = getProfileRegistry();
        if (profileRegistry == null)
            return null;

        return profileRegistry.getProfile(self);
    }

    private static boolean contains(URI[] existingMetaRepos, URI updateSiteURI) {
        if (existingMetaRepos == null) {
            return false;
        }
        for (int i = 0; i < existingMetaRepos.length; ++i) {
            if (existingMetaRepos[i].equals(updateSiteURI)) {
                return true;
            }
        }
        return false;
    }

    private static IInstallableUnit[] getInstallationUnits(final IPlugin[] plugins, final String profileId)
            throws PluginManagerException {
        final List<IInstallableUnit> units = new ArrayList<IInstallableUnit>();

        IRunnableWithProgress runnable = new IRunnableWithProgress() {

            public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                SubMonitor sub = SubMonitor.convert(monitor, plugins.length * 4);
                sub.setTaskName(P2Eclipse36Messages.P2PluginManager_Locating_selected_features_job_title);
                try {
                    for (IPlugin plugin : plugins) {
                        URI siteURL = plugin.getURL().toURI();

                        IMetadataRepositoryManager manager = getMetadataRepositoryManager();
                        IMetadataRepository repo = manager.loadRepository(siteURL, sub.newChild(1));
                        if (repo == null) {
                            throw new ProvisionException(
                                    P2Eclipse36Messages.P2PluginManager_ERR_MSG_Metadata_repo_not_found + siteURL);
                        }
                        if (!manager.isEnabled(siteURL)) {
                            manager.setEnabled(siteURL, true);
                        }

                        IArtifactRepositoryManager artifactManager = getArtifactRepositoryManager();
                        IArtifactRepository artifactRepo = artifactManager.loadRepository(siteURL, sub.newChild(1));
                        if (artifactRepo == null) {
                            throw new ProvisionException(
                                    P2Eclipse36Messages.P2PluginManager_ERR_MSG_Artifact_repo_not_found + siteURL);
                        }
                        if (!artifactManager.isEnabled(siteURL)) {
                            artifactManager.setEnabled(siteURL, true);
                        }

                        IQuery<IInstallableUnit> query = QueryUtil.createIUQuery(getFeatureGroupName(plugin));
                        query = QueryUtil.createLatestQuery(query);
                        IQueryResult<IInstallableUnit> roots = repo.query(query, sub.newChild(2));

                        if (roots.isEmpty()) {
                            if (monitor.isCanceled()) {
                                return;
                            }

                            IProfile profile = getProfile(profileId);
                            if (profile == null) {
                                profile = getFirstProfile();
                            }
                            roots = profile.query(query, sub.newChild(2));
                        }
                        units.addAll(roots.toUnmodifiableSet());
                    }
                } catch (Exception e) {
                    throw new InvocationTargetException(e);
                } finally {
                    sub.done();
                }
            }
        };
        try {
            new ProgressMonitorDialog(Display.getDefault().getActiveShell()).run(true, true, runnable);
        } catch (InterruptedException e) {
            // don't report thread interruption
        } catch (InvocationTargetException e) {
            throw new PluginManagerException(P2Eclipse36Messages.ProfileModificationAction_UnexpectedError,
                    e.getCause());
        }
        return units.toArray(new IInstallableUnit[units.size()]);
    }

    protected static IArtifactRepositoryManager getArtifactRepositoryManager() {
        return (IArtifactRepositoryManager) getAgent().getService(IArtifactRepositoryManager.SERVICE_NAME);
    }

    protected static IMetadataRepositoryManager getMetadataRepositoryManager() {
        return (IMetadataRepositoryManager) getAgent().getService(IMetadataRepositoryManager.SERVICE_NAME);
    }

    private static IProvisioningAgent getAgent() {
        return (IProvisioningAgent) ServiceHelper.getService(Activator.getContext(),
                IProvisioningAgent.SERVICE_NAME);
    }

    protected static IProfileRegistry getProfileRegistry() {
        return (IProfileRegistry) getAgent().getService(IProfileRegistry.SERVICE_NAME);
    }

    private static String getFeatureGroupName(IPlugin plugin) throws CoreException {
        return plugin.getId() + FEATURE_IU_SUFFIX;
    }

    public boolean isFeatureInstalled(String id) {
        return getInstalledFeature(id) != null;
    }

    public IPlugin getInstalledFeature(String id) {
        if (id == null)
            return null;

        if (!id.endsWith(FEATURE_IU_SUFFIX)) {
            id += FEATURE_IU_SUFFIX;
        }
        IProfileRegistry profileRegistry = getProfileRegistry();
        if (profileRegistry == null)
            return null;

        IProfile profile = getProfile(IProfileRegistry.SELF);
        if (profile == null) {
            profile = getFirstProfile();
        }
        if (profile == null)
            return null;

        IQuery<IInstallableUnit> query = QueryUtil.createIUQuery(id);
        query = QueryUtil.createLimitQuery(query, 1);

        IQueryResult<IInstallableUnit> roots = profile.available(query, new NullProgressMonitor());
        if (roots == null || roots.isEmpty())
            return null;
        try {
            return toPlugin((IInstallableUnit) roots.iterator().next());
        } catch (MalformedURLException e) {
            IdeLog.logError(Activator.getDefault(), e.getMessage(), e);
        }
        return null;
    }

    private static IProfile getFirstProfile() {
        IProfileRegistry profileRegistry = getProfileRegistry();
        if (profileRegistry == null) {
            return null;
        }

        IProfile[] profiles = profileRegistry.getProfiles();
        if (profiles != null && profiles.length > 0) {
            return profiles[0];
        }
        return null;
    }

    public List<IPlugin> getInstalledPlugins() {
        IProfileRegistry profileRegistry = getProfileRegistry();
        if (profileRegistry == null)
            return Collections.emptyList();
        IProfile profile = profileRegistry.getProfile(IProfileRegistry.SELF);
        if (profile == null) {
            IProfile[] profiles = profileRegistry.getProfiles();

            if (profiles != null && profiles.length > 0) {
                profile = profiles[0];
            }
        }
        if (profile == null)
            return Collections.emptyList();
        IQuery<IInstallableUnit> query = QueryUtil.createIUGroupQuery();
        IQueryResult<IInstallableUnit> roots = profile.available(query, new NullProgressMonitor());
        Iterator<IInstallableUnit> iter = roots.iterator();
        // Convert them to Plugin objects
        List<IPlugin> plugins = new ArrayList<IPlugin>();
        while (iter.hasNext()) {
            IInstallableUnit unit = iter.next();
            String name = unit.getId();
            // limit to features only...
            if (name == null || !name.endsWith(FEATURE_IU_SUFFIX)) {
                continue;
            }

            try {
                plugins.add(toPlugin(unit));
            } catch (MalformedURLException e) {
                IdeLog.logError(Activator.getDefault(), e.getMessage(), e);
            }
        }
        return plugins;
    }

    public String getUpdatePreferencePageId() {
        return "org.eclipse.equinox.internal.p2.ui.sdk.scheduler.AutomaticUpdatesPreferencePage"; //$NON-NLS-1$
    }

    private Plugin toPlugin(IInstallableUnit iu) throws MalformedURLException {
        String name = iu.getProperty("df_LT.featureName"); //$NON-NLS-1$
        if (name == null)
            name = iu.getProperty(IInstallableUnit.PROP_NAME);
        if (name == null)
            name = iu.getId();
        return new Plugin(stripFeatureGroup(iu.getId()), name, iu.getVersion().toString(), null,
                iu.getProperty("df_LT.description"), new URL("file:/fake/" + iu.getId()), "", "", 0, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
                null, "", null); //$NON-NLS-1$
    }

    private String stripFeatureGroup(String id) {
        if (id == null)
            return null;
        if (id.endsWith(FEATURE_IU_SUFFIX))
            return id.substring(0, id.length() - FEATURE_IU_SUFFIX.length());
        return id;
    }

    public URI[] getAllMetadataRepositories() {
        IMetadataRepositoryManager manager = getMetadataRepositoryManager();
        if (manager == null) {
            return new URI[0];
        }
        return manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL);
    }

}