2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
9 package eu
.etaxonomy
.taxeditor
.editor
.name
.e4
;
11 import java
.util
.ArrayList
;
12 import java
.util
.HashSet
;
13 import java
.util
.List
;
15 import java
.util
.UUID
;
17 import javax
.annotation
.PostConstruct
;
18 import javax
.annotation
.PreDestroy
;
19 import javax
.inject
.Inject
;
21 import org
.apache
.commons
.lang3
.StringUtils
;
22 import org
.eclipse
.core
.commands
.operations
.IUndoContext
;
23 import org
.eclipse
.core
.commands
.operations
.UndoContext
;
24 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
25 import org
.eclipse
.core
.runtime
.OperationCanceledException
;
26 import org
.eclipse
.e4
.core
.contexts
.IEclipseContext
;
27 import org
.eclipse
.e4
.core
.di
.annotations
.Optional
;
28 import org
.eclipse
.e4
.core
.services
.events
.IEventBroker
;
29 import org
.eclipse
.e4
.ui
.di
.Focus
;
30 import org
.eclipse
.e4
.ui
.di
.Persist
;
31 import org
.eclipse
.e4
.ui
.di
.UIEventTopic
;
32 import org
.eclipse
.e4
.ui
.di
.UISynchronize
;
33 import org
.eclipse
.e4
.ui
.model
.application
.MApplication
;
34 import org
.eclipse
.e4
.ui
.model
.application
.ui
.MDirtyable
;
35 import org
.eclipse
.e4
.ui
.model
.application
.ui
.basic
.MPart
;
36 import org
.eclipse
.e4
.ui
.services
.EMenuService
;
37 import org
.eclipse
.e4
.ui
.workbench
.modeling
.EModelService
;
38 import org
.eclipse
.e4
.ui
.workbench
.modeling
.EPartService
;
39 import org
.eclipse
.e4
.ui
.workbench
.modeling
.ESelectionService
;
40 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
41 import org
.eclipse
.jface
.viewers
.ISelection
;
42 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
43 import org
.eclipse
.swt
.dnd
.DND
;
44 import org
.eclipse
.swt
.dnd
.DropTarget
;
45 import org
.eclipse
.swt
.dnd
.Transfer
;
46 import org
.eclipse
.swt
.graphics
.Color
;
47 import org
.eclipse
.swt
.widgets
.Composite
;
48 import org
.eclipse
.ui
.ISelectionListener
;
49 import org
.eclipse
.ui
.IWorkbenchPart
;
50 import org
.eclipse
.ui
.IWorkbenchPartReference
;
51 import org
.eclipse
.ui
.forms
.ManagedForm
;
52 import org
.eclipse
.ui
.forms
.widgets
.FormToolkit
;
53 import org
.eclipse
.ui
.forms
.widgets
.ScrolledForm
;
54 import org
.eclipse
.ui
.forms
.widgets
.TableWrapLayout
;
56 import eu
.etaxonomy
.cdm
.api
.service
.DeleteResult
;
57 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
58 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
59 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroup
;
60 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
61 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivedUnit
;
62 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
63 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
64 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
65 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationship
;
66 import eu
.etaxonomy
.cdm
.persistence
.dto
.TaxonNodeDto
;
67 import eu
.etaxonomy
.taxeditor
.editor
.CdmDataTransfer
;
68 import eu
.etaxonomy
.taxeditor
.editor
.EditorUtil
;
69 import eu
.etaxonomy
.taxeditor
.editor
.ISecuredEditor
;
70 import eu
.etaxonomy
.taxeditor
.editor
.ITaxonEditor
;
71 import eu
.etaxonomy
.taxeditor
.editor
.e4
.TaxonEditorInput
;
72 import eu
.etaxonomy
.taxeditor
.editor
.internal
.TaxeditorEditorPlugin
;
73 import eu
.etaxonomy
.taxeditor
.editor
.l10n
.Messages
;
74 import eu
.etaxonomy
.taxeditor
.editor
.name
.e4
.container
.AbstractGroup
;
75 import eu
.etaxonomy
.taxeditor
.editor
.name
.e4
.container
.AbstractGroupedContainer
;
76 import eu
.etaxonomy
.taxeditor
.editor
.name
.e4
.container
.AcceptedGroup
;
77 import eu
.etaxonomy
.taxeditor
.editor
.name
.e4
.container
.AcceptedNameContainerE4
;
78 import eu
.etaxonomy
.taxeditor
.editor
.name
.e4
.container
.ConceptContainer
;
79 import eu
.etaxonomy
.taxeditor
.editor
.name
.e4
.container
.ContainerFactory
;
80 import eu
.etaxonomy
.taxeditor
.editor
.name
.e4
.container
.HomotypicalSynonymGroup
;
81 import eu
.etaxonomy
.taxeditor
.editor
.name
.e4
.container
.MisappliedGroup
;
82 import eu
.etaxonomy
.taxeditor
.editor
.name
.e4
.dnd
.NameEditorDropTargetListener
;
83 import eu
.etaxonomy
.taxeditor
.event
.EventUtility
;
84 import eu
.etaxonomy
.taxeditor
.event
.WorkbenchEventConstants
;
85 import eu
.etaxonomy
.taxeditor
.model
.AbstractUtility
;
86 import eu
.etaxonomy
.taxeditor
.model
.IDirtyMarkable
;
87 import eu
.etaxonomy
.taxeditor
.model
.IPartChangeListener
;
88 import eu
.etaxonomy
.taxeditor
.model
.IPartContentHasDetails
;
89 import eu
.etaxonomy
.taxeditor
.model
.IPartContentHasFactualData
;
90 import eu
.etaxonomy
.taxeditor
.model
.IPartContentHasMedia
;
91 import eu
.etaxonomy
.taxeditor
.model
.IPartContentHasSupplementalData
;
92 import eu
.etaxonomy
.taxeditor
.model
.MessagingUtils
;
93 import eu
.etaxonomy
.taxeditor
.model
.TaxeditorPartService
;
94 import eu
.etaxonomy
.taxeditor
.operation
.AbstractPostOperation
;
95 import eu
.etaxonomy
.taxeditor
.preference
.Resources
;
96 import eu
.etaxonomy
.taxeditor
.security
.RequiredPermissions
;
97 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
98 import eu
.etaxonomy
.taxeditor
.workbench
.part
.IE4SavablePart
;
104 public class TaxonEditor
105 implements IDirtyMarkable
, IPartContentHasDetails
,
106 IPartContentHasSupplementalData
, IPartContentHasMedia
, IPartContentHasFactualData
, IPartChangeListener
,
107 ISelectionListener
, ISecuredEditor
, IE4SavablePart
, ITaxonEditor
, IDropTargetable
{
111 private ManagedForm managedForm
;
112 private ScrolledForm scrolledForm
;
113 private Composite parent
;
115 private EModelService modelService
;
118 private EPartService partService
;
119 private TaxonBase
<?
> selection
;
121 private AcceptedGroup acceptedGroup
;
122 private List
<HomotypicalSynonymGroup
> heterotypicSynonymGroups
= new ArrayList
<>();
123 private MisappliedGroup misappliedGroup
;
125 private DropTarget target
;
128 private UISynchronize sync
;
130 private TaxonBase
<?
> objectAffectedByLastOperation
;
133 private EMenuService menuService
;
136 private ESelectionService selService
;
139 private IEclipseContext context
;
142 private MDirtyable dirty
;
145 private MApplication application
;
147 private MPart thisPart
;
149 private TaxonEditorInput input
;
151 private UndoContext undoContext
;
154 private IEventBroker eventBroker
;
157 public TaxonEditor() {
158 undoContext
= new UndoContext();
162 public void createPartControl(Composite parent
, MPart thisPart
) {
163 this.thisPart
= thisPart
;
165 createManagedForm(parent
);
167 TaxeditorPartService
.getInstance().addListener(TaxeditorPartService
.PART_ACTIVATED
, this);
170 protected void createManagedForm(Composite composite
) {
172 managedForm
= new ManagedForm(composite
) {
175 public void dirtyStateChanged() {
176 dirty
.setDirty(true);
180 public boolean setInput(Object input
) {
181 if (input
instanceof AbstractGroupedContainer
) {
182 TaxonBase
<?
> newSelection
= ((AbstractGroupedContainer
<?
>) input
).getData();
183 if (selection
!= newSelection
|| TaxonEditor
.this.isDirty()) {
184 selection
= newSelection
;
185 selService
.setSelection(new StructuredSelection(selection
));
188 } else if (input
== null) {
190 selService
.setSelection(new StructuredSelection());
193 return super.setInput(input
);
197 scrolledForm
= managedForm
.getForm();
198 parent
= scrolledForm
.getBody();
200 parent
.setData(taxon
);
202 TableWrapLayout layout
= new TableWrapLayout();
203 layout
.leftMargin
= 0;
204 layout
.rightMargin
= 0;
205 layout
.topMargin
= 0;
206 layout
.bottomMargin
= 0;
208 layout
.verticalSpacing
= 0;
209 layout
.horizontalSpacing
= 0;
211 parent
.setLayout(layout
);
212 parent
.setBackground(AbstractUtility
.getColor(Resources
.COLOR_COMPOSITE_BACKGROUND
));
215 public void createOrUpdateNameComposites(boolean accepted
, boolean heterotypicGroups
, boolean misappliedNames
) {
218 ContainerFactory
.createOrUpdateAcceptedTaxonsHomotypicGroup(this);
220 if (heterotypicGroups
) {
221 ContainerFactory
.createOrUpdateHeterotypicSynonymyGroups(this);
223 if (misappliedNames
) {
224 ContainerFactory
.createOrUpdateMisapplicationsGroup(this);
226 ContainerFactory
.setMenuToAllContainers(this);
230 managedForm
.refresh();
231 managedForm
.reflow(true);
235 public Taxon
getTaxon() {
236 return HibernateProxyHelper
.deproxy(taxon
);
240 public void addOperation(AbstractPostOperation operation
) {
241 input
.addOperation(operation
);
244 public void setDirty() {
245 managedForm
.dirtyStateChanged();
249 public void setFocus() {
250 // make sure to bind again if maybe in another view the conversation was
253 eventBroker
.post(WorkbenchEventConstants
.CURRENT_ACTIVE_EDITOR
, this);
255 if (EditorUtil
.isFactsVisible()){
256 EditorUtil
.showFacts(modelService
, partService
);
257 EditorUtil
.setFactsVisible(false);
259 if (EditorUtil
.isMediaVisible()){
260 EditorUtil
.showMedia(modelService
, partService
);
261 EditorUtil
.setMediaVisible(false);
264 if (getSelectedContainer() == null) {
265 throw new IllegalStateException(Messages
.TaxonNameEditor_THERE_SHOULD_ALWAYS_BE
);
268 if (input
.getCdmEntitySession() != null && !input
.getCdmEntitySession().isActive()) {
275 boolean doEnable
= permissionsSatisfied();
276 managedForm
.getForm().setEnabled(doEnable
);
280 public boolean permissionsSatisfied() {
281 boolean doEnable
= false;
283 TaxonNode taxonNode
= input
.getTaxonNode();
284 doEnable
= CdmStore
.currentAuthentiationHasPermission(taxonNode
,
285 RequiredPermissions
.TAXON_EDIT
);
291 * Redraws this editor return true on success
295 public boolean redraw() {
296 return redraw(true, true, true, true);
302 * Redraws the editor controls
304 public boolean redraw(boolean focus
, boolean accepted
, boolean heterotypic
, boolean misappliedNames
) {
306 createOrUpdateNameComposites(accepted
, heterotypic
, misappliedNames
);
316 public boolean postOperation(Object objectAffectedByOperation
) {
317 if (objectAffectedByOperation
instanceof TaxonBase
) {
318 objectAffectedByLastOperation
= (TaxonBase
<?
>) objectAffectedByOperation
;
320 redraw(true, true, true, true);
321 changed(objectAffectedByOperation
);
323 getContainer(objectAffectedByLastOperation
).setFocus();
327 public ManagedForm
getManagedForm() {
336 * @return true if there are empty names
338 public boolean checkForEmptyNames() {
339 for (AbstractGroupedContainer
<?
> container
: getGroupedContainers()) {
340 if (container
!= null
341 && (container
.getName() == null || StringUtils
.isEmpty(container
.getName().getTitleCache()))) {
348 public Set
<AbstractGroupedContainer
> getEmptyContainers() {
349 Set
<AbstractGroupedContainer
> containersWithEmptyNames
= new HashSet
<>();
351 for (AbstractGroupedContainer
<?
> container
: getGroupedContainers()) {
352 if (container
.getName() == null || StringUtils
.isEmpty(container
.getName().getTitleCache())) {
353 containersWithEmptyNames
.add(container
);
357 return containersWithEmptyNames
;
362 public void save(IProgressMonitor monitor
) {
364 monitor
.beginTask(Messages
.TaxonNameEditor_SAVING_NAMES
, getGroupedContainers().size());
366 //this.getDirtyNames().forEach(container -> container.refresh());
367 // check for empty names
368 if (checkForEmptyNames()) {
369 MessageDialog
.openWarning(AbstractUtility
.getShell(), Messages
.MultiPageTaxonEditor_NO_NAME_SPECIFIED
,
370 Messages
.MultiPageTaxonEditor_NO_NAME_SPECIFIED_MESSAGE
);
373 for (AbstractGroupedContainer
<?
> container
: getGroupedContainers()) {
375 monitor
.subTask(Messages
.TaxonNameEditor_SAVING_COMPOSITES
+ container
.getTaxonBase().getTitleCache());
376 container
.persistName();
377 // because of missing cascading the concepts need to be saved
379 if (container
instanceof ConceptContainer
) {
380 input
.addToSaveConcept((Taxon
) container
.getData());
382 // In case the progress monitor was canceled throw an exception.
383 if (monitor
.isCanceled()) {
384 throw new OperationCanceledException();
387 // Otherwise declare this step as done.
393 dirty
.setDirty(false);
395 EventUtility
.postEvent(WorkbenchEventConstants
.REFRESH_NAVIGATOR
, new TaxonNodeDto(input
.getTaxonNode().getParent()));
396 EventUtility
.postEvent(WorkbenchEventConstants
.SAVE_TAXON
, true);
397 // Stop the progress monitor.
401 public void init(TaxonEditorInput input
) {
402 if (this.input
!= null) {
403 this.input
.dispose();
404 // this.acceptedGroup = null;
405 // this.heterotypicSynonymGroups.clear();
406 // this.misappliedGroup = null;
408 eventBroker
.post(WorkbenchEventConstants
.CURRENT_ACTIVE_EDITOR
, this);
409 if (!(input
!= null)) {
410 MessagingUtils
.error(this.getClass(), new Exception(Messages
.TaxonNameEditor_INVALID_INPUT
));
414 if (input
.getAdapter(Taxon
.class) != null) {
415 taxon
= CdmBase
.deproxy(input
.getAdapter(Taxon
.class), Taxon
.class);
417 MessagingUtils
.error(this.getClass(), new Exception(Messages
.TaxonNameEditor_INVALID_INPUT_TAXON_NULL
));
422 createOrUpdateNameComposites(true, true, true);
428 // set initial selection
429 TaxonBase
<?
> initiallySelectedTaxonBase
= input
.getInitiallySelectedTaxonBase();
430 if (initiallySelectedTaxonBase
!= null) {
431 selService
.setSelection(new StructuredSelection(initiallySelectedTaxonBase
));
432 getContainer(initiallySelectedTaxonBase
).setSelected();
436 private void createDragSupport() {
437 // Listen for names being dragged outside of existing homotypic groups -
438 // user wants to create a new group
439 Transfer
[] types
= new Transfer
[] { CdmDataTransfer
.getInstance() };
440 int operations
= DND
.DROP_MOVE
;
441 if (target
== null) {
442 target
= new DropTarget(parent
, operations
);
443 target
.setTransfer(types
);
444 target
.addDropListener(new NameEditorDropTargetListener(this));
448 public AcceptedNameContainerE4
getAcceptedNameContainer() {
449 return getAcceptedGroup().getAcceptedNameContainer();
452 public HomotypicalSynonymGroup
getHomotypicalGroupContainer(HomotypicalGroup homotypicalGroup
) {
453 for (HomotypicalSynonymGroup group
: getHeterotypicSynonymGroups()) {
454 if (group
.getGroup().equals(homotypicalGroup
)) {
467 * @return a Set containing all composites that have been edited
469 public Set
<AbstractGroupedContainer
> getDirtyNames() {
470 Set
<AbstractGroupedContainer
> dirtyNames
= new HashSet
<>();
472 for (AbstractGroupedContainer
<?
> composite
: getGroupedContainers()) {
473 if (composite
.isDirty()) {
474 dirtyNames
.add(composite
);
481 public List
<AbstractGroupedContainer
> getGroupedContainers() {
482 List
<AbstractGroupedContainer
> groupedComposites
= new ArrayList
<>();
484 for (AbstractGroup group
: getAllGroups()) {
486 groupedComposites
.addAll(group
.getGroupedContainers());
490 return groupedComposites
;
493 public List
<AbstractGroup
> getAllGroups() {
494 List
<AbstractGroup
> allGroups
= new ArrayList
<>();
496 allGroups
.add(getAcceptedGroup());
498 heterotypicSynonymGroups
= getHeterotypicSynonymGroups();
500 if (heterotypicSynonymGroups
!= null) {
501 allGroups
.addAll(heterotypicSynonymGroups
);
504 if (misappliedGroup
!= null) {
505 allGroups
.add(misappliedGroup
);
512 public IEclipseContext
getContext() {
517 public boolean isDirty() {
518 return dirty
.isDirty();
522 public void dispose() {
526 dirty
.setDirty(false);
527 eventBroker
.post(WorkbenchEventConstants
.CURRENT_ACTIVE_EDITOR
, null);
531 public void selectionChanged(IWorkbenchPart part
, ISelection selection
) {
535 public AbstractGroupedContainer
getSelectedContainer() {
536 if (selection
== null && input
!= null){
537 selection
= this.input
.getTaxon();
539 return (selection
!= null) ?
getContainer(selection
) : getAcceptedNameContainer();
543 public void dragEntered() {
545 getControl().setBackground(AbstractUtility
.getColor(Resources
.COLOR_DRAG_ENTER
));
549 public void dragLeft() {
550 getControl().setBackground(AbstractUtility
.getColor(Resources
.COLOR_COMPOSITE_BACKGROUND
));
553 public void setMisapplicationsGroup(MisappliedGroup misappliedGroup
) {
554 this.misappliedGroup
= misappliedGroup
;
557 public FormToolkit
getToolkit() {
558 return managedForm
.getToolkit();
561 public List
<HomotypicalSynonymGroup
> getHeterotypicSynonymGroups() {
562 return heterotypicSynonymGroups
;
565 public void addHeterotypicSynonymGroup(HomotypicalSynonymGroup group
) {
566 heterotypicSynonymGroups
.add(group
);
569 public AcceptedGroup
getAcceptedGroup() {
570 return acceptedGroup
;
573 public void setAcceptedGroup(AcceptedGroup acceptedGroup
) {
574 this.acceptedGroup
= acceptedGroup
;
577 public MisappliedGroup
getMisappliedGroup() {
578 return misappliedGroup
;
581 public boolean isActive() {
582 return this.equals(AbstractUtility
.getActivePart());
586 public boolean onComplete() {
587 getContainer(objectAffectedByLastOperation
).setSelected();
592 public void partChanged(Integer eventType
, IWorkbenchPartReference partRef
) {
593 if (!partRef
.getPart(false).equals(this)) {
599 public void removeGroup(AbstractGroup group
) {
603 // if (heterotypicSynonymGroups != null) {
604 heterotypicSynonymGroups
.remove(group
);
609 public AbstractGroupedContainer
getContainer(TaxonBase taxonBase
) {
610 @SuppressWarnings("rawtypes")
611 List
<AbstractGroupedContainer
> groupedContainers
= getGroupedContainers();
612 for (AbstractGroupedContainer
<?
> container
: groupedContainers
) {
613 if (container
.getData().equals(taxonBase
) && container
.getNameViewer().getTextWidget() != null) {
617 return getAcceptedNameContainer();
620 public void setOnError() {
621 Color disabledColor
= AbstractUtility
.getColor(Resources
.COLOR_EDITOR_ERROR
);
622 setEnabled(false, disabledColor
);
625 public void setDisabled() {
626 Color disabledColor
= AbstractUtility
.getColor(Resources
.COLOR_TEXT_DISABLED_BACKGROUND
);
627 setEnabled(false, disabledColor
);
630 protected void setEnabled(boolean enabled
, Color background
) {
632 for (AbstractGroupedContainer
<?
> groupedContainer
: getGroupedContainers()) {
633 groupedContainer
.setEnabled(enabled
);
636 // send an empty selection to the current provider - TODO only on error
639 getManagedForm().setInput(null);
641 for (AbstractGroupedContainer
<?
> groupedContainer
: getGroupedContainers()) {
642 groupedContainer
.setBackground(background
);
645 getControl().setBackground(background
);
649 public void changed(Object element
) {
651 // if the attribute is null then do not set the dirty flag -> hotfix for
652 // the problem that for tasks done in service methods the changes are
653 // saved automatically
654 if (element
!= null) {
655 dirty
.setDirty(true);
656 // refresh part title
657 // TODO: refresh taxon node in taxon navigator
661 if (element
instanceof TaxonBase
) {
662 AbstractGroupedContainer
<?
> container
= getContainer((TaxonBase
<?
>) element
);
663 if (container
!= null) {
665 container
.setDirty(false);
669 if (element
instanceof TaxonRelationship
) {
670 AbstractGroupedContainer container
= getContainer(((TaxonRelationship
) element
).getFromTaxon());
671 if (container
!= null) {
673 container
.setDirty(false);
678 public void setPartName() {
679 // FIXME: temporary fix for #6437 to avoid outdated title caches
680 thisPart
.setLabel(this.taxon
.getName().generateFullTitle());
681 // thisPart.setLabel(this.taxon.getName().getFullTitleCache());
685 public void forceDirty() {
689 public IUndoContext
getUndoContext() {
694 public Composite
getControl() {
695 return managedForm
.getForm().getBody();
698 public EMenuService
getMenuService() {
702 public ESelectionService
getSelectionService() {
707 public boolean canAttachMedia() {
711 public TaxonEditorInput
getEditorInput() {
716 public TaxonEditor
getEditor() {
722 private void updateView(@UIEventTopic(WorkbenchEventConstants
.REFRESH_NAME_EDITOR
) CdmBase cdmbase
) {
724 if(this.taxon
!= null && (this.taxon
.equals(cdmbase
)
725 || (this.taxon
.getName() != null && this.taxon
.getName().equals(cdmbase
)))) {
726 this.redraw(false, true, true, true);
728 if (cdmbase
instanceof TaxonBase
) {
729 this.selection
= (TaxonBase
<?
>) cdmbase
;
736 private void updateView(@UIEventTopic(WorkbenchEventConstants
.REFRESH_NAME_EDITOR
) List
<CdmBase
> cdmBases
) {
738 if (cdmBases
== null){
741 for (CdmBase cdmBase
: cdmBases
){
742 if (cdmBase
instanceof Taxon
|| cdmBase
instanceof TaxonName
){
743 if (this.taxon
!= null && (this.taxon
.equals(cdmBase
)
744 || (this.taxon
.getName() != null && this.taxon
.getName().equals(cdmBase
)))) {
753 private void updateView(@UIEventTopic(WorkbenchEventConstants
.REFRESH_NAME_EDITOR
) UUID cdmbaseUuid
) {
754 if (this.taxon
.getUuid().equals(cdmbaseUuid
)) {
755 TaxonEditorInput input
= TaxonEditorInput
.NewInstanceFromTaxonBase(cdmbaseUuid
);
762 private void updatefromDelete(@UIEventTopic(WorkbenchEventConstants
.DELETE_DERIVATIVE
) DeleteResult result
) {
763 if (taxon
.getName() == null) {
766 Set
<DerivedUnit
> typeDesignationSpecimens
= new HashSet
<>();
767 this.taxon
.getName().getSpecimenTypeDesignations()
768 .forEach(designation
-> typeDesignationSpecimens
.add(designation
.getTypeSpecimen()));
769 // check if any deleted object was a type specimen
770 if (result
.getUpdatedObjects().stream()
771 // filter only DerivedUnits
772 .filter(cdmBase
-> cdmBase
.isInstanceOf(DerivedUnit
.class))
773 // deproxy from CdmBase to DerivedUnit
774 .map(unit
-> HibernateProxyHelper
.deproxy(unit
, DerivedUnit
.class))
775 // check for match in type designations
776 .anyMatch(unit
-> typeDesignationSpecimens
.contains(unit
))) {
777 EditorUtil
.updateEditor(this.input
.getTaxonNode(), this);
782 public void update() {
783 EPartService partService
= TaxeditorEditorPlugin
.getDefault().getWorkbench().getActiveWorkbenchWindow().getService(EPartService
.class);
784 EModelService modelService
= TaxeditorEditorPlugin
.getDefault().getWorkbench().getActiveWorkbenchWindow().getService(EModelService
.class);
785 EditorUtil
.openTaxonBaseE4(this.getTaxon().getUuid(), modelService
, partService
, application
);
789 public TaxonNode
getTaxonNode() {
790 return input
.getTaxonNode();