blob: 1a797d2dc7daba4b4693efa5bf3498897567e99b [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 IBM Corporation 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:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.epf.common.service.utils.CommandLineRunUtil;
import org.eclipse.epf.library.preferences.LibraryPreferences;
import org.eclipse.epf.library.services.SafeUpdateController;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.UmaFactory;
/**
* The default Library Service implementation.
*
* @author Kelvin Low
* @author Jinhua Xi
* @since 1.0
*/
public class LibraryService implements ILibraryService {
protected static final int EVENT_CREATE_LIBRARY = 1;
protected static final int EVENT_OPEN_LIBRARY = 2;
protected static final int EVENT_REOPEN_LIBRARY = 3;
protected static final int EVENT_CLOSE_LIBRARY = 4;
protected static final int EVENT_SET_CURRENT_LIBRARY = 5;
protected static final int EVENT_SET_CURRENT_CONFIGURATION = 6;
// The shared instance.
protected static ILibraryService instance;
// A map of method libraries to library managers.
protected Map<MethodLibrary, ILibraryManager> libraryManagers = new HashMap<MethodLibrary, ILibraryManager>();
// A map of method configurations to configuration managers.
protected Map<MethodConfiguration, IConfigurationManager> configManagers = new HashMap<MethodConfiguration, IConfigurationManager>();
// The library service listeners.
protected List<ILibraryServiceListener> listeners = new ArrayList<ILibraryServiceListener>();
// The current method library.
protected MethodLibrary currentLibrary;
// The current method configuration.
protected MethodConfiguration currentConfig;
// If true, the current method library is being closed.
private boolean closingCurrentLibrary;
/**
* Returns the shared instance.
*/
public static ILibraryService getInstance() {
if (instance == null) {
synchronized (LibraryService.class) {
if (instance == null) {
instance = new LibraryService();
}
}
}
return instance;
}
/**
* Creates a new instance.
*/
private LibraryService() {
init();
}
/**
* Performs the necessary initialization.
*/
protected void init() {
// Initialize the library manager factory to pre-process the
// "org.eclipse.epf.library.libraryManagers" extension point.
LibraryManagerFactory.getInstance();
if (CommandLineRunUtil.getInstance().isNeedToRun()) {
return;
}
}
/**
* Creates a new method library.
*
* @param name
* a name for the new method library
* @param type
* the method library type
* @param args
* method library specific arguments
* @return a method library
* @throw <code>LibraryServiceException</code> if an error occurs while
* performing the operation
*/
public MethodLibrary createMethodLibrary(String name, String type,
Map<String, Object> params) throws LibraryServiceException {
if (name == null || type == null || params == null) {
throw new IllegalArgumentException();
}
boolean reopenLibrary = LibraryService.getInstance()
.getCurrentMethodLibrary() != null;
try {
LibraryService.getInstance().closeCurrentMethodLibrary();
ILibraryManager manager = LibraryManagerFactory.getInstance()
.createLibraryManager(type);
MethodLibrary library = manager.createMethodLibrary(name, params);
if (library != null) {
// open newly created method library without sending out notification
//
library = manager.openMethodLibrary(manager.getMethodLibraryURI());
setLibraryManager(manager);
// Set the current library, do this before notifying the library
// listeners.
setCurrentMethodLibrary(library);
// Save the library URI and type to preference store.
saveMethodLibraryPreferences(manager.getMethodLibraryURI(),
type);
notifyListeners(library, EVENT_CREATE_LIBRARY);
}
reopenLibrary = false;
return library;
} catch (LibraryServiceException e) {
throw e;
} catch (Exception e) {
throw new LibraryServiceException(e);
} finally {
if (reopenLibrary) {
openLastOpenedMethodLibrary();
}
}
}
/**
* Opens an existing method library.
*
* @param type
* the method library type
* @param uri
* the method library URI
* @return a method library
* @throw <code>LibraryServiceException</code> if an error occurs while
* performing the operation
*/
public MethodLibrary openMethodLibrary(String type, URI uri)
throws LibraryServiceException {
if (uri == null) {
throw new IllegalArgumentException();
}
try {
ILibraryManager manager = LibraryManagerFactory.getInstance()
.createLibraryManager(type);
MethodLibrary library = manager.openMethodLibrary(uri);
if (library != null) {
setLibraryManager(manager);
// Set the current library, do this before notifying the library
// listeners.
setCurrentMethodLibrary(library);
// Save the library URI and type to preference store.
saveMethodLibraryPreferences(manager.getMethodLibraryURI(),
type);
notifyListeners(library, EVENT_OPEN_LIBRARY);
}
return library;
} catch (CreateLibraryManagerException e) {
throw e;
} catch (Exception e) {
throw new LibraryServiceException(e);
}
}
/**
* Opens an existing method library.
*
* @param type
* the method library type
* @param params
* method library specific arguments
* @return a method library
* @throw <code>LibraryServiceException</code> if an error occurs while
* performing the operation
*/
public MethodLibrary openMethodLibrary(String type,
Map<String, Object> params) throws LibraryServiceException {
if (params == null) {
throw new IllegalArgumentException();
}
try {
ILibraryManager manager = LibraryManagerFactory.getInstance()
.createLibraryManager(type);
MethodLibrary library = manager.openMethodLibrary(params);
if (library != null) {
setLibraryManager(manager);
// Set the current library, do this before notifying the library
// listeners.
setCurrentMethodLibrary(library);
// Save the library URI and type to preference store.
saveMethodLibraryPreferences(manager.getMethodLibraryURI(),
type);
notifyListeners(library, EVENT_OPEN_LIBRARY);
}
return library;
} catch (CreateLibraryManagerException e) {
throw e;
} catch (Exception e) {
throw new LibraryServiceException(e);
}
}
/**
* Opens the last opened method library.
*
* @return a method library or <code>null</code>
*/
public MethodLibrary openLastOpenedMethodLibrary() {
String savedMethodLibraryURI = LibraryPreferences
.getSavedMethodLibraryURI();
try {
URI uri = new URI(savedMethodLibraryURI);
if (uri.getPath().length() == 0) {
return null;
}
String type = LibraryPreferences.getSavedMethodLibraryType();
if (type == null || type.length() == 0) {
return null;
}
return openMethodLibrary(type, uri);
} catch (Exception e) {
LibraryPlugin.getDefault().getLogger().logWarning(
"Unable to open the last opened method library '" //$NON-NLS-1$
+ savedMethodLibraryURI + "'."); //$NON-NLS-1$
LibraryPreferences.setSavedMethodLibraryURI(""); //$NON-NLS-1$
}
return null;
}
/**
* Reopens a method library.
*
* @param library
* a method library
* @return a method library
* @throw <code>LibraryServiceException</code> if an error occurs while
* performing the operation
*/
public MethodLibrary reopenMethodLibrary(MethodLibrary library)
throws LibraryServiceException {
ILibraryManager manager = getLibraryManager(library);
if (manager != null) {
try {
removeLibraryManager(manager);
library = manager.reopenMethodLibrary();
// Re-register the library manager since the library instance
// will be changed.
setLibraryManager(manager);
// Set the current library, do this before notifying the library
// listeners.
setCurrentMethodLibrary(library);
notifyListeners(library, EVENT_REOPEN_LIBRARY);
} catch (Exception e) {
throw new LibraryServiceException(e);
}
}
return null;
}
/**
* Reopens the current method library.
*
* @return a method library
* @throw <code>LibraryServiceException</code> if an error occurs while
* performing the operation
*/
public MethodLibrary reopenCurrentMethodLibrary()
throws LibraryServiceException {
return reopenMethodLibrary(currentLibrary);
}
/**
* Saves a method library.
*
* @param library
* a method library
* @throw <code>LibraryServiceException</code> if an error occurs while
* performing the operation
*/
public void saveMethodLibrary(MethodLibrary library)
throws LibraryServiceException {
ILibraryManager manager = getLibraryManager(library);
if (manager != null) {
manager.saveMethodLibrary();
}
}
/**
* Saves the current method library.
*
* @throw <code>LibraryServiceException</code> if an error occurs while
* performing the operation
*/
public void saveCurrentMethodLibrary() throws LibraryServiceException {
saveMethodLibrary(currentLibrary);
}
/**
* Closes a method library.
* <p>
* This automatically disposes its library manager and the configuration
* managers that manage the method configurations in the method library.
*
* @param library
* a method library
* @throw <code>LibraryServiceException</code> if an error occurs while
* performing the operation
*/
public void closeMethodLibrary(MethodLibrary library)
throws LibraryServiceException {
ILibraryManager manager = getLibraryManager(library);
if (manager != null) {
notifyListeners(library, EVENT_CLOSE_LIBRARY);
manager.closeMethodLibrary();
if (currentLibrary == library) {
setCurrentMethodLibrary(null);
setCurrentMethodConfiguration(null);
}
removeLibraryManager(manager);
manager.dispose();
}
}
/**
* Closes the current method library.
*
* @throw <code>LibraryServiceException</code> if an error occurs while
* performing the operation
*/
public synchronized void closeCurrentMethodLibrary()
throws LibraryServiceException {
if (closingCurrentLibrary)
return;
try {
closingCurrentLibrary = true;
if (currentLibrary != null) {
closeMethodLibrary(currentLibrary);
}
} finally {
closingCurrentLibrary = false;
}
}
/**
* Replaces a the method library.
*
* @param oldLibrary
* the old method library
* @param newLibrary
* the new method library
*/
public void replaceMethodLibrary(MethodLibrary oldLibrary,
MethodLibrary newLibrary) {
ILibraryManager manager = getLibraryManager(oldLibrary);
if (manager != null) {
removeLibraryManager(manager);
// Set the new library instance to prevent the library manager from
// referencing the old library instance.
manager.setMethodLibrary(newLibrary);
setLibraryManager(manager);
}
}
/**
* Adds a listener to monitor Library Service events.
*
* @param listener
* a library service listener
*/
public void addListener(ILibraryServiceListener listener) {
listeners.add(listener);
}
/**
* Removes a listener that was added to monitor Library Service events.
*
* @param listener
* a library service listener
*/
public void removeListener(ILibraryServiceListener listener) {
listeners.remove(listener);
}
/**
* Gets the current method library.
*
* @return a method library
*/
public MethodLibrary getCurrentMethodLibrary() {
return currentLibrary;
}
/**
* Sets the current method library.
*
* @param library
* a method library
*/
public void setCurrentMethodLibrary(MethodLibrary library) {
currentLibrary = library;
notifyListeners(library, EVENT_SET_CURRENT_LIBRARY);
}
/**
* Gets the current method library location path.
* <p>
* Note: A file-based method library may return <code>null</code>.
*
* @return an absolute path to the current method library
*/
public String getCurrentMethodLibraryLocation() {
ILibraryManager manager = getLibraryManager(currentLibrary);
if (manager != null) {
return manager.getMethodLibraryLocation();
} else {
return null;
}
}
/**
* Gets the library manager for a method library.
*
* @param library
* a method library
* @return a library manager
*/
public ILibraryManager getLibraryManager(MethodLibrary library) {
return (ILibraryManager) libraryManagers.get(library);
}
public void removeLibraryManager(ILibraryManager libMgr) {
if (libMgr != null) {
MethodLibrary lib = libMgr.getMethodLibrary();
if (lib != null) {
removeConfigurationManagers(lib);
libraryManagers.remove(lib);
}
}
}
public void setLibraryManager(ILibraryManager libMgr) {
MethodLibrary lib = libMgr.getMethodLibrary();
if (lib != null) {
libraryManagers.put(lib, libMgr);
}
}
/**
* Gets the library manager for the current method library.
*
* @return a library manager
*/
public ILibraryManager getCurrentLibraryManager() {
return getLibraryManager(currentLibrary);
}
/**
* Creates a new method configuration.
*
* @param name
* a name for the new method configuration
* @param library
* the containing method library
* @return a method configuration
* @throw <code>LibraryServiceException</code> if an error occurs while
* performing the operation
*/
public MethodConfiguration createMethodConfiguration(String name,
MethodLibrary library) throws LibraryServiceException {
if (name == null || library == null) {
throw new IllegalArgumentException();
}
MethodConfiguration config;
List configs = library.getPredefinedConfigurations();
for (Iterator it = configs.iterator(); it.hasNext();) {
config = (MethodConfiguration) it.next();
if (name.equals(config.getName())) {
throw new ConfigurationAlreadyExistsException();
}
}
config = UmaFactory.eINSTANCE.createMethodConfiguration();
config.setName(name);
configs.add(config);
return config;
}
/**
* Gets the current method configuration.
*
* @return a method configuration
*/
public MethodConfiguration getCurrentMethodConfiguration() {
return currentConfig;
}
/**
* Sets the current method configuration.
*
* @param config
* a method configuration
*/
public void setCurrentMethodConfiguration(MethodConfiguration config) {
currentConfig = config;
notifyListeners(config, EVENT_SET_CURRENT_CONFIGURATION);
}
/**
* Gets the configuration manager for a method configuration.
*
* @param config
* a method configuration
* @return a configuration manager
*/
public IConfigurationManager getConfigurationManager(
MethodConfiguration config) {
if (config == null) {
throw new IllegalArgumentException();
}
IConfigurationManager manager = (IConfigurationManager) configManagers
.get(config);
if (manager == null) {
manager = new ConfigurationManager(config);
configManagers.put(config, manager);
}
return manager;
}
public void removeConfigurationManager(MethodConfiguration config) {
if (config == null) {
throw new IllegalArgumentException();
}
IConfigurationManager mgr = (IConfigurationManager) configManagers
.remove(config);
if (mgr != null) {
mgr.dispose();
}
}
public void removeConfigurationManagers(MethodLibrary library) {
if (library == null) {
throw new IllegalArgumentException();
}
MethodConfiguration[] configs = LibraryServiceUtil
.getMethodConfigurations(library);
for (int i = 0; i < configs.length; i++) {
removeConfigurationManager(configs[i]);
}
}
/**
* Gets the configuration manager for the current method configuration.
*
* @return a configuration manager
*/
public IConfigurationManager getCurrentConfigurationManager() {
if (currentConfig != null) {
return getConfigurationManager(currentConfig);
}
return null;
}
/**
* Sends a method library related event to all library service listeners.
*/
protected void notifyListeners(final MethodLibrary library, int eventId) {
for (Iterator<ILibraryServiceListener> it = new ArrayList<ILibraryServiceListener>(
listeners).iterator(); it.hasNext();) {
final ILibraryServiceListener listener = it.next();
switch (eventId) {
case EVENT_CREATE_LIBRARY:
SafeUpdateController.asyncExec(new Runnable() {
public void run() {
listener.libraryCreated(library);
}
});
break;
case EVENT_OPEN_LIBRARY:
SafeUpdateController.asyncExec(new Runnable() {
public void run() {
listener.libraryOpened(library);
}
});
break;
case EVENT_REOPEN_LIBRARY:
SafeUpdateController.asyncExec(new Runnable() {
public void run() {
listener.libraryReopened(library);
}
});
break;
case EVENT_CLOSE_LIBRARY:
SafeUpdateController.asyncExec(new Runnable() {
public void run() {
listener.libraryClosed(library);
}
});
break;
case EVENT_SET_CURRENT_LIBRARY:
SafeUpdateController.asyncExec(new Runnable() {
public void run() {
listener.librarySet(library);
}
});
break;
}
}
}
/**
* Sends a method configuration related event to all library service
* listeners.
*/
protected void notifyListeners(final MethodConfiguration config, int eventId) {
for (Iterator<ILibraryServiceListener> it = new ArrayList<ILibraryServiceListener>(
listeners).iterator(); it.hasNext();) {
final ILibraryServiceListener listener = it.next();
switch (eventId) {
case EVENT_SET_CURRENT_CONFIGURATION:
SafeUpdateController.syncExec(new Runnable() {
public void run() {
listener.configurationSet(config);
}
});
break;
}
}
}
/**
* Saves the method library URI and type to preference store.
*
* @param uri
* the method library URI
* @param type
* the menthod library type
*/
protected void saveMethodLibraryPreferences(URI uri, String type) {
LibraryPreferences.setSavedMethodLibraryURI(uri.toString());
LibraryPreferences.setSavedMethodLibraryType(type);
}
/* (non-Javadoc)
* @see org.eclipse.epf.library.ILibraryService#registerMethodLibrary(org.eclipse.epf.uma.MethodLibrary, java.lang.String, java.util.Map)
*/
public void registerMethodLibrary(MethodLibrary lib, String type,
Map<String, Object> params) throws LibraryServiceException {
//For now, still simply wraping up old implementation (copied from ConfigurationExportService) for smoother change; will definetly change later
//so that creating a new lib would not be needed
ILibraryManager libMgr = LibraryManagerFactory.getInstance()
.createLibraryManager(type);
libMgr.registerMethodLibrary(lib, params);
//libMgr.createMethodLibrary(name, params);
//libMgr.setMethodLibrary(lib);
LibraryService.getInstance().setLibraryManager(libMgr);
}
/* (non-Javadoc)
* @see org.eclipse.epf.library.ILibraryService#unRegisterMethodLibrary(org.eclipse.epf.uma.MethodLibrary)
*/
public void unRegisterMethodLibrary(MethodLibrary lib) throws LibraryServiceException {
//For now, still simply wraping up old implementation (copied from ConfigurationExportService) for smoother change
ILibraryManager libMgr = getLibraryManager(lib);
if (libMgr == null) {
return;
}
removeLibraryManager(libMgr);
//libMgr.closeMethodLibrary();
libMgr.unRegisterMethodLibrary();
libMgr.dispose();
}
}