1 /*******************************************************************************
2 * Copyright (C) 2008, 2009 Robin Rosenberg <robin.rosenberg@dewire.com>
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 * See LICENSE for the full license text, also available.
7 *******************************************************************************/
8 package org
.spearce
.egit
.ui
.internal
.decorators
;
10 import java
.io
.IOException
;
12 import java
.util
.WeakHashMap
;
14 import org
.eclipse
.core
.resources
.IEncodedStorage
;
15 import org
.eclipse
.core
.resources
.IProject
;
16 import org
.eclipse
.core
.resources
.IResource
;
17 import org
.eclipse
.core
.runtime
.CoreException
;
18 import org
.eclipse
.jface
.text
.Document
;
19 import org
.eclipse
.team
.core
.RepositoryProvider
;
20 import org
.spearce
.egit
.core
.GitProvider
;
21 import org
.spearce
.egit
.core
.project
.RepositoryMapping
;
22 import org
.spearce
.egit
.ui
.Activator
;
23 import org
.spearce
.jgit
.lib
.Constants
;
24 import org
.spearce
.jgit
.lib
.IndexChangedEvent
;
25 import org
.spearce
.jgit
.lib
.ObjectLoader
;
26 import org
.spearce
.jgit
.lib
.RefsChangedEvent
;
27 import org
.spearce
.jgit
.lib
.Repository
;
28 import org
.spearce
.jgit
.lib
.RepositoryListener
;
29 import org
.spearce
.jgit
.lib
.Tree
;
30 import org
.spearce
.jgit
.lib
.TreeEntry
;
32 class GitDocument
extends Document
implements RepositoryListener
{
33 private final IResource resource
;
34 static Map
<GitDocument
,Repository
> doc2repo
= new WeakHashMap
<GitDocument
, Repository
>();
36 static GitDocument
create(final IResource resource
) throws IOException
{
37 GitDocument ret
= null;
38 if (RepositoryProvider
.getProvider(resource
.getProject()) instanceof GitProvider
) {
39 ret
= new GitDocument(resource
);
45 private GitDocument(IResource resource
) {
46 this.resource
= resource
;
47 GitDocument
.doc2repo
.put(this, getRepository());
50 void populate() throws IOException
{
52 final IProject project
= resource
.getProject();
53 RepositoryMapping mapping
= RepositoryMapping
.getMapping(project
);
56 final String gitPath
= mapping
.getRepoRelativePath(resource
);
57 final Repository repository
= getRepository();
58 repository
.addRepositoryChangedListener(this);
59 String baseline
= GitQuickDiffProvider
.baseline
.get(repository
);
61 baseline
= Constants
.HEAD
;
62 Tree baselineTree
= repository
.mapTree(baseline
);
63 if (baselineTree
== null) {
64 Activator
.logError("Could not resolve quickdiff baseline "
65 + baseline
+ " corresponding to " + resource
+ " in "
66 + repository
, new Throwable());
69 TreeEntry blobEnry
= baselineTree
.findBlobMember(gitPath
);
70 if (blobEnry
!= null) {
71 Activator
.trace("(GitQuickDiffProvider) compareTo: " + baseline
);
72 ObjectLoader loader
= repository
.openBlob(blobEnry
.getId());
73 byte[] bytes
= loader
.getBytes();
75 // Get the encoding for the current version. As a matter of
76 // principle one might want to use the eclipse settings for the
77 // version we are retrieving as that may be defined by the
78 // project settings, but there is no historic API for this.
79 IEncodedStorage encodedStorage
= ((IEncodedStorage
)resource
);
81 if (encodedStorage
!= null)
82 charset
= encodedStorage
.getCharset();
84 charset
= resource
.getParent().getDefaultCharset();
85 } catch (CoreException e
) {
86 charset
= Constants
.CHARACTER_ENCODING
;
88 // Finally we could consider validating the content with respect
89 // to the content. We don't do that here.
90 String s
= new String(bytes
, charset
);
92 Activator
.trace("(GitQuickDiffProvider) has reference doc, size=" + s
.length() + " bytes");
94 Activator
.trace("(GitQuickDiffProvider) no revision.");
99 doc2repo
.remove(this);
100 Repository repository
= getRepository();
101 if (repository
!= null)
102 repository
.removeRepositoryChangedListener(this);
105 public void refsChanged(final RefsChangedEvent e
) {
108 } catch (IOException e1
) {
109 Activator
.logError("Failed to refresh quickdiff", e1
);
113 public void indexChanged(final IndexChangedEvent e
) {
114 // Index not relevant at this moment
117 private Repository
getRepository() {
118 IProject project
= resource
.getProject();
119 RepositoryMapping mapping
= RepositoryMapping
.getMapping(project
);
121 return mapping
.getRepository();
126 * A change occurred to a repository. Update any GitDocument instances
127 * referring to such repositories.
129 * @param repository Repository which changed
130 * @throws IOException
132 static void refreshRelevant(final Repository repository
) throws IOException
{
133 for (Map
.Entry
<GitDocument
, Repository
> i
: doc2repo
.entrySet()) {
134 if (i
.getValue() == repository
) {
135 i
.getKey().populate();