| //------------------------------------------------------------------------------ |
| // 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.xmi; |
| |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Map; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IWorkspace; |
| import org.eclipse.core.resources.IWorkspaceRunnable; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.epf.common.service.versioning.VersionUtil; |
| import org.eclipse.epf.common.serviceability.DebugTrace; |
| import org.eclipse.epf.library.AbstractLibraryManager; |
| import org.eclipse.epf.library.ILibraryResourceManager; |
| import org.eclipse.epf.library.LibraryAlreadyExistsException; |
| import org.eclipse.epf.library.LibraryNotFoundException; |
| import org.eclipse.epf.library.LibraryResources; |
| import org.eclipse.epf.library.LibraryServiceException; |
| import org.eclipse.epf.library.layout.LayoutResources; |
| import org.eclipse.epf.library.persistence.ILibraryResourceSet; |
| import org.eclipse.epf.library.persistence.PersistenceService; |
| import org.eclipse.epf.library.project.MethodLibraryProject; |
| import org.eclipse.epf.library.util.ModelStorage; |
| import org.eclipse.epf.persistence.MultiFileResourceSetImpl; |
| import org.eclipse.epf.persistence.MultiFileSaveUtil; |
| import org.eclipse.epf.persistence.migration.MappingUtil; |
| import org.eclipse.epf.persistence.util.PersistenceUtil; |
| import org.eclipse.epf.services.Services; |
| import org.eclipse.epf.uma.MethodLibrary; |
| import org.eclipse.osgi.util.NLS; |
| |
| import com.ibm.icu.util.Calendar; |
| |
| /** |
| * The default XMI Library Manager implementation. |
| * |
| * @author Kelvin Low |
| * @author Jinhua Xi |
| * @author Phong Nguyen Le |
| * |
| * @since 1.0 |
| */ |
| public class XMILibraryManager extends AbstractLibraryManager { |
| /** |
| * The supported library type. |
| */ |
| public static final String LIBRARY_TYPE = Services.XMI_PERSISTENCE_TYPE; |
| |
| /** |
| * The library XMI file name. |
| */ |
| public static final String LIBRARY_XMI = MultiFileSaveUtil.DEFAULT_LIBRARY_MODEL_FILENAME; |
| |
| /** |
| * The plugin and config spec export file name. |
| */ |
| public static final String exportFile = MultiFileSaveUtil.DEFAULT_PLUGIN_EXPORT_FILENAME; |
| |
| /** |
| * The library path. |
| */ |
| public static final String ARG_LIBRARY_PATH = "library.path"; //$NON-NLS-1$ |
| |
| // The absolute path to the managed library. |
| protected String path; |
| |
| private ILibraryResourceManager resourceMgr; |
| |
| private IProject project; |
| |
| private String registerType = "Default"; //$NON-NLS-1$ |
| |
| public XMILibraryManager() { |
| super(); |
| resourceMgr = new XMILibraryResourceManager(); |
| } |
| |
| /** |
| * Creates a new method library. |
| * |
| * @param name |
| * a name for the new method library |
| * @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(final String name, final Map<String, Object> args) |
| throws LibraryServiceException { |
| final MethodLibrary[] resultHolder = new MethodLibrary[1]; |
| final LibraryServiceException[] exceptionHolder = new LibraryServiceException[1]; |
| IWorkspaceRunnable action = new IWorkspaceRunnable() { |
| |
| public void run(IProgressMonitor monitor) throws CoreException { |
| try { |
| resultHolder[0] = doCreateMethodLibrary(name, args); |
| } |
| catch(LibraryServiceException e) { |
| exceptionHolder[0] = e; |
| } |
| } |
| |
| }; |
| try { |
| IWorkspace workspace = ResourcesPlugin.getWorkspace(); |
| workspace.run(action, workspace.getRuleFactory().createRule(workspace.getRoot()), IWorkspace.AVOID_UPDATE, null); |
| } catch (CoreException e) { |
| XMILibraryPlugin.getDefault().getLogger().logError(e); |
| throw new LibraryServiceException(e); |
| } |
| |
| if(exceptionHolder[0] != null) { |
| throw exceptionHolder[0]; |
| } |
| return resultHolder[0]; |
| } |
| |
| private MethodLibrary doCreateMethodLibrary(String name, Map<String, Object> args) |
| throws LibraryServiceException { |
| if (debug) { |
| DebugTrace.print(this, "createMethodLibrary", "name=" + name); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| if (name == null || name.length() == 0 || args == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| String path = (String) args.get(ARG_LIBRARY_PATH); |
| if (path == null || path.length() == 0) { |
| throw new IllegalArgumentException(); |
| } |
| |
| File libraryPath = new File(path); |
| File libraryXMIFile = new File(libraryPath, LIBRARY_XMI); |
| if (libraryXMIFile.exists()) { |
| String msg = NLS.bind( |
| XMILibraryResources.libraryAlreadyExistsError_msg, |
| libraryPath.getAbsolutePath()); |
| throw new LibraryAlreadyExistsException(msg); |
| } |
| |
| if (!libraryPath.exists()) { |
| libraryPath.mkdirs(); |
| } |
| |
| try { |
| skipEventProcessing = true; |
| String regType = (String) args.get(ARG_LIBRARY_REGISTER_TYPE); |
| if (regType != null && regType.equals("ConfigExport")) { //$NON-NLS-1$ |
| String time = Long.toHexString(Calendar.getInstance().getTimeInMillis()); |
| MethodLibraryProject.openProject(libraryPath.getAbsolutePath(), "ExportLib" + time, //$NON-NLS-1$ |
| null); |
| } else { |
| // Open the method library project file. |
| project = MethodLibraryProject.openProject(libraryPath.getAbsolutePath(), |
| null); |
| } |
| // Create the resource set. |
| ILibraryResourceSet resourceSet = (ILibraryResourceSet) editingDomain |
| .getResourceSet(); |
| |
| // Create a new method library. |
| ModelStorage.newLibrary(resourceSet, name, libraryPath |
| .getAbsolutePath(), true); |
| library = resourceSet.getFirstMethodLibrary(); |
| |
| // Add a listener to monitor library resource changes. |
| addResourceChangedListeners(); |
| |
| if (debug) { |
| DebugTrace.print(this, |
| "createMethodLibrary", "library=" + library); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| return library; |
| } catch (Exception e) { |
| throw new LibraryServiceException(e); |
| } finally { |
| skipEventProcessing = false; |
| |
| // // event processed in LibraryService |
| // notifyListeners(ILibraryChangeListener.OPTION_CREATED, null); |
| } |
| } |
| |
| /** |
| * Opens a method library. |
| * |
| * @param uri |
| * a method library URI |
| * @return a method library |
| * @throw <code>LibraryServiceException</code> if an error occurs while |
| * performing the operation |
| */ |
| public MethodLibrary openMethodLibrary(java.net.URI uri) |
| throws LibraryServiceException { |
| if (debug) { |
| DebugTrace.print(this, "openMethodLibrary"); //$NON-NLS-1$ |
| } |
| |
| if (uri == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| try { |
| File file = new File(uri); |
| library = openMethodLibrary(file); |
| } |
| catch(LibraryServiceException e) { |
| throw e; |
| } |
| catch (Exception e) { |
| library = null; |
| } |
| |
| if (debug) { |
| DebugTrace.print(this, "openMethodLibrary", "library=" + library); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| return library; |
| } |
| |
| /** |
| * Opens a method library. |
| * |
| * @param path |
| * a <code>File</code> object that contains the path to the |
| * method library. |
| * @return a <code>MethodLibrary</code>. |
| * @throw <code>LibraryServiceException</code> if an error occurred while |
| * performing the operation. |
| */ |
| protected MethodLibrary openMethodLibrary(File path) |
| throws LibraryServiceException { |
| File libraryXMIFile = new File(path, LIBRARY_XMI); |
| if (!libraryXMIFile.exists()) { |
| throw new LibraryNotFoundException(); |
| } |
| |
| VersionUtil.VersionCheckInfo info = VersionUtil.checkLibraryVersion(libraryXMIFile); |
| IStatus status = XMILibraryUtil.checkVersion(libraryXMIFile, info); |
| if(!status.isOK()) { |
| throw new LibraryServiceException(status.getMessage()); |
| } |
| else if(MappingUtil.conversionRequired(libraryXMIFile.getAbsolutePath(), info)) { |
| throw new LibraryServiceException(LibraryResources.libUpgradeRequired_err_msg); |
| } |
| |
| try { |
| skipEventProcessing = true; |
| |
| // Open the method library project file. |
| project = MethodLibraryProject.openProject(path.getAbsolutePath(), null); |
| |
| // Create the resource set. |
| ILibraryResourceSet resourceSet = ((ILibraryResourceSet) editingDomain |
| .getResourceSet()); |
| |
| // Load the method library. |
| resourceSet.loadMethodLibraries(URI.createFileURI(libraryXMIFile |
| .getAbsolutePath()), Collections.EMPTY_MAP); |
| library = resourceSet.getFirstMethodLibrary(); |
| |
| // Add a listener to monitor library resource changes. |
| addResourceChangedListeners(); |
| |
| System.gc(); |
| |
| return library; |
| } catch (Exception e) { |
| if (debug) { |
| DebugTrace.print(e); |
| } |
| throw new LibraryServiceException(e); |
| } finally { |
| firePropertyChange(library, PROP_DIRTY); |
| skipEventProcessing = false; |
| } |
| } |
| |
| /** |
| * Opens a method library. |
| * |
| * @param args |
| * method library specific arguments |
| * @return a method library |
| * @throw <code>LibraryServiceException</code> if an error occurs while |
| * performing the operation |
| */ |
| public MethodLibrary openMethodLibrary(Map args) |
| throws LibraryServiceException { |
| if (debug) { |
| DebugTrace.print(this, "openMethodLibrary"); //$NON-NLS-1$ |
| } |
| |
| if (args == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| String path = (String) args.get(ARG_LIBRARY_PATH); |
| if (path == null || path.length() == 0) { |
| throw new IllegalArgumentException(); |
| } |
| |
| library = openMethodLibrary(new File(path)); |
| |
| if (debug) { |
| DebugTrace.print(this, "openMethodLibrary", "library=" + library); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| return library; |
| } |
| |
| /** |
| * Reopens the managed method library. |
| * |
| * @return a method library |
| * @throw <code>LibraryServiceException</code> if an error occurs while |
| * performing the operation |
| */ |
| public MethodLibrary reopenMethodLibrary() throws LibraryServiceException { |
| if (debug) { |
| DebugTrace.print(this, "reopenMethodLibrary"); //$NON-NLS-1$ |
| } |
| |
| library = openMethodLibrary(new File(getMethodLibraryLocation())); |
| |
| if (debug) { |
| DebugTrace.print(this, "reopenMethodLibrary", "library=" + library); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| return library; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.epf.library.AbstractLibraryManager#getLibraryPersisterType() |
| */ |
| protected String getLibraryPersisterType() { |
| return Services.XMI_PERSISTENCE_TYPE; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.epf.library.AbstractLibraryManager#createResourceSet() |
| */ |
| protected ILibraryResourceSet createResourceSet() { |
| return PersistenceService.INSTANCE |
| .createResourceSet(Services.XMI_PERSISTENCE_TYPE); |
| } |
| |
| /** |
| * Gets the absolute path to the managed method library. |
| * For distributed library, this is the library's workspace path. |
| * |
| * @return an absolute path to the method library |
| */ |
| public String getMethodLibraryLocation() { |
| if (debug) { |
| DebugTrace.print(this, "getMethodLibraryPath"); //$NON-NLS-1$ |
| } |
| |
| java.net.URI libraryURI = getMethodLibraryURI(); |
| if (libraryURI != null) { |
| File libraryXMIFile = new File(libraryURI); |
| if (libraryXMIFile.getName().equalsIgnoreCase(LIBRARY_XMI)) { |
| libraryXMIFile = libraryXMIFile.getParentFile(); |
| } |
| return libraryXMIFile.getAbsolutePath(); |
| } |
| return null; |
| } |
| |
| /** |
| * Gets the project of the method library managed by this manager. |
| * |
| * @return the method library project |
| */ |
| public IProject getMethodLibraryProject() { |
| return project; |
| } |
| |
| public void handleLibraryMoved() { |
| if(library == null) { |
| return; |
| } |
| String location = getMethodLibraryLocation(); |
| if(!project.isOpen() || project.getLocation().equals(new Path(location))) { |
| // not moved |
| // |
| return; |
| } |
| |
| // update URI of all library resources |
| // |
| Resource libResource = library.eResource(); |
| if(libResource == null || libResource.getResourceSet() == null) { |
| return; |
| } |
| String newLocation = project.getLocation().toOSString(); |
| if(libResource.getResourceSet() instanceof MultiFileResourceSetImpl) { |
| ((MultiFileResourceSetImpl)libResource.getResourceSet()).handleLibraryMoved(newLocation); |
| } |
| else { |
| PersistenceUtil.replaceURIPrefix(new ArrayList<Resource>(libResource.getResourceSet().getResources()), |
| location, newLocation); |
| } |
| } |
| |
| |
| /** |
| * get the resource manager for the library |
| * @return ILibraryResourceManager |
| */ |
| public ILibraryResourceManager getResourceManager() { |
| return resourceMgr; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.epf.library.ILibraryManager#backupMethodLibrary(java.lang.String) |
| */ |
| public void backupMethodLibrary(String path) { |
| String libPathStr = getMethodLibraryLocation(); |
| File libPath = new File(libPathStr); |
| // excude the non-library files that might be locked by rmc. |
| // these files may cause backup to fail due to file lock. |
| String excludes = ".lock"; //$NON-NLS-1$ |
| LayoutResources.copyDir(libPath, new File(path), "**", excludes); //$NON-NLS-1$ |
| } |
| |
| private String getRegisterType() { |
| return registerType; |
| } |
| |
| private void setRegisterType(String registerType) { |
| this.registerType = registerType; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.epf.library.ILibraryManager#registerMethodLibrary(org.eclipse.epf.uma.MethodLibrary, java.util.Map) |
| */ |
| public void registerMethodLibrary(MethodLibrary lib, |
| Map<String, Object> params) throws LibraryServiceException { |
| String regType = (String) params.get(ARG_LIBRARY_REGISTER_TYPE); |
| if (regType != null) { |
| setRegisterType(regType); |
| } |
| regType = getRegisterType(); |
| if (regType.equals("ConfigExport")) {//$NON-NLS-1$ |
| //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 |
| String name = "library.xmi"; //$NON-NLS-1$; |
| createMethodLibrary(name, params); |
| setMethodLibrary(lib); |
| return; |
| } |
| |
| //Minimum implementation for defaul register type, to minimize caller code change |
| this.library = lib; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.epf.library.ILibraryManager#unRegisterMethodLibrary() |
| */ |
| public void unRegisterMethodLibrary() throws LibraryServiceException { |
| if (getRegisterType().equals("ConfigExport")) {//$NON-NLS-1$ |
| closeMethodLibrary(); |
| return; |
| } |
| //Minimum implementation for defaul register type, to minimize caller code change |
| this.library = null; |
| } |
| |
| } |