Revert "#4114 sort order in taxon navigator " to avoid blocking bug
[taxeditor.git] / eu.etaxonomy.taxeditor.navigation / src / main / java / eu / etaxonomy / taxeditor / navigation / navigator / TaxonNavigator.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.taxeditor.navigation.navigator;
12
13 import java.util.ArrayList;
14 import java.util.HashSet;
15 import java.util.List;
16 import java.util.Observable;
17 import java.util.Observer;
18 import java.util.Set;
19 import java.util.UUID;
20
21 import org.eclipse.core.runtime.IAdaptable;
22 import org.eclipse.core.runtime.IProgressMonitor;
23 import org.eclipse.jface.viewers.DoubleClickEvent;
24 import org.eclipse.jface.viewers.TreePath;
25 import org.eclipse.ui.IMemento;
26 import org.eclipse.ui.IViewSite;
27 import org.eclipse.ui.PartInitException;
28 import org.eclipse.ui.navigator.CommonNavigator;
29
30 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
31 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
32 import eu.etaxonomy.cdm.api.service.IClassificationService;
33 import eu.etaxonomy.cdm.model.common.CdmBase;
34 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
35 import eu.etaxonomy.taxeditor.model.DataChangeBridge;
36 import eu.etaxonomy.taxeditor.model.IDataChangeBehavior;
37 import eu.etaxonomy.taxeditor.navigation.NavigationUtil;
38 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
39 import eu.etaxonomy.taxeditor.store.CdmStore;
40 import eu.etaxonomy.taxeditor.store.LoginManager;
41
42 /**
43 * Taxonomic tree implementation using Common Navigator Framework.
44 *
45 * @author p.ciardelli
46 * @author n.hoffmann
47 * @created 02.06.2009
48 * @version 1.0
49 */
50 public class TaxonNavigator extends CommonNavigator implements
51 IPostOperationEnabled, IConversationEnabled, Observer {
52
53 /**
54 * Constant
55 * <code>ID="eu.etaxonomy.taxeditor.navigation.navig"{trunked}</code>
56 */
57 public static final String ID = "eu.etaxonomy.taxeditor.navigation.navigator"; //$NON-NLS-1$
58
59 private static final String TREE_PATH = "treepath";
60
61 private static final String TREE_PATHS = "treepaths";
62
63 private ConversationHolder conversation;
64
65 private String partNameCache;
66
67 private IDataChangeBehavior dataChangeBehavior;
68
69 /*
70 * (non-Javadoc)
71 *
72 * @see org.eclipse.ui.navigator.CommonNavigator#getInitialInput()
73 */
74 /** {@inheritDoc} */
75 @Override
76 protected IAdaptable getInitialInput() {
77 if (CdmStore.isActive()) {
78 // TODO when closing and reopening the taxon navigator
79 // we do not preserve state. Closing the view, in contrary to
80 // closing the whole application
81 // should be handled by the state manager too
82
83 return new Root(conversation);
84 }
85 return new EmptyRoot();
86 }
87
88 /** {@inheritDoc} */
89 @Override
90 public void init(IViewSite site) throws PartInitException {
91 super.init(site);
92 init();
93 }
94
95 /**
96 * <p>
97 * init
98 * </p>
99 */
100 public void init() {
101 if (CdmStore.isActive() && conversation == null) {
102 conversation = CdmStore.createConversation();
103 conversation.registerForDataStoreChanges(TaxonNavigator.this);
104 }
105 CdmStore.getLoginManager().addObserver(this);
106 }
107
108 /**
109 * Refresh this navigators viewer
110 */
111 public void refresh() {
112 if(getConversationHolder() != null){
113 getConversationHolder().bind();
114 //FIXME : Need to make sure this is a stable fix (ticket 3822)
115 getConversationHolder().commit();
116 }
117 getCommonViewer().refresh();
118 }
119
120 /**
121 * Removes all content
122 */
123 public void clear() {
124 getCommonViewer().setInput(new EmptyRoot());
125 }
126
127 /**
128 * <p>
129 * restore
130 * </p>
131 *
132 * @param memento
133 * a {@link org.eclipse.ui.IMemento} object.
134 * @param monitor
135 * a {@link org.eclipse.core.runtime.IProgressMonitor} object.
136 */
137 public void restore(IMemento memento, IProgressMonitor monitor) {
138 if (memento == null) {
139 getCommonViewer().setInput(new Root(conversation));
140 return;
141 }
142 int mementoWork = 0;
143 Set<TreePath> treePaths = new HashSet<TreePath>();
144 IMemento[] treePathMementos = null;
145
146 IMemento treePathsMemento = memento.getChild(TREE_PATHS);
147
148 if (treePathsMemento != null) {
149 treePathMementos = treePathsMemento.getChildren(TREE_PATH);
150 mementoWork = treePathMementos.length;
151 }
152 // begin the monitor with steps for all tree paths and steps for
153 // creating
154 // conversation s.o., refreshing the tree and setting the paths
155 IProgressMonitor subProgressMonitor = NavigationUtil
156 .getSubProgressMonitor(monitor, 1);
157
158 subProgressMonitor.beginTask("Restoring Taxon Navigator",
159 1 + mementoWork + 5);
160 subProgressMonitor.subTask("Restoring Taxon Navigator");
161 subProgressMonitor.worked(1);
162
163 conversation = CdmStore.createConversation();
164 subProgressMonitor.worked(1);
165 conversation.registerForDataStoreChanges(TaxonNavigator.this);
166 subProgressMonitor.worked(1);
167 getCommonViewer().setInput(new Root(conversation));
168 subProgressMonitor.worked(1);
169 getCommonViewer().refresh();
170 subProgressMonitor.worked(1);
171
172 if (treePathMementos != null && treePathMementos.length > 0) {
173 for (IMemento treePathMemento : treePathMementos) {
174 TreePath treePath = createTreePathFromString(treePathMemento
175 .getID());
176 if (!subProgressMonitor.isCanceled() && treePath != null) {
177 treePaths.add(treePath);
178 subProgressMonitor.worked(1);
179 }
180 }
181 }
182 if (treePaths.size() > 0) {
183 TaxonNavigator.this.getCommonViewer().setExpandedTreePaths(
184 treePaths.toArray(new TreePath[0]));
185 subProgressMonitor.worked(1);
186 }
187 subProgressMonitor.done();
188 }
189
190 /**
191 * @param string
192 * @return
193 */
194 private TreePath createTreePathFromString(String string) {
195
196 List<CdmBase> pathList = new ArrayList<CdmBase>();
197
198 if (string.length() == 0) {
199 return null;
200 }
201
202 for (String uuid : string.split(" ")) {
203 CdmBase cdmBaseObject = CdmStore.getService(
204 IClassificationService.class).getTaxonNodeByUuid(
205 UUID.fromString(uuid));
206 if (cdmBaseObject == null) {
207 // is this a tree uuid?
208 cdmBaseObject = CdmStore.getService(
209 IClassificationService.class).load(
210 UUID.fromString(uuid));
211
212 if (cdmBaseObject == null) {
213 return null;
214 }
215 }
216 pathList.add(cdmBaseObject);
217 }
218 return new TreePath(pathList.toArray());
219 }
220
221 /** {@inheritDoc} */
222 @Override
223 public void saveState(IMemento aMemento) {
224 //
225 }
226
227 /**
228 * <p>
229 * saveTreeState
230 * </p>
231 *
232 * @param memento
233 * a {@link org.eclipse.ui.IMemento} object.
234 * @param progressMonitor
235 * a {@link org.eclipse.core.runtime.IProgressMonitor} object.
236 */
237 public void saveTreeState(IMemento memento, IProgressMonitor progressMonitor) {
238 if (memento == null) {
239 return;
240 }
241 IProgressMonitor monitor = NavigationUtil.getSubProgressMonitor(
242 progressMonitor, 1);
243
244 super.saveState(memento);
245
246 memento = memento.createChild(TREE_PATHS);
247 TreePath[] treePaths = this.getCommonViewer().getExpandedTreePaths();
248
249 monitor.beginTask("Saving Taxon Navigator State", treePaths.length);
250
251 for (TreePath treePath : treePaths) {
252 int pathLength = treePath.getSegmentCount();
253 String path = "";
254 for (int i = 0; i < pathLength; i++) {
255 Object segment = treePath.getSegment(i);
256 if (segment instanceof CdmBase) {
257 path += ((CdmBase) segment).getUuid().toString() + " ";
258 monitor.worked(1);
259 } else {
260 NavigationUtil.warn(getClass(),
261 "Non-taxon tree path segment " + segment);
262 }
263 }
264 memento.createChild(TREE_PATH, path.trim());
265 }
266 monitor.done();
267 }
268
269 /*
270 * (non-Javadoc)
271 *
272 * @see
273 * eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder
274 * ()
275 */
276 /**
277 * <p>
278 * getConversationHolder
279 * </p>
280 *
281 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
282 * object.
283 */
284 @Override
285 public ConversationHolder getConversationHolder() {
286 return conversation;
287 }
288
289 /*
290 * (non-Javadoc)
291 *
292 * @see
293 * eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver#update
294 * (eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap)
295 */
296 /** {@inheritDoc} */
297 @Override
298 public void update(CdmDataChangeMap changeEvents) {
299 if (dataChangeBehavior == null) {
300 dataChangeBehavior = new TaxonNavigatorDataChangeBehavior(this);
301 }
302
303 DataChangeBridge.handleDataChange(changeEvents, dataChangeBehavior);
304 }
305
306 /** {@inheritDoc} */
307 @Override
308 public String getFrameToolTipText(Object element) {
309 if (element instanceof Root) {
310 return "Taxonomic Tree";
311 }
312 return super.getFrameToolTipText(element);
313 }
314
315 /*
316 * (non-Javadoc)
317 *
318 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
319 */
320 /** {@inheritDoc} */
321 @Override
322 public void dispose() {
323 super.dispose();
324 dataChangeBehavior = null;
325 if (conversation != null) {
326 conversation.unregisterForDataStoreChanges(this);
327 }
328 }
329
330 /*
331 * (non-Javadoc)
332 *
333 * @see org.eclipse.ui.navigator.CommonNavigator#setFocus()
334 */
335 /** {@inheritDoc} */
336 @Override
337 public void setFocus() {
338 // logger.warn("Setting focus to navigator");
339 super.setFocus();
340 if (getConversationHolder() != null) {
341 getConversationHolder().bind();
342 }
343 }
344
345 /*
346 * (non-Javadoc)
347 *
348 * @see
349 * eu.etaxonomy.taxeditor.operations.IPostOperationEnabled#postOperation
350 * (eu.etaxonomy.cdm.model.common.CdmBase)
351 */
352 /** {@inheritDoc} */
353 @Override
354 public boolean postOperation(CdmBase objectAffectedByOperation) {
355 // nothing to do here
356 return true;
357 }
358
359 /**
360 * <p>
361 * save
362 * </p>
363 *
364 * @param memento
365 * a {@link org.eclipse.ui.IMemento} object.
366 * @param monitor
367 * a {@link org.eclipse.core.runtime.IProgressMonitor} object.
368 */
369 public void save(IMemento memento, IProgressMonitor monitor) {
370 saveTreeState(memento, monitor);
371 if (conversation != null) {
372 conversation.unregisterForDataStoreChanges(this);
373 conversation = null;
374 }
375 }
376
377 /** {@inheritDoc} */
378 @Override
379 protected void handleDoubleClick(DoubleClickEvent anEvent) {
380 NavigationUtil.executeEditHandler();
381 // If the double click is passed up to the super-class it will
382 // expand/collapse trees.
383 // We do not want that
384 // super.handleDoubleClick(anEvent);
385 }
386
387 /**
388 * <p>
389 * onComplete
390 * </p>
391 *
392 * @return a boolean.
393 */
394 @Override
395 public boolean onComplete() {
396 return true;
397 }
398
399 /*
400 * (non-Javadoc)
401 *
402 * @see org.eclipse.ui.part.WorkbenchPart#showBusy(boolean)
403 */
404 /** {@inheritDoc} */
405 @Override
406 public void showBusy(boolean busy) {
407 super.showBusy(busy);
408 getCommonViewer().getControl().setEnabled(!busy);
409 if (busy) {
410 partNameCache = getPartName();
411 setPartName("Loading datasources");
412 } else {
413 if (partNameCache != null) {
414 setPartName(partNameCache);
415 }
416 }
417 }
418
419
420 /* (non-Javadoc)
421 * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
422 */
423 @Override
424 public void update(Observable o, Object arg) {
425 if(o instanceof LoginManager){
426 refresh();
427 }
428
429 }
430 }