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
		if (CdmStore.isActive()) {
83
			
84
			// TODO when closing and reopening the taxon navigator
85
			// we do not preserve state. Closing the view, in contrary to
86
			// closing the whole application
87
			// should be handled by the state manager too
88

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
252
		super.saveState(memento);
253

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
427

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

    
437
	}
438
}
(9-9/15)