/******************************************************************************* | |
* Copyright (C) 2015, Obeo. | |
* | |
* 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 | |
*******************************************************************************/ | |
package org.eclipse.emf.compare.egit.internal.merge; | |
//CHECKSTYLE:OFF | |
import java.io.IOException; | |
import java.util.LinkedHashSet; | |
import java.util.Set; | |
import org.eclipse.core.resources.IResource; | |
import org.eclipse.emf.compare.egit.internal.ModelEGitResourceUtil; | |
import org.eclipse.emf.compare.egit.internal.storage.GitLocalResourceVariant; | |
import org.eclipse.emf.compare.egit.internal.storage.IndexResourceVariant; | |
import org.eclipse.jgit.dircache.DirCache; | |
import org.eclipse.jgit.dircache.DirCacheEntry; | |
import org.eclipse.jgit.lib.FileMode; | |
import org.eclipse.jgit.lib.Repository; | |
import org.eclipse.team.core.variants.IResourceVariantTree; | |
/** | |
* This will populate its three {@link IResourceVariantTree} by looking up information within the repository's | |
* DirCache. | |
* <p> | |
* Files that are not located within the workspace will be ignored and thus will not be accessible through the | |
* trees created by this provider. | |
* </p> | |
* | |
* @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a> | |
*/ | |
public class DirCacheResourceVariantTreeProvider implements GitResourceVariantTreeProvider { | |
private final IResourceVariantTree baseTree; | |
private final IResourceVariantTree sourceTree; | |
private final IResourceVariantTree remoteTree; | |
private final Set<IResource> roots; | |
private final Set<IResource> knownResources; | |
private final Repository repository; | |
/** | |
* Constructs the resource variant trees by iterating over the given repository's DirCache entries. | |
* | |
* @param repository | |
* The repository which DirCache info we need to cache as IResourceVariantTrees. | |
* @param useWorkspace | |
* Whether we should use local data instead of what's in the index for our side. | |
* @throws IOException | |
* if we somehow cannot read the DirCache. | |
*/ | |
public DirCacheResourceVariantTreeProvider(Repository repository, boolean useWorkspace) | |
throws IOException { | |
this.repository = repository; | |
final DirCache cache = repository.readDirCache(); | |
final GitResourceVariantCache baseCache = new GitResourceVariantCache(); | |
final GitResourceVariantCache sourceCache = new GitResourceVariantCache(); | |
final GitResourceVariantCache remoteCache = new GitResourceVariantCache(); | |
for (int i = 0; i < cache.getEntryCount(); i++) { | |
final DirCacheEntry entry = cache.getEntry(i); | |
final IResource resource = ModelEGitResourceUtil.getResourceHandleForLocation(repository, | |
entry.getPathString(), FileMode.fromBits(entry.getRawMode()) == FileMode.TREE); | |
// Resource variants only make sense for IResources. Do not consider | |
// files outside of the workspace or otherwise non accessible. | |
if (resource == null || resource.getProject() == null || !resource.getProject().isAccessible()) { | |
continue; | |
} | |
switch (entry.getStage()) { | |
case DirCacheEntry.STAGE_0: | |
if (useWorkspace) { | |
sourceCache.setVariant(resource, new GitLocalResourceVariant(resource)); | |
} else { | |
sourceCache.setVariant(resource, IndexResourceVariant.create(repository, entry)); | |
} | |
baseCache.setVariant(resource, IndexResourceVariant.create(repository, entry)); | |
remoteCache.setVariant(resource, IndexResourceVariant.create(repository, entry)); | |
break; | |
case DirCacheEntry.STAGE_1: | |
baseCache.setVariant(resource, IndexResourceVariant.create(repository, entry)); | |
break; | |
case DirCacheEntry.STAGE_2: | |
if (useWorkspace) { | |
sourceCache.setVariant(resource, new GitLocalResourceVariant(resource)); | |
} else { | |
sourceCache.setVariant(resource, IndexResourceVariant.create(repository, entry)); | |
} | |
break; | |
case DirCacheEntry.STAGE_3: | |
remoteCache.setVariant(resource, IndexResourceVariant.create(repository, entry)); | |
break; | |
default: | |
throw new IllegalStateException("Invalid stage: " + entry.getStage()); //$NON-NLS-1$ | |
} | |
} | |
baseTree = new GitCachedResourceVariantTree(baseCache); | |
sourceTree = new GitCachedResourceVariantTree(sourceCache); | |
remoteTree = new GitCachedResourceVariantTree(remoteCache); | |
roots = new LinkedHashSet<>(); | |
roots.addAll(baseCache.getRoots()); | |
roots.addAll(sourceCache.getRoots()); | |
roots.addAll(remoteCache.getRoots()); | |
knownResources = new LinkedHashSet<>(); | |
knownResources.addAll(baseCache.getKnownResources()); | |
knownResources.addAll(sourceCache.getKnownResources()); | |
knownResources.addAll(remoteCache.getKnownResources()); | |
} | |
public IResourceVariantTree getBaseTree() { | |
return baseTree; | |
} | |
public IResourceVariantTree getRemoteTree() { | |
return remoteTree; | |
} | |
public IResourceVariantTree getSourceTree() { | |
return sourceTree; | |
} | |
public Set<IResource> getKnownResources() { | |
return knownResources; | |
} | |
public Set<IResource> getRoots() { | |
return roots; | |
} | |
public Repository getRepository() { | |
return repository; | |
} | |
} | |
// CHECKSTYLE:ON |