Capture current selection before opening dialogs in replace actions
[egit/eclipse.git] / org.eclipse.egit.core / src / org / eclipse / egit / core / internal / merge / GitResourceVariantTreeSubscriber.java
blob97f040691c999e15d95004c5bafed1f0d1209aca
1 /*******************************************************************************
2 * Copyright (C) 2015, Obeo.
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9 package org.eclipse.egit.core.internal.merge;
11 import java.util.Arrays;
12 import java.util.Set;
14 import org.eclipse.core.resources.IResource;
15 import org.eclipse.core.runtime.CoreException;
16 import org.eclipse.egit.core.internal.CoreText;
17 import org.eclipse.team.core.TeamException;
18 import org.eclipse.team.core.diff.IDiff;
19 import org.eclipse.team.core.synchronize.SyncInfo;
20 import org.eclipse.team.core.variants.IResourceVariant;
21 import org.eclipse.team.core.variants.IResourceVariantComparator;
22 import org.eclipse.team.core.variants.IResourceVariantTree;
23 import org.eclipse.team.core.variants.ResourceVariantTreeSubscriber;
24 import org.eclipse.team.internal.core.mapping.SyncInfoToDiffConverter;
26 /**
27 * This implementation of a {@link ResourceVariantTreeSubscriber} takes its
28 * input from a {@link GitResourceVariantTreeProvider}.
29 * <p>
30 * This allows us to hijack all calls from the default subscriber for "local"
31 * resources to our actual source tree, which could be the local working
32 * directory as well as it could be a branch.
33 * </p>
35 public class GitResourceVariantTreeSubscriber extends
36 ResourceVariantTreeSubscriber {
37 private GitResourceVariantTreeProvider variantTreeProvider;
39 private final SyncInfoToDiffConverter syncInfoConverter;
41 private final IResourceVariantComparator comparator;
43 /**
44 * @param variantTreeProvider
45 * The instance that will provide the base, source and remote
46 * trees to this subscriber.
48 public GitResourceVariantTreeSubscriber(
49 GitResourceVariantTreeProvider variantTreeProvider) {
50 this.variantTreeProvider = variantTreeProvider;
51 syncInfoConverter = new GitSyncInfoToDiffConverter(variantTreeProvider);
52 comparator = new GitVariantComparator(
53 variantTreeProvider.getSourceTree());
56 @Override
57 protected IResourceVariantTree getBaseTree() {
58 return variantTreeProvider.getBaseTree();
61 @Override
62 protected IResourceVariantTree getRemoteTree() {
63 return variantTreeProvider.getRemoteTree();
66 /**
67 * @return the source resource variant tree.
69 protected IResourceVariantTree getSourceTree() {
70 return variantTreeProvider.getSourceTree();
73 @Override
74 public IDiff getDiff(IResource resource) throws CoreException {
75 final SyncInfo info = getSyncInfo(resource);
76 if (info == null || info.getKind() == SyncInfo.IN_SYNC)
77 return null;
78 return syncInfoConverter.getDeltaFor(info);
81 @Override
82 public SyncInfo getSyncInfo(IResource resource) throws TeamException {
83 // Overridden here to properly catch and re-throw the forwarded
84 // TeamException
85 try {
86 return super.getSyncInfo(resource);
87 } catch (ForwardedTeamException e) {
88 throw (TeamException) e.getCause();
92 @Override
93 public String getName() {
94 return CoreText.GitResourceVariantTreeSubscriber_name;
97 @Override
98 public boolean isSupervised(IResource resource) throws TeamException {
99 return variantTreeProvider.getKnownResources().contains(resource);
102 @Override
103 public IResource[] roots() {
104 final Set<IResource> roots = variantTreeProvider.getRoots();
105 return roots.toArray(new IResource[roots.size()]);
108 @Override
109 public IResourceVariantComparator getResourceComparator() {
110 return comparator;
114 * We have a source tree whereas Team only knows about "local" files. This
115 * will always use said {@link #oursTree source tree} when comparing
116 * variants.
118 private static class GitVariantComparator implements
119 IResourceVariantComparator {
120 private final IResourceVariantTree oursTree;
122 public GitVariantComparator(IResourceVariantTree oursTree) {
123 this.oursTree = oursTree;
126 @Override
127 public boolean compare(IResource local, IResourceVariant remote) {
128 try {
129 final IResourceVariant oursVariant = oursTree
130 .getResourceVariant(local);
131 if (oursVariant == null)
132 return remote == null;
133 return compare(oursVariant, remote);
134 } catch (TeamException e) {
135 // We can't throw the TeamException from here, but we can't let
136 // the comparison go through either.
137 // This is only called from "getSyncInfo", we'll forward this
138 // exception and rethrow it from there.
139 throw new ForwardedTeamException(e);
143 @Override
144 public boolean compare(IResourceVariant base, IResourceVariant remote) {
145 return Arrays.equals(base.asBytes(), remote.asBytes());
148 @Override
149 public boolean isThreeWay() {
150 return true;
155 * This should never be thrown outside of this class. The only purpose of
156 * this exception is to encapsulate a TeamException where it cannot be
157 * thrown.
159 private static class ForwardedTeamException extends RuntimeException {
160 /** Generated SUID. */
161 private static final long serialVersionUID = 4074010396155542178L;
163 public ForwardedTeamException(TeamException e) {
164 super(e);