| //------------------------------------------------------------------------------ |
| // 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.library.util.LibraryProblemMonitor; |
| import org.eclipse.epf.uma.MethodConfiguration; |
| import org.eclipse.epf.uma.MethodLibrary; |
| import org.eclipse.epf.uma.UmaFactory; |
| import org.eclipse.epf.uma.util.Scope; |
| |
| /** |
| * 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; |
| |
| private LibraryProblemMonitor libraryProblemMonitor; |
| /** |
| * 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(); |
| |
| } |
| |
| /** |
| * 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() { |
| if (CommandLineRunUtil.getInstance().isNeedToRun()) { |
| return null; |
| } |
| |
| 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 synchronized IConfigurationManager getConfigurationManager( |
| MethodConfiguration config) { |
| if (config == null) { |
| throw new IllegalArgumentException(); |
| } |
| if (config instanceof Scope) { //Don't cache it |
| new ConfigurationManager(config); |
| } |
| |
| 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(); |
| } |
| |
| public LibraryProblemMonitor getLibraryProblemMonitor() { |
| if (libraryProblemMonitor == null) { |
| libraryProblemMonitor = new LibraryProblemMonitor(); |
| } |
| return libraryProblemMonitor; |
| } |
| |
| } |