blob: 59094b6f9c027c36811f2ee23e9870b1fa022783 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2011 Tasktop Technologies and others.
* 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:
* Tasktop Technologies - initial API and implementation
* Itema AS - Added support for build service messages
* Itema AS - Automatic refresh when a new repo has been added; bug 330910
*******************************************************************************/
package org.eclipse.mylyn.internal.builds.ui;
import java.io.IOException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.mylyn.builds.ui.BuildsUiStartup;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.statushandlers.StatusManager;
import org.osgi.framework.BundleContext;
/**
* @author Steffen Pingel
* @author Torkild U. Resheim
*/
public class BuildsUiPlugin extends AbstractUIPlugin {
public static final String ID_PLUGIN = "org.eclipse.mylyn.builds.ui"; //$NON-NLS-1$
private static BuildsUiPlugin instance;
public static BuildsUiPlugin getDefault() {
return instance;
}
private BuildRefresher refresher;
private BuildNotifier notifier;
private boolean startupExtensionsInitialized;
@Override
public void start(BundleContext context) throws Exception {
instance = this;
super.start(context);
}
@Override
public void stop(BundleContext context) throws Exception {
if (refresher != null) {
refresher.stop();
refresher = null;
}
try {
BuildsUiInternal.save();
} catch (IOException e) {
StatusManager.getManager().handle(
new Status(IStatus.ERROR, BuildsUiPlugin.ID_PLUGIN, "Unexpected error while saving builds", e));
}
super.stop(context);
instance = null;
}
protected IPath getBuildsFile() {
IPath stateLocation = Platform.getStateLocation(getBundle());
IPath cacheFile = stateLocation.append("builds.xmi"); //$NON-NLS-1$
return cacheFile;
}
public void initializeRefresh() {
if (notifier == null) {
notifier = new BuildNotifier();
notifier.register(BuildsUiInternal.getModel());
}
if (refresher == null) {
refresher = new BuildRefresher(getPreferenceStore(), BuildsUiInternal.getModel().getScheduler());
refresher.start();
}
if (!startupExtensionsInitialized) {
// start automatic discovery services etc.
UiStartupExtensionPointReader.runStartupExtensions();
startupExtensionsInitialized = true;
}
}
/**
* Performs a one-shot refresh of build server data regardless of the automatic refresh preference setting. This
* method should be called when build service settings has been changed in a way that require update of the data.
* For instance when a new repository has been added.
*/
public void refreshBuilds() {
initializeRefresh();
refresher.refresh();
// delay the save until other async tasks complete to ensure that the model is updated before it's persisted
BuildsUiInternal.getModel().getLoader().getRealm().asyncExec(new Runnable() {
public void run() {
// trigger a save in case Eclipse crashes and stop() is not executed
try {
BuildsUiInternal.save();
} catch (IOException e) {
StatusManager.getManager().handle(
new Status(IStatus.ERROR, BuildsUiPlugin.ID_PLUGIN, "Unexpected error while saving builds",
e));
}
}
});
}
static class UiStartupExtensionPointReader {
private static final String EXTENSION_ID_STARTUP = "org.eclipse.mylyn.builds.ui.startup"; //$NON-NLS-1$
private static final String ELEMENT_STARTUP = "startup"; //$NON-NLS-1$
private static final String ELEMENT_CLASS = "class"; //$NON-NLS-1$
public static void runStartupExtensions() {
IExtensionRegistry registry = Platform.getExtensionRegistry();
IExtensionPoint extensionPoint = registry.getExtensionPoint(EXTENSION_ID_STARTUP);
IExtension[] extensions = extensionPoint.getExtensions();
for (IExtension extension : extensions) {
IConfigurationElement[] elements = extension.getConfigurationElements();
for (IConfigurationElement element : elements) {
if (element.getName().compareTo(ELEMENT_STARTUP) == 0) {
runStartupExtension(element);
}
}
}
}
private static void runStartupExtension(IConfigurationElement configurationElement) {
try {
Object object = configurationElement.createExecutableExtension(ELEMENT_CLASS);
if (!(object instanceof BuildsUiStartup)) {
StatusHandler.log(new Status(IStatus.ERROR, BuildsUiPlugin.ID_PLUGIN, NLS.bind(
"Startup extension failed: {0} does notimplement {1}", //$NON-NLS-1$
object.getClass().getCanonicalName(), BuildsUiStartup.class.getCanonicalName())));
return;
}
final BuildsUiStartup startup = (BuildsUiStartup) object;
SafeRunner.run(new ISafeRunnable() {
public void run() throws Exception {
startup.lazyStartup();
}
public void handleException(Throwable exception) {
// ignore, handled by SafeRunner
}
});
} catch (Throwable e) {
StatusHandler.log(new Status(IStatus.ERROR, BuildsUiPlugin.ID_PLUGIN, "Startup extension failed", e)); //$NON-NLS-1$
}
}
}
}