Replace System.out with proper tracing
[egit/spearce.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / decorators / GitDocument.java
blobb5e238eaecdb59d837601adf603be649c1cf74bd
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 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9 package org.eclipse.egit.ui.internal.decorators;
11 import java.io.IOException;
12 import java.util.Map;
13 import java.util.WeakHashMap;
15 import org.eclipse.core.resources.IEncodedStorage;
16 import org.eclipse.core.resources.IResource;
17 import org.eclipse.core.runtime.CoreException;
18 import org.eclipse.egit.core.GitProvider;
19 import org.eclipse.egit.core.internal.trace.GitTraceLocation;
20 import org.eclipse.egit.core.project.RepositoryMapping;
21 import org.eclipse.egit.ui.Activator;
22 import org.eclipse.jface.text.Document;
23 import org.eclipse.team.core.RepositoryProvider;
24 import org.eclipse.jgit.lib.AnyObjectId;
25 import org.eclipse.jgit.lib.Commit;
26 import org.eclipse.jgit.lib.Constants;
27 import org.eclipse.jgit.lib.IndexChangedEvent;
28 import org.eclipse.jgit.lib.ObjectId;
29 import org.eclipse.jgit.lib.ObjectLoader;
30 import org.eclipse.jgit.lib.RefsChangedEvent;
31 import org.eclipse.jgit.lib.Repository;
32 import org.eclipse.jgit.lib.RepositoryListener;
33 import org.eclipse.jgit.lib.Tree;
34 import org.eclipse.jgit.lib.TreeEntry;
36 class GitDocument extends Document implements RepositoryListener {
37 private final IResource resource;
39 private ObjectId lastCommit;
40 private ObjectId lastTree;
41 private ObjectId lastBlob;
43 static Map<GitDocument,Repository> doc2repo = new WeakHashMap<GitDocument, Repository>();
45 static GitDocument create(final IResource resource) throws IOException {
46 // TODO is this the right location?
47 if (GitTraceLocation.UI.isActive())
48 GitTraceLocation.getTrace().trace(
49 GitTraceLocation.UI.getLocation(),
50 "(GitDocument) create: " + resource); //$NON-NLS-1$
51 GitDocument ret = null;
52 if (RepositoryProvider.getProvider(resource.getProject()) instanceof GitProvider) {
53 ret = new GitDocument(resource);
54 ret.populate();
55 final Repository repository = ret.getRepository();
56 if (repository != null)
57 repository.addRepositoryChangedListener(ret);
59 return ret;
62 private GitDocument(IResource resource) {
63 this.resource = resource;
64 GitDocument.doc2repo.put(this, getRepository());
67 private void setResolved(final AnyObjectId commit, final AnyObjectId tree, final AnyObjectId blob, final String value) {
68 lastCommit = commit != null ? commit.copy() : null;
69 lastTree = tree != null ? tree.copy() : null;
70 lastBlob = blob != null ? blob.copy() : null;
71 set(value);
72 if (blob != null)
73 // TODO is this the right location?
74 if (GitTraceLocation.UI.isActive())
75 GitTraceLocation
76 .getTrace()
77 .trace(
78 GitTraceLocation.UI.getLocation(),
79 "(GitDocument) resolved " + resource + " to " + lastBlob + " in " + lastCommit + "/" + lastTree); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
80 else
81 // TODO is this the right location?
82 if (GitTraceLocation.UI.isActive())
83 GitTraceLocation.getTrace().trace(
84 GitTraceLocation.UI.getLocation(),
85 "(GitDocument) unresolved " + resource); //$NON-NLS-1$
88 void populate() throws IOException {
89 // TODO is this the right location?
90 if (GitTraceLocation.UI.isActive())
91 GitTraceLocation.getTrace().trace(
92 GitTraceLocation.UI.getLocation(),"(GitDocument) populate: " + resource); //$NON-NLS-1$
93 RepositoryMapping mapping = RepositoryMapping.getMapping(resource);
94 if (mapping == null) {
95 setResolved(null, null, null, ""); //$NON-NLS-1$
96 return;
98 final String gitPath = mapping.getRepoRelativePath(resource);
99 final Repository repository = mapping.getRepository();
100 String baseline = GitQuickDiffProvider.baseline.get(repository);
101 if (baseline == null)
102 baseline = Constants.HEAD;
103 ObjectId commitId = repository.resolve(baseline);
104 if (commitId != null) {
105 if (commitId.equals(lastCommit)) {
106 // TODO is this the right location?
107 if (GitTraceLocation.UI.isActive())
108 GitTraceLocation.getTrace().trace(
109 GitTraceLocation.UI.getLocation(),
110 "(GitDocument) already resolved"); //$NON-NLS-1$
111 return;
113 } else {
114 Activator.logError("Could not resolve quickdiff baseline "
115 + baseline + " corresponding to " + resource + " in "
116 + repository, new Throwable());
117 setResolved(null, null, null, ""); //$NON-NLS-1$
118 return;
120 Commit baselineCommit = repository.mapCommit(commitId);
121 if (baselineCommit == null) {
122 Activator.logError("Could not load commit " + commitId + " for "
123 + baseline + " corresponding to " + resource + " in "
124 + repository, new Throwable());
125 setResolved(null, null, null, ""); //$NON-NLS-1$
126 return;
128 ObjectId treeId = baselineCommit.getTreeId();
129 if (treeId.equals(lastTree)) {
130 // TODO is this the right location?
131 if (GitTraceLocation.UI.isActive())
132 GitTraceLocation.getTrace().trace(
133 GitTraceLocation.UI.getLocation(),
134 "(GitDocument) already resolved"); //$NON-NLS-1$
135 return;
137 Tree baselineTree = baselineCommit.getTree();
138 if (baselineTree == null) {
139 Activator.logError("Could not load tree " + treeId + " for "
140 + baseline + " corresponding to " + resource + " in "
141 + repository, new Throwable());
142 setResolved(null, null, null, ""); //$NON-NLS-1$
143 return;
145 TreeEntry blobEntry = baselineTree.findBlobMember(gitPath);
146 if (blobEntry != null && !blobEntry.getId().equals(lastBlob)) {
147 // TODO is this the right location?
148 if (GitTraceLocation.UI.isActive())
149 GitTraceLocation.getTrace().trace(
150 GitTraceLocation.UI.getLocation(),
151 "(GitDocument) compareTo: " + baseline); //$NON-NLS-1$
152 ObjectLoader loader = repository.openBlob(blobEntry.getId());
153 byte[] bytes = loader.getBytes();
154 String charset;
155 // Get the encoding for the current version. As a matter of
156 // principle one might want to use the eclipse settings for the
157 // version we are retrieving as that may be defined by the
158 // project settings, but there is no historic API for this.
159 IEncodedStorage encodedStorage = ((IEncodedStorage)resource);
160 try {
161 if (encodedStorage != null)
162 charset = encodedStorage.getCharset();
163 else
164 charset = resource.getParent().getDefaultCharset();
165 } catch (CoreException e) {
166 charset = Constants.CHARACTER_ENCODING;
168 // Finally we could consider validating the content with respect
169 // to the content. We don't do that here.
170 String s = new String(bytes, charset);
171 setResolved(commitId, baselineTree.getId(), blobEntry.getId(), s);
172 // TODO is this the right location?
173 if (GitTraceLocation.UI.isActive())
174 GitTraceLocation
175 .getTrace()
176 .trace(
177 GitTraceLocation.UI.getLocation(),
178 "(GitDocument) has reference doc, size=" + s.length() + " bytes"); //$NON-NLS-1$ //$NON-NLS-2$
179 } else {
180 if (blobEntry == null)
181 setResolved(null, null, null, ""); //$NON-NLS-1$
182 else
183 // TODO is this the right location?
184 if (GitTraceLocation.UI.isActive())
185 GitTraceLocation.getTrace().trace(
186 GitTraceLocation.UI.getLocation(),
187 "(GitDocument) already resolved"); //$NON-NLS-1$
191 void dispose() {
192 // TODO is this the right location?
193 if (GitTraceLocation.UI.isActive())
194 GitTraceLocation.getTrace().trace(
195 GitTraceLocation.UI.getLocation(),
196 "(GitDocument) dispose: " + resource); //$NON-NLS-1$
197 doc2repo.remove(this);
198 Repository repository = getRepository();
199 if (repository != null)
200 repository.removeRepositoryChangedListener(this);
203 public void refsChanged(final RefsChangedEvent e) {
204 try {
205 populate();
206 } catch (IOException e1) {
207 Activator.logError("Failed to refresh quickdiff", e1);
211 public void indexChanged(final IndexChangedEvent e) {
212 // Index not relevant at this moment
215 private Repository getRepository() {
216 RepositoryMapping mapping = RepositoryMapping.getMapping(resource);
217 return (mapping != null) ? mapping.getRepository() : null;
221 * A change occurred to a repository. Update any GitDocument instances
222 * referring to such repositories.
224 * @param repository Repository which changed
225 * @throws IOException
227 static void refreshRelevant(final Repository repository) throws IOException {
228 for (Map.Entry<GitDocument, Repository> i : doc2repo.entrySet()) {
229 if (i.getValue() == repository) {
230 i.getKey().populate();