blob: ee8463a9c0ab9afe93245709be339d2c5e1ce2e8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 The Regents of the University of California.
* This material was produced under U.S. Government contract W-7405-ENG-36
* for Los Alamos National Laboratory, which is operated by the University
* of California for the U.S. Department of Energy. The U.S. Government has
* rights to use, reproduce, and distribute this software. NEITHER THE
* GOVERNMENT NOR THE UNIVERSITY MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
* ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
* to produce derivative works, such modified software should be clearly marked,
* so as not to confuse it with the version available from LANL.
*
* Additionally, 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
*
* LA-CC 04-115
*******************************************************************************/
package org.eclipse.ptp.core;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
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.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.ptp.core.elements.IPUniverse;
import org.eclipse.ptp.core.events.IResourceManagerAddedEvent;
import org.eclipse.ptp.core.events.IResourceManagerChangedEvent;
import org.eclipse.ptp.core.events.IResourceManagerErrorEvent;
import org.eclipse.ptp.core.events.IResourceManagerRemovedEvent;
import org.eclipse.ptp.core.listeners.IResourceManagerListener;
import org.eclipse.ptp.core.messages.Messages;
import org.eclipse.ptp.internal.core.elements.PUniverse;
import org.eclipse.ptp.internal.core.events.ResourceManagerAddedEvent;
import org.eclipse.ptp.internal.core.events.ResourceManagerChangedEvent;
import org.eclipse.ptp.internal.core.events.ResourceManagerErrorEvent;
import org.eclipse.ptp.internal.core.events.ResourceManagerRemovedEvent;
import org.eclipse.ptp.rmsystem.AbstractResourceManagerFactory;
import org.eclipse.ptp.rmsystem.IResourceManager;
import org.eclipse.ptp.rmsystem.IResourceManagerComponentConfiguration;
import org.eclipse.ptp.rmsystem.IResourceManagerConfiguration;
import org.eclipse.ptp.rmsystem.IResourceManagerControl;
import org.eclipse.ptp.rmsystem.IResourceManagerControlFactory;
import org.eclipse.ptp.rmsystem.IResourceManagerMonitor;
import org.eclipse.ptp.rmsystem.IResourceManagerMonitorFactory;
import org.eclipse.ptp.rmsystem.ResourceManagerServiceProvider;
import org.eclipse.ptp.services.core.IService;
import org.eclipse.ptp.services.core.IServiceConfiguration;
import org.eclipse.ptp.services.core.IServiceModelEvent;
import org.eclipse.ptp.services.core.IServiceModelEventListener;
import org.eclipse.ptp.services.core.IServiceModelManager;
import org.eclipse.ptp.services.core.IServiceProvider;
import org.eclipse.ptp.services.core.ServiceModelManager;
/**
* Model manager for resource manager framework.
*
* @since 5.0
*/
public class ModelManager implements IModelManager {
private class RMFactory {
private String fId;
private String fControlId;
private String fMonitorId;
private AbstractResourceManagerFactory fFactory;
/**
* @return the controlFactory
*/
public String getControlId() {
return fControlId;
}
public AbstractResourceManagerFactory getFactory() {
return fFactory;
}
/**
* @return the id
*/
public String getId() {
return fId;
}
/**
* @return the monitorFactory
*/
public String getMonitorId() {
return fMonitorId;
}
/**
* @param id
* the controlFactory to set
*/
public void setControlId(String id) {
fControlId = id;
}
public void setFactory(AbstractResourceManagerFactory factory) {
fFactory = factory;
}
/**
* @param id
* the id to set
*/
public void setId(String id) {
fId = id;
}
/**
* @param monitorFactory
* the monitorFactory to set
*/
public void setMonitorId(String id) {
fMonitorId = id;
}
}
private class RMStartupJob extends Job {
private final IResourceManager[] resourceManagers;
public RMStartupJob(IResourceManager[] rms) {
super(Messages.ModelManager_0);
resourceManagers = rms;
}
@Override
protected IStatus run(IProgressMonitor monitor) {
SubMonitor subMon = SubMonitor.convert(monitor, resourceManagers.length);
try {
try {
for (IResourceManager rm : resourceManagers) {
rm.start(subMon.newChild(1));
if (subMon.isCanceled()) {
return Status.CANCEL_STATUS;
}
}
} catch (CoreException e) {
return e.getStatus();
}
return Status.OK_STATUS;
} finally {
if (monitor != null) {
monitor.done();
}
}
}
}
private static String RM_NAME = "resourceManager"; //$NON-NLS-1$
private static String RM_CONTROL_NAME = "resourceManagerControl"; //$NON-NLS-1$
private static String RM_MONITOR_NAME = "resourceManagerMonitor"; //$NON-NLS-1$
private static String ID_ATTRIBUTE = "id"; //$NON-NLS-1$
private static String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$
private static String EXTENSION_POINT = "org.eclipse.ptp.core.resourceManagers"; //$NON-NLS-1$
private final IServiceModelEventListener fServiceEventListener = new IServiceModelEventListener() {
public void handleEvent(IServiceModelEvent event) {
switch (event.getType()) {
case IServiceModelEvent.SERVICE_CONFIGURATION_REMOVED: {
/*
* The service configuration has been removed, so remove the
* resource manager associated with it (if any).
*/
IServiceProvider provider = ((IServiceConfiguration) event.getSource()).getServiceProvider(fLaunchService);
if (provider != null && provider instanceof ResourceManagerServiceProvider) {
IResourceManager rm = getResourceManagerFromUniqueName(((ResourceManagerServiceProvider) provider)
.getUniqueName());
if (rm != null) {
doRemoveResourceManager(rm);
}
}
break;
}
case IServiceModelEvent.SERVICE_CONFIGURATION_CHANGED: {
/*
* The service configuration has changed. Check if the old
* provider is null, in which case this is likely to be a new
* provider being added to a new configuration.
*/
IServiceConfiguration config = (IServiceConfiguration) event.getSource();
if (event.getOldProvider() == null) {
IServiceProvider newProvider = config.getServiceProvider(fLaunchService);
if (newProvider != null && newProvider instanceof ResourceManagerServiceProvider) {
/*
* Check if the rm already exists. Only add a new one if
* it doesn't.
*/
IResourceManager rm = getResourceManagerFromUniqueName(((ResourceManagerServiceProvider) newProvider)
.getUniqueName());
if (rm == null) {
RMFactory factory = getResourceManagerFactory(newProvider.getId());
if (factory != null) {
addResourceManager(createResourceManager(factory, newProvider));
}
}
}
}
break;
}
case IServiceModelEvent.SERVICE_PROVIDER_CHANGED: {
/*
* The service provider has been modified, so let the UI know
* that something has changed and it should update.
*/
IServiceProvider provider = (IServiceProvider) event.getSource();
if (provider != null && provider instanceof ResourceManagerServiceProvider) {
IResourceManager rm = getResourceManagerFromUniqueName(((ResourceManagerServiceProvider) provider)
.getUniqueName());
if (rm != null) {
fireResourceManagerChanged(rm);
}
}
break;
}
}
}
};
private static final ModelManager fInstance = new ModelManager();
private final ListenerList fResourceManagerListeners = new ListenerList();
private final IServiceModelManager fServiceManager = ServiceModelManager.getInstance();
private final Map<String, IResourceManager> fResourceManagers = new HashMap<String, IResourceManager>();
private final IService fLaunchService = fServiceManager.getService(IServiceConstants.LAUNCH_SERVICE);
private final IPUniverse fUniverse = new PUniverse();
private Map<String, RMFactory> fResourceManagerFactories = null;
private Map<String, IResourceManagerControlFactory> fResourceManagerControlFactories = null;
private Map<String, IResourceManagerMonitorFactory> fResourceManagerMonitorFactories = null;
public ModelManager() {
fServiceManager.addEventListener(fServiceEventListener, IServiceModelEvent.SERVICE_CONFIGURATION_ADDED
| IServiceModelEvent.SERVICE_CONFIGURATION_REMOVED | IServiceModelEvent.SERVICE_CONFIGURATION_CHANGED
| IServiceModelEvent.SERVICE_PROVIDER_CHANGED);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ptp.core.IModelManager#addListener(org.eclipse.ptp.core.listeners
* .IResourceManagerListener)
*/
public void addListener(IResourceManagerListener listener) {
fResourceManagerListeners.add(listener);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ptp.core.IModelManager#addResourceManager(org.eclipse.ptp
* .rmsystem.IResourceManager)
*/
public void addResourceManager(IResourceManager rm) {
synchronized (fResourceManagers) {
fResourceManagers.put(rm.getUniqueName(), rm);
}
fireNewResourceManager(rm);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ptp.core.IModelManager#addResourceManagers(org.eclipse.ptp
* .rmsystem.IResourceManager[])
*/
public void addResourceManagers(IResourceManager[] rms) {
for (IResourceManager rm : rms) {
addResourceManager(rm);
}
}
/**
* Create a base configuration from the given service provider
*
* @param provider
* service provider
* @return base configuration
*/
public IResourceManagerConfiguration createBaseConfiguration(IServiceProvider provider) {
RMFactory factory = getResourceManagerFactory(provider.getId());
if (factory != null) {
return factory.getFactory().createConfiguration(provider);
}
return null;
}
/**
* Create a control configuration from the given service provider
*
* @param provider
* service provider
* @return control configuration
*/
public IResourceManagerComponentConfiguration createControlConfiguration(IServiceProvider provider) {
RMFactory factory = getResourceManagerFactory(provider.getId());
if (factory != null) {
IResourceManagerControlFactory controlFactory = fResourceManagerControlFactories.get(factory.getControlId());
if (controlFactory != null) {
return controlFactory.createControlConfiguration(provider);
}
}
return null;
}
/**
* Create a monitor configuration from the given service provider
*
* @param provider
* service provider
* @return monitor configuration
*/
public IResourceManagerComponentConfiguration createMonitorConfiguration(IServiceProvider provider) {
RMFactory factory = getResourceManagerFactory(provider.getId());
if (factory != null) {
IResourceManagerMonitorFactory monitorFactory = fResourceManagerMonitorFactories.get(factory.getMonitorId());
if (monitorFactory != null) {
return monitorFactory.createMonitorConfiguration(provider);
}
}
return null;
}
/**
* Fire an event to notify that a resource manager has changed
*
* @param rm
* rm that has changed
* @since 5.0
*/
public void fireResourceManagerChanged(IResourceManager rm) {
IResourceManagerChangedEvent e = new ResourceManagerChangedEvent(rm);
for (Object listener : fResourceManagerListeners.getListeners()) {
((IResourceManagerListener) listener).handleEvent(e);
}
}
/**
* Fire an event to notify that a resource manager error has occurred
*
* @param rm
* rm that caused the error
* @param message
* error message
*/
public void fireResourceManagerError(IResourceManager rm, String message) {
IResourceManagerErrorEvent e = new ResourceManagerErrorEvent(rm, message);
for (Object listener : fResourceManagerListeners.getListeners()) {
((IResourceManagerListener) listener).handleEvent(e);
}
}
public String getControlFactoryId(String rmId) {
RMFactory factory = getResourceManagerFactory(rmId);
if (factory != null) {
return factory.getControlId();
}
return null;
}
public String getMonitorFactoryId(String rmId) {
RMFactory factory = getResourceManagerFactory(rmId);
if (factory != null) {
return factory.getMonitorId();
}
return null;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ptp.core.IModelManager#getResourceManagerFromUniqueName(java
* .lang.String)
*/
public IResourceManager getResourceManagerFromUniqueName(String rmUniqueName) {
synchronized (fResourceManagers) {
return fResourceManagers.get(rmUniqueName);
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ptp.core.IModelManager#getResourceManagers()
*/
public IResourceManager[] getResourceManagers() {
synchronized (fResourceManagers) {
return fResourceManagers.values().toArray(new IResourceManager[0]);
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ptp.core.IModelPresentation#getUniverse()
*/
public IPUniverse getUniverse() {
return fUniverse;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ptp.core.elements.listeners.IResourceManagerListener#handleEvent
* (org.eclipse.ptp.core.elements.events.IResourceManagerErrorEvent)
*/
public void handleEvent(IResourceManagerErrorEvent e) {
// Ignore - handled by listener on RM
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ptp.core.IModelManager#loadResourceManagers()
*/
public void loadResourceManagers() throws CoreException {
Set<IResourceManager> rmsNeedStarting = new HashSet<IResourceManager>();
/*
* Need to force service model to load so that the resource managers are
* created.
*/
fServiceManager.getActiveConfiguration();
synchronized (fResourceManagers) {
for (IResourceManager rm : fResourceManagers.values()) {
if (rm.getConfiguration().getAutoStart()) {
rmsNeedStarting.add(rm);
}
}
}
if (Preferences.getBoolean(PTPCorePlugin.getUniqueIdentifier(), PreferenceConstants.PREFS_AUTO_START_RMS)) {
startResourceManagers(rmsNeedStarting.toArray(new IResourceManager[0]));
}
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ptp.core.IModelManager#removeListener(org.eclipse.ptp.core
* .listeners.IResourceManagerListener)
*/
public void removeListener(IResourceManagerListener listener) {
fResourceManagerListeners.remove(listener);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ptp.core.IModelManager#removeResourceManager(org.eclipse.
* ptp.rmsystem.IResourceManager)
*/
public void removeResourceManager(IResourceManager rm) {
IServiceProvider provider = (IServiceProvider) rm.getConfiguration().getAdapter(IServiceProvider.class);
if (provider != null) {
removeProviderFromConfiguration(provider);
}
doRemoveResourceManager(rm);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ptp.core.IModelManager#removeResourceManagers(org.eclipse
* .ptp.rmsystem.IResourceManager[])
*/
public void removeResourceManagers(IResourceManager[] rms) {
for (IResourceManager rm : rms) {
removeResourceManager(rm);
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ptp.core.IModelManager#saveResourceManagers()
*/
public void saveResourceManagers() {
// No longer needed
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ptp.core.IModelManager#shutdown()
*/
public void shutdown() throws CoreException {
saveResourceManagers();
stopResourceManagers();
disposeResourceManagers();
fResourceManagerListeners.clear();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ptp.core.IModelManager#start()
*/
public void start() throws CoreException {
loadResourceManagers();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ptp.core.IModelManager#stopResourceManagers()
*/
public void stopResourceManagers() throws CoreException {
for (IResourceManager resourceManager : getResourceManagers()) {
resourceManager.stop();
}
}
private String addControlFactory(IConfigurationElement element) {
String id = element.getAttribute(ID_ATTRIBUTE);
if (element.getAttribute(CLASS_ATTRIBUTE) != null) {
try {
IResourceManagerControlFactory factory = (IResourceManagerControlFactory) element
.createExecutableExtension(CLASS_ATTRIBUTE);
fResourceManagerControlFactories.put(id, factory);
} catch (Exception e) {
PTPCorePlugin.log(e);
}
}
return id;
}
private String addMonitorFactory(IConfigurationElement element) {
String id = element.getAttribute(ID_ATTRIBUTE);
if (element.getAttribute(CLASS_ATTRIBUTE) != null) {
try {
IResourceManagerMonitorFactory factory = (IResourceManagerMonitorFactory) element
.createExecutableExtension(CLASS_ATTRIBUTE);
fResourceManagerMonitorFactories.put(id, factory);
} catch (Exception e) {
PTPCorePlugin.log(e);
}
}
return id;
}
private IResourceManager createResourceManager(RMFactory factory, IServiceProvider provider) {
IResourceManagerControl control = null;
IResourceManagerMonitor monitor = null;
IResourceManagerControlFactory controlFactory = fResourceManagerControlFactories.get(factory.getControlId());
if (controlFactory != null) {
IResourceManagerComponentConfiguration controlConfig = controlFactory.createControlConfiguration(provider);
control = controlFactory.createControl(controlConfig);
}
IResourceManagerMonitorFactory monitorFactory = fResourceManagerMonitorFactories.get(factory.getMonitorId());
if (monitorFactory != null) {
IResourceManagerComponentConfiguration monitorConfig = monitorFactory.createMonitorConfiguration(provider);
monitor = monitorFactory.createMonitor(monitorConfig);
}
IResourceManagerConfiguration config = factory.getFactory().createConfiguration(provider);
return factory.getFactory().create(config, control, monitor);
}
/**
* Dispose of all of the resource managers.
*/
private void disposeResourceManagers() {
for (IResourceManager resourceManager : getResourceManagers()) {
resourceManager.dispose();
}
}
private void doRemoveResourceManager(IResourceManager rm) {
synchronized (fResourceManagers) {
fResourceManagers.remove(rm.getUniqueName());
}
fireRemoveResourceManager(rm);
rm.dispose();
}
/**
* Fire a new resource manager event.
*
* @param rm
*/
private void fireNewResourceManager(final IResourceManager rm) {
IResourceManagerAddedEvent event = new ResourceManagerAddedEvent(this, rm);
for (Object listener : fResourceManagerListeners.getListeners()) {
((IResourceManagerListener) listener).handleEvent(event);
}
}
/**
* Fire a remove resource manager event.
*
* @param rm
*/
private void fireRemoveResourceManager(final IResourceManager rm) {
IResourceManagerRemovedEvent event = new ResourceManagerRemovedEvent(this, rm);
for (Object listener : fResourceManagerListeners.getListeners()) {
((IResourceManagerListener) listener).handleEvent(event);
}
}
private void getResourceManagerFactories() {
if (fResourceManagerFactories == null) {
fResourceManagerFactories = new HashMap<String, RMFactory>();
fResourceManagerControlFactories = new HashMap<String, IResourceManagerControlFactory>();
fResourceManagerMonitorFactories = new HashMap<String, IResourceManagerMonitorFactory>();
IExtensionRegistry registry = Platform.getExtensionRegistry();
IExtensionPoint extensionPoint = registry.getExtensionPoint(EXTENSION_POINT);
for (IExtension ext : extensionPoint.getExtensions()) {
for (IConfigurationElement ce : ext.getConfigurationElements()) {
if (ce.getName().equals(RM_NAME)) {
RMFactory factory = new RMFactory();
IConfigurationElement[] el = ce.getChildren();
if (el.length == 2) {
try {
factory.setFactory((AbstractResourceManagerFactory) ce.createExecutableExtension(CLASS_ATTRIBUTE));
factory.setControlId(addControlFactory(el[0]));
factory.setMonitorId(addMonitorFactory(el[1]));
factory.setId(ce.getAttribute(ID_ATTRIBUTE));
fResourceManagerFactories.put(factory.getId(), factory);
} catch (Exception e) {
PTPCorePlugin.log(e);
}
}
} else if (ce.getName().equals(RM_CONTROL_NAME)) {
addControlFactory(ce);
} else if (ce.getName().equals(RM_MONITOR_NAME)) {
addMonitorFactory(ce);
}
}
}
}
}
/**
* Get the resource manager factory corresponding to the id
*
* @param id
* id of factory
* @return resource manager factory
*/
private RMFactory getResourceManagerFactory(String id) {
getResourceManagerFactories();
return fResourceManagerFactories.get(id);
}
/**
* Remove provider from a service configurations, or if the configuration
* has the same name as the resource manager, remove it from service
* manager.
*
* @param provider
* provider to remove
*/
private void removeProviderFromConfiguration(IServiceProvider provider) {
Set<IServiceConfiguration> configs = fServiceManager.getConfigurations();
for (IServiceConfiguration config : configs) {
if (provider.equals(config.getServiceProvider(fLaunchService))) {
config.setServiceProvider(fLaunchService, null);
break;
}
}
}
/**
* Start all resource managers.
*
* @param rmsNeedStarting
* @throws CoreException
*/
private void startResourceManagers(IResourceManager[] rmsNeedStarting) throws CoreException {
Job job = new RMStartupJob(rmsNeedStarting);
job.schedule();
}
public static ModelManager getInstance() {
return fInstance;
}
}