Remove System.out.println from RevWalkFilterTest
[jgit.git] / org.spearce.egit.ui / src / org / spearce / egit / ui / internal / decorators / GitDocument.java
blob16f01ced523c63173dbbf2010516d89b7bbc2fff
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;
11 import java.util.Map;
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.AnyObjectId;
24 import org.spearce.jgit.lib.Commit;
25 import org.spearce.jgit.lib.Constants;
26 import org.spearce.jgit.lib.IndexChangedEvent;
27 import org.spearce.jgit.lib.ObjectId;
28 import org.spearce.jgit.lib.ObjectLoader;
29 import org.spearce.jgit.lib.RefsChangedEvent;
30 import org.spearce.jgit.lib.Repository;
31 import org.spearce.jgit.lib.RepositoryListener;
32 import org.spearce.jgit.lib.Tree;
33 import org.spearce.jgit.lib.TreeEntry;
35 class GitDocument extends Document implements RepositoryListener {
36 private final IResource resource;
38 private ObjectId lastCommit;
39 private ObjectId lastTree;
40 private ObjectId lastBlob;
42 static Map<GitDocument,Repository> doc2repo = new WeakHashMap<GitDocument, Repository>();
44 static GitDocument create(final IResource resource) throws IOException {
45 Activator.trace("(GitDocument) create: " + resource);
46 GitDocument ret = null;
47 if (RepositoryProvider.getProvider(resource.getProject()) instanceof GitProvider) {
48 ret = new GitDocument(resource);
49 ret.populate();
50 final Repository repository = ret.getRepository();
51 if (repository != null)
52 repository.addRepositoryChangedListener(ret);
54 return ret;
57 private GitDocument(IResource resource) {
58 this.resource = resource;
59 GitDocument.doc2repo.put(this, getRepository());
62 private void setResolved(final AnyObjectId commit, final AnyObjectId tree, final AnyObjectId blob, final String value) {
63 lastCommit = commit != null ? commit.copy() : null;
64 lastTree = tree != null ? tree.copy() : null;
65 lastBlob = blob != null ? blob.copy() : null;
66 set(value);
67 if (blob != null)
68 Activator.trace("(GitDocument) resolved " + resource + " to " + lastBlob + " in " + lastCommit + "/" + lastTree);
69 else
70 Activator.trace("(GitDocument) unresolved " + resource);
73 void populate() throws IOException {
74 Activator.trace("(GitDocument) populate: " + resource);
75 final IProject project = resource.getProject();
76 RepositoryMapping mapping = RepositoryMapping.getMapping(project);
77 if (mapping == null) {
78 setResolved(null, null, null, "");
79 return;
81 final String gitPath = mapping.getRepoRelativePath(resource);
82 final Repository repository = mapping.getRepository();
83 String baseline = GitQuickDiffProvider.baseline.get(repository);
84 if (baseline == null)
85 baseline = Constants.HEAD;
86 ObjectId commitId = repository.resolve(baseline);
87 if (commitId != null) {
88 if (commitId.equals(lastCommit)) {
89 Activator.trace("(GitDocument) already resolved");
90 return;
92 } else {
93 Activator.logError("Could not resolve quickdiff baseline "
94 + baseline + " corresponding to " + resource + " in "
95 + repository, new Throwable());
96 setResolved(null, null, null, "");
97 return;
99 Commit baselineCommit = repository.mapCommit(commitId);
100 if (baselineCommit == null) {
101 Activator.logError("Could not load commit " + commitId + " for "
102 + baseline + " corresponding to " + resource + " in "
103 + repository, new Throwable());
104 setResolved(null, null, null, "");
105 return;
107 ObjectId treeId = baselineCommit.getTreeId();
108 if (treeId.equals(lastTree)) {
109 Activator.trace("(GitDocument) already resolved");
110 return;
112 Tree baselineTree = baselineCommit.getTree();
113 if (baselineTree == null) {
114 Activator.logError("Could not load tree " + treeId + " for "
115 + baseline + " corresponding to " + resource + " in "
116 + repository, new Throwable());
117 setResolved(null, null, null, "");
118 return;
120 TreeEntry blobEntry = baselineTree.findBlobMember(gitPath);
121 if (blobEntry != null && !blobEntry.getId().equals(lastBlob)) {
122 Activator.trace("(GitDocument) compareTo: " + baseline);
123 ObjectLoader loader = repository.openBlob(blobEntry.getId());
124 byte[] bytes = loader.getBytes();
125 String charset;
126 // Get the encoding for the current version. As a matter of
127 // principle one might want to use the eclipse settings for the
128 // version we are retrieving as that may be defined by the
129 // project settings, but there is no historic API for this.
130 IEncodedStorage encodedStorage = ((IEncodedStorage)resource);
131 try {
132 if (encodedStorage != null)
133 charset = encodedStorage.getCharset();
134 else
135 charset = resource.getParent().getDefaultCharset();
136 } catch (CoreException e) {
137 charset = Constants.CHARACTER_ENCODING;
139 // Finally we could consider validating the content with respect
140 // to the content. We don't do that here.
141 String s = new String(bytes, charset);
142 setResolved(commitId, baselineTree.getId(), blobEntry.getId(), s);
143 Activator.trace("(GitDocument) has reference doc, size=" + s.length() + " bytes");
144 } else {
145 if (blobEntry == null)
146 setResolved(null, null, null, "");
147 else
148 Activator.trace("(GitDocument) already resolved");
152 void dispose() {
153 Activator.trace("(GitDocument) dispose: " + resource);
154 doc2repo.remove(this);
155 Repository repository = getRepository();
156 if (repository != null)
157 repository.removeRepositoryChangedListener(this);
160 public void refsChanged(final RefsChangedEvent e) {
161 try {
162 populate();
163 } catch (IOException e1) {
164 Activator.logError("Failed to refresh quickdiff", e1);
168 public void indexChanged(final IndexChangedEvent e) {
169 // Index not relevant at this moment
172 private Repository getRepository() {
173 IProject project = resource.getProject();
174 RepositoryMapping mapping = RepositoryMapping.getMapping(project);
175 if (mapping != null)
176 return mapping.getRepository();
177 return null;
181 * A change occurred to a repository. Update any GitDocument instances
182 * referring to such repositories.
184 * @param repository Repository which changed
185 * @throws IOException
187 static void refreshRelevant(final Repository repository) throws IOException {
188 for (Map.Entry<GitDocument, Repository> i : doc2repo.entrySet()) {
189 if (i.getValue() == repository) {
190 i.getKey().populate();