/*******************************************************************************
* Copyright (C) 2010, 2013 Dariusz Luksza <dariusz@luksza.org> 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
*******************************************************************************/
package org.eclipse.egit.core.synchronize;
import java.io.IOException;
import java.util.Collection;
import org.eclipse.core.resources.IFile;
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.ResourcesPlugin;
import org.eclipse.core.resources.mapping.ResourceTraversal;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.internal.CoreText;
import org.eclipse.egit.core.internal.indexdiff.GitResourceDeltaVisitor;
import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
import org.eclipse.egit.core.internal.indexdiff.IndexDiffChangedListener;
import org.eclipse.egit.core.internal.indexdiff.IndexDiffData;
import org.eclipse.egit.core.op.AddToIndexOperation;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.diff.IDiff;
import org.eclipse.team.core.mapping.ISynchronizationScopeManager;
import org.eclipse.team.core.subscribers.SubscriberMergeContext;
/**
*
*/
public class GitSubscriberMergeContext extends SubscriberMergeContext {
private final GitSynchronizeDataSet gsds;
private final IndexDiffChangedListener indexChangeListener;
private final IResourceChangeListener resourceChangeListener;
private final GitResourceVariantTreeSubscriber subscriber;
/**
* @param subscriber
* @param manager
* @param gsds
*/
public GitSubscriberMergeContext(final GitResourceVariantTreeSubscriber subscriber,
ISynchronizationScopeManager manager, GitSynchronizeDataSet gsds) {
super(subscriber, manager);
this.subscriber = subscriber;
this.gsds = gsds;
indexChangeListener = new IndexDiffChangedListener() {
public void indexDiffChanged(Repository repository,
IndexDiffData indexDiffData) {
handleRepositoryChange(repository);
}
};
resourceChangeListener = new IResourceChangeListener() {
public void resourceChanged(IResourceChangeEvent event) {
IResourceDelta delta = event.getDelta();
if (delta == null)
return;
handleResourceChange(delta);
}
};
IndexDiffCache indexDiffCache = Activator.getDefault().getIndexDiffCache();
if (indexDiffCache != null)
indexDiffCache.addIndexDiffChangedListener(indexChangeListener);
ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceChangeListener);
initialize();
}
public void markAsMerged(IDiff node, boolean inSyncHint,
IProgressMonitor monitor) throws CoreException {
IResource resource = getDiffTree().getResource(node);
AddToIndexOperation operation = new AddToIndexOperation(
new IResource[] { resource });
operation.execute(monitor);
}
public void reject(IDiff diff, IProgressMonitor monitor)
throws CoreException {
// TODO Auto-generated method stub
}
/**
* @return git synchronization data
*/
public GitSynchronizeDataSet getSyncData() {
return gsds;
}
@Override
protected void makeInSync(IDiff diff, IProgressMonitor monitor)
throws CoreException {
// TODO Auto-generated method stub
}
@Override
public void dispose() {
Activator activator = Activator.getDefault();
if (activator == null)
return;
IndexDiffCache indexDiffCache = activator.getIndexDiffCache();
if (indexDiffCache != null)
indexDiffCache.removeIndexDiffChangedListener(indexChangeListener);
ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceChangeListener);
subscriber.dispose();
super.dispose();
}
private void handleRepositoryChange(Repository which) {
boolean shouldRefresh = false;
for (GitSynchronizeData gsd : gsds) {
if (which.equals(gsd.getRepository())) {
updateRevs(gsd);
shouldRefresh = true;
}
}
if (!shouldRefresh)
return;
subscriber.reset(this.gsds);
ResourceTraversal[] traversals = getScopeManager().getScope()
.getTraversals();
try {
subscriber.refresh(traversals, new NullProgressMonitor());
} catch (TeamException e) {
Activator.logError(
CoreText.GitSubscriberMergeContext_FailedRefreshSyncView, e);
}
}
private void handleResourceChange(IResourceDelta delta) {
IResourceDelta[] children = delta.getAffectedChildren();
for (IResourceDelta resourceDelta : children) {
IResource resource = resourceDelta.getResource();
RepositoryMapping mapping = RepositoryMapping.getMapping(resource);
if (mapping == null)
continue;
scanDeltaAndRefresh(mapping, resourceDelta);
}
}
private void scanDeltaAndRefresh(RepositoryMapping mapping,
IResourceDelta delta) {
Repository repo = mapping.getRepository();
GitResourceDeltaVisitor visitor = new GitResourceDeltaVisitor(repo);
try {
delta.accept(visitor);
Collection<IFile> files = visitor.getFileResourcesToUpdate();
if (files != null && files.isEmpty())
return;
for (GitSynchronizeData gsd : gsds) {
if (repo.equals(gsd.getRepository()))
refreshResources(files);
}
} catch (CoreException e) {
Activator.logError(e.getMessage(), e);
}
}
private void refreshResources(Collection<IFile> resources) {
IResource[] files = resources.toArray(new IResource[resources
.size()]);
try {
subscriber.refresh(files, IResource.DEPTH_ONE,
new NullProgressMonitor());
} catch (final CoreException e) {
Activator.logError(
CoreText.GitSubscriberMergeContext_FailedRefreshSyncView, e);
}
}
private void updateRevs(GitSynchronizeData gsd) {
try {
gsd.updateRevs();
} catch (IOException e) {
Activator.logError(
CoreText.GitSubscriberMergeContext_FailedUpdateRevs, e);
return;
}
}
}