3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
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.
11 package eu
.etaxonomy
.taxeditor
.navigation
.navigator
;
13 import java
.lang
.reflect
.InvocationTargetException
;
14 import java
.util
.ArrayList
;
15 import java
.util
.HashSet
;
16 import java
.util
.List
;
18 import java
.util
.UUID
;
20 import org
.apache
.log4j
.Logger
;
21 import org
.eclipse
.core
.commands
.Command
;
22 import org
.eclipse
.core
.commands
.common
.NotDefinedException
;
23 import org
.eclipse
.core
.runtime
.IAdaptable
;
24 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
25 import org
.eclipse
.jface
.dialogs
.ProgressMonitorDialog
;
26 import org
.eclipse
.jface
.operation
.IRunnableWithProgress
;
27 import org
.eclipse
.jface
.viewers
.DoubleClickEvent
;
28 import org
.eclipse
.jface
.viewers
.TreePath
;
29 import org
.eclipse
.swt
.widgets
.Composite
;
30 import org
.eclipse
.ui
.IMemento
;
31 import org
.eclipse
.ui
.IViewSite
;
32 import org
.eclipse
.ui
.PartInitException
;
33 import org
.eclipse
.ui
.commands
.ICommandService
;
34 import org
.eclipse
.ui
.handlers
.IHandlerService
;
35 import org
.eclipse
.ui
.navigator
.CommonNavigator
;
37 import eu
.etaxonomy
.cdm
.api
.conversation
.ConversationHolder
;
38 import eu
.etaxonomy
.cdm
.api
.conversation
.IConversationEnabled
;
39 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
40 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.CdmDataChangeMap
;
41 import eu
.etaxonomy
.taxeditor
.model
.DataChangeBridge
;
42 import eu
.etaxonomy
.taxeditor
.model
.IDataChangeBehavior
;
43 import eu
.etaxonomy
.taxeditor
.navigation
.NavigationUtil
;
44 import eu
.etaxonomy
.taxeditor
.operations
.IPostOperationEnabled
;
45 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
48 * Taxonomic tree implementation using Common Navigator Framework.
54 public class TaxonNavigator
extends CommonNavigator
implements IPostOperationEnabled
, IConversationEnabled
{
55 private static final Logger logger
= Logger
56 .getLogger(TaxonNavigator
.class);
58 public static final String ID
= "eu.etaxonomy.taxeditor.navigation.navigator"; //$NON-NLS-1$
60 public static final String OPEN_COMMAND_ID
= "eu.etaxonomy.taxeditor.navigation.command.editSelection";
62 private static final String TREE_PATH
= "treepath";
64 private static final String TREE_PATHS
= "treepaths";
66 private ConversationHolder conversation
;
68 private IDataChangeBehavior dataChangeBehavior
;
71 * @see org.eclipse.ui.navigator.CommonNavigator#getInitialInput()
74 protected IAdaptable
getInitialInput() {
75 if(CdmStore
.isActive()){
76 // TODO when closing and reopening the taxon navigator
77 // we do not preserve state. Closing the view, in contrary to closing the whole application
78 // should be handled by the state manager too
81 return new EmptyRoot();
87 public void init(IViewSite site
)
88 throws PartInitException
{
90 if(CdmStore
.isActive() && conversation
== null){
91 conversation
= CdmStore
.createConversation();
92 conversation
.registerForDataStoreChanges(TaxonNavigator
.this);
97 * Refresh this navigators viewer
99 public void refresh(){
100 logger
.warn("Refreshing navigator");
101 getConversationHolder().bind();
102 this.getCommonViewer().refresh();
109 public void restore(final IMemento memento
) {
111 ProgressMonitorDialog progressMonitorDialog
= new ProgressMonitorDialog(NavigationUtil
.getShell());
112 IRunnableWithProgress runnable
= new IRunnableWithProgress() {
115 public void run(IProgressMonitor monitor
) throws InvocationTargetException
,
116 InterruptedException
{
117 monitor
.setTaskName("Restoring Taxon Navigator");
119 Set
<TreePath
> treePaths
= new HashSet
<TreePath
>();
120 IMemento
[] treePathMementos
= null;
121 if (memento
!= null) {
124 IMemento treePathsMemento
= memento
.getChild(TREE_PATHS
);
126 if (treePathsMemento
!= null) {
127 treePathMementos
= treePathsMemento
.getChildren(TREE_PATH
);
128 mementoWork
= treePathMementos
.length
;
131 // begin the monitor with steps for all tree paths and steps for creating
132 // conversation s.o., refreshing the tree and setting the paths
133 monitor
.beginTask("Restoring Taxon Navigator", 1 + mementoWork
+ 5);
136 conversation
= CdmStore
.createConversation();
138 conversation
.registerForDataStoreChanges(TaxonNavigator
.this);
140 TaxonNavigator
.this.getCommonViewer().setInput(new Root());
142 TaxonNavigator
.this.getCommonViewer().refresh();
147 if (treePathMementos
!= null && treePathMementos
.length
> 0) {
148 for (IMemento treePathMemento
: treePathMementos
) {
149 TreePath treePath
= createTreePathFromString(treePathMemento
.getID());
150 if (!monitor
.isCanceled() && treePath
!= null) {
151 treePaths
.add(treePath
);
156 if (treePaths
.size() > 0) {
157 TaxonNavigator
.this.getCommonViewer().setExpandedTreePaths(treePaths
.toArray(new TreePath
[0]));
165 progressMonitorDialog
.run(false, true, runnable
);
166 } catch (InvocationTargetException e
) {
167 logger
.error("InvocationTargetException when trying to restore navigator", e
);
168 } catch (InterruptedException e
) {
169 logger
.error("InterruptedException when trying to restore navigator", e
);
177 private TreePath
createTreePathFromString(String string
) {
179 List
<CdmBase
> pathList
= new ArrayList
<CdmBase
>();
181 if(string
.length() == 0) return null;
183 for (String uuid
: string
.split(" ")) {
184 CdmBase cdmBaseObject
= CdmStore
.getTaxonTreeService().getTaxonNodeByUuid(UUID
.fromString(uuid
));
185 if (cdmBaseObject
== null) {
186 // is this a tree uuid?
187 cdmBaseObject
= CdmStore
.getTaxonTreeService().getTaxonomicTreeByUuid(UUID
.fromString(uuid
));
189 if(cdmBaseObject
== null) return null;
191 pathList
.add(cdmBaseObject
);
193 return new TreePath(pathList
.toArray());
198 public void saveState(IMemento aMemento
) {
202 public void saveTreeState(IMemento memento
) {
204 if (memento
!= null) {
205 super.saveState(memento
);
207 memento
= memento
.createChild(TREE_PATHS
);
208 TreePath
[] treePaths
= this.getCommonViewer().getExpandedTreePaths();
209 for (TreePath treePath
: treePaths
) {
210 int pathLength
= treePath
.getSegmentCount();
212 for (int i
= 0; i
< pathLength
; i
++) {
213 Object segment
= treePath
.getSegment(i
);
214 if (segment
instanceof CdmBase
) {
215 path
+= ((CdmBase
) segment
).getUuid().toString() + " ";
217 logger
.warn("Non-taxon tree path segment " + segment
);
220 logger
.info("Creating memento child for path " + path
.trim());
221 memento
.createChild(TREE_PATH
, path
.trim());
224 logger
.warn("TreeState could not be saved: Memento is null");
229 * Activates the current view.
231 private void activateView() {
232 getSite().getPage().activate(this);
236 * @see org.eclipse.ui.navigator.CommonNavigator#createPartControl(org.eclipse.swt.widgets.Composite)
238 public void createPartControl(Composite aParent
) {
239 super.createPartControl(aParent
);
241 // It seems the workbench does not set the focus at the right time. This should fix this.
242 // getCommonViewer().addSelectionChangedListener(new ISelectionChangedListener() {
243 // public void selectionChanged(SelectionChangedEvent event) {
251 * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
253 public ConversationHolder
getConversationHolder() {
258 * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap)
260 public void update(CdmDataChangeMap changeEvents
) {
261 if(dataChangeBehavior
== null){
262 dataChangeBehavior
= new TaxonNavigatorDataChangeBehavior(this);
265 DataChangeBridge
.handleDataChange(changeEvents
, dataChangeBehavior
);
268 public String
getFrameToolTipText(Object element
) {
269 if (element
instanceof Root
) {
270 return "Taxonomic Tree";
272 return super.getFrameToolTipText(element
);
276 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
279 public void dispose() {
281 dataChangeBehavior
= null;
282 if(conversation
!= null){
283 conversation
.unregisterForDataStoreChanges(this);
288 * @see org.eclipse.ui.navigator.CommonNavigator#setFocus()
291 public void setFocus() {
292 //logger.warn("Setting focus to navigator");
294 if(getConversationHolder() != null){
295 getConversationHolder().bind();
300 * @see eu.etaxonomy.taxeditor.operations.IPostOperationEnabled#postOperation(eu.etaxonomy.cdm.model.common.CdmBase)
302 public boolean postOperation(CdmBase objectAffectedByOperation
) {
303 // nothing to do here
307 public void save(IMemento memento
) {
308 saveTreeState(memento
);
309 if(conversation
!= null){
310 conversation
.unregisterForDataStoreChanges(this);
313 // this.getCommonViewer().setInput(new EmptyRoot());
317 // public ISelection getSelection() {
318 // return getCommonViewer().getSelection();
322 * @see http://www.eclipse.org/forums/index.php?t=msg&goto=512094&
325 protected void handleDoubleClick(DoubleClickEvent anEvent
) {
327 ICommandService commandService
= (ICommandService
)getSite().getService(ICommandService
.class);
329 Command command
= commandService
.getCommand(OPEN_COMMAND_ID
);
330 if(command
.isEnabled()) {
331 IHandlerService handlerService
= (IHandlerService
)getSite().getService(IHandlerService
.class);
333 handlerService
.executeCommand(OPEN_COMMAND_ID
, null);
334 } catch (NotDefinedException e
) {
335 throw new RuntimeException("Could not find open command: " + OPEN_COMMAND_ID
);
336 } catch (Exception e
) {
337 logger
.error("An exception occured while trying to open a selection", e
);
340 // Pass the double click up to the super-class so it can expand/collapse trees
341 super.handleDoubleClick(anEvent
);