Project

General

Profile

Download (12.7 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.model.MessagingUtils;
39
import eu.etaxonomy.taxeditor.navigation.NavigationUtil;
40
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
41
import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
42
import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
43
import eu.etaxonomy.taxeditor.store.CdmStore;
44
import eu.etaxonomy.taxeditor.store.LoginManager;
45

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

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

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

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

    
67
	private ConversationHolder conversation;
68

    
69
	private ICdmEntitySession cdmEntitySession;
70

    
71
	private String partNameCache;
72

    
73
	private IDataChangeBehavior dataChangeBehavior;
74

    
75
	/*
76
	 * (non-Javadoc)
77
	 *
78
	 * @see org.eclipse.ui.navigator.CommonNavigator#getInitialInput()
79
	 */
80
	/** {@inheritDoc} */
81
	@Override
82
	protected IAdaptable getInitialInput() {
83

    
84
		TaxonComparatorSearch comparator = new TaxonComparatorSearch();
85
		TaxonNodeComparator viewerComparator = new TaxonNodeComparator(comparator);
86
		this.getCommonViewer().setComparator(viewerComparator);
87
        setLinkingEnabled(true);
88
//		this.getCommonViewer().addSelectionChangedListener(new ISelectionChangedListener() {
89
//
90
//			@Override
91
//			public void selectionChanged(SelectionChangedEvent arg0) {
92
//				IStructuredSelection selection = (IStructuredSelection) getCommonViewer().getSelection();
93
//
94
//				Object firstElement =  selection.getFirstElement();
95
//				//
96
//				if (!(firstElement instanceof Classification)){
97
//					//NavigationUtil.selectInNavigator(firstElement, null);
98
//					NavigationUtil.openEditor(firstElement);
99
//				}
100
//
101
//			}
102
//		} );
103

    
104
		if (CdmStore.isActive()) {
105

    
106
			// TODO when closing and reopening the taxon navigator
107
			// we do not preserve state. Closing the view, in contrary to
108
			// closing the whole application
109
			// should be handled by the state manager too
110

    
111
			return new Root(conversation);
112
		}
113
		return new EmptyRoot();
114
	}
115

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

    
123
	/**
124
	 * <p>
125
	 * init
126
	 * </p>
127
	 */
128
	public void init() {
129

    
130
		if (CdmStore.isActive() && conversation == null) {
131
			conversation = CdmStore.createConversation();
132
			conversation.registerForDataStoreChanges(TaxonNavigator.this);
133
		}
134
		if (CdmStore.isActive() && cdmEntitySession == null) {
135
		    cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
136
		    cdmEntitySession.registerForDataStoreChanges(TaxonNavigator.this);
137
		}
138
		CdmStore.getLoginManager().addObserver(this);
139
	}
140

    
141
	/**
142
	 * Refresh this navigators viewer
143
	 */
144
	public void refresh() {
145
		if(getConversationHolder() != null){
146
			getConversationHolder().bind();
147
			//FIXME : Need to make sure this is a stable fix (ticket 3822)
148
			if(!getConversationHolder().isCompleted()){
149
			    getConversationHolder().commit();
150
			}
151
		}
152
		if (cdmEntitySession != null) {
153
		    cdmEntitySession.fireNotifications();
154
		}
155
		getCommonViewer().refresh();
156
	}
157

    
158
	   /**
159
     * Refresh this navigators viewer
160
     */
161
    public void refresh(Set objects) {
162

    
163
        for(Object obj : objects) {
164
            getCommonViewer().refresh(obj);
165
        }
166
    }
167

    
168
	/**
169
	 * Removes all content
170
	 */
171
	public void clear() {
172
		getCommonViewer().setInput(new EmptyRoot());
173
	}
174

    
175
	/**
176
	 * <p>
177
	 * restore
178
	 * </p>
179
	 *
180
	 * @param memento
181
	 *            a {@link org.eclipse.ui.IMemento} object.
182
	 * @param monitor
183
	 *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
184
	 */
185
	public void restore(IMemento memento, IProgressMonitor monitor) {
186
		if (memento == null) {
187
			getCommonViewer().setInput(new Root(conversation));
188
			return;
189
		}
190
		int mementoWork = 0;
191
		Set<TreePath> treePaths = new HashSet<TreePath>();
192
		IMemento[] treePathMementos = null;
193

    
194
		IMemento treePathsMemento = memento.getChild(TREE_PATHS);
195

    
196
		if (treePathsMemento != null) {
197
			treePathMementos = treePathsMemento.getChildren(TREE_PATH);
198
			mementoWork = treePathMementos.length;
199
		}
200
		// begin the monitor with steps for all tree paths and steps for
201
		// creating
202
		// conversation s.o., refreshing the tree and setting the paths
203
		IProgressMonitor subProgressMonitor = NavigationUtil
204
				.getSubProgressMonitor(monitor, 1);
205

    
206
		subProgressMonitor.beginTask("Restoring Taxon Navigator",
207
				1 + mementoWork + 5);
208
		subProgressMonitor.subTask("Restoring Taxon Navigator");
209
		subProgressMonitor.worked(1);
210

    
211
		conversation = CdmStore.createConversation();
212
		subProgressMonitor.worked(1);
213
		conversation.registerForDataStoreChanges(TaxonNavigator.this);
214
		subProgressMonitor.worked(1);
215
		getCommonViewer().setInput(new Root(conversation));
216
		subProgressMonitor.worked(1);
217
		getCommonViewer().refresh();
218
		subProgressMonitor.worked(1);
219

    
220
		if (treePathMementos != null && treePathMementos.length > 0) {
221
			for (IMemento treePathMemento : treePathMementos) {
222
				TreePath treePath = createTreePathFromString(treePathMemento
223
						.getID());
224
				if (!subProgressMonitor.isCanceled() && treePath != null) {
225
					treePaths.add(treePath);
226
					subProgressMonitor.worked(1);
227
				}
228
			}
229
		}
230
		if (treePaths.size() > 0) {
231
			TaxonNavigator.this.getCommonViewer().setExpandedTreePaths(
232
					treePaths.toArray(new TreePath[0]));
233
			subProgressMonitor.worked(1);
234
		}
235
		subProgressMonitor.done();
236
	}
237

    
238
	/**
239
	 * @param string
240
	 * @return
241
	 */
242
	private TreePath createTreePathFromString(String string) {
243

    
244
		List<CdmBase> pathList = new ArrayList<CdmBase>();
245

    
246
		if (string.length() == 0) {
247
            return null;
248
        }
249

    
250
		for (String uuid : string.split(" ")) {
251
			CdmBase cdmBaseObject = CdmStore.getService(
252
					IClassificationService.class).getTaxonNodeByUuid(
253
					UUID.fromString(uuid));
254
			if (cdmBaseObject == null) {
255
				// is this a tree uuid?
256
				cdmBaseObject = CdmStore.getService(
257
						IClassificationService.class).load(
258
						UUID.fromString(uuid));
259

    
260
				if (cdmBaseObject == null) {
261
                    return null;
262
                }
263
			}
264
			pathList.add(cdmBaseObject);
265
		}
266
		return new TreePath(pathList.toArray());
267
	}
268

    
269
	/** {@inheritDoc} */
270
	@Override
271
	public void saveState(IMemento aMemento) {
272
		//
273
	}
274

    
275
	/**
276
	 * <p>
277
	 * saveTreeState
278
	 * </p>
279
	 *
280
	 * @param memento
281
	 *            a {@link org.eclipse.ui.IMemento} object.
282
	 * @param progressMonitor
283
	 *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
284
	 */
285
	public void saveTreeState(IMemento memento, IProgressMonitor progressMonitor) {
286
		if (memento == null) {
287
			return;
288
		}
289
		IProgressMonitor monitor = NavigationUtil.getSubProgressMonitor(
290
				progressMonitor, 1);
291

    
292
		super.saveState(memento);
293

    
294
		memento = memento.createChild(TREE_PATHS);
295
		TreePath[] treePaths = this.getCommonViewer().getExpandedTreePaths();
296

    
297
		monitor.beginTask("Saving Taxon Navigator State", treePaths.length);
298

    
299
		for (TreePath treePath : treePaths) {
300
			int pathLength = treePath.getSegmentCount();
301
			String path = "";
302
			for (int i = 0; i < pathLength; i++) {
303
				Object segment = treePath.getSegment(i);
304
				if (segment instanceof CdmBase) {
305
					path += ((CdmBase) segment).getUuid().toString() + " ";
306
					monitor.worked(1);
307
				} else {
308
					MessagingUtils.warn(getClass(),
309
							"Non-taxon tree path segment " + segment);
310
				}
311
			}
312
			memento.createChild(TREE_PATH, path.trim());
313
		}
314
		monitor.done();
315
	}
316

    
317
	/*
318
	 * (non-Javadoc)
319
	 *
320
	 * @see
321
	 * eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder
322
	 * ()
323
	 */
324
	/**
325
	 * <p>
326
	 * getConversationHolder
327
	 * </p>
328
	 *
329
	 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
330
	 *         object.
331
	 */
332
	@Override
333
	public ConversationHolder getConversationHolder() {
334
		return conversation;
335
	}
336

    
337
	/*
338
	 * (non-Javadoc)
339
	 *
340
	 * @see
341
	 * eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver#update
342
	 * (eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap)
343
	 */
344
	/** {@inheritDoc} */
345
	@Override
346
	public void update(CdmDataChangeMap changeEvents) {
347
		if (dataChangeBehavior == null) {
348
			dataChangeBehavior = new TaxonNavigatorDataChangeBehavior(this);
349
		}
350

    
351
		DataChangeBridge.handleDataChange(changeEvents, dataChangeBehavior);
352
	}
353

    
354
	/** {@inheritDoc} */
355
	@Override
356
	public String getFrameToolTipText(Object element) {
357
		if (element instanceof Root) {
358
			return "Taxonomic Tree";
359
		}
360
		return super.getFrameToolTipText(element);
361
	}
362

    
363
	/*
364
	 * (non-Javadoc)
365
	 *
366
	 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
367
	 */
368
	/** {@inheritDoc} */
369
	@Override
370
	public void dispose() {
371
		super.dispose();
372
		dataChangeBehavior = null;
373
		if (conversation != null) {
374
			conversation.unregisterForDataStoreChanges(this);
375
		}
376
		if(cdmEntitySession != null) {
377
		    cdmEntitySession.dispose();
378
		}
379
	}
380

    
381
	/*
382
	 * (non-Javadoc)
383
	 *
384
	 * @see org.eclipse.ui.navigator.CommonNavigator#setFocus()
385
	 */
386
	/** {@inheritDoc} */
387
	@Override
388
	public void setFocus() {
389
		// logger.warn("Setting focus to navigator");
390
		super.setFocus();
391
		if (getConversationHolder() != null) {
392
			getConversationHolder().bind();
393
		}
394
		if(cdmEntitySession != null) {
395
		    cdmEntitySession.bind();
396
		}
397
	}
398

    
399
	/*
400
	 * (non-Javadoc)
401
	 *
402
	 * @see
403
	 * eu.etaxonomy.taxeditor.operations.IPostOperationEnabled#postOperation
404
	 * (eu.etaxonomy.cdm.model.common.CdmBase)
405
	 */
406
	/** {@inheritDoc} */
407
	@Override
408
	public boolean postOperation(CdmBase objectAffectedByOperation) {
409
		// nothing to do here
410
		return true;
411
	}
412

    
413
	/**
414
	 * <p>
415
	 * save
416
	 * </p>
417
	 *
418
	 * @param memento
419
	 *            a {@link org.eclipse.ui.IMemento} object.
420
	 * @param monitor
421
	 *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
422
	 */
423
	public void save(IMemento memento, IProgressMonitor monitor) {
424
		saveTreeState(memento, monitor);
425
		if (conversation != null) {
426
			conversation.unregisterForDataStoreChanges(this);
427
			conversation = null;
428
		}
429
	}
430

    
431
	/** {@inheritDoc} */
432
	@Override
433
	protected void handleDoubleClick(DoubleClickEvent anEvent) {
434
		NavigationUtil.executeEditHandler();
435
		// If the double click is passed up to the super-class it will
436
		// expand/collapse trees.
437
		// We do not want that
438
		// super.handleDoubleClick(anEvent);
439
	}
440

    
441
	/**
442
	 * <p>
443
	 * onComplete
444
	 * </p>
445
	 *
446
	 * @return a boolean.
447
	 */
448
	@Override
449
	public boolean onComplete() {
450
		return true;
451
	}
452

    
453
	/*
454
	 * (non-Javadoc)
455
	 *
456
	 * @see org.eclipse.ui.part.WorkbenchPart#showBusy(boolean)
457
	 */
458
	/** {@inheritDoc} */
459
	@Override
460
	public void showBusy(boolean busy) {
461
		super.showBusy(busy);
462
		getCommonViewer().getControl().setEnabled(!busy);
463
		if (busy) {
464
			partNameCache = getPartName();
465
			setPartName("Loading datasources");
466
		} else {
467
			if (partNameCache != null) {
468
				setPartName(partNameCache);
469
			}
470
		}
471
	}
472

    
473

    
474
	/* (non-Javadoc)
475
	 * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
476
	 */
477
	@Override
478
	public void update(Observable o, Object arg) {
479
		if(o instanceof LoginManager){
480
			refresh();
481
		}
482

    
483
	}
484

    
485
    /* (non-Javadoc)
486
     * @see eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled#getCdmEntitySession()
487
     */
488
    @Override
489
    public ICdmEntitySession getCdmEntitySession() {
490
       return cdmEntitySession;
491
    }
492

    
493
    /* (non-Javadoc)
494
     * @see eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled#getRootEntities()
495
     */
496
    @Override
497
    public <T extends CdmBase> List<T> getRootEntities() {
498
        return null;
499
    }
500
}
(9-9/15)