Project

General

Profile

Download (10.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.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
			//FIXME : Need to make sure this is a stable fix (ticket 3822)
115
			getConversationHolder().commit();
116
		}
117
		getCommonViewer().refresh();
118
	}
119

    
120
	/**
121
	 * Removes all content
122
	 */
123
	public void clear() {
124
		getCommonViewer().setInput(new EmptyRoot());
125
	}
126

    
127
	/**
128
	 * <p>
129
	 * restore
130
	 * </p>
131
	 *
132
	 * @param memento
133
	 *            a {@link org.eclipse.ui.IMemento} object.
134
	 * @param monitor
135
	 *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
136
	 */
137
	public void restore(IMemento memento, IProgressMonitor monitor) {
138
		if (memento == null) {
139
			getCommonViewer().setInput(new Root(conversation));
140
			return;
141
		}
142
		int mementoWork = 0;
143
		Set<TreePath> treePaths = new HashSet<TreePath>();
144
		IMemento[] treePathMementos = null;
145

    
146
		IMemento treePathsMemento = memento.getChild(TREE_PATHS);
147

    
148
		if (treePathsMemento != null) {
149
			treePathMementos = treePathsMemento.getChildren(TREE_PATH);
150
			mementoWork = treePathMementos.length;
151
		}
152
		// begin the monitor with steps for all tree paths and steps for
153
		// creating
154
		// conversation s.o., refreshing the tree and setting the paths
155
		IProgressMonitor subProgressMonitor = NavigationUtil
156
				.getSubProgressMonitor(monitor, 1);
157

    
158
		subProgressMonitor.beginTask("Restoring Taxon Navigator",
159
				1 + mementoWork + 5);
160
		subProgressMonitor.subTask("Restoring Taxon Navigator");
161
		subProgressMonitor.worked(1);
162

    
163
		conversation = CdmStore.createConversation();
164
		subProgressMonitor.worked(1);
165
		conversation.registerForDataStoreChanges(TaxonNavigator.this);
166
		subProgressMonitor.worked(1);
167
		getCommonViewer().setInput(new Root(conversation));
168
		subProgressMonitor.worked(1);
169
		getCommonViewer().refresh();
170
		subProgressMonitor.worked(1);
171

    
172
		if (treePathMementos != null && treePathMementos.length > 0) {
173
			for (IMemento treePathMemento : treePathMementos) {
174
				TreePath treePath = createTreePathFromString(treePathMemento
175
						.getID());
176
				if (!subProgressMonitor.isCanceled() && treePath != null) {
177
					treePaths.add(treePath);
178
					subProgressMonitor.worked(1);
179
				}
180
			}
181
		}
182
		if (treePaths.size() > 0) {
183
			TaxonNavigator.this.getCommonViewer().setExpandedTreePaths(
184
					treePaths.toArray(new TreePath[0]));
185
			subProgressMonitor.worked(1);
186
		}
187
		subProgressMonitor.done();
188
	}
189

    
190
	/**
191
	 * @param string
192
	 * @return
193
	 */
194
	private TreePath createTreePathFromString(String string) {
195

    
196
		List<CdmBase> pathList = new ArrayList<CdmBase>();
197

    
198
		if (string.length() == 0) {
199
            return null;
200
        }
201

    
202
		for (String uuid : string.split(" ")) {
203
			CdmBase cdmBaseObject = CdmStore.getService(
204
					IClassificationService.class).getTaxonNodeByUuid(
205
					UUID.fromString(uuid));
206
			if (cdmBaseObject == null) {
207
				// is this a tree uuid?
208
				cdmBaseObject = CdmStore.getService(
209
						IClassificationService.class).load(
210
						UUID.fromString(uuid));
211

    
212
				if (cdmBaseObject == null) {
213
                    return null;
214
                }
215
			}
216
			pathList.add(cdmBaseObject);
217
		}
218
		return new TreePath(pathList.toArray());
219
	}
220

    
221
	/** {@inheritDoc} */
222
	@Override
223
	public void saveState(IMemento aMemento) {
224
		//
225
	}
226

    
227
	/**
228
	 * <p>
229
	 * saveTreeState
230
	 * </p>
231
	 *
232
	 * @param memento
233
	 *            a {@link org.eclipse.ui.IMemento} object.
234
	 * @param progressMonitor
235
	 *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
236
	 */
237
	public void saveTreeState(IMemento memento, IProgressMonitor progressMonitor) {
238
		if (memento == null) {
239
			return;
240
		}
241
		IProgressMonitor monitor = NavigationUtil.getSubProgressMonitor(
242
				progressMonitor, 1);
243

    
244
		super.saveState(memento);
245

    
246
		memento = memento.createChild(TREE_PATHS);
247
		TreePath[] treePaths = this.getCommonViewer().getExpandedTreePaths();
248

    
249
		monitor.beginTask("Saving Taxon Navigator State", treePaths.length);
250

    
251
		for (TreePath treePath : treePaths) {
252
			int pathLength = treePath.getSegmentCount();
253
			String path = "";
254
			for (int i = 0; i < pathLength; i++) {
255
				Object segment = treePath.getSegment(i);
256
				if (segment instanceof CdmBase) {
257
					path += ((CdmBase) segment).getUuid().toString() + " ";
258
					monitor.worked(1);
259
				} else {
260
					NavigationUtil.warn(getClass(),
261
							"Non-taxon tree path segment " + segment);
262
				}
263
			}
264
			memento.createChild(TREE_PATH, path.trim());
265
		}
266
		monitor.done();
267
	}
268

    
269
	/*
270
	 * (non-Javadoc)
271
	 *
272
	 * @see
273
	 * eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder
274
	 * ()
275
	 */
276
	/**
277
	 * <p>
278
	 * getConversationHolder
279
	 * </p>
280
	 *
281
	 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
282
	 *         object.
283
	 */
284
	@Override
285
	public ConversationHolder getConversationHolder() {
286
		return conversation;
287
	}
288

    
289
	/*
290
	 * (non-Javadoc)
291
	 *
292
	 * @see
293
	 * eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver#update
294
	 * (eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap)
295
	 */
296
	/** {@inheritDoc} */
297
	@Override
298
	public void update(CdmDataChangeMap changeEvents) {
299
		if (dataChangeBehavior == null) {
300
			dataChangeBehavior = new TaxonNavigatorDataChangeBehavior(this);
301
		}
302

    
303
		DataChangeBridge.handleDataChange(changeEvents, dataChangeBehavior);
304
	}
305

    
306
	/** {@inheritDoc} */
307
	@Override
308
	public String getFrameToolTipText(Object element) {
309
		if (element instanceof Root) {
310
			return "Taxonomic Tree";
311
		}
312
		return super.getFrameToolTipText(element);
313
	}
314

    
315
	/*
316
	 * (non-Javadoc)
317
	 *
318
	 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
319
	 */
320
	/** {@inheritDoc} */
321
	@Override
322
	public void dispose() {
323
		super.dispose();
324
		dataChangeBehavior = null;
325
		if (conversation != null) {
326
			conversation.unregisterForDataStoreChanges(this);
327
		}
328
	}
329

    
330
	/*
331
	 * (non-Javadoc)
332
	 *
333
	 * @see org.eclipse.ui.navigator.CommonNavigator#setFocus()
334
	 */
335
	/** {@inheritDoc} */
336
	@Override
337
	public void setFocus() {
338
		// logger.warn("Setting focus to navigator");
339
		super.setFocus();
340
		if (getConversationHolder() != null) {
341
			getConversationHolder().bind();
342
		}
343
	}
344

    
345
	/*
346
	 * (non-Javadoc)
347
	 *
348
	 * @see
349
	 * eu.etaxonomy.taxeditor.operations.IPostOperationEnabled#postOperation
350
	 * (eu.etaxonomy.cdm.model.common.CdmBase)
351
	 */
352
	/** {@inheritDoc} */
353
	@Override
354
	public boolean postOperation(CdmBase objectAffectedByOperation) {
355
		// nothing to do here
356
		return true;
357
	}
358

    
359
	/**
360
	 * <p>
361
	 * save
362
	 * </p>
363
	 *
364
	 * @param memento
365
	 *            a {@link org.eclipse.ui.IMemento} object.
366
	 * @param monitor
367
	 *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
368
	 */
369
	public void save(IMemento memento, IProgressMonitor monitor) {
370
		saveTreeState(memento, monitor);
371
		if (conversation != null) {
372
			conversation.unregisterForDataStoreChanges(this);
373
			conversation = null;
374
		}
375
	}
376

    
377
	/** {@inheritDoc} */
378
	@Override
379
	protected void handleDoubleClick(DoubleClickEvent anEvent) {
380
		NavigationUtil.executeEditHandler();
381
		// If the double click is passed up to the super-class it will
382
		// expand/collapse trees.
383
		// We do not want that
384
		// super.handleDoubleClick(anEvent);
385
	}
386

    
387
	/**
388
	 * <p>
389
	 * onComplete
390
	 * </p>
391
	 *
392
	 * @return a boolean.
393
	 */
394
	@Override
395
	public boolean onComplete() {
396
		return true;
397
	}
398

    
399
	/*
400
	 * (non-Javadoc)
401
	 *
402
	 * @see org.eclipse.ui.part.WorkbenchPart#showBusy(boolean)
403
	 */
404
	/** {@inheritDoc} */
405
	@Override
406
	public void showBusy(boolean busy) {
407
		super.showBusy(busy);
408
		getCommonViewer().getControl().setEnabled(!busy);
409
		if (busy) {
410
			partNameCache = getPartName();
411
			setPartName("Loading datasources");
412
		} else {
413
			if (partNameCache != null) {
414
				setPartName(partNameCache);
415
			}
416
		}
417
	}
418

    
419

    
420
	/* (non-Javadoc)
421
	 * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
422
	 */
423
	@Override
424
	public void update(Observable o, Object arg) {
425
		if(o instanceof LoginManager){
426
			refresh();
427
		}
428

    
429
	}
430
}
(9-9/14)