RepositoryTreeNode: fix compareTo() implemenation
[egit/spearce.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / repository / RepositoryTreeNode.java
blob425fba0738bb86bdb0642082986591d0e1fd812c
1 /*******************************************************************************
2 * Copyright (c) 2010 SAP AG.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
8 * Contributors:
9 * Mathias Kinzler (SAP AG) - initial implementation
10 *******************************************************************************/
11 package org.eclipse.egit.ui.internal.repository;
13 import java.io.File;
15 import org.eclipse.egit.ui.Activator;
16 import org.eclipse.egit.ui.UIIcons;
17 import org.eclipse.jgit.lib.Ref;
18 import org.eclipse.jgit.lib.Repository;
19 import org.eclipse.swt.graphics.Image;
20 import org.eclipse.ui.ISharedImages;
21 import org.eclipse.ui.PlatformUI;
23 /**
24 * A node in the Git Repositories view tree
26 * @param <T>
27 * the type
29 public class RepositoryTreeNode<T> implements Comparable<RepositoryTreeNode> {
31 private final Repository myRepository;
33 private final T myObject;
35 private final RepositoryTreeNodeType myType;
37 private final RepositoryTreeNode myParent;
39 /**
40 * Constructs a node
42 * @param parent
43 * the parent (may be null)
44 * @param type
45 * the type
46 * @param repository
47 * the {@link Repository}
48 * @param treeObject
49 * an object (depending on the type)
51 public RepositoryTreeNode(RepositoryTreeNode parent,
52 RepositoryTreeNodeType type, Repository repository, T treeObject) {
53 myParent = parent;
54 myRepository = repository;
55 myType = type;
56 myObject = treeObject;
59 @SuppressWarnings("unchecked")
60 private RepositoryTreeNode<Repository> getRepositoryNode() {
61 if (myType == RepositoryTreeNodeType.REPO) {
62 return (RepositoryTreeNode<Repository>) this;
63 } else {
64 return getParent().getRepositoryNode();
68 /**
69 * @return the parent, or null
71 public RepositoryTreeNode getParent() {
72 return myParent;
75 /**
76 * @return the type
78 public RepositoryTreeNodeType getType() {
79 return myType;
82 /**
83 * @return the repository
85 public Repository getRepository() {
86 return myRepository;
89 /**
90 * Depending on the node type, the returned type is:
92 * <table border=1>
93 * <th>Type</th>
94 * <th>Object type</th>
95 * <tr>
96 * <td>{@link RepositoryTreeNodeType#BRANCHES}</td>
97 * <td>{@link String}</td>
98 * </tr>
99 * <tr>
100 * <td>{@link RepositoryTreeNodeType#LOCALBRANCHES}</td>
101 * <td>{@link String}</td>
102 * </tr>
103 * <tr>
104 * <td>{@link RepositoryTreeNodeType#REMOTEBRANCHES}</td>
105 * <td>{@link String}</td>
106 * </tr>
107 * <tr>
108 * <td>{@link RepositoryTreeNodeType#TAGS}</td>
109 * <td>{@link String}</td>
110 * </tr>
111 * <tr>
112 * <td>{@link RepositoryTreeNodeType#REMOTE}</td>
113 * <td>{@link String}</td>
114 * </tr>
115 * <tr>
116 * <td>{@link RepositoryTreeNodeType#REMOTES}</td>
117 * <td>{@link String}</td>
118 * </tr>
119 * <tr>
120 * <td>{@link RepositoryTreeNodeType#REPO}</td>
121 * <td>{@link Repository}</td>
122 * </tr>
123 * </table>
125 * @return the type-specific object
127 public T getObject() {
128 return myObject;
131 @Override
132 public int hashCode() {
133 final int prime = 31;
134 int result = 1;
135 switch (myType) {
136 case REPO:
137 // fall through
138 case REMOTES:
139 // fall through
140 case LOCALBRANCHES:
141 // fall through
142 case REMOTEBRANCHES:
143 // fall through
144 case BRANCHES:
145 // fall through
146 case SYMBOLICREFS:
147 // fall through
148 case WORKINGDIR:
149 result = prime
150 * result
151 + ((myObject == null) ? 0 : ((Repository) myObject)
152 .getDirectory().hashCode());
153 break;
154 case REF:
155 // fall through
156 case TAG:
157 // fall through
158 case SYMBOLICREF:
159 result = prime
160 * result
161 + ((myObject == null) ? 0 : ((Ref) myObject).getName()
162 .hashCode());
163 break;
164 case FILE:
165 // fall through
166 case FOLDER:
167 result = prime
168 * result
169 + ((myObject == null) ? 0 : ((File) myObject).getPath()
170 .hashCode());
171 break;
172 case TAGS:
173 // fall through
174 case REMOTE:
175 // fall through
176 case PUSH:
177 // fall through
178 case FETCH:
179 // fall through
180 case ERROR:
181 result = prime * result
182 + ((myObject == null) ? 0 : myObject.hashCode());
186 result = prime * result
187 + ((myParent == null) ? 0 : myParent.hashCode());
188 result = prime
189 * result
190 + ((myRepository == null) ? 0 : myRepository.getDirectory()
191 .hashCode());
192 result = prime * result + ((myType == null) ? 0 : myType.hashCode());
193 return result;
196 @Override
197 public boolean equals(Object obj) {
198 if (this == obj)
199 return true;
200 if (obj == null)
201 return false;
202 if (getClass() != obj.getClass())
203 return false;
205 RepositoryTreeNode other = (RepositoryTreeNode) obj;
207 if (myType == null) {
208 if (other.myType != null)
209 return false;
210 } else if (!myType.equals(other.myType))
211 return false;
212 if (myParent == null) {
213 if (other.myParent != null)
214 return false;
215 } else if (!myParent.equals(other.myParent))
216 return false;
217 if (myRepository == null) {
218 if (other.myRepository != null)
219 return false;
220 } else if (!myRepository.getDirectory().equals(
221 other.myRepository.getDirectory()))
222 return false;
223 if (myObject == null) {
224 if (other.myObject != null)
225 return false;
226 } else if (!checkObjectsEqual(other.myObject))
227 return false;
229 return true;
232 public int compareTo(RepositoryTreeNode otherNode) {
233 int typeDiff = this.myType.ordinal() - otherNode.getType().ordinal();
234 if (typeDiff != 0)
235 return typeDiff;
237 // we only implement this for sorting, so we only have to
238 // implement this for nodes that can be on the same level
239 // i.e. siblings to each other
241 switch (myType) {
243 case BRANCHES:
244 // fall through
245 case LOCALBRANCHES:
246 // fall through
247 case REMOTEBRANCHES:
248 // fall through
249 case REMOTES:
250 // fall through
251 case SYMBOLICREFS:
252 // fall through
253 case TAGS:
254 // fall through
255 case ERROR:
256 // fall through
257 case WORKINGDIR:
258 return 0;
260 case FETCH:
261 // fall through
262 case PUSH:
263 // fall through
264 case REMOTE:
265 return ((String) myObject)
266 .compareTo((String) otherNode.getObject());
267 case FILE:
268 // fall through
269 case FOLDER:
270 return ((File) myObject).getName().compareTo(
271 ((File) otherNode.getObject()).getName());
272 case TAG:
273 // fall through
274 case SYMBOLICREF:
275 // fall through
276 case REF:
277 return ((Ref) myObject).getName().compareTo(
278 ((Ref) otherNode.getObject()).getName());
279 case REPO:
280 int nameCompare = ((Repository) myObject).getDirectory()
281 .getParentFile().getName().compareTo(
282 (((Repository) otherNode.getObject())
283 .getDirectory().getParentFile().getName()));
284 if (nameCompare != 0)
285 return nameCompare;
286 // if the name is not unique, let's look at the whole path
287 return ((Repository) myObject).getDirectory().getParentFile()
288 .getParentFile().getPath().compareTo(
289 (((Repository) otherNode.getObject())
290 .getDirectory().getParentFile()
291 .getParentFile().getPath()));
294 return 0;
297 private boolean checkObjectsEqual(Object otherObject) {
298 switch (myType) {
299 case REPO:
300 // fall through
301 case REMOTES:
302 // fall through
303 case BRANCHES:
304 // fall through
305 case LOCALBRANCHES:
306 // fall through
307 case REMOTEBRANCHES:
308 // fall through
309 case SYMBOLICREFS:
310 // fall through
311 case ERROR:
312 // fall through
313 case WORKINGDIR:
314 return ((Repository) myObject).getDirectory().equals(
315 ((Repository) otherObject).getDirectory());
316 case REF:
317 // fall through
318 case TAG:
319 // fall through
320 case SYMBOLICREF:
321 return ((Ref) myObject).getName().equals(
322 ((Ref) otherObject).getName());
323 case FOLDER:
324 // fall through
325 case FILE:
326 return ((File) myObject).getPath().equals(
327 ((File) otherObject).getPath());
328 case REMOTE:
329 // fall through
330 case FETCH:
331 // fall through
332 case PUSH:
333 // fall through
334 case TAGS:
335 return myObject.equals(otherObject);
337 return false;
341 * Specifies the type of a {@link RepositoryTreeNode}
343 public enum RepositoryTreeNodeType {
345 /** */
346 REPO(UIIcons.REPOSITORY.createImage()), //
347 /** */
348 BRANCHES(UIIcons.BRANCHES.createImage()), //
349 /** */
350 REF(UIIcons.BRANCH.createImage()), //
351 /** */
352 LOCALBRANCHES(PlatformUI.getWorkbench().getSharedImages().getImage(
353 ISharedImages.IMG_OBJ_FOLDER)), //
354 /** */
355 REMOTEBRANCHES(PlatformUI.getWorkbench().getSharedImages().getImage(
356 ISharedImages.IMG_OBJ_FOLDER)), //
357 /** */
358 TAGS(UIIcons.TAGS.createImage()), //
359 /** */
360 SYMBOLICREFS(PlatformUI.getWorkbench().getSharedImages().getImage(
361 ISharedImages.IMG_OBJ_FOLDER)), //
362 /** */
363 SYMBOLICREF(PlatformUI.getWorkbench().getSharedImages().getImage(
364 ISharedImages.IMG_OBJ_FILE)), // TODO icon
365 /** */
366 TAG(UIIcons.TAG.createImage()), //
367 /** */
368 FILE(PlatformUI.getWorkbench().getSharedImages().getImage(
369 ISharedImages.IMG_OBJ_FILE)), //
370 /** */
371 FOLDER(PlatformUI.getWorkbench().getSharedImages().getImage(
372 ISharedImages.IMG_OBJ_FOLDER)), //
373 /** */
374 REMOTES(UIIcons.REMOTE_REPOSITORY.createImage()), //
375 /** */
376 REMOTE(PlatformUI.getWorkbench().getSharedImages().getImage(
377 ISharedImages.IMG_OBJ_FOLDER)), //
378 /** */
379 FETCH(UIIcons.IMPORT.createImage()), // TODO icon
380 /** */
381 PUSH(UIIcons.EXPORT.createImage()), // TODO icon
382 /** */
383 WORKINGDIR(PlatformUI.getWorkbench().getSharedImages().getImage(
384 ISharedImages.IMG_OBJ_FOLDER)), //
385 /** */
386 ERROR(PlatformUI.getWorkbench().getSharedImages().getImage(
387 ISharedImages.IMG_ELCL_STOP)) // TODO icon?
391 private final Image myImage;
393 private RepositoryTreeNodeType(String iconName) {
395 if (iconName != null) {
396 myImage = Activator.getDefault().getImageRegistry().get(
397 iconName);
398 } else {
399 myImage = null;
404 private RepositoryTreeNodeType(Image icon) {
405 myImage = icon;
410 * @return the icon for this type
412 public Image getIcon() {
413 return myImage;