eu.etaxonomy.taxeditor.cdmlib,
eu.etaxonomy.taxeditor.store,
eu.etaxonomy.taxeditor.editor,
- org.eclipse.e4.ui.model.workbench;bundle-version="1.2.0.v20160229-1459"
+ org.eclipse.e4.ui.model.workbench;bundle-version="1.2.0.v20160229-1459",
+ org.eclipse.e4.ui.di,
+ javax.inject
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.eclipse.core.resources,
org.eclipse.core.runtime,
<?xml version="1.0" encoding="ASCII"?>
-<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmi:id="_OhwnQCTfEeeiN5lBIuqN3g">
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/descriptor/basic" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmlns:ui="http://www.eclipse.org/ui/2010/UIModel/application/ui" xmi:id="_OhwnQCTfEeeiN5lBIuqN3g">
<fragments xsi:type="fragment:StringModelFragment" xmi:id="_oDvMsCTfEeeiN5lBIuqN3g" featurename="children" parentElementId="eu.etaxonomy.taxeditor.workbench.trimcontribution.mainToolbar">
<elements xsi:type="menu:ToolControl" xmi:id="_7kZI4CTfEeeiN5lBIuqN3g" elementId="eu.etaxonomy.taxeditor.navigation.toolcontrol.search_bar" contributionURI="bundleclass://eu.etaxonomy.taxeditor.navigation/eu.etaxonomy.taxeditor.navigation.search.SearchBar"/>
</fragments>
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_Z-4rwJIVEeeJAdt8ZUxyaw" featurename="descriptors" parentElementId="org.eclipse.e4.legacy.ide.application">
+ <elements xsi:type="basic:PartDescriptor" xmi:id="_gH5RYJIVEeeJAdt8ZUxyaw" elementId="eu.etaxonomy.taxeditor.navigation.navigator" label="%view.name.2" iconURI="platform:/plugin/eu.etaxonomy.taxeditor.navigation/icons/edit_16x16.gif" closeable="true" contributionURI="bundleclass://eu.etaxonomy.taxeditor.navigation/eu.etaxonomy.taxeditor.navigation.navigator.e4.TaxonNavigatorE4"/>
+ </fragments>
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_wITZ8JIVEeeJAdt8ZUxyaw" featurename="children" parentElementId="eu.etaxonomy.taxeditor.menu.showView" positionInList="">
+ <elements xsi:type="menu:HandledMenuItem" xmi:id="_wITZ8ZIVEeeJAdt8ZUxyaw" elementId="eu.etaxonomy.taxeditor.navigator.showViewMenu.navigator" label="%command.label" iconURI="platform:/plugin/eu.etaxonomy.taxeditor.navigation/icons/edit_16x16.gif">
+ <visibleWhen xsi:type="ui:CoreExpression" xmi:id="_wITZ8pIVEeeJAdt8ZUxyaw" coreExpressionId="isCdmStoreConnected"/>
+ <command href="../eu.etaxonomy.taxeditor.store/fragment.e4xmi#_bnVKsCZxEeeQLpuomSmVoQ"/>
+ <parameters xmi:id="_wITZ85IVEeeJAdt8ZUxyaw" elementId="eu.etaxonomy.taxeditor.store.showView.parameter.detailsView" name="eu.etaxonomy.taxeditor.workbench.commandparameter.partName" value="eu.etaxonomy.taxeditor.navigation.navigator"/>
+ </elements>
+ </fragments>
</fragment:ModelFragments>
name="%view.name"
restorable="false">
</view>
- <view
- allowMultiple="false"
- class="eu.etaxonomy.taxeditor.navigation.navigator.TaxonNavigator"
- icon="icons/preferences-system-windows.png"
- id="eu.etaxonomy.taxeditor.navigation.navigator"
- name="%view.name.0"
- restorable="true">
- </view>
<view
allowMultiple="false"
class="eu.etaxonomy.taxeditor.navigation.key.polytomous.PolytomousKeyViewPart"
</menuContribution>
<menuContribution
locationURI="menu:eu.etaxonomy.taxeditor.menu.showView?before=eu.etaxonomy.taxeditor.editor.showViewMenu">
- <command
- commandId="org.eclipse.ui.views.showView"
- label="%command.label"
- style="push">
- <parameter
- name="org.eclipse.ui.views.showView.viewId"
- value="eu.etaxonomy.taxeditor.navigation.navigator">
- </parameter>
- <visibleWhen
- checkEnabled="true">
- <reference
- definitionId="isCdmStoreConnected">
- </reference>
- </visibleWhen>
- </command>
<command
commandId="org.eclipse.ui.views.showView"
label="%command.label.0"
</and>
</activeWhen>
</handler>
- </extension>
-
-
- <!--extension
- point="org.eclipse.ui.navigator.viewer">
- <viewer
- viewerId="org.eclipse.ui.examples.navigator.view">
- </viewer>
- <viewerContentBinding
- viewerId="org.eclipse.ui.examples.navigator.view">
- <includes>
- <contentExtension
- pattern="org.eclipse.ui.navigator.resourceContent" />
- <contentExtension
- pattern="org.eclipse.ui.navigator.resources.filters.*" />
- </includes>
- </viewerContentBinding>
- <viewerActionBinding
- viewerId="org.eclipse.ui.examples.navigator.view">
- <includes>
- <actionExtension
- pattern="org.eclipse.ui.navigator.resources.*">
- </actionExtension>
- </includes>
- </viewerActionBinding>
- </extension>
- <extension
- point="org.eclipse.ui.navigator.navigatorContent">
- <commonFilter
- id="org.eclipse.ui.examples.navigator.filters.hideNonJavaProjects"
- name="Hide non-Java projects">
- <filterExpression>
- <not>
- <adapt
- type="org.eclipse.core.resources.IProject">
- <test
- property="org.eclipse.core.resources.projectNature"
- value="org.eclipse.jdt.core.javanature">
- </test>
- </adapt>
- </not>
- </filterExpression>
- </commonFilter>
- </extension-->
-
-
-
-
-
-
- <extension
- point="org.eclipse.ui.views">
- <view
- class="eu.etaxonomy.taxeditor.navigation.navigator.TaxonNavigator"
- icon="icons/edit_16x16.gif"
- id="eu.etaxonomy.taxeditor.navigation.navigator"
- name="%view.name.2"/>
- </extension>
+ </extension>
<extension
point="org.eclipse.ui.navigator.navigatorContent">
<navigatorContent
</contentExtension>
</includes>
</viewerContentBinding>
- <!--viewer
- popupMenuId="eu.etaxonomy.taxeditor.navigation.navigator#PopupMenu"
- viewerId="eu.etaxonomy.taxeditor.navigation.navigator">
- <options>
- <property
- name="org.eclipse.ui.navigator.hideAvailableExtensionsTab"
- value="true">
- </property>
- </options>
- </viewer-->
<dragAssistant
class="eu.etaxonomy.taxeditor.navigation.navigator.dnd.TaxonNavigatorDragAdapterAssistant"
viewerId="eu.etaxonomy.taxeditor.navigation.navigator">
import eu.etaxonomy.taxeditor.navigation.internal.TaxeditorNavigationPlugin;
import eu.etaxonomy.taxeditor.navigation.l10n.Messages;
import eu.etaxonomy.taxeditor.navigation.navigator.TaxonNavigator;
+import eu.etaxonomy.taxeditor.navigation.navigator.e4.TaxonNavigatorE4;
import eu.etaxonomy.taxeditor.newWizard.NewClassificationWizard;
import eu.etaxonomy.taxeditor.store.CdmStore;
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
return (TaxonNavigator) showView(TaxonNavigator.ID);
}
- /**
- * <p>getNavigator</p>
- *
- * @param restore a boolean.
- * @return a {@link eu.etaxonomy.taxeditor.navigation.navigator.TaxonNavigator} object.
- */
- public static TaxonNavigator getNavigator(boolean restore) {
- return (TaxonNavigator) getView(TaxonNavigator.ID, restore);
+ public static TaxonNavigatorE4 getNavigator(boolean restore) {
+ //FIXME E4 migrate or delete
+ return null;
+// return (TaxonNavigatorE4) getView(TaxonNavigator.ID, restore);
}
/**
import org.eclipse.ui.IMemento;
import eu.etaxonomy.taxeditor.model.ContextListenerAdapter;
-import eu.etaxonomy.taxeditor.navigation.navigator.TaxonNavigator;
-import eu.etaxonomy.taxeditor.preference.CdmPreferences;
+import eu.etaxonomy.taxeditor.navigation.navigator.e4.TaxonNavigatorE4;
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
/**
- * <p>NavigatorStateManager class.</p>
- *
* @author n.hoffmann
* @created Apr 1, 2010
* @version 1.0
*/
public class NavigatorStateManager extends ContextListenerAdapter {
-
+
/**
* {@inheritDoc}
*
*/
@Override
public void contextStart(IMemento memento, IProgressMonitor monitor) {
- TaxonNavigator navigator = NavigationUtil.getNavigator(true);
+ TaxonNavigatorE4 navigator = NavigationUtil.getNavigator(true);
if(navigator != null){
navigator.init();
if (PreferencesUtil.isStoreNavigatorState()){
} else {
navigator.restore(null, monitor);
}
-
+
}
}
-
- /* (non-Javadoc)
- * @see eu.etaxonomy.taxeditor.model.ContextListenerAdapter#contextRefresh(org.eclipse.core.runtime.IProgressMonitor)
- */
+
@Override
public void contextRefresh(IProgressMonitor monitor) {
- TaxonNavigator navigator = NavigationUtil.getNavigator(true);
+ TaxonNavigatorE4 navigator = NavigationUtil.getNavigator(true);
if(navigator != null){
navigator.refresh();
}
}
-
+
/**
* {@inheritDoc}
*
clearNavigator();
}
- /* (non-Javadoc)
- * @see eu.etaxonomy.taxeditor.model.ContextListenerAdapter#workbenchShutdown(org.eclipse.ui.IMemento, org.eclipse.core.runtime.IProgressMonitor)
- */
/** {@inheritDoc} */
@Override
public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
saveNavigatorState(memento, monitor);
-
+
}
-
+
/**
* @param memento
*/
private void saveNavigatorState(IMemento memento, IProgressMonitor monitor) {
- TaxonNavigator navigator = NavigationUtil.getNavigator(false);
+ TaxonNavigatorE4 navigator = NavigationUtil.getNavigator(false);
if(navigator != null){
- navigator.save(memento, monitor);
+ //FIXME E4 migrate or delete
+// navigator.save(memento, monitor);
}
}
-
+
/**
* Removes all content form the TaxonNavigator
*/
private void clearNavigator() {
- TaxonNavigator navigator = NavigationUtil.getNavigator(false);
+ TaxonNavigatorE4 navigator = NavigationUtil.getNavigator(false);
if(navigator != null){
navigator.clear();
}
--- /dev/null
+// $Id$
+/**
+* Copyright (C) 2017 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.taxeditor.navigation.navigator.e4;
+
+import java.util.List;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+
+import eu.etaxonomy.cdm.hibernate.HHH_9751_Util;
+import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
+import eu.etaxonomy.cdm.model.taxon.Classification;
+import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
+import eu.etaxonomy.cdm.model.taxon.TaxonNode;
+import eu.etaxonomy.taxeditor.navigation.navigator.Root;
+
+/**
+ * @author pplitzner
+ * @date 05.09.2017
+ *
+ */
+public class TaxonNavigatorContentProviderE4 implements ITreeContentProvider {
+
+ private static final Object[] NO_CHILDREN = new Object[0];
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object[] getElements(Object inputElement) {
+ return this.getChildren(inputElement);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ Object[] children = null;
+
+ if (parentElement instanceof Root) {
+ children = ((Root) parentElement).getParentBeans().toArray();
+ }else if(parentElement instanceof Classification){
+ children = ((Classification) parentElement).getChildNodes().toArray();
+ }
+ //FIXME E4 show synonym in navigator?
+// //synonym
+// if (parentElement instanceof Synonym) {
+// children = NO_CHILDREN;
+// } else if (parentElement instanceof TaxonNode) {
+// List<TaxonBase> list = new ArrayList<TaxonBase>();
+//
+// Taxon taxon = ((TaxonNode) parentElement).getTaxon();
+//
+// for (TaxonBase taxonBase : new IterableSynonymyList(taxon)) {
+// if (taxonBase instanceof Synonym) {
+// list.add(taxonBase);
+// }
+// }
+// children = list.toArray();
+// }
+ //taxon node
+ if(parentElement instanceof ITaxonTreeNode){
+ ITaxonTreeNode treeNode = (ITaxonTreeNode) HibernateProxyHelper.deproxy(parentElement);
+ List<TaxonNode> childrenSet = treeNode.getChildNodes();
+ HHH_9751_Util.removeAllNull(childrenSet);
+ children = childrenSet.toArray();
+ }
+ return children != null ? children : NO_CHILDREN;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getParent(Object element) {
+ if(element instanceof TaxonNode){
+ return ((TaxonNode) element).getParent();
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean hasChildren(Object element) {
+ if(element instanceof TaxonNode){
+ return ((TaxonNode) element).getCountChildren() > 0;
+ }
+ return this.getChildren(element).length > 0;
+ }
+
+}
--- /dev/null
+/**
+* Copyright (C) 2007 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+
+package eu.etaxonomy.taxeditor.navigation.navigator.e4;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.swt.widgets.Display;
+
+import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.cdm.model.name.TaxonName;
+import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
+import eu.etaxonomy.cdm.model.taxon.Taxon;
+import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeEvent;
+import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeEvent.EventType;
+import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
+import eu.etaxonomy.taxeditor.model.AbstractDataChangeBehaviour;
+import eu.etaxonomy.taxeditor.model.IDataChangeBehavior;
+import eu.etaxonomy.taxeditor.navigation.l10n.Messages;
+
+/**
+ * <p>TaxonNavigatorDataChangeBehavior class.</p>
+ *
+ * @author n.hoffmann
+ * @created 01.04.2009
+ * @version 1.0
+ */
+public class TaxonNavigatorDataChangeBehaviorE4 extends AbstractDataChangeBehaviour implements
+ IDataChangeBehavior {
+
+ private static final String UPDATING_TAXON_NAVIGATOR = Messages.TaxonNavigatorDataChangeBehavior_UPDATE_NAVIGATOR;
+
+ private final TaxonNavigatorE4 source;
+
+ private Set<CdmBase> staleObjects;
+
+ /**
+ * <p>Constructor for TaxonNavigatorDataChangeBehavior.</p>
+ *
+ * @param taxonNavigator a {@link eu.etaxonomy.taxeditor.navigation.navigator.TaxonNavigator} object.
+ */
+ public TaxonNavigatorDataChangeBehaviorE4(TaxonNavigatorE4 taxonNavigator) {
+ source = taxonNavigator;
+ }
+
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.taxeditor.store.model.IDataChangeBehavior#isRelevant(java.lang.Object, eu.etaxonomy.cdm.persistence.hibernate.CdmCrudEvent)
+ */
+ /**
+ * <p>isRelevant</p>
+ *
+ * @param events a {@link eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap} object.
+ * @return a boolean.
+ */
+ public boolean isRelevant(CdmDataChangeMap events) {
+
+ // TODO react only on insert/update/delete of taxon and synonym objects
+ // and on update of name objects
+ boolean relevant = false;
+ staleObjects = new HashSet<CdmBase>();
+
+ for(CdmDataChangeEvent event : events.getAllEvents()){
+ EventType eventType = event.getEventType();
+ CdmBase eventEntity = event.getEntity();
+
+ Set<CdmBase> affectedObjects = event.getAffectedObjects();
+ if(affectedObjects != null) {
+ for(CdmBase cb : affectedObjects) {
+ staleObjects.add(HibernateProxyHelper.deproxy(cb));
+ }
+ }
+
+ // all tree node changes are relevant
+ if((eventType == EventType.INSERT || eventType == EventType.DELETE || eventType == EventType.UPDATE)
+ && event.getEntity() instanceof ITaxonTreeNode){
+ return true;
+ }
+
+ if (eventType == EventType.DELETE){
+ return true;
+ }
+
+
+
+ if(eventType == EventType.UPDATE && event.getEntity() instanceof Taxon){
+ TaxonName name = null;
+ if(eventEntity instanceof Taxon){
+ name = ((Taxon) eventEntity).getName();
+ }else{
+ continue;
+ }
+
+ // Set<IEditorPart> openEditors = NavigationUtil.getOpenEditors();
+ /*for(IEditorPart editor : openEditors){
+
+ if(name.equals(((TaxonEditorInput) editor.getEditorInput()).getTaxon().getName())){
+ return true;
+ }
+ }*/
+ }
+
+// if(eventType == EventType.UPDATE){
+// relevant = true;
+// CdmBase entity = event.getEntity();
+// if((entity instanceof TaxonNameBase)
+// || (entity instanceof Taxon)
+// || (entity instanceof Synonym)){
+// staleObjects.add(entity);
+// }
+// }
+ }
+
+ return false;
+
+ // @deprecated
+ // react on everything except load
+// if(events.sizeByEventType(EventType.INSERT) > 0){
+// return true;
+// }else if(events.sizeByEventType(EventType.UPDATE) > 0){
+// return true;
+// }else if(events.sizeByEventType(EventType.DELETE) > 0){
+// return true;
+// }else{
+// return false;
+// }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void reactOnDataChange(CdmDataChangeMap events) {
+ if(isRelevant(events)){
+
+ final Display display = Display.getCurrent();
+ Job job = new Job(UPDATING_TAXON_NAVIGATOR) {
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ monitor.beginTask(UPDATING_TAXON_NAVIGATOR, 3);
+ monitor.worked(1);
+
+ // clear the session completely
+ monitor.subTask(Messages.TaxonNavigatorDataChangeBehavior_CLEAR_SESSION);
+ display.asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ source.getConversationHolder().clear();
+ }
+ });
+ // FIXME completely clearing the session is a brute force approach.
+ // It would be much more elegant to clear only those elements that have been changed.
+ // I could not get that to work but we should consider workin on this because we might
+ // run into serious performance issues, especially when it comes to large trees
+ //
+ // at least, we moved this to a job so it can run in a background thred
+ // seems to improve the situation but not sure if final solution
+ monitor.worked(1);
+
+ monitor.subTask(Messages.TaxonNavigatorDataChangeBehavior_REFRESH_VIEWER);
+
+ display.asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ if(staleObjects != null && staleObjects.size() > 0) {
+ source.refresh(staleObjects);
+ } else {
+ source.refresh();
+ }
+ }
+ });
+
+
+
+ monitor.worked(1);
+ monitor.done();
+ return Status.OK_STATUS;
+ }
+ };
+
+ job.setPriority(Job.SHORT);
+ job.schedule();
+
+ }
+ }
+}
--- /dev/null
+/**
+ * Copyright (C) 2007 EDIT
+ * European Distributed Institute of Taxonomy
+ * http://www.e-taxonomy.eu
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * See LICENSE.TXT at the top of this package for the full license terms.
+ */
+
+package eu.etaxonomy.taxeditor.navigation.navigator.e4;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.e4.ui.di.Focus;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IMemento;
+
+import eu.etaxonomy.cdm.api.application.CdmApplicationState;
+import eu.etaxonomy.cdm.api.application.CdmChangeEvent;
+import eu.etaxonomy.cdm.api.application.ICdmChangeListener;
+import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
+import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
+import eu.etaxonomy.cdm.api.service.IClassificationService;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.cdm.model.common.ITreeNode;
+import eu.etaxonomy.cdm.model.taxon.Classification;
+import eu.etaxonomy.cdm.model.taxon.TaxonNaturalComparator;
+import eu.etaxonomy.cdm.model.taxon.TaxonNode;
+import eu.etaxonomy.cdm.model.taxon.TaxonNodeByNameComparator;
+import eu.etaxonomy.cdm.model.taxon.TaxonNodeByRankAndNameComparator;
+import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
+import eu.etaxonomy.taxeditor.model.DataChangeBridge;
+import eu.etaxonomy.taxeditor.model.IDataChangeBehavior;
+import eu.etaxonomy.taxeditor.navigation.NavigationUtil;
+import eu.etaxonomy.taxeditor.navigation.l10n.Messages;
+import eu.etaxonomy.taxeditor.navigation.navigator.EmptyRoot;
+import eu.etaxonomy.taxeditor.navigation.navigator.Root;
+import eu.etaxonomy.taxeditor.navigation.navigator.TaxonNodeNavigatorComparator;
+import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
+import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
+import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
+import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+import eu.etaxonomy.taxeditor.store.LoginManager;
+import eu.etaxonomy.taxeditor.ui.element.LayoutConstants;
+
+/**
+ * Taxonomic tree implementation using Common Navigator Framework.
+ *
+ * @author p.ciardelli
+ * @author n.hoffmann
+ * @created 02.06.2009
+ * @version 1.0+-
+ */
+public class TaxonNavigatorE4 implements
+ IPostOperationEnabled, IConversationEnabled, Observer,
+ ICdmEntitySessionEnabled, ICdmChangeListener {
+
+ private static final String RESTORING_TAXON_NAVIGATOR = Messages.TaxonNavigator_RESTORE;
+
+ private static final String TREE_PATH = "treepath"; //$NON-NLS-1$
+
+ private static final String TREE_PATHS = "treepaths"; //$NON-NLS-1$
+
+ private ConversationHolder conversation;
+
+ private ICdmEntitySession cdmEntitySession;
+
+ private String partNameCache;
+
+ private IDataChangeBehavior dataChangeBehavior;
+
+ private Root root;
+
+ private TreeViewer viewer;
+
+ @Inject
+ public TaxonNavigatorE4() {
+ }
+
+ @PostConstruct
+ private void create(Composite parent){
+ FillLayout layout = new FillLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ layout.type = SWT.VERTICAL;
+
+ parent.setLayout(layout);
+ viewer = new TreeViewer(parent);
+ viewer.getControl().setLayoutData(LayoutConstants.FILL());
+
+ init();
+ }
+
+ /** {@inheritDoc} */
+ protected IAdaptable getInitialInput() {
+ Comparator<TaxonNode> comparator;
+ if (PreferencesUtil.getSortNodesNaturally()){
+ comparator = new TaxonNaturalComparator();
+ } else if (PreferencesUtil.getSortNodesStrictlyAlphabetically()){
+ comparator = new TaxonNodeByNameComparator();
+ }else {
+ comparator = new TaxonNodeByRankAndNameComparator();
+ }
+ TaxonNodeNavigatorComparator viewerComparator = new TaxonNodeNavigatorComparator(comparator);
+ viewer.setComparator(viewerComparator);
+ //FIXME E4 migrate linking with editor
+// setLinkingEnabled(true);
+
+ if (CdmStore.isActive()) {
+
+ // TODO when closing and reopening the taxon navigator
+ // we do not preserve state. Closing the view, in contrary to
+ // closing the whole application
+ // should be handled by the state manager too
+ root = new Root(conversation);
+
+ return root;
+ }
+ return new EmptyRoot();
+ }
+
+ public void init() {
+ if (CdmStore.isActive() && conversation == null) {
+ conversation = CdmStore.createConversation();
+ conversation.registerForDataStoreChanges(TaxonNavigatorE4.this);
+ }
+ if (CdmStore.isActive()) {
+ cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
+ CdmApplicationState.getCurrentDataChangeService().register(this);
+ }
+ CdmStore.getLoginManager().addObserver(this);
+
+ viewer.setContentProvider(new TaxonNavigatorContentProviderE4());
+ viewer.setLabelProvider(new TaxonNavigatorLabelProviderE4());
+ viewer.setInput(getInitialInput());
+ }
+
+ /**
+ * Refresh this navigators viewer
+ */
+ public void refresh() {
+ if(getConversationHolder() != null){
+ getConversationHolder().bind();
+ //FIXME : Need to make sure this is a stable fix (ticket 3822)
+ if(!getConversationHolder().isCompleted()){
+ getConversationHolder().commit();
+ }
+ }
+ if(!viewer.getTree().isDisposed()){
+ viewer.refresh();
+ }
+ }
+
+ /**
+ * Refresh this navigators viewer
+ */
+ public void refresh(Set<?> objects) {
+ for(Object obj : objects) {
+ viewer.refresh(obj);
+ }
+ }
+
+ /**
+ * Removes all content
+ */
+ public void clear() {
+ viewer.setInput(new EmptyRoot());
+ }
+
+ public void restore(IMemento memento, IProgressMonitor monitor) {
+ root = new Root(conversation);
+ if (memento == null) {
+ viewer.setInput(root);
+ return;
+ }
+ int mementoWork = 0;
+ Set<TreePath> treePaths = new HashSet<TreePath>();
+ IMemento[] treePathMementos = null;
+
+ IMemento treePathsMemento = memento.getChild(TREE_PATHS);
+
+ if (treePathsMemento != null) {
+ treePathMementos = treePathsMemento.getChildren(TREE_PATH);
+ mementoWork = treePathMementos.length;
+ }
+ // begin the monitor with steps for all tree paths and steps for
+ // creating
+ // conversation s.o., refreshing the tree and setting the paths
+ IProgressMonitor subProgressMonitor = NavigationUtil
+ .getSubProgressMonitor(monitor, 1);
+
+ subProgressMonitor.beginTask(RESTORING_TAXON_NAVIGATOR,
+ 1 + mementoWork + 5);
+ subProgressMonitor.subTask(RESTORING_TAXON_NAVIGATOR);
+ subProgressMonitor.worked(1);
+
+ conversation = CdmStore.createConversation();
+ subProgressMonitor.worked(1);
+ conversation.registerForDataStoreChanges(TaxonNavigatorE4.this);
+ subProgressMonitor.worked(1);
+ viewer.setInput(root);
+ subProgressMonitor.worked(1);
+ viewer.refresh();
+ subProgressMonitor.worked(1);
+
+ if (treePathMementos != null && treePathMementos.length > 0) {
+ for (IMemento treePathMemento : treePathMementos) {
+ TreePath treePath = createTreePathFromString(treePathMemento
+ .getID());
+ if (!subProgressMonitor.isCanceled() && treePath != null) {
+ treePaths.add(treePath);
+ subProgressMonitor.worked(1);
+ }
+ }
+ }
+ if (treePaths.size() > 0) {
+ TaxonNavigatorE4.this.viewer.setExpandedTreePaths(
+ treePaths.toArray(new TreePath[0]));
+ subProgressMonitor.worked(1);
+ }
+ subProgressMonitor.done();
+ }
+
+ private TreePath createTreePathFromString(String string) {
+
+ List<CdmBase> pathList = new ArrayList<CdmBase>();
+
+ if (string.length() == 0) {
+ return null;
+ }
+
+ for (String uuid : string.split(" ")) { //$NON-NLS-1$
+ CdmBase cdmBaseObject = CdmStore.getService(
+ IClassificationService.class).getTaxonNodeByUuid(
+ UUID.fromString(uuid));
+ if (cdmBaseObject == null) {
+ // is this a tree uuid?
+ cdmBaseObject = CdmStore.getService(
+ IClassificationService.class).load(
+ UUID.fromString(uuid));
+
+ if (cdmBaseObject == null) {
+ return null;
+ }
+ }
+ pathList.add(cdmBaseObject);
+ }
+ return new TreePath(pathList.toArray());
+ }
+
+ @Override
+ public ConversationHolder getConversationHolder() {
+ return conversation;
+ }
+
+ /** {@inheritDoc} */
+ @PreDestroy
+ public void dispose() {
+ dataChangeBehavior = null;
+ if (conversation != null) {
+ conversation.unregisterForDataStoreChanges(this);
+ }
+ if(cdmEntitySession != null) {
+ cdmEntitySession.dispose();
+ }
+ if(CdmApplicationState.getCurrentDataChangeService() != null) {
+ CdmApplicationState.getCurrentDataChangeService().unregister(this);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Focus
+ public void setFocus() {
+ if (getConversationHolder() != null) {
+ getConversationHolder().bind();
+ }
+ if(cdmEntitySession != null) {
+ cdmEntitySession.bind();
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean postOperation(CdmBase objectAffectedByOperation) {
+ // nothing to do here
+ return true;
+ }
+
+ //FIXME E4 migrate double click
+// /** {@inheritDoc} */
+// @Override
+// protected void handleDoubleClick(DoubleClickEvent event) {
+// ISelection selection = event.getSelection();
+// if(selection instanceof IStructuredSelection){
+// Object firstElement = ((IStructuredSelection) selection).getFirstElement();
+// if(firstElement instanceof ICdmBase){
+// NavigationUtil.openEditor((ICdmBase) firstElement);
+// }
+// }
+// // If the double click is passed up to the super-class it will
+// // expand/collapse trees.
+// // We do not want that
+// // super.handleDoubleClick(anEvent);
+// }
+
+ @Override
+ public boolean onComplete() {
+ return true;
+ }
+
+ @Override
+ public void update(Observable o, Object arg) {
+ if(o instanceof LoginManager){
+ refresh();
+ }
+ }
+ /** {@inheritDoc} */
+ @Override
+ public void update(CdmDataChangeMap changeEvents) {
+ if (dataChangeBehavior == null) {
+ dataChangeBehavior = new TaxonNavigatorDataChangeBehaviorE4(this);
+ }
+
+ DataChangeBridge.handleDataChange(changeEvents, dataChangeBehavior);
+ }
+
+ @Override
+ public ICdmEntitySession getCdmEntitySession() {
+ return cdmEntitySession;
+ }
+
+ @Override
+ public List<ITreeNode> getRootEntities() {
+ if(root != null) {
+ return root.getParentBeans();
+ }
+ return null;
+ }
+
+ @Override
+ public void onChange(CdmChangeEvent event) {
+ refresh();
+ for(CdmBase cb : event.getChangedObjects()) {
+ if(cb instanceof TaxonNode) {
+ TaxonNode tn = (TaxonNode)cb;
+ if(tn.getTaxon() == null) {
+ viewer.refresh(tn.getClassification());
+ } else {
+ viewer.refresh(cb);
+ }
+ } else if (cb instanceof Classification) {
+ viewer.refresh();
+ }
+ }
+ }
+
+ @Override
+ public Map<Object, List<String>> getPropertyPathsMap() {
+ Map<Object, List<String>> propertyPathsMap = new HashMap<Object, List<String>>();
+ List<String> taxonNodePropertyPaths = Arrays.asList(new String[] {
+ "taxon.name" //$NON-NLS-1$
+ });
+ propertyPathsMap.put("childNodes", taxonNodePropertyPaths); //$NON-NLS-1$
+ return propertyPathsMap;
+ }
+}
--- /dev/null
+// $Id$
+/**
+ * Copyright (C) 2017 EDIT
+ * European Distributed Institute of Taxonomy
+ * http://www.e-taxonomy.eu
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * See LICENSE.TXT at the top of this package for the full license terms.
+ */
+package eu.etaxonomy.taxeditor.navigation.navigator.e4;
+
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
+import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.jface.viewers.StyledString.Styler;
+import org.eclipse.swt.graphics.TextStyle;
+import org.eclipse.ui.navigator.IDescriptionProvider;
+import org.hibernate.LazyInitializationException;
+
+import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.cdm.model.common.IIdentifiableEntity;
+import eu.etaxonomy.cdm.model.taxon.Classification;
+import eu.etaxonomy.cdm.model.taxon.Taxon;
+import eu.etaxonomy.cdm.model.taxon.TaxonNode;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
+import eu.etaxonomy.taxeditor.navigation.l10n.Messages;
+import eu.etaxonomy.taxeditor.preference.Resources;
+import eu.etaxonomy.taxeditor.security.RequiredPermissions;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+import eu.etaxonomy.taxeditor.store.StoreUtil;
+
+/**
+ * @author pplitzner
+ * @date 05.09.2017
+ *
+ */
+public class TaxonNavigatorLabelProviderE4 extends ColumnLabelProvider
+implements IDescriptionProvider, IStyledLabelProvider {
+
+ private Styler notGrantedStyler = null;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getText(Object element) {
+ //classification
+ if(element instanceof Classification){
+ String text = ((Classification) element).getName().getText();
+ return text != null ? text : Messages.ClassificationLabelProvider_UNNAMED_TREE;
+ }
+ //FIXME E4 show synonym in navigator?
+ //synonym
+// else if (element instanceof Synonym && ((Synonym) element).getName()!=null) {
+// return "= " + ((Synonym) element).getName().getTitleCache(); //$NON-NLS-1$
+// }
+ //taxon node
+ else if (element instanceof TaxonNode){
+ TaxonNode taxonNode = (TaxonNode) HibernateProxyHelper.deproxy(element);
+
+ try{
+ Taxon taxon = HibernateProxyHelper.deproxy(taxonNode.getTaxon());
+ if(taxon == null){
+ String text = taxonNode.getClassification().getName().getText();
+ if(text==null){
+ text = taxonNode.getClassification().getTitleCache();
+ }
+ return text;
+ }else{
+ try{
+ return taxon.getName() != null ? ((IIdentifiableEntity) HibernateProxyHelper.deproxy(taxon.getName())).getTitleCache() : new String();
+ }catch(Exception e){
+ MessagingUtils.error(getClass(), e);
+ }
+ }
+ }catch (LazyInitializationException e){
+ MessagingUtils.error(getClass(), e);
+ }
+ }
+ return new String();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getDescription(Object anElement) {
+ //classification
+ if (anElement instanceof Classification) {
+ return "Taxonomic Tree: " + ((Classification) anElement).getTitleCache(); //$NON-NLS-1$
+ }
+ //FIXME E4 show synonym in navigator?
+ //synonym
+// else if (anElement instanceof Synonym) {
+// Synonym data = (Synonym) anElement;
+// return "Synonym: " + data.getTitleCache(); //$NON-NLS-1$
+// }
+ //taxon node
+ else if (anElement instanceof TaxonNode) {
+ Taxon data = ((TaxonNode) anElement).getTaxon();
+ String text = (data != null ? Messages.TaxonNodeLabelProvider_TAXON + data.getTitleCache() : Messages.TaxonNodeLabelProvider_CLASSIFICATION + ((TaxonNode)anElement).getClassification().getTitleCache());
+ return text;
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public StyledString getStyledText(Object element) {
+ //classification
+ if(element instanceof Classification){
+ return new StyledString(getText(element), StyledString.DECORATIONS_STYLER);
+ }
+ //FIXME E4 show synonym in navigator?
+ //synonym
+// else if(element instanceof Synonym){
+// return new StyledString(getText(element), StyledString.QUALIFIER_STYLER);
+// }
+ //taxon node
+ else if(element instanceof TaxonNode){
+ // determine style base on user grants
+ Styler styler = null;
+ if(!CdmStore.currentAuthentiationHasPermission((CdmBase) element, RequiredPermissions.TAXONNODE_EDIT)){
+ styler = getNotGrantedStyler();
+ }
+ return new StyledString(getText(element), styler);
+ }
+ return new StyledString(getText(element));
+ }
+
+ private Styler getNotGrantedStyler() {
+ if (notGrantedStyler == null) {
+ notGrantedStyler = new Styler() {
+ @Override
+ public void applyStyles(TextStyle textStyle) {
+ textStyle.underline = false;
+ textStyle.foreground = StoreUtil.getColor(Resources.COLOR_TEXT_DISABLED);
+ }
+ };
+ }
+ return notGrantedStyler;
+ }
+}