Use try-with-resource to avoid leaks with RevWalk and TreeWalk
[egit/eclipse.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / components / RefContentProposal.java
blobd332d6100669427a8bf47c2354b475603109b88a
1 /*******************************************************************************
2 * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
3 * Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com>
5 * All rights reserved. This program and the accompanying materials
6 * are made available under the terms of the Eclipse Public License v1.0
7 * which accompanies this distribution, and is available at
8 * http://www.eclipse.org/legal/epl-v10.html
9 *******************************************************************************/
10 package org.eclipse.egit.ui.internal.components;
12 import java.io.IOException;
14 import org.eclipse.egit.ui.Activator;
15 import org.eclipse.egit.ui.internal.UIText;
16 import org.eclipse.jface.fieldassist.IContentProposal;
17 import org.eclipse.jgit.lib.Constants;
18 import org.eclipse.jgit.lib.ObjectId;
19 import org.eclipse.jgit.lib.ObjectLoader;
20 import org.eclipse.jgit.lib.ObjectReader;
21 import org.eclipse.jgit.lib.PersonIdent;
22 import org.eclipse.jgit.lib.Ref;
23 import org.eclipse.jgit.lib.Repository;
24 import org.eclipse.jgit.revwalk.RevCommit;
25 import org.eclipse.jgit.revwalk.RevTag;
26 import org.eclipse.jgit.revwalk.RevWalk;
27 import org.eclipse.osgi.util.NLS;
29 /**
30 * Content proposal class for refs names, specifically Ref objects - name with
31 * optionally associated object id. This class can be used for Eclipse field
32 * assist as content proposal.
33 * <p>
34 * Content of this proposal is simply a ref name, but description and labels
35 * tries to be smarter - showing easier to read label for user (stripping
36 * prefixes) and information about pointed object if it exists locally.
38 public class RefContentProposal implements IContentProposal {
39 private static final String PREFIXES[] = new String[] { Constants.R_HEADS,
40 Constants.R_REMOTES, Constants.R_TAGS };
42 private final static String branchPF = " [" //$NON-NLS-1$
43 + UIText.RefContentProposal_branch
44 + "]"; //$NON-NLS-1$
46 private final static String trackingBranchPF = " [" //$NON-NLS-1$
47 + UIText.RefContentProposal_trackingBranch
48 + "]"; //$NON-NLS-1$
50 private final static String tagPF = " [" //$NON-NLS-1$
51 + UIText.RefContentProposal_tag
52 + "]"; //$NON-NLS-1$
54 private static final String PREFIXES_DESCRIPTIONS[] = new String[] {
55 branchPF, trackingBranchPF, tagPF };
57 private static void appendObjectSummary(final StringBuilder sb,
58 final String type, final PersonIdent author, final String message) {
59 sb.append(type);
60 sb.append(" "); //$NON-NLS-1$
61 sb.append(UIText.RefContentProposal_by);
62 sb.append(" "); //$NON-NLS-1$
63 sb.append(author.getName());
64 sb.append("\n"); //$NON-NLS-1$
65 sb.append(author.getWhen());
66 sb.append("\n\n"); //$NON-NLS-1$
67 final int newLine = message.indexOf('\n');
68 final int last = (newLine != -1 ? newLine : message.length());
69 sb.append(message.substring(0, last));
72 private final Repository db;
74 private final String refName;
76 private final ObjectId objectId;
78 /**
79 * Create content proposal for specified ref.
81 * @param repo
82 * repository for accessing information about objects. Could be a
83 * local repository even for remote objects.
84 * @param ref
85 * ref being a content proposal. May have null or locally
86 * non-existent object id.
88 public RefContentProposal(final Repository repo, final Ref ref) {
89 this(repo, ref.getName(), ref.getObjectId());
92 /**
93 * Create content proposal for specified ref name and object id.
95 * @param repo
96 * repository for accessing information about objects. Could be a
97 * local repository even for remote objects.
98 * @param refName
99 * ref name being a content proposal.
100 * @param objectId
101 * object being pointed by this ref name. May be null or locally
102 * non-existent object.
104 public RefContentProposal(final Repository repo, final String refName,
105 final ObjectId objectId) {
106 this.db = repo;
107 this.refName = refName;
108 this.objectId = objectId;
111 @Override
112 public String getContent() {
113 return refName;
116 @Override
117 public int getCursorPosition() {
118 return refName.length();
121 @Override
122 public String getDescription() {
123 if (objectId == null)
124 return null;
125 try (ObjectReader reader = db.newObjectReader()) {
126 final ObjectLoader loader = reader.open(objectId);
127 final StringBuilder sb = new StringBuilder();
128 sb.append(refName);
129 sb.append('\n');
130 sb.append(reader.abbreviate(objectId).name());
131 sb.append(" - "); //$NON-NLS-1$
133 switch (loader.getType()) {
134 case Constants.OBJ_COMMIT:
135 try (RevWalk rw = new RevWalk(db)) {
136 RevCommit c = rw.parseCommit(objectId);
137 appendObjectSummary(sb, UIText.RefContentProposal_commit,
138 c.getAuthorIdent(), c.getFullMessage());
140 break;
141 case Constants.OBJ_TAG:
142 try (RevWalk rw = new RevWalk(db)) {
143 RevTag t = rw.parseTag(objectId);
144 appendObjectSummary(sb, UIText.RefContentProposal_tag,
145 t.getTaggerIdent(), t.getFullMessage());
147 break;
148 case Constants.OBJ_TREE:
149 sb.append(UIText.RefContentProposal_tree);
150 break;
151 case Constants.OBJ_BLOB:
152 sb.append(UIText.RefContentProposal_blob);
153 break;
154 default:
155 sb.append(UIText.RefContentProposal_unknownObject);
157 return sb.toString();
158 } catch (IOException e) {
159 Activator.logError(NLS.bind(
160 UIText.RefContentProposal_errorReadingObject, objectId), e);
161 return null;
165 @Override
166 public String getLabel() {
167 for (int i = 0; i < PREFIXES.length; i++)
168 if (refName.startsWith(PREFIXES[i]))
169 return refName.substring(PREFIXES[i].length())
170 + PREFIXES_DESCRIPTIONS[i];
171 return refName;