View Javadoc

1   /**
2    * Copyright (C) 2008 Atlassian
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *    http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package com.atlassian.theplugin.idea.crucible.tree;
17  
18  import com.atlassian.theplugin.commons.cfg.ProjectId;
19  import com.atlassian.theplugin.commons.cfg.ServerId;
20  import com.atlassian.theplugin.commons.crucible.api.model.ReviewAdapter;
21  import com.atlassian.theplugin.crucible.model.CrucibleReviewListModel;
22  import com.atlassian.theplugin.idea.config.ProjectCfgManagerImpl;
23  import com.atlassian.theplugin.idea.crucible.CrucibleReviewGroupBy;
24  import com.atlassian.theplugin.idea.crucible.tree.node.*;
25  import org.jetbrains.annotations.NotNull;
26  
27  import javax.swing.tree.DefaultMutableTreeNode;
28  import javax.swing.tree.DefaultTreeModel;
29  import javax.swing.tree.TreePath;
30  import java.util.ArrayList;
31  
32  /**
33   * @author Jacek Jaroczynski
34   */
35  public class ReviewTreeModel extends DefaultTreeModel {
36  
37  	private CrucibleReviewListModel reviewListModel;
38  
39  
40  	private CrucibleReviewGroupBy groupBy = CrucibleReviewGroupBy.NONE;
41  
42  	private NodeManipulator generalNodeManipulator;
43  	private NodeManipulator stateNodeManipulator;
44  	private NodeManipulator serverNodeManipulator;
45  	private NodeManipulator authorNodeManipulator;
46  	private NodeManipulator projectNodeManipulator;
47  
48  	public ReviewTreeModel(CrucibleReviewListModel reviewListModel, @NotNull ProjectCfgManagerImpl projectCfgManager,
49  			ProjectId projectId) {
50  		super(new DefaultMutableTreeNode());
51  
52  		this.reviewListModel = reviewListModel;
53  
54  		generalNodeManipulator = new GeneralNodeManipulator(reviewListModel, getRoot());
55  		stateNodeManipulator = new StateNodeManipulator(reviewListModel, getRoot());
56  		serverNodeManipulator = new ServerNodeManipulator(reviewListModel, getRoot(), projectCfgManager);
57  		authorNodeManipulator = new AuthorNodeManipulator(reviewListModel, getRoot());
58  		projectNodeManipulator = new ProjectNodeManipulator(reviewListModel, getRoot());
59  	}
60  
61  	/**
62  	 * Sets groupBy field used to group the tree and triggers tree to rebuild
63  	 * Only tree should use that method.
64  	 *
65  	 * @param aGroupBy
66  	 */
67  	public void groupBy(CrucibleReviewGroupBy aGroupBy) {
68  		this.groupBy = aGroupBy;
69  
70  		// clear entire tree
71  		getRoot().removeAllChildren();
72  
73  		// redraw tree
74  		nodeStructureChanged(getRoot());
75  	}
76  
77  	/**
78  	 * Simple setter (does not trigger tree to rebuild)
79  	 *
80  	 * @param groupBy
81  	 */
82  	public void setGroupBy(CrucibleReviewGroupBy groupBy) {
83  		this.groupBy = groupBy;
84  	}
85  
86  	/*
87  	Override TreeModel methods
88  	 */
89  
90  	@Override
91  	public DefaultMutableTreeNode getRoot() {
92  		return (DefaultMutableTreeNode) super.getRoot();
93  	}
94  
95  	@Override
96  	public Object getChild(Object parent, int index) {
97  
98  		switch (groupBy) {
99  			case AUTHOR:
100 				return authorNodeManipulator.getChild(parent, index);
101 			case PROJECT:
102 				return projectNodeManipulator.getChild(parent, index);
103 			case SERVER:
104 				return serverNodeManipulator.getChild(parent, index);
105 			case STATE:
106 				return stateNodeManipulator.getChild(parent, index);
107 			case NONE:
108 			default:
109 				return generalNodeManipulator.getChild(parent, index);
110 		}
111 	}
112 
113 	@Override
114 	public int getChildCount(Object parent) {
115 
116 		switch (groupBy) {
117 			case AUTHOR:
118 				return authorNodeManipulator.getChildCount(parent);
119 			case PROJECT:
120 				return projectNodeManipulator.getChildCount(parent);
121 			case SERVER:
122 				return serverNodeManipulator.getChildCount(parent);
123 			case STATE:
124 				return stateNodeManipulator.getChildCount(parent);
125 			case NONE:
126 			default:
127 				return generalNodeManipulator.getChildCount(parent);
128 		}
129 	}
130 
131 	@Override
132 	public boolean isLeaf(Object node) {
133 		if (node == getRoot()
134 				|| node instanceof CrucibleReviewStateTreeNode
135 				|| node instanceof CrucibleReviewServerTreeNode
136 				|| node instanceof CrucibleReviewAuthorTreeNode
137 				|| node instanceof CrucibleReviewProjectTreeNode) {
138 			return false;
139 		}
140 
141 		return true;
142 	}
143 
144 	@Override
145 	public void valueForPathChanged(TreePath path, Object newValue) {
146 	}
147 
148 	@Override
149 	// todo add group by handling if necessary
150 	public int getIndexOfChild(Object parent, Object child) {
151 		if (parent == getRoot()) {
152 			if (child instanceof CrucibleReviewTreeNode) {
153 				ReviewAdapter review = ((CrucibleReviewTreeNode) child).getReview();
154 				return new ArrayList<ReviewAdapter>(reviewListModel.getReviews()).indexOf(review);
155 			}
156 		}
157 
158 		return -1;
159 	}
160 
161 	public DefaultMutableTreeNode findParentNode(ReviewAdapter review) {
162 		DefaultMutableTreeNode root = getRoot();
163 
164 		switch (groupBy) {
165 
166 			case AUTHOR:
167 				// todo move that code to node manipulator and make it generic if worth
168 				for (int i = 0; i < getChildCount(root); ++i) {
169 					Object node = getChild(root, i);
170 					if (node instanceof CrucibleReviewAuthorTreeNode) {
171 						CrucibleReviewAuthorTreeNode parent = (CrucibleReviewAuthorTreeNode) node;
172 						if (parent.getAuthor().equals(review.getAuthor())) {
173 							return parent;
174 						}
175 					}
176 				}
177 				break;
178 			case PROJECT:
179 				for (int i = 0; i < getChildCount(root); ++i) {
180 					Object node = getChild(root, i);
181 					if (node instanceof CrucibleReviewProjectTreeNode) {
182 						CrucibleReviewProjectTreeNode parent = (CrucibleReviewProjectTreeNode) node;
183 						if (parent.getProject().getKey().equals(review.getProjectKey())) {
184 							return parent;
185 						}
186 					}
187 				}
188 				break;
189 			case SERVER:
190 				for (int i = 0; i < getChildCount(root); ++i) {
191 					Object node = getChild(root, i);
192 					if (node instanceof CrucibleReviewServerTreeNode) {
193 						CrucibleReviewServerTreeNode parent = (CrucibleReviewServerTreeNode) node;
194 						if (parent.getCrucibleServer().getServerId()
195 								.equals(new ServerId(review.getServerData().getServerId()))) {
196 							return parent;
197 						}
198 					}
199 				}
200 				break;
201 			case STATE:
202 				for (int i = 0; i < getChildCount(root); ++i) {
203 					Object node = getChild(root, i);
204 					if (node instanceof CrucibleReviewStateTreeNode) {
205 						CrucibleReviewStateTreeNode parent = (CrucibleReviewStateTreeNode) node;
206 						if (parent.getCrucibleState().equals(review.getState())) {
207 							return parent;
208 						}
209 					}
210 				}
211 				break;
212 			case NONE:
213 			default:
214 				break;
215 		}
216 
217 		return root;
218 	}
219 
220 	public CrucibleReviewListModel getReviewListModel() {
221 		return reviewListModel;
222 	}
223 }