Project

General

Profile

Download (10.5 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
			getConversationHolder().commit();
115
		}
116
		getCommonViewer().refresh();
117
	}
118

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
243
		super.saveState(memento);
244

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
418

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

    
428
	}
429
}
(9-9/14)