merged trunk into branch
[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 }
115 getCommonViewer().refresh();
116 }
117
118 /**
119 * Removes all content
120 */
121 public void clear() {
122 getCommonViewer().setInput(new EmptyRoot());
123 }
124
125 /**
126 * <p>
127 * restore
128 * </p>
129 *
130 * @param memento
131 * a {@link org.eclipse.ui.IMemento} object.
132 * @param monitor
133 * a {@link org.eclipse.core.runtime.IProgressMonitor} object.
134 */
135 public void restore(IMemento memento, IProgressMonitor monitor) {
136 if (memento == null) {
137 getCommonViewer().setInput(new Root(conversation));
138 return;
139 }
140 int mementoWork = 0;
141 Set<TreePath> treePaths = new HashSet<TreePath>();
142 IMemento[] treePathMementos = null;
143
144 IMemento treePathsMemento = memento.getChild(TREE_PATHS);
145
146 if (treePathsMemento != null) {
147 treePathMementos = treePathsMemento.getChildren(TREE_PATH);
148 mementoWork = treePathMementos.length;
149 }
150 // begin the monitor with steps for all tree paths and steps for
151 // creating
152 // conversation s.o., refreshing the tree and setting the paths
153 IProgressMonitor subProgressMonitor = NavigationUtil
154 .getSubProgressMonitor(monitor, 1);
155
156 subProgressMonitor.beginTask("Restoring Taxon Navigator",
157 1 + mementoWork + 5);
158 subProgressMonitor.subTask("Restoring Taxon Navigator");
159 subProgressMonitor.worked(1);
160
161 conversation = CdmStore.createConversation();
162 subProgressMonitor.worked(1);
163 conversation.registerForDataStoreChanges(TaxonNavigator.this);
164 subProgressMonitor.worked(1);
165 getCommonViewer().setInput(new Root(conversation));
166 subProgressMonitor.worked(1);
167 getCommonViewer().refresh();
168 subProgressMonitor.worked(1);
169
170 if (treePathMementos != null && treePathMementos.length > 0) {
171 for (IMemento treePathMemento : treePathMementos) {
172 TreePath treePath = createTreePathFromString(treePathMemento
173 .getID());
174 if (!subProgressMonitor.isCanceled() && treePath != null) {
175 treePaths.add(treePath);
176 subProgressMonitor.worked(1);
177 }
178 }
179 }
180 if (treePaths.size() > 0) {
181 TaxonNavigator.this.getCommonViewer().setExpandedTreePaths(
182 treePaths.toArray(new TreePath[0]));
183 subProgressMonitor.worked(1);
184 }
185 subProgressMonitor.done();
186 }
187
188 /**
189 * @param string
190 * @return
191 */
192 private TreePath createTreePathFromString(String string) {
193
194 List<CdmBase> pathList = new ArrayList<CdmBase>();
195
196 if (string.length() == 0) {
197 return null;
198 }
199
200 for (String uuid : string.split(" ")) {
201 CdmBase cdmBaseObject = CdmStore.getService(
202 IClassificationService.class).getTaxonNodeByUuid(
203 UUID.fromString(uuid));
204 if (cdmBaseObject == null) {
205 // is this a tree uuid?
206 cdmBaseObject = CdmStore.getService(
207 IClassificationService.class).load(
208 UUID.fromString(uuid));
209
210 if (cdmBaseObject == null) {
211 return null;
212 }
213 }
214 pathList.add(cdmBaseObject);
215 }
216 return new TreePath(pathList.toArray());
217 }
218
219 /** {@inheritDoc} */
220 @Override
221 public void saveState(IMemento aMemento) {
222 //
223 }
224
225 /**
226 * <p>
227 * saveTreeState
228 * </p>
229 *
230 * @param memento
231 * a {@link org.eclipse.ui.IMemento} object.
232 * @param progressMonitor
233 * a {@link org.eclipse.core.runtime.IProgressMonitor} object.
234 */
235 public void saveTreeState(IMemento memento, IProgressMonitor progressMonitor) {
236 if (memento == null) {
237 return;
238 }
239 IProgressMonitor monitor = NavigationUtil.getSubProgressMonitor(
240 progressMonitor, 1);
241
242 super.saveState(memento);
243
244 memento = memento.createChild(TREE_PATHS);
245 TreePath[] treePaths = this.getCommonViewer().getExpandedTreePaths();
246
247 monitor.beginTask("Saving Taxon Navigator State", treePaths.length);
248
249 for (TreePath treePath : treePaths) {
250 int pathLength = treePath.getSegmentCount();
251 String path = "";
252 for (int i = 0; i < pathLength; i++) {
253 Object segment = treePath.getSegment(i);
254 if (segment instanceof CdmBase) {
255 path += ((CdmBase) segment).getUuid().toString() + " ";
256 monitor.worked(1);
257 } else {
258 NavigationUtil.warn(getClass(),
259 "Non-taxon tree path segment " + segment);
260 }
261 }
262 memento.createChild(TREE_PATH, path.trim());
263 }
264 monitor.done();
265 }
266
267 /*
268 * (non-Javadoc)
269 *
270 * @see
271 * eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder
272 * ()
273 */
274 /**
275 * <p>
276 * getConversationHolder
277 * </p>
278 *
279 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
280 * object.
281 */
282 @Override
283 public ConversationHolder getConversationHolder() {
284 return conversation;
285 }
286
287 /*
288 * (non-Javadoc)
289 *
290 * @see
291 * eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver#update
292 * (eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap)
293 */
294 /** {@inheritDoc} */
295 @Override
296 public void update(CdmDataChangeMap changeEvents) {
297 if (dataChangeBehavior == null) {
298 dataChangeBehavior = new TaxonNavigatorDataChangeBehavior(this);
299 }
300
301 DataChangeBridge.handleDataChange(changeEvents, dataChangeBehavior);
302 }
303
304 /** {@inheritDoc} */
305 @Override
306 public String getFrameToolTipText(Object element) {
307 if (element instanceof Root) {
308 return "Taxonomic Tree";
309 }
310 return super.getFrameToolTipText(element);
311 }
312
313 /*
314 * (non-Javadoc)
315 *
316 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
317 */
318 /** {@inheritDoc} */
319 @Override
320 public void dispose() {
321 super.dispose();
322 dataChangeBehavior = null;
323 if (conversation != null) {
324 conversation.unregisterForDataStoreChanges(this);
325 }
326 }
327
328 /*
329 * (non-Javadoc)
330 *
331 * @see org.eclipse.ui.navigator.CommonNavigator#setFocus()
332 */
333 /** {@inheritDoc} */
334 @Override
335 public void setFocus() {
336 // logger.warn("Setting focus to navigator");
337 super.setFocus();
338 if (getConversationHolder() != null) {
339 getConversationHolder().bind();
340 }
341 }
342
343 /*
344 * (non-Javadoc)
345 *
346 * @see
347 * eu.etaxonomy.taxeditor.operations.IPostOperationEnabled#postOperation
348 * (eu.etaxonomy.cdm.model.common.CdmBase)
349 */
350 /** {@inheritDoc} */
351 @Override
352 public boolean postOperation(CdmBase objectAffectedByOperation) {
353 // nothing to do here
354 return true;
355 }
356
357 /**
358 * <p>
359 * save
360 * </p>
361 *
362 * @param memento
363 * a {@link org.eclipse.ui.IMemento} object.
364 * @param monitor
365 * a {@link org.eclipse.core.runtime.IProgressMonitor} object.
366 */
367 public void save(IMemento memento, IProgressMonitor monitor) {
368 saveTreeState(memento, monitor);
369 if (conversation != null) {
370 conversation.unregisterForDataStoreChanges(this);
371 conversation = null;
372 }
373 }
374
375 /** {@inheritDoc} */
376 @Override
377 protected void handleDoubleClick(DoubleClickEvent anEvent) {
378 NavigationUtil.executeEditHandler();
379 // If the double click is passed up to the super-class it will
380 // expand/collapse trees.
381 // We do not want that
382 // super.handleDoubleClick(anEvent);
383 }
384
385 /**
386 * <p>
387 * onComplete
388 * </p>
389 *
390 * @return a boolean.
391 */
392 @Override
393 public boolean onComplete() {
394 return true;
395 }
396
397 /*
398 * (non-Javadoc)
399 *
400 * @see org.eclipse.ui.part.WorkbenchPart#showBusy(boolean)
401 */
402 /** {@inheritDoc} */
403 @Override
404 public void showBusy(boolean busy) {
405 super.showBusy(busy);
406 getCommonViewer().getControl().setEnabled(!busy);
407 if (busy) {
408 partNameCache = getPartName();
409 setPartName("Loading datasources");
410 } else {
411 if (partNameCache != null) {
412 setPartName(partNameCache);
413 }
414 }
415 }
416
417
418 /* (non-Javadoc)
419 * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
420 */
421 @Override
422 public void update(Observable o, Object arg) {
423 if(o instanceof LoginManager){
424 refresh();
425 }
426
427 }
428 }