/******************************************************************************* * 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() { @Override public void indexDiffChanged(Repository repository, IndexDiffData indexDiffData) { handleRepositoryChange(repository); } }; resourceChangeListener = new IResourceChangeListener() { @Override 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(); } @Override 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); } @Override 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; } } }