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
;
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
;
27 * This implementation of a {@link ResourceVariantTreeSubscriber} takes its
28 * input from a {@link GitResourceVariantTreeProvider}.
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.
35 public class GitResourceVariantTreeSubscriber
extends
36 ResourceVariantTreeSubscriber
{
37 private GitResourceVariantTreeProvider variantTreeProvider
;
39 private final SyncInfoToDiffConverter syncInfoConverter
;
41 private final IResourceVariantComparator comparator
;
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());
57 protected IResourceVariantTree
getBaseTree() {
58 return variantTreeProvider
.getBaseTree();
62 protected IResourceVariantTree
getRemoteTree() {
63 return variantTreeProvider
.getRemoteTree();
67 * @return the source resource variant tree.
69 protected IResourceVariantTree
getSourceTree() {
70 return variantTreeProvider
.getSourceTree();
74 public IDiff
getDiff(IResource resource
) throws CoreException
{
75 final SyncInfo info
= getSyncInfo(resource
);
76 if (info
== null || info
.getKind() == SyncInfo
.IN_SYNC
)
78 return syncInfoConverter
.getDeltaFor(info
);
82 public SyncInfo
getSyncInfo(IResource resource
) throws TeamException
{
83 // Overridden here to properly catch and re-throw the forwarded
86 return super.getSyncInfo(resource
);
87 } catch (ForwardedTeamException e
) {
88 throw (TeamException
) e
.getCause();
93 public String
getName() {
94 return CoreText
.GitResourceVariantTreeSubscriber_name
;
98 public boolean isSupervised(IResource resource
) throws TeamException
{
99 return variantTreeProvider
.getKnownResources().contains(resource
);
103 public IResource
[] roots() {
104 final Set
<IResource
> roots
= variantTreeProvider
.getRoots();
105 return roots
.toArray(new IResource
[roots
.size()]);
109 public IResourceVariantComparator
getResourceComparator() {
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
118 private static class GitVariantComparator
implements
119 IResourceVariantComparator
{
120 private final IResourceVariantTree oursTree
;
122 public GitVariantComparator(IResourceVariantTree oursTree
) {
123 this.oursTree
= oursTree
;
127 public boolean compare(IResource local
, IResourceVariant remote
) {
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
);
144 public boolean compare(IResourceVariant base
, IResourceVariant remote
) {
145 return Arrays
.equals(base
.asBytes(), remote
.asBytes());
149 public boolean isThreeWay() {
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
159 private static class ForwardedTeamException
extends RuntimeException
{
160 /** Generated SUID. */
161 private static final long serialVersionUID
= 4074010396155542178L;
163 public ForwardedTeamException(TeamException e
) {