blob: c93b6ec8a9bddf019c8ae5c956801dd145f81e5c [file] [log] [blame]
/*******************************************************************************
* 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