Project

General

Profile

Download (10.9 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.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.model.taxon.TaxonComparatorSearch;
35
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
36
import eu.etaxonomy.taxeditor.model.DataChangeBridge;
37
import eu.etaxonomy.taxeditor.model.IDataChangeBehavior;
38
import eu.etaxonomy.taxeditor.navigation.NavigationUtil;
39
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
40
import eu.etaxonomy.taxeditor.store.CdmStore;
41
import eu.etaxonomy.taxeditor.store.LoginManager;
42

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

    
54
	/**
55
	 * Constant
56
	 * <code>ID="eu.etaxonomy.taxeditor.navigation.navig"{trunked}</code>
57
	 */
58
	public static final String ID = "eu.etaxonomy.taxeditor.navigation.navigator"; //$NON-NLS-1$
59

    
60
	private static final String TREE_PATH = "treepath";
61

    
62
	private static final String TREE_PATHS = "treepaths";
63

    
64
	private ConversationHolder conversation;
65

    
66
	private String partNameCache;
67

    
68
	private IDataChangeBehavior dataChangeBehavior;
69

    
70
	/*
71
	 * (non-Javadoc)
72
	 *
73
	 * @see org.eclipse.ui.navigator.CommonNavigator#getInitialInput()
74
	 */
75
	/** {@inheritDoc} */
76
	@Override
77
	protected IAdaptable getInitialInput() {
78
		
79
		TaxonComparatorSearch comparator = new TaxonComparatorSearch();
80
		TaxonNodeComparator viewerComparator = new TaxonNodeComparator(comparator);
81
		this.getCommonViewer().setComparator(viewerComparator);
82
		
83
		if (CdmStore.isActive()) {
84
			
85
			// TODO when closing and reopening the taxon navigator
86
			// we do not preserve state. Closing the view, in contrary to
87
			// closing the whole application
88
			// should be handled by the state manager too
89

    
90
			return new Root(conversation);
91
		}
92
		return new EmptyRoot();
93
	}
94

    
95
	/** {@inheritDoc} */
96
	@Override
97
	public void init(IViewSite site) throws PartInitException {
98
		super.init(site);
99
		init();
100
	}
101

    
102
	/**
103
	 * <p>
104
	 * init
105
	 * </p>
106
	 */
107
	public void init() {
108
		if (CdmStore.isActive() && conversation == null) {
109
			conversation = CdmStore.createConversation();
110
			conversation.registerForDataStoreChanges(TaxonNavigator.this);
111
		}
112
		CdmStore.getLoginManager().addObserver(this);
113
	}
114

    
115
	/**
116
	 * Refresh this navigators viewer
117
	 */
118
	public void refresh() {
119
		if(getConversationHolder() != null){
120
			getConversationHolder().bind();
121
			//FIXME : Need to make sure this is a stable fix (ticket 3822)
122
			if(!getConversationHolder().isCompleted()){
123
			    getConversationHolder().commit();
124
			}
125
		}
126
		getCommonViewer().refresh();
127
	}
128

    
129
	/**
130
	 * Removes all content
131
	 */
132
	public void clear() {
133
		getCommonViewer().setInput(new EmptyRoot());
134
	}
135

    
136
	/**
137
	 * <p>
138
	 * restore
139
	 * </p>
140
	 *
141
	 * @param memento
142
	 *            a {@link org.eclipse.ui.IMemento} object.
143
	 * @param monitor
144
	 *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
145
	 */
146
	public void restore(IMemento memento, IProgressMonitor monitor) {
147
		if (memento == null) {
148
			getCommonViewer().setInput(new Root(conversation));
149
			return;
150
		}
151
		int mementoWork = 0;
152
		Set<TreePath> treePaths = new HashSet<TreePath>();
153
		IMemento[] treePathMementos = null;
154

    
155
		IMemento treePathsMemento = memento.getChild(TREE_PATHS);
156

    
157
		if (treePathsMemento != null) {
158
			treePathMementos = treePathsMemento.getChildren(TREE_PATH);
159
			mementoWork = treePathMementos.length;
160
		}
161
		// begin the monitor with steps for all tree paths and steps for
162
		// creating
163
		// conversation s.o., refreshing the tree and setting the paths
164
		IProgressMonitor subProgressMonitor = NavigationUtil
165
				.getSubProgressMonitor(monitor, 1);
166

    
167
		subProgressMonitor.beginTask("Restoring Taxon Navigator",
168
				1 + mementoWork + 5);
169
		subProgressMonitor.subTask("Restoring Taxon Navigator");
170
		subProgressMonitor.worked(1);
171

    
172
		conversation = CdmStore.createConversation();
173
		subProgressMonitor.worked(1);
174
		conversation.registerForDataStoreChanges(TaxonNavigator.this);
175
		subProgressMonitor.worked(1);
176
		getCommonViewer().setInput(new Root(conversation));
177
		subProgressMonitor.worked(1);
178
		getCommonViewer().refresh();
179
		subProgressMonitor.worked(1);
180

    
181
		if (treePathMementos != null && treePathMementos.length > 0) {
182
			for (IMemento treePathMemento : treePathMementos) {
183
				TreePath treePath = createTreePathFromString(treePathMemento
184
						.getID());
185
				if (!subProgressMonitor.isCanceled() && treePath != null) {
186
					treePaths.add(treePath);
187
					subProgressMonitor.worked(1);
188
				}
189
			}
190
		}
191
		if (treePaths.size() > 0) {
192
			TaxonNavigator.this.getCommonViewer().setExpandedTreePaths(
193
					treePaths.toArray(new TreePath[0]));
194
			subProgressMonitor.worked(1);
195
		}
196
		subProgressMonitor.done();
197
	}
198

    
199
	/**
200
	 * @param string
201
	 * @return
202
	 */
203
	private TreePath createTreePathFromString(String string) {
204

    
205
		List<CdmBase> pathList = new ArrayList<CdmBase>();
206

    
207
		if (string.length() == 0) {
208
            return null;
209
        }
210

    
211
		for (String uuid : string.split(" ")) {
212
			CdmBase cdmBaseObject = CdmStore.getService(
213
					IClassificationService.class).getTaxonNodeByUuid(
214
					UUID.fromString(uuid));
215
			if (cdmBaseObject == null) {
216
				// is this a tree uuid?
217
				cdmBaseObject = CdmStore.getService(
218
						IClassificationService.class).load(
219
						UUID.fromString(uuid));
220

    
221
				if (cdmBaseObject == null) {
222
                    return null;
223
                }
224
			}
225
			pathList.add(cdmBaseObject);
226
		}
227
		return new TreePath(pathList.toArray());
228
	}
229

    
230
	/** {@inheritDoc} */
231
	@Override
232
	public void saveState(IMemento aMemento) {
233
		//
234
	}
235

    
236
	/**
237
	 * <p>
238
	 * saveTreeState
239
	 * </p>
240
	 *
241
	 * @param memento
242
	 *            a {@link org.eclipse.ui.IMemento} object.
243
	 * @param progressMonitor
244
	 *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
245
	 */
246
	public void saveTreeState(IMemento memento, IProgressMonitor progressMonitor) {
247
		if (memento == null) {
248
			return;
249
		}
250
		IProgressMonitor monitor = NavigationUtil.getSubProgressMonitor(
251
				progressMonitor, 1);
252

    
253
		super.saveState(memento);
254

    
255
		memento = memento.createChild(TREE_PATHS);
256
		TreePath[] treePaths = this.getCommonViewer().getExpandedTreePaths();
257

    
258
		monitor.beginTask("Saving Taxon Navigator State", treePaths.length);
259

    
260
		for (TreePath treePath : treePaths) {
261
			int pathLength = treePath.getSegmentCount();
262
			String path = "";
263
			for (int i = 0; i < pathLength; i++) {
264
				Object segment = treePath.getSegment(i);
265
				if (segment instanceof CdmBase) {
266
					path += ((CdmBase) segment).getUuid().toString() + " ";
267
					monitor.worked(1);
268
				} else {
269
					NavigationUtil.warn(getClass(),
270
							"Non-taxon tree path segment " + segment);
271
				}
272
			}
273
			memento.createChild(TREE_PATH, path.trim());
274
		}
275
		monitor.done();
276
	}
277

    
278
	/*
279
	 * (non-Javadoc)
280
	 *
281
	 * @see
282
	 * eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder
283
	 * ()
284
	 */
285
	/**
286
	 * <p>
287
	 * getConversationHolder
288
	 * </p>
289
	 *
290
	 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
291
	 *         object.
292
	 */
293
	@Override
294
	public ConversationHolder getConversationHolder() {
295
		return conversation;
296
	}
297

    
298
	/*
299
	 * (non-Javadoc)
300
	 *
301
	 * @see
302
	 * eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver#update
303
	 * (eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap)
304
	 */
305
	/** {@inheritDoc} */
306
	@Override
307
	public void update(CdmDataChangeMap changeEvents) {
308
		if (dataChangeBehavior == null) {
309
			dataChangeBehavior = new TaxonNavigatorDataChangeBehavior(this);
310
		}
311

    
312
		DataChangeBridge.handleDataChange(changeEvents, dataChangeBehavior);
313
	}
314

    
315
	/** {@inheritDoc} */
316
	@Override
317
	public String getFrameToolTipText(Object element) {
318
		if (element instanceof Root) {
319
			return "Taxonomic Tree";
320
		}
321
		return super.getFrameToolTipText(element);
322
	}
323

    
324
	/*
325
	 * (non-Javadoc)
326
	 *
327
	 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
328
	 */
329
	/** {@inheritDoc} */
330
	@Override
331
	public void dispose() {
332
		super.dispose();
333
		dataChangeBehavior = null;
334
		if (conversation != null) {
335
			conversation.unregisterForDataStoreChanges(this);
336
		}
337
	}
338

    
339
	/*
340
	 * (non-Javadoc)
341
	 *
342
	 * @see org.eclipse.ui.navigator.CommonNavigator#setFocus()
343
	 */
344
	/** {@inheritDoc} */
345
	@Override
346
	public void setFocus() {
347
		// logger.warn("Setting focus to navigator");
348
		super.setFocus();
349
		if (getConversationHolder() != null) {
350
			getConversationHolder().bind();
351
		}
352
	}
353

    
354
	/*
355
	 * (non-Javadoc)
356
	 *
357
	 * @see
358
	 * eu.etaxonomy.taxeditor.operations.IPostOperationEnabled#postOperation
359
	 * (eu.etaxonomy.cdm.model.common.CdmBase)
360
	 */
361
	/** {@inheritDoc} */
362
	@Override
363
	public boolean postOperation(CdmBase objectAffectedByOperation) {
364
		// nothing to do here
365
		return true;
366
	}
367

    
368
	/**
369
	 * <p>
370
	 * save
371
	 * </p>
372
	 *
373
	 * @param memento
374
	 *            a {@link org.eclipse.ui.IMemento} object.
375
	 * @param monitor
376
	 *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
377
	 */
378
	public void save(IMemento memento, IProgressMonitor monitor) {
379
		saveTreeState(memento, monitor);
380
		if (conversation != null) {
381
			conversation.unregisterForDataStoreChanges(this);
382
			conversation = null;
383
		}
384
	}
385

    
386
	/** {@inheritDoc} */
387
	@Override
388
	protected void handleDoubleClick(DoubleClickEvent anEvent) {
389
		NavigationUtil.executeEditHandler();
390
		// If the double click is passed up to the super-class it will
391
		// expand/collapse trees.
392
		// We do not want that
393
		// super.handleDoubleClick(anEvent);
394
	}
395

    
396
	/**
397
	 * <p>
398
	 * onComplete
399
	 * </p>
400
	 *
401
	 * @return a boolean.
402
	 */
403
	@Override
404
	public boolean onComplete() {
405
		return true;
406
	}
407

    
408
	/*
409
	 * (non-Javadoc)
410
	 *
411
	 * @see org.eclipse.ui.part.WorkbenchPart#showBusy(boolean)
412
	 */
413
	/** {@inheritDoc} */
414
	@Override
415
	public void showBusy(boolean busy) {
416
		super.showBusy(busy);
417
		getCommonViewer().getControl().setEnabled(!busy);
418
		if (busy) {
419
			partNameCache = getPartName();
420
			setPartName("Loading datasources");
421
		} else {
422
			if (partNameCache != null) {
423
				setPartName(partNameCache);
424
			}
425
		}
426
	}
427

    
428

    
429
	/* (non-Javadoc)
430
	 * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
431
	 */
432
	@Override
433
	public void update(Observable o, Object arg) {
434
		if(o instanceof LoginManager){
435
			refresh();
436
		}
437

    
438
	}
439
}
(9-9/15)