Project

General

Profile

Download (11.6 KB) Statistics
| Branch: | Tag: | Revision:
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.ISelectionChangedListener;
25
import org.eclipse.jface.viewers.IStructuredSelection;
26
import org.eclipse.jface.viewers.SelectionChangedEvent;
27
import org.eclipse.jface.viewers.TreePath;
28
import org.eclipse.ui.IMemento;
29
import org.eclipse.ui.IViewSite;
30
import org.eclipse.ui.PartInitException;
31
import org.eclipse.ui.navigator.CommonNavigator;
32

    
33
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
34
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
35
import eu.etaxonomy.cdm.api.service.IClassificationService;
36
import eu.etaxonomy.cdm.model.common.CdmBase;
37
import eu.etaxonomy.cdm.model.taxon.Classification;
38
import eu.etaxonomy.cdm.model.taxon.TaxonComparatorSearch;
39
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
40
import eu.etaxonomy.taxeditor.model.DataChangeBridge;
41
import eu.etaxonomy.taxeditor.model.IDataChangeBehavior;
42
import eu.etaxonomy.taxeditor.navigation.NavigationUtil;
43
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
44
import eu.etaxonomy.taxeditor.store.CdmStore;
45
import eu.etaxonomy.taxeditor.store.LoginManager;
46

    
47
/**
48
 * Taxonomic tree implementation using Common Navigator Framework.
49
 *
50
 * @author p.ciardelli
51
 * @author n.hoffmann
52
 * @created 02.06.2009
53
 * @version 1.0
54
 */
55
public class TaxonNavigator extends CommonNavigator implements
56
		IPostOperationEnabled, IConversationEnabled, Observer {
57

    
58
	/**
59
	 * Constant
60
	 * <code>ID="eu.etaxonomy.taxeditor.navigation.navig"{trunked}</code>
61
	 */
62
	public static final String ID = "eu.etaxonomy.taxeditor.navigation.navigator"; //$NON-NLS-1$
63

    
64
	private static final String TREE_PATH = "treepath";
65

    
66
	private static final String TREE_PATHS = "treepaths";
67

    
68
	private ConversationHolder conversation;
69

    
70
	private String partNameCache;
71

    
72
	private IDataChangeBehavior dataChangeBehavior;
73

    
74
	/*
75
	 * (non-Javadoc)
76
	 *
77
	 * @see org.eclipse.ui.navigator.CommonNavigator#getInitialInput()
78
	 */
79
	/** {@inheritDoc} */
80
	@Override
81
	protected IAdaptable getInitialInput() {
82
		
83
		TaxonComparatorSearch comparator = new TaxonComparatorSearch();
84
		TaxonNodeComparator viewerComparator = new TaxonNodeComparator(comparator);
85
		this.getCommonViewer().setComparator(viewerComparator);
86
//		this.getCommonViewer().addSelectionChangedListener(new ISelectionChangedListener() {
87
//			
88
//			@Override
89
//			public void selectionChanged(SelectionChangedEvent arg0) {
90
//				IStructuredSelection selection = (IStructuredSelection) getCommonViewer().getSelection();
91
//				
92
//				Object firstElement =  selection.getFirstElement();
93
//				//
94
//				if (!(firstElement instanceof Classification)){
95
//					//NavigationUtil.selectInNavigator(firstElement, null);
96
//					NavigationUtil.openEditor(firstElement);
97
//				}
98
//				
99
//			}
100
//		} );
101
		
102
		if (CdmStore.isActive()) {
103
			
104
			// TODO when closing and reopening the taxon navigator
105
			// we do not preserve state. Closing the view, in contrary to
106
			// closing the whole application
107
			// should be handled by the state manager too
108

    
109
			return new Root(conversation);
110
		}
111
		return new EmptyRoot();
112
	}
113

    
114
	/** {@inheritDoc} */
115
	@Override
116
	public void init(IViewSite site) throws PartInitException {
117
		super.init(site);
118
		init();
119
	}
120

    
121
	/**
122
	 * <p>
123
	 * init
124
	 * </p>
125
	 */
126
	public void init() {
127
		if (CdmStore.isActive() && conversation == null) {
128
			conversation = CdmStore.createConversation();
129
			conversation.registerForDataStoreChanges(TaxonNavigator.this);
130
		}
131
		CdmStore.getLoginManager().addObserver(this);
132
	}
133

    
134
	/**
135
	 * Refresh this navigators viewer
136
	 */
137
	public void refresh() {
138
		if(getConversationHolder() != null){
139
			getConversationHolder().bind();
140
			//FIXME : Need to make sure this is a stable fix (ticket 3822)
141
			if(!getConversationHolder().isCompleted()){
142
			    getConversationHolder().commit();
143
			}
144
		}
145
		getCommonViewer().refresh();
146
	}
147

    
148
	/**
149
	 * Removes all content
150
	 */
151
	public void clear() {
152
		getCommonViewer().setInput(new EmptyRoot());
153
	}
154

    
155
	/**
156
	 * <p>
157
	 * restore
158
	 * </p>
159
	 *
160
	 * @param memento
161
	 *            a {@link org.eclipse.ui.IMemento} object.
162
	 * @param monitor
163
	 *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
164
	 */
165
	public void restore(IMemento memento, IProgressMonitor monitor) {
166
		if (memento == null) {
167
			getCommonViewer().setInput(new Root(conversation));
168
			return;
169
		}
170
		int mementoWork = 0;
171
		Set<TreePath> treePaths = new HashSet<TreePath>();
172
		IMemento[] treePathMementos = null;
173

    
174
		IMemento treePathsMemento = memento.getChild(TREE_PATHS);
175

    
176
		if (treePathsMemento != null) {
177
			treePathMementos = treePathsMemento.getChildren(TREE_PATH);
178
			mementoWork = treePathMementos.length;
179
		}
180
		// begin the monitor with steps for all tree paths and steps for
181
		// creating
182
		// conversation s.o., refreshing the tree and setting the paths
183
		IProgressMonitor subProgressMonitor = NavigationUtil
184
				.getSubProgressMonitor(monitor, 1);
185

    
186
		subProgressMonitor.beginTask("Restoring Taxon Navigator",
187
				1 + mementoWork + 5);
188
		subProgressMonitor.subTask("Restoring Taxon Navigator");
189
		subProgressMonitor.worked(1);
190

    
191
		conversation = CdmStore.createConversation();
192
		subProgressMonitor.worked(1);
193
		conversation.registerForDataStoreChanges(TaxonNavigator.this);
194
		subProgressMonitor.worked(1);
195
		getCommonViewer().setInput(new Root(conversation));
196
		subProgressMonitor.worked(1);
197
		getCommonViewer().refresh();
198
		subProgressMonitor.worked(1);
199

    
200
		if (treePathMementos != null && treePathMementos.length > 0) {
201
			for (IMemento treePathMemento : treePathMementos) {
202
				TreePath treePath = createTreePathFromString(treePathMemento
203
						.getID());
204
				if (!subProgressMonitor.isCanceled() && treePath != null) {
205
					treePaths.add(treePath);
206
					subProgressMonitor.worked(1);
207
				}
208
			}
209
		}
210
		if (treePaths.size() > 0) {
211
			TaxonNavigator.this.getCommonViewer().setExpandedTreePaths(
212
					treePaths.toArray(new TreePath[0]));
213
			subProgressMonitor.worked(1);
214
		}
215
		subProgressMonitor.done();
216
	}
217

    
218
	/**
219
	 * @param string
220
	 * @return
221
	 */
222
	private TreePath createTreePathFromString(String string) {
223

    
224
		List<CdmBase> pathList = new ArrayList<CdmBase>();
225

    
226
		if (string.length() == 0) {
227
            return null;
228
        }
229

    
230
		for (String uuid : string.split(" ")) {
231
			CdmBase cdmBaseObject = CdmStore.getService(
232
					IClassificationService.class).getTaxonNodeByUuid(
233
					UUID.fromString(uuid));
234
			if (cdmBaseObject == null) {
235
				// is this a tree uuid?
236
				cdmBaseObject = CdmStore.getService(
237
						IClassificationService.class).load(
238
						UUID.fromString(uuid));
239

    
240
				if (cdmBaseObject == null) {
241
                    return null;
242
                }
243
			}
244
			pathList.add(cdmBaseObject);
245
		}
246
		return new TreePath(pathList.toArray());
247
	}
248

    
249
	/** {@inheritDoc} */
250
	@Override
251
	public void saveState(IMemento aMemento) {
252
		//
253
	}
254

    
255
	/**
256
	 * <p>
257
	 * saveTreeState
258
	 * </p>
259
	 *
260
	 * @param memento
261
	 *            a {@link org.eclipse.ui.IMemento} object.
262
	 * @param progressMonitor
263
	 *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
264
	 */
265
	public void saveTreeState(IMemento memento, IProgressMonitor progressMonitor) {
266
		if (memento == null) {
267
			return;
268
		}
269
		IProgressMonitor monitor = NavigationUtil.getSubProgressMonitor(
270
				progressMonitor, 1);
271

    
272
		super.saveState(memento);
273

    
274
		memento = memento.createChild(TREE_PATHS);
275
		TreePath[] treePaths = this.getCommonViewer().getExpandedTreePaths();
276

    
277
		monitor.beginTask("Saving Taxon Navigator State", treePaths.length);
278

    
279
		for (TreePath treePath : treePaths) {
280
			int pathLength = treePath.getSegmentCount();
281
			String path = "";
282
			for (int i = 0; i < pathLength; i++) {
283
				Object segment = treePath.getSegment(i);
284
				if (segment instanceof CdmBase) {
285
					path += ((CdmBase) segment).getUuid().toString() + " ";
286
					monitor.worked(1);
287
				} else {
288
					NavigationUtil.warn(getClass(),
289
							"Non-taxon tree path segment " + segment);
290
				}
291
			}
292
			memento.createChild(TREE_PATH, path.trim());
293
		}
294
		monitor.done();
295
	}
296

    
297
	/*
298
	 * (non-Javadoc)
299
	 *
300
	 * @see
301
	 * eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder
302
	 * ()
303
	 */
304
	/**
305
	 * <p>
306
	 * getConversationHolder
307
	 * </p>
308
	 *
309
	 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
310
	 *         object.
311
	 */
312
	@Override
313
	public ConversationHolder getConversationHolder() {
314
		return conversation;
315
	}
316

    
317
	/*
318
	 * (non-Javadoc)
319
	 *
320
	 * @see
321
	 * eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver#update
322
	 * (eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap)
323
	 */
324
	/** {@inheritDoc} */
325
	@Override
326
	public void update(CdmDataChangeMap changeEvents) {
327
		if (dataChangeBehavior == null) {
328
			dataChangeBehavior = new TaxonNavigatorDataChangeBehavior(this);
329
		}
330

    
331
		DataChangeBridge.handleDataChange(changeEvents, dataChangeBehavior);
332
	}
333

    
334
	/** {@inheritDoc} */
335
	@Override
336
	public String getFrameToolTipText(Object element) {
337
		if (element instanceof Root) {
338
			return "Taxonomic Tree";
339
		}
340
		return super.getFrameToolTipText(element);
341
	}
342

    
343
	/*
344
	 * (non-Javadoc)
345
	 *
346
	 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
347
	 */
348
	/** {@inheritDoc} */
349
	@Override
350
	public void dispose() {
351
		super.dispose();
352
		dataChangeBehavior = null;
353
		if (conversation != null) {
354
			conversation.unregisterForDataStoreChanges(this);
355
		}
356
	}
357

    
358
	/*
359
	 * (non-Javadoc)
360
	 *
361
	 * @see org.eclipse.ui.navigator.CommonNavigator#setFocus()
362
	 */
363
	/** {@inheritDoc} */
364
	@Override
365
	public void setFocus() {
366
		// logger.warn("Setting focus to navigator");
367
		super.setFocus();
368
		if (getConversationHolder() != null) {
369
			getConversationHolder().bind();
370
		}
371
	}
372

    
373
	/*
374
	 * (non-Javadoc)
375
	 *
376
	 * @see
377
	 * eu.etaxonomy.taxeditor.operations.IPostOperationEnabled#postOperation
378
	 * (eu.etaxonomy.cdm.model.common.CdmBase)
379
	 */
380
	/** {@inheritDoc} */
381
	@Override
382
	public boolean postOperation(CdmBase objectAffectedByOperation) {
383
		// nothing to do here
384
		return true;
385
	}
386

    
387
	/**
388
	 * <p>
389
	 * save
390
	 * </p>
391
	 *
392
	 * @param memento
393
	 *            a {@link org.eclipse.ui.IMemento} object.
394
	 * @param monitor
395
	 *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
396
	 */
397
	public void save(IMemento memento, IProgressMonitor monitor) {
398
		saveTreeState(memento, monitor);
399
		if (conversation != null) {
400
			conversation.unregisterForDataStoreChanges(this);
401
			conversation = null;
402
		}
403
	}
404

    
405
	/** {@inheritDoc} */
406
	@Override
407
	protected void handleDoubleClick(DoubleClickEvent anEvent) {
408
		NavigationUtil.executeEditHandler();
409
		// If the double click is passed up to the super-class it will
410
		// expand/collapse trees.
411
		// We do not want that
412
		// super.handleDoubleClick(anEvent);
413
	}
414

    
415
	/**
416
	 * <p>
417
	 * onComplete
418
	 * </p>
419
	 *
420
	 * @return a boolean.
421
	 */
422
	@Override
423
	public boolean onComplete() {
424
		return true;
425
	}
426

    
427
	/*
428
	 * (non-Javadoc)
429
	 *
430
	 * @see org.eclipse.ui.part.WorkbenchPart#showBusy(boolean)
431
	 */
432
	/** {@inheritDoc} */
433
	@Override
434
	public void showBusy(boolean busy) {
435
		super.showBusy(busy);
436
		getCommonViewer().getControl().setEnabled(!busy);
437
		if (busy) {
438
			partNameCache = getPartName();
439
			setPartName("Loading datasources");
440
		} else {
441
			if (partNameCache != null) {
442
				setPartName(partNameCache);
443
			}
444
		}
445
	}
446

    
447

    
448
	/* (non-Javadoc)
449
	 * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
450
	 */
451
	@Override
452
	public void update(Observable o, Object arg) {
453
		if(o instanceof LoginManager){
454
			refresh();
455
		}
456

    
457
	}
458
}
(9-9/15)