| /******************************************************************************* |
| * Copyright (c) 2000, 2010 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 API and implementation |
| *******************************************************************************/ |
| package org.eclipse.egit.internal.relengtools; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IResourceChangeEvent; |
| import org.eclipse.core.resources.IResourceChangeListener; |
| import org.eclipse.core.resources.IResourceDelta; |
| import org.eclipse.core.resources.IWorkspace; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.egit.core.GitTag; |
| |
| public class MapProject implements IResourceChangeListener { |
| |
| public static final String MAP_PROJECT_NAME = Messages |
| .getString("RelEngPlugin.1"); //$NON-NLS-1$ |
| |
| public static final String MAP_FOLDER = Messages |
| .getString("RelEngPlugin.2"); //$NON-NLS-1$ |
| |
| private static MapProject mapProject = null; |
| |
| private IProject project; |
| |
| private MapFile[] mapFiles; |
| |
| /** |
| * Return the default map project (org.eclipse.releng) or <code>null</code> |
| * if the project does not exist or there is an error processing it. If |
| * there is an error, it will be logged. |
| * |
| * @return the default map project |
| */ |
| public static MapProject getDefaultMapProject() { |
| if (mapProject == null) { |
| IProject project = getProjectFromWorkspace(); |
| try { |
| mapProject = new MapProject(project); |
| } catch (CoreException e) { |
| // RelEngPlugin.log(e); |
| } |
| } |
| return mapProject; |
| } |
| |
| private static IProject getProjectFromWorkspace() { |
| IWorkspace workspace = ResourcesPlugin.getWorkspace(); |
| IWorkspaceRoot root = workspace.getRoot(); |
| IProject project = root.getProject(MAP_PROJECT_NAME); |
| return project; |
| } |
| |
| public MapProject(IProject p) throws CoreException { |
| this.project = p; |
| loadMapFiles(); |
| ResourcesPlugin.getWorkspace().addResourceChangeListener(this, |
| IResourceChangeEvent.POST_CHANGE); |
| } |
| |
| public IProject getProject() { |
| return project; |
| } |
| |
| public void setProject(IProject p) { |
| this.project = p; |
| } |
| |
| private MapFile getMapFile(IProject p) { |
| for (int i = 0; i < mapFiles.length; i++) { |
| if (mapFiles[i].contains(p)) { |
| return mapFiles[i]; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Return the MapEntry for the given project |
| * |
| * @param string |
| * @param string1 |
| */ |
| public MapEntry getMapEntry(IProject p) { |
| MapFile file = getMapFile(p); |
| if (file != null) { |
| return file.getMapEntry(p); |
| } |
| return null; |
| } |
| |
| public boolean mapsAreLoaded() { |
| return project.exists(); |
| } |
| |
| public MapFile[] getValidMapFiles() { |
| List list = new ArrayList(); |
| for (int i = 0; i < mapFiles.length; i++) { |
| IProject[] projects = mapFiles[i].getAccessibleProjects(); |
| if (projects != null && projects.length > 0) { |
| list.add(mapFiles[i]); |
| } |
| } |
| return (MapFile[]) list.toArray(new MapFile[list.size()]); |
| } |
| |
| /** |
| * @param aProject |
| * The map entry of the specified project will be changed to the |
| * specified tag |
| * @param tag |
| * The specified tag |
| * @return returns if no map file having such a map entry is found |
| */ |
| public void updateFile(IProject aProject, String tag) throws CoreException { |
| MapFile aFile = getMapFile(aProject); |
| if (aFile == null) |
| return; |
| MapContentDocument changed = new MapContentDocument(aFile); |
| changed.updateTag(aProject, tag); |
| if (changed.isChanged()) { |
| aFile.getFile().setContents(changed.getContents(), |
| IFile.KEEP_HISTORY, null); |
| } |
| } |
| |
| public void commitMapProject(String comment, IProgressMonitor monitor) |
| throws CoreException { |
| // try { |
| // new CommitOperation(null, |
| // RepositoryProviderOperation.asResourceMappers(new IResource[] { |
| // project }), new Command.LocalOption[0], comment).run(monitor); |
| // } catch (InvocationTargetException e) { |
| // throw TeamException.asTeamException(e); |
| // } catch (InterruptedException e) { |
| // // Ignore; |
| // e.printStackTrace(); |
| // } |
| } |
| |
| public MapFile[] getMapFilesFor(IProject[] projects) { |
| Set alist = new HashSet(); |
| for (int i = 0; i < projects.length; i++) { |
| MapFile aMapFile = getMapFile(projects[i]); |
| alist.add(aMapFile); |
| } |
| return (MapFile[]) alist.toArray(new MapFile[alist.size()]); |
| } |
| |
| /** |
| * Get the tags for the given projects. If no tag is found for whatever |
| * reason, HEAD is used. |
| * |
| * @param projects |
| * @return |
| */ |
| public GitTag[] getTagsFor(IProject[] projects) { |
| if (projects == null || projects.length == 0) |
| return null; |
| GitTag[] tags = new GitTag[projects.length]; |
| for (int i = 0; i < tags.length; i++) { |
| MapEntry entry = getMapEntry(projects[i]); |
| if (entry == null) |
| tags[i] = MapEntry.DEFAULT; |
| else |
| tags[i] = entry.getTag(); |
| } |
| return tags; |
| } |
| |
| /** |
| * Deregister the IResourceChangeListner. It is reserved for use in the |
| * future. It is never called for now |
| */ |
| public void dispose() { |
| ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); |
| mapFiles = null; |
| } |
| |
| /** |
| * @see IResourceChangeListener#resourceChanged(IResourceChangeEvent) |
| */ |
| public void resourceChanged(IResourceChangeEvent event) { |
| IResourceDelta root = event.getDelta(); |
| |
| // TODO: Need to add code to handle map project deletion, addition and |
| // rename |
| IResourceDelta folderDelta = root.findMember(getMapFolder() |
| .getFullPath()); |
| if (folderDelta == null) |
| return; |
| |
| // Handle map files deletion, addition and rename |
| IResourceDelta[] deltas = folderDelta.getAffectedChildren(); |
| if (deltas == null || deltas.length == 0) |
| return; |
| for (int i = 0; i < deltas.length; i++) { |
| IResourceDelta delta = deltas[i]; |
| if (delta.getResource().getType() == IResource.FILE) { |
| try { |
| IFile aFile = (IFile) (delta.getResource()); |
| MapFile mFile = null; |
| if (MapFile.isMapFile(aFile)) { |
| // Handle content change |
| if (delta.getKind() == IResourceDelta.CHANGED) { |
| mFile = getMapFileFor(aFile); |
| mFile.loadEntries(); |
| } |
| // Handle deletion. We cannot simply remove the map file |
| // directly bacause we have to call |
| // getMapFileFor(IFile) in order to do so. But the IFile |
| // is already deleted. So we have to |
| // reconstuct the map files. |
| if (delta.getKind() == IResourceDelta.REMOVED) { |
| loadMapFiles(); |
| } |
| // Handle addition |
| if (delta.getKind() == IResourceDelta.ADDED) { |
| mFile = getMapFileFor(aFile); |
| addMapFile(mFile); |
| } |
| } |
| } catch (CoreException e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| } |
| |
| private IFolder getMapFolder() { |
| return getProject().getFolder(MAP_FOLDER); |
| } |
| |
| private void loadMapFiles() throws CoreException { |
| mapFiles = MapFile.findAllMapFiles(project); |
| } |
| |
| private MapFile getMapFileFor(IFile file) throws CoreException { |
| for (int i = 0; i < mapFiles.length; i++) { |
| if (mapFiles[i].getFile().equals(file)) |
| return mapFiles[i]; |
| } |
| return new MapFile(file); |
| } |
| |
| private void addMapFile(MapFile aFile) { |
| Set set = new HashSet(Arrays.asList(mapFiles)); |
| set.add(aFile); |
| mapFiles = (MapFile[]) set.toArray(new MapFile[set.size()]); |
| } |
| } |