| //------------------------------------------------------------------------------ |
| // Copyright (c) 2005, 2006 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.util; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Iterator; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IProjectDescription; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspace; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.epf.library.LibraryPlugin; |
| import org.eclipse.epf.library.LibraryResources; |
| import org.eclipse.epf.library.project.MethodLibraryProject; |
| import org.eclipse.epf.persistence.FileManager; |
| import org.eclipse.epf.uma.MethodLibrary; |
| |
| /** |
| * Helper class for managing the Method Library as a project in the Eclipse |
| * workspace. |
| * |
| * @author Phong Nguyen Le |
| * @author Kelvin Low |
| * @since 1.0 |
| */ |
| public class ResourceUtil { |
| |
| private static final String methodLibraryNature = "org.eclipse.epf.library.project.MethodLibraryProjectNature"; //$NON-NLS-1$ |
| |
| private static final String[] methodLibraryNatures = { methodLibraryNature }; |
| |
| private static final boolean debug = LibraryPlugin.getDefault().isDebugging(); |
| |
| public static final String LOCK_FILENAME = ".lock"; //$NON-NLS-1$ |
| |
| /** |
| * |
| * @param lib MethodLibrary |
| * @param monitor IProgressMonitor |
| * @throws CoreException |
| * @throws IOException |
| */ |
| public static final void open(MethodLibrary lib, IProgressMonitor monitor) |
| throws CoreException, IOException { |
| open(getLibraryDirectory(lib), monitor); |
| } |
| |
| /** |
| * |
| * @param libDir String |
| * @param monitor IProgressMonitor |
| * @throws CoreException |
| * @throws IOException |
| */ |
| public static final void open(String libDir, IProgressMonitor monitor) |
| throws CoreException, IOException { |
| IPath path = new Path(libDir + File.separator |
| + IProjectDescription.DESCRIPTION_FILE_NAME); |
| IProjectDescription description = null; |
| |
| try { |
| description = ResourcesPlugin.getWorkspace() |
| .loadProjectDescription(path); |
| } catch (CoreException exception) { |
| // missing .project file |
| if (debug) { |
| System.out.println("### - exception in loadProjectDescription"); //$NON-NLS-1$ |
| } |
| } |
| |
| IProject project = null; |
| try { |
| if (description == null) { |
| // .project file is missing - create a new project |
| if (debug) { |
| System.out |
| .println("### - creating new method library project"); //$NON-NLS-1$ |
| } |
| project = createValidProjectFromPath(libDir, monitor); |
| } else { |
| // .project file exists |
| if (debug) { |
| System.out |
| .println("### - opening existing method library project " + description.getName()); //$NON-NLS-1$ |
| } |
| |
| // check if project of this name exists in workspace |
| project = ResourcesPlugin.getWorkspace().getRoot().getProject( |
| description.getName()); |
| |
| if (!project.exists()) { |
| // project doesn't exist in workspace, so make one with the |
| // project name in .project |
| try { |
| if (debug) { |
| System.out |
| .println("### - creating existing .project " + description.getName() + " in workspace"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| project = createProject(libDir, project.getName(), |
| monitor); |
| } catch (CoreException ex) { |
| // failed to make this project in the workspace - |
| // another project may exist in the workspace at this |
| // location |
| // so we need to delete that conflicting project and try |
| // again |
| if (debug) { |
| System.out |
| .println("### - creating existing .project failed - deleting workspace-project in " + //$NON-NLS-1$ |
| libDir |
| + " and creating workspace-project " + project.getName()); //$NON-NLS-1$ |
| } |
| deleteProject(libDir, monitor); |
| project = createProject(libDir, project.getName(), |
| monitor); |
| } |
| } else { |
| // project does exist in workspace - make sure location |
| // matches, if not, make a new project |
| if (debug) { |
| System.out |
| .println("### - project " + project.getName() + " exists in workspace"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| if (new File(libDir).compareTo(project.getLocation() |
| .toFile()) != 0) { |
| if (debug) { |
| System.out |
| .println("### - project " + project.getName() + " exists in workspace, but location differs - create a new project"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| File projectFile = path.toFile(); |
| if (projectFile.canWrite()) { |
| projectFile.delete(); |
| } else { |
| // this will cause the caller to display a |
| // messagebox asking the user to make .project |
| // writable |
| // TODO: use our own type of Exception? |
| throw new IOException( |
| "###" + projectFile.getAbsolutePath()); //$NON-NLS-1$ |
| } |
| project = createValidProjectFromPath(libDir, monitor); |
| } |
| } |
| } |
| if (project == null) { |
| // libDir must be an invalid path (overlaps workspace?) |
| // TODO: this exception isn't handled well - it shouldn't happen |
| throw new IOException(LibraryResources.invalidLibraryPathError_reason); |
| } |
| project.open(IResource.BACKGROUND_REFRESH, monitor); |
| |
| // Set lock file as team private member so it will not be shared (added to source control). |
| // This must be done before the project folder got refreshed. So this portion of code must be |
| // executed right after IProject.open() returned. Project must be opened with IResource.BACKGROUND_REFRESH |
| // to prevent lock file from being added to the project before it is set as team private member |
| // |
| File lockFile = new File(libDir, ResourceUtil.LOCK_FILENAME); |
| if(lockFile.exists()) { |
| try { |
| IResource wsRes = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(lockFile.getAbsolutePath())); |
| if(wsRes != null) { |
| wsRes.refreshLocal(IResource.DEPTH_ZERO, null); |
| wsRes.setTeamPrivateMember(true); |
| } |
| } catch (Exception e) { |
| LibraryPlugin.getDefault().getLogger().logError(e); |
| } |
| } |
| |
| // monitor for change in the resource |
| // RefreshManager.getInstance().monitor(project); |
| |
| description = project.getDescription(); |
| |
| // make sure project has the MethodLibraryNature |
| String[] existingNatures = description.getNatureIds(); |
| if (!(Arrays.asList(existingNatures).contains(methodLibraryNature))) { |
| if (debug) { |
| System.out |
| .println("### - adding methodlibrarynature to " + description.getName()); //$NON-NLS-1$ |
| } |
| description.setNatureIds(methodLibraryNatures); |
| project.setDescription(description, IProject.FORCE |
| | IProject.KEEP_HISTORY, monitor); |
| } |
| } catch (CoreException ex) { |
| LibraryPlugin.getDefault().getLogger().logError(ex); |
| throw ex; |
| } |
| } |
| |
| /** |
| * Closes a library's project. It finds the project by locating a project |
| * with the same location as the library. |
| * |
| * @param lib |
| * @param monitor |
| * @throws CoreException |
| */ |
| public static final void close(MethodLibrary lib, IProgressMonitor monitor) |
| throws CoreException { |
| // IProject project = findProject(lib); |
| // if (project != null && project.isOpen()) { |
| // if (debug) { |
| // System.out |
| // .println("### - closing project " + project.getName()); //$NON-NLS-1$ |
| // } |
| // project.close(monitor); |
| // } else { |
| // if (debug) { |
| // System.out |
| // .println("### - ERROR closing project for library in \"" + getLibraryDirectory(lib) + "\": project could not be found."); //$NON-NLS-1$ //$NON-NLS-2$ |
| // } |
| // } |
| |
| close(getLibraryDirectory(lib), monitor); |
| } |
| |
| /** |
| * |
| * @param dir String |
| * @param monitor IProgressMonitor |
| * @throws CoreException |
| */ |
| public static final void close(String dir, IProgressMonitor monitor) |
| throws CoreException { |
| IProject project = findProject(dir); |
| if (project != null && project.isOpen()) { |
| if (debug) { |
| System.out |
| .println("### - closing project " + project.getName()); //$NON-NLS-1$ |
| } |
| project.close(monitor); |
| |
| // stop monitoring change on the project |
| // |
| // RefreshManager.getInstance().unmonitor(project); |
| |
| } else { |
| if (debug) { |
| System.out |
| .println("### - ERROR closing project for library in \"" + dir + "\": project could not be found."); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| } |
| |
| |
| /** |
| * Locates the project with the same location as the library's directory. |
| * |
| * @param lib MethodLibrary |
| * @return IProject |
| */ |
| public static IProject findProject(MethodLibrary lib) { |
| return findProject(getLibraryDirectory(lib)); |
| } |
| |
| /** |
| * Locatest the project whose location matches the specified directory. |
| * |
| * @param dir String |
| * @return IProject |
| */ |
| public static IProject findProject(String dir) { |
| final IWorkspace workspace = ResourcesPlugin.getWorkspace(); |
| IProject[] projects = workspace.getRoot().getProjects(); |
| try { |
| for (int i = 0; i < projects.length; i++) { |
| IProject project = projects[i]; |
| if (new File(dir).compareTo(project.getLocation().toFile()) == 0) { |
| if (debug) { |
| System.out |
| .println("### - found project " + project.getName() + " with location " + dir); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| return project; |
| } |
| } |
| } catch (Exception ex) { |
| ex.printStackTrace(); |
| LibraryPlugin.getDefault().getLogger().logError(ex); |
| } |
| return null; |
| } |
| |
| /** |
| * Deletes the project whose location is the same as the library. |
| * |
| * @param lib MethodLibrary |
| * @param monitor IProgressMonitor |
| * @throws CoreException |
| */ |
| public static final boolean deleteProject(MethodLibrary lib, |
| IProgressMonitor monitor) throws CoreException { |
| return deleteProject(getLibraryDirectory(lib), monitor); |
| } |
| |
| /** |
| * Deletes the project whose location is the same as the given path. |
| * |
| * @param path |
| * @param monitor |
| * @return |
| * @throws CoreException |
| */ |
| private static boolean deleteProject(String path, IProgressMonitor monitor) |
| throws CoreException { |
| // delete any workspace project that exists for this path |
| IProject project = findProject(path); |
| try { |
| if (project != null) { |
| if (debug) { |
| System.out |
| .println("### - deleting project " + project.getName()); //$NON-NLS-1$ |
| } |
| if (monitor == null) { |
| monitor = new NullProgressMonitor(); |
| } |
| project.delete(IProject.FORCE |
| | IProject.NEVER_DELETE_PROJECT_CONTENT, monitor); |
| } |
| } catch (CoreException ex) { |
| ex.printStackTrace(); |
| LibraryPlugin.getDefault().getLogger().logError(ex); |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * Creates a project for the library. |
| * |
| * @return null if the library is not in a valid project location (ie, |
| * overlaps the workspace). |
| */ |
| public static IProject createProject(MethodLibrary lib, |
| IProgressMonitor monitor) { |
| return createValidProjectFromPath(getLibraryDirectory(lib), monitor); |
| } |
| |
| /** |
| * Creates a project for the path specified, using the last path fragment as |
| * the project name. Will append increasing integers to the project name in |
| * order to create a valid project. First deletes any workspace project |
| * whose location is the given path. |
| * |
| * @param path |
| * @param monitor |
| * @return IProject |
| */ |
| public static IProject createValidProjectFromPath(String path, |
| IProgressMonitor monitor) { |
| // delete any workspace project that exists for this path |
| IProject project = findProject(path); |
| try { |
| if (project != null) { |
| project.delete(IProject.FORCE |
| | IProject.NEVER_DELETE_PROJECT_CONTENT, monitor); |
| } |
| } catch (CoreException ex) { |
| LibraryPlugin.getDefault().getLogger().logError(ex); |
| return null; |
| } |
| |
| String libName = new File(path).getName(); |
| String libDir = new File(path).getAbsolutePath(); |
| |
| String projectName = libName; |
| int i = 2; |
| while (i < 100) { |
| try { |
| project = createProject(libDir, projectName, monitor); |
| if (debug) { |
| System.out |
| .println("### - creating new method library project " + projectName); //$NON-NLS-1$ |
| } |
| return project; |
| } catch (CoreException ex) { |
| projectName = new StringBuffer(libName).append(' ').append(i++) |
| .toString(); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Attempts to create a project named projectName in the directory dir. |
| * Throws CoreException if this fails for any reason. |
| * |
| * @param dir |
| * @param projectName |
| * @param monitor |
| * @return |
| * @throws CoreException |
| */ |
| private static final IProject createProject(String dir, String projectName, |
| IProgressMonitor monitor) throws CoreException { |
| IWorkspace workspace = ResourcesPlugin.getWorkspace(); |
| |
| // get a project handle |
| IProject newProjectHandle = workspace.getRoot().getProject(projectName); |
| IProjectDescription description = workspace |
| .newProjectDescription(newProjectHandle.getName()); |
| description.setNatureIds(methodLibraryNatures); |
| IPath projectPath = new Path(dir); |
| if (!Platform.getLocation().isPrefixOf(projectPath)) { |
| description.setLocation(projectPath); |
| } |
| |
| newProjectHandle.create(description, monitor); |
| return newProjectHandle; |
| } |
| |
| /** |
| * Closes all (open) projects that have the MethodLibrary nature |
| * |
| * @param monitor IProgressMonitor |
| */ |
| public static void closeAllMethodLibraryProjects(IProgressMonitor monitor) { |
| final IWorkspace workspace = ResourcesPlugin.getWorkspace(); |
| IProject[] projects = workspace.getRoot().getProjects(); |
| try { |
| for (int i = 0; i < projects.length; i++) { |
| IProject project = projects[i]; |
| if (project.isOpen() |
| && project.getNature(methodLibraryNature) != null) { |
| if (debug) { |
| System.out |
| .println("### - closing method library project " + project.getName()); //$NON-NLS-1$ |
| } |
| project.close(monitor); |
| } |
| } |
| } catch (CoreException ex) { |
| ex.printStackTrace(); |
| LibraryPlugin.getDefault().getLogger().logError(ex); |
| } |
| } |
| |
| /** |
| * |
| * @param lib MethodLibrary |
| * @return String |
| */ |
| public static String getLibraryDirectory(MethodLibrary lib) { |
| return new File(lib.eResource().getURI().toFileString()).getParent(); |
| } |
| |
| /** |
| * |
| * @param usedResources |
| * @return Collection |
| */ |
| public static Collection getOutOfSynchResources(Collection usedResources) { |
| ArrayList changedResources = new ArrayList(); |
| for (Iterator iter = usedResources.iterator(); iter.hasNext();) { |
| Resource resource = (Resource) iter.next(); |
| String filePath = resource.getURI().toFileString(); |
| IResource wsRes = FileManager.getResourceForLocation(filePath); |
| if(wsRes != null && !wsRes.isSynchronized(IResource.DEPTH_ZERO)) { |
| changedResources.add(resource); |
| } |
| |
| } |
| return changedResources; |
| } |
| |
| /** |
| * |
| * @param resources Collection |
| * @return boolean |
| */ |
| public static boolean hasOutOfSynch(Collection resources) { |
| for (Iterator iter = resources.iterator(); iter.hasNext();) { |
| Resource resource = (Resource) iter.next(); |
| if(resource.getURI().isFile()) { |
| String filePath = resource.getURI().toFileString(); |
| IResource wsRes = FileManager.getResourceForLocation(filePath); |
| if(wsRes != null && !wsRes.isSynchronized(IResource.DEPTH_ZERO)) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * |
| * @param resourcesToCheck Collection |
| * @param removedResources Collection |
| * @param changedResources Collection |
| */ |
| public static void checkOutOfSynchResources(Collection resourcesToCheck, |
| Collection removedResources, Collection changedResources) |
| { |
| for (Iterator iter = resourcesToCheck.iterator(); iter.hasNext();) { |
| Resource resource = (Resource) iter.next(); |
| String filePath = resource.getURI().toFileString(); |
| IResource wsRes = FileManager.getResourceForLocation(filePath); |
| if(wsRes == null) { |
| removedResources.add(resource); |
| } |
| else if(!wsRes.isSynchronized(IResource.DEPTH_ZERO)) { |
| changedResources.add(resource); |
| } |
| |
| } |
| } |
| |
| /** |
| * |
| * @param lib MethodLibrary |
| * @param monitor IProgressMonitor |
| */ |
| public static void refreshResources(MethodLibrary lib, IProgressMonitor monitor) { |
| if(lib != null) { |
| IProject prj = MethodLibraryProject.findProject(lib); |
| if(prj != null) { |
| try { |
| prj.refreshLocal(IResource.DEPTH_INFINITE, monitor); |
| } catch (CoreException e) { |
| LibraryPlugin.getDefault().getLogger().logError(e); |
| } |
| } |
| } |
| } |
| } |