ref #9541 further fixes for referencing objects and related issues
authorAndreas Müller <a.mueller@bgbm.org>
Fri, 2 Apr 2021 19:52:55 +0000 (21:52 +0200)
committerAndreas Müller <a.mueller@bgbm.org>
Fri, 2 Apr 2021 19:52:55 +0000 (21:52 +0200)
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/referencingobjects/e4/ReferencingObjectsViewE4.java
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/EditorUtil.java
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/view/checklist/e4/DistributionEditorPart.java
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/view/checklist/e4/handler/OpenChecklistEditorHandlerE4.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/editor/IReferencingObjectsView.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/handler/defaultHandler/OpenReferencingObjectsViewHandler.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/view/e4/AbstractCdmEditorPartE4.java

index 4347b6e0c56ced45e47d686f684c88939f2c54d2..2611897b4bdfd4754a4dd6ab238b11d9cd6454ff 100644 (file)
@@ -23,6 +23,7 @@ import java.util.UUID;
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
@@ -47,7 +48,6 @@ import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Table;
 
-import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
 import eu.etaxonomy.cdm.api.service.IAgentService;
 import eu.etaxonomy.cdm.api.service.IDescriptionService;
 import eu.etaxonomy.cdm.api.service.IEventBaseService;
@@ -83,8 +83,15 @@ import eu.etaxonomy.cdm.model.taxon.TaxonBase;
 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
 import eu.etaxonomy.cdm.model.term.DefinedTermBase;
 import eu.etaxonomy.cdm.model.term.TermBase;
+import eu.etaxonomy.cdm.model.term.TermNode;
+import eu.etaxonomy.cdm.model.term.TermTree;
+import eu.etaxonomy.cdm.model.term.TermVocabulary;
+import eu.etaxonomy.cdm.persistence.dto.AbstractTermDto;
 import eu.etaxonomy.cdm.persistence.dto.ReferencingObjectDto;
 import eu.etaxonomy.cdm.persistence.dto.TermDto;
+import eu.etaxonomy.cdm.persistence.dto.TermNodeDto;
+import eu.etaxonomy.cdm.persistence.dto.TermTreeDto;
+import eu.etaxonomy.cdm.persistence.dto.TermVocabularyDto;
 import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
 import eu.etaxonomy.taxeditor.bulkeditor.referencingobjects.ReferencingObjectsContentProvider;
 import eu.etaxonomy.taxeditor.bulkeditor.referencingobjects.ReferencingObjectsLabelProvider;
@@ -95,7 +102,13 @@ import eu.etaxonomy.taxeditor.store.CdmStore;
 import eu.etaxonomy.taxeditor.view.e4.AbstractCdmEditorPartE4;
 
 /**
+ * This view loads and presents referencing objects information asynchronously.
+ *
+ * Most of the task is done in UpdateRefObjectsJob.run()
+ *
  * @author pplitzner
+ * @author k.luther
+ * @author a.mueller
  * @since Aug 16, 2017
  */
 public class ReferencingObjectsViewE4 extends AbstractCdmEditorPartE4 implements IReferencingObjectsView{
@@ -105,25 +118,17 @@ public class ReferencingObjectsViewE4 extends AbstractCdmEditorPartE4 implements
     public static final String IS_LOADING = "Loading ...";
 //    public static final String CANCELED = "Canceled ...";
 
+    private static final List<ReferencingObjectDto> EMPTY_LIST = Arrays.asList();  //immutable empty list
+    private static final RefObjectDtoComparator COMPARATOR = new RefObjectDtoComparator();
+
     private Label contentDescription;
-    private String description;
 
-//     private String referencedObjectTitleCache;
-       private ConversationHolder conversation;
-       private UUID actualUuid;
-       private List<ReferencingObjectDto> referencingObjects = null;
-       private Set<ReferencingObjectDto> referencingObjectsSet = null;
-       private IProgressMonitor actualMonitor = null;
-       private Job currentJob = null;
+       private volatile UUID actualUuid;  //volatile as it used used between threads but only written in the synchronized method
+       private Job currentJob = null;  //this variable should only be accessed in synchronized updateToNewItem
 
     @PostConstruct
     public void create(Composite parent, EMenuService menuService) {
-        if (CdmStore.isActive()){
-            if(conversation == null){
-                conversation = CdmStore.createConversation();
-            }
-        }
-        else{
+        if (!CdmStore.isActive()){
             return;
         }
         parent.setLayout(new GridLayout());
@@ -170,7 +175,6 @@ public class ReferencingObjectsViewE4 extends AbstractCdmEditorPartE4 implements
 
         //create context menu
         menuService.registerContextMenu(viewer.getControl(), "eu.etaxonomy.taxeditor.bulkeditor.popupmenu.referencingobjectsview");
-
        }
 
        /**
@@ -199,144 +203,151 @@ public class ReferencingObjectsViewE4 extends AbstractCdmEditorPartE4 implements
                viewer.setColumnProperties(titles);
        }
 
-       @Override
-    public void updateReferencingObjects(final UUID entityUUID, final Class objectClass) {
-           if (actualUuid == entityUUID){
-               return ;
-           }
 
-           if(actualMonitor!=null && !actualMonitor.isCanceled()){
-               while(!actualMonitor.isCanceled()){
-                   actualMonitor.setCanceled(true);
-               }
-           }
+    private class ItemDto {
+        String typeName;
+        String itemLabel;
+        UUID itemUuid;
+        Integer itemId;
+        Class<? extends CdmBase> itemClass;
 
-               currentJob = new Job("Update Referencing Objects for " + entityUUID) {
-
-                       @Override
-                       protected IStatus run(final IProgressMonitor monitor) {
-                               monitor.beginTask("Calculating referencing objects", 100);
-                               actualUuid = entityUUID;
-
-                               monitor.worked(2);
-                               ReferencingObjectDto loadDto = new ReferencingObjectDto();
-                               loadDto.setTitleCache(IS_LOADING);
-                               referencingObjects = Arrays.asList(loadDto);
-                               updateView();
-                               if(monitor.isCanceled()) {
-//                                 actualUuid = null;
-                    return Status.CANCEL_STATUS;
-                }
-                               if (actualMonitor != null){
-                                   actualMonitor.setCanceled(true);
-                               }
-                               actualMonitor = monitor;
-                               if (entityUUID != null){
-                                   monitor.subTask("Load data from server");
-                                   monitor.worked(1);
-                       Set<ReferencingObjectDto> refObjectsFromServer = loadReferencingObjects(entityUUID, objectClass);
-                       if (refObjectsFromServer == null){
-                           return Status.CANCEL_STATUS;  //TODO is this correct?, null can happen e.g. if server call throws exception
-                       }
-                       monitor.worked(25);
-                       if(monitor.isCanceled()) {
-//                       actualUuid = null;
-                           return Status.CANCEL_STATUS;
-                       }
-                       referencingObjectsSet = refObjectsFromServer;
+        private String bestLabel(){
+            return (StringUtils.isNotBlank(this.typeName)? this.typeName + " " : "")
+                    + "'"+(StringUtils.isNotBlank(this.itemLabel)? this.itemLabel : this.itemUuid.toString()) +"'"
+                    + (this.itemId != null? " (id=" + this.itemId+")" : "");
+        }
+    }
 
-                       monitor.subTask("Show without description");
-                       monitor.worked(1);//maybe this helps to update the subtask label
+       private class UpdateRefObjectsJob extends Job{
 
-                       //TODO have a status line instead
-                       int count = referencingObjectsSet == null? 0: referencingObjectsSet.size();
-                       updateDescriptionLabel(CdmUtils.Nz(description) + "(n="+count+")"); //
+           final private ItemDto item;
 
+        public UpdateRefObjectsJob(String name, ItemDto item) {
+            super(name);
+            this.item = item;
+            if (item.itemUuid == null){
+                throw new RuntimeException("Item uuid must always exist at this point");
+            }
+        }
 
-                       List<ReferencingObjectDto> localDtos = sortToList(referencingObjectsSet, monitor);
-                       monitor.worked(10);
-                       if(monitor.isCanceled()) {
-//                         actualUuid = null;
-                           return Status.CANCEL_STATUS;
-                       }
-                       referencingObjects = localDtos;
-                       updateView();
-
-                       monitor.subTask("Initialize");
-                       monitor.worked(1);//maybe this helps to update the subtask label
-                    initializeDtos(localDtos, monitor, 50);
-                    if (monitor.isCanceled()){
-//                        actualUuid = null;
-                        //TODO use status line instead
-//                        referencingObjects = Arrays.asList(CANCELED);
-                        updateView();
-//                        monitor.done();
-                        return Status.CANCEL_STATUS;
-                    }
+        @Override
+        protected IStatus run(final IProgressMonitor monitor) {
 
-                       if(monitor.isCanceled()) {
-                           return Status.CANCEL_STATUS;
-                       }
-                       monitor.subTask("Update View");
+            monitor.beginTask("Calculating referencing objects for " + item.itemLabel, 100);
+
+            //set to loading
+            monitor.subTask("Load empty");
+            monitor.worked(1);
+            updateView("Loading " + item.bestLabel(), EMPTY_LIST, item.itemUuid);
+            if(monitor.isCanceled()) {
+                return Status.CANCEL_STATUS;
+            }
 
-                       updateView();
-                       monitor.worked(5);
-                               }
-                               monitor.done();
-                               actualMonitor = null;
+            //handle transient instance
+            if (item.itemId != null && item.itemId.equals(0)){
+                updateView("Not yet persisted: " + item.bestLabel(), EMPTY_LIST, item.itemUuid);
+                monitor.done();
+                return Status.OK_STATUS;
+            }
+            monitor.worked(1);  //sum = 2
+
+            //load uninitialized DTOs from server
+            monitor.subTask("Load base data from server");
+            Set<ReferencingObjectDto> refObjectsFromServer = loadReferencingObjects(item.itemUuid, item.itemClass);
+            if (refObjectsFromServer == null){
+                updateView("An error occurred when loading " + item.bestLabel(), EMPTY_LIST, item.itemUuid);
+                return Status.CANCEL_STATUS;  //TODO is this correct?, null can happen e.g. if server call throws exception
+            }
+            if(monitor.isCanceled()) {
+                return Status.CANCEL_STATUS;
+            }
+            monitor.worked(10); //sum = 12
+
+            //show count
+            monitor.subTask("Show without description");
+            int count = refObjectsFromServer.size();
+            updateView("Loading " + count + " items for " + item.bestLabel(), EMPTY_LIST, item.itemUuid);
+            monitor.worked(1);  //sum = 13
+
+            //sort
+            List<ReferencingObjectDto> localDtos = sortToList(refObjectsFromServer);
+            updateView("0/" + count + " items for " + item.bestLabel(), localDtos, item.itemUuid);
+            if(monitor.isCanceled()) {
+                return Status.CANCEL_STATUS;
+            }
+            monitor.worked(2);  //sum = 15
 
-                               return Status.OK_STATUS;
-                       }
+            //initialize
+            monitor.subTask("Initialize");
+            initializeDtos(localDtos, item, monitor, 83);  //is calling updateView itself; sum = 95
+            if(monitor.isCanceled()) {
+                return Status.CANCEL_STATUS;
+            }
+            monitor.worked(2);  //sum = 100 (just in case)
+            monitor.done();
 
-               };
-               currentJob.setUser(true);
+            return Status.OK_STATUS;
+        }
+       }
 
+       private synchronized void updateToNewItem(final ItemDto item) {
+               if (currentJob != null){
+                   currentJob.cancel();
+               }
+               Job newJob = new UpdateRefObjectsJob("Update Referencing Objects for " + item.bestLabel(), item);
+               newJob.setUser(true);
+               actualUuid = item.itemUuid;
+               currentJob = newJob;
                currentJob.schedule();
        }
 
-    private List<ReferencingObjectDto> sortToList(Set<ReferencingObjectDto> referencingObjectsSet, IProgressMonitor monitor) {
+    private List<ReferencingObjectDto> sortToList(Set<ReferencingObjectDto> referencingObjectsSet) {
         List<ReferencingObjectDto> result = new ArrayList<>(referencingObjectsSet);
-        //TODO make singleton
-        Collections.sort(result, new RefObjectDtoComparator());
+        Collections.sort(result, COMPARATOR);
         return result;
     }
 
-    protected boolean initializeDtos(List<ReferencingObjectDto> localDtos, IProgressMonitor monitor, int work) {
+    protected boolean initializeDtos(List<ReferencingObjectDto> localDtos, ItemDto item, IProgressMonitor monitor, int work) {
+
         IProgressMonitor subMonitor = AbstractUtility.getSubProgressMonitor(monitor, work);
         subMonitor.beginTask("Initialize DTOs", localDtos.size());
-
         int i = 100 - 20;  //the first run should only include 20 records
+        int initCount = 0;
 
         Set<ReferencingObjectDto> toInitialize = new HashSet<>();
         for (ReferencingObjectDto dto : localDtos){
+            initCount++;
             toInitialize.add(dto);
-
-//            dto.setTitleCache(ReferencingObjectFormatter.format(dto.getReferencedEntity(), CdmStore.getDefaultLanguage() ));
-            if (monitor.isCanceled()){
-                return false;
-            }
             subMonitor.worked(1);
             if (++i == 100){
-                initBulk(toInitialize);
-                updateView();
+                if (monitor.isCanceled()){
+                    return false;
+                }
+                initBulk(toInitialize, initCount, localDtos, item);
+                //reset
                 toInitialize = new HashSet<>();
                 i = 0;
             }
         }
-        initBulk(toInitialize);
+        //final bulk
+        if (monitor.isCanceled()){
+            return false;
+        }
+        initBulk(toInitialize, initCount, localDtos, item);
         return true;
     }
 
-    private void initBulk(Set<ReferencingObjectDto> toInitialize) {
+    private void initBulk(Set<ReferencingObjectDto> toInitialize, int initCount,
+            List<ReferencingObjectDto> localDtos, ItemDto item) {
         Set<ReferencingObjectDto> initialized = CdmStore.getCommonService().initializeReferencingObjectDtos(toInitialize, true, true, true, CdmStore.getDefaultLanguage());
         Map<UUID,ReferencingObjectDto> map = new HashMap<>();
         initialized.forEach(i->map.put(i.getUuid(), i));
-        toInitialize.forEach(dto->merge(dto, map.get(dto.getUuid())));
-        updateView();
-
+        toInitialize.forEach(dto->mergeInitializedData(dto, map.get(dto.getUuid())));
+        String initStr = initCount < localDtos.size()? initCount + "/" + localDtos.size() + " items": "Items";
+        updateView(initStr + " for " + item.bestLabel(), localDtos, item.itemUuid);
     }
 
-    private void merge(ReferencingObjectDto to, ReferencingObjectDto from) {
+    private void mergeInitializedData(ReferencingObjectDto to, ReferencingObjectDto from) {
         to.setTitleCache(from.getTitleCache());
         to.setOpenInTarget(from.getOpenInTarget());
         to.setReferencedEntity(from.getReferencedEntity());
@@ -384,21 +395,9 @@ public class ReferencingObjectsViewE4 extends AbstractCdmEditorPartE4 implements
             else if(CdmBase.class.isAssignableFrom(objectClass)){
                 referencedObject = CdmStore.getCommonService().find(objectClass, entity);
             }
-                       //referencedObject =(CdmBase) CdmStore.getService(IIdentifiableEntityService.class).load(referencedObject.getUuid());
                Set<ReferencingObjectDto> setOfReferencingObjects = null;
 
                if (referencedObject != null){
-//                 if(referencedObject.isInstanceOf(IdentifiableEntity.class)){
-//                     referencedObjectTitleCache = (HibernateProxyHelper.deproxy(referencedObject, IdentifiableEntity.class)).getTitleCache();
-//                 }
-//                 else if(referencedObject.isInstanceOf(DescriptionElementBase.class)){
-//                     referencedObjectTitleCache = DescriptionHelper.getLabel(referencedObject);
-//                 }
-//                 else if (referencedObject.isInstanceOf(User.class)){
-//                     referencedObjectTitleCache = ((User)referencedObject).getUsername();
-//                 }else{
-//                     referencedObjectTitleCache = DescriptionHelper.getLabel(referencedObject);
-//                 }
                        setOfReferencingObjects = CdmStore.getCommonService().getReferencingObjectDtos(referencedObject);
                        return setOfReferencingObjects;
                }
@@ -411,7 +410,11 @@ public class ReferencingObjectsViewE4 extends AbstractCdmEditorPartE4 implements
                return null;
        }
 
-       class RefObjectDtoComparator implements Comparator<ReferencingObjectDto>{
+       /**
+        * Compares the referencing object by type and id. Using "description" for
+        * comparation has been given up to avoid initialization before comparison.
+        */
+       static class RefObjectDtoComparator implements Comparator<ReferencingObjectDto>{
 
         @Override
         public int compare(ReferencingObjectDto dto1, ReferencingObjectDto dto2) {
@@ -423,22 +426,30 @@ public class ReferencingObjectsViewE4 extends AbstractCdmEditorPartE4 implements
         }
        }
 
-       private void updateView() {
-           Display.getDefault().asyncExec(()->{
-               if (viewer != null && !viewer.getControl().isDisposed()){
-                try{
-                    viewer.setInput(referencingObjects);
-                    viewer.refresh();
-
-                    //enable/disable table
-                    viewer.getControl().setEnabled(referencingObjects!=null);
-                }catch(Exception e){
-                    e.printStackTrace();
-                    logger.debug(e.getStackTrace());
-                    updateDescriptionLabel("The referencing objects view could not be updated completely. Some Problems occurred: " + e.getMessage());
-                }
-            }
-           });
+       //not sure if it needs to be synchronized, only the local variable actualUuid is read
+       private void updateView(final String label,
+               final List<ReferencingObjectDto> referencingObjects, UUID itemUuid) {
+
+           if (this.actualUuid == itemUuid){
+               Display.getDefault().asyncExec(()->{
+                   if (contentDescription != null && !contentDescription.isDisposed()){
+                       contentDescription.setText(label);
+                   }
+                   if (viewer != null && !viewer.getControl().isDisposed()){
+                       try{
+                           viewer.setInput(referencingObjects);
+                           viewer.refresh();
+
+                           //enable/disable table
+                           viewer.getControl().setEnabled(referencingObjects!=null);
+                       }catch(Exception e){
+                           e.printStackTrace();
+                           logger.debug(e.getStackTrace());
+                           updateDescriptionLabel("The referencing objects view could not be updated completely. Some Problems occurred: " + e.getMessage());
+                       }
+                   }
+               });
+           }
        }
 
 
@@ -451,6 +462,11 @@ public class ReferencingObjectsViewE4 extends AbstractCdmEditorPartE4 implements
          );
         }
 
+    @Override
+    protected boolean showEmptyIfNoActiveEditor(){
+        return false;
+    }
+
     @Override
     public void selectionChanged_internal(Object selection, MPart activePart, MPart thisPart) {
         if(activePart==thisPart){
@@ -459,74 +475,124 @@ public class ReferencingObjectsViewE4 extends AbstractCdmEditorPartE4 implements
 
         IStructuredSelection structuredSelection = createSelection(selection);
         if(structuredSelection!=null){
-               //referencedObjectTitleCache = null;
                showViewer(structuredSelection, activePart, viewer);
         }
        }
 
        @Override
        public void showViewer(IStructuredSelection selection, MPart activePart, Viewer viewer){
-       //      this.part = part;
-
-               Object firstElement = selection.getFirstElement();
-               if (firstElement instanceof TermDto){
-                  TermDto termDto = (TermDto) firstElement;
-                  description = "'"+termDto.getRepresentation_L10n() + "' is referenced by:";
-                  updateDescriptionLabel(description);
-                  updateReferencingObjects(termDto.getUuid(), TermBase.class );
-                  return;
-               }
-               if(firstElement instanceof TreeNode){
-                   firstElement = ((TreeNode) firstElement).getValue();
-               }
-               if (firstElement instanceof TaxonNode && !((TaxonNode)firstElement).hasTaxon()){
-                       firstElement = ((TaxonNode)firstElement).getClassification();
+           handleNewSelection(selection.getFirstElement());
+       }
+
+       //Note AM: this can probably be done better together with base class methods
+       //         As I am not so familiar with this structure I only adapt it this way to be on the safe side
+       @Override
+    public void handleNewSelection(Object firstElement){
+        ItemDto dto = makeItemDto(firstElement);
+               if (dto.itemUuid == null || dto.itemClass == null || dto.itemUuid.equals(this.actualUuid)){
+                   return;
                }
-               if(firstElement instanceof CdmBase){
-                   firstElement= CdmBase.deproxy(firstElement, CdmBase.class);
-                   CdmBase referencedCdmObject = (CdmBase)firstElement;
-                   if (referencedCdmObject.getUuid() == actualUuid){
-                       return;
-                   }
-                   String referencedObjectTitleCache = null;
-               if(referencedCdmObject.isInstanceOf(IdentifiableEntity.class)){
-                referencedObjectTitleCache = (HibernateProxyHelper.deproxy(referencedCdmObject, IdentifiableEntity.class)).getTitleCache();
+               updateToNewItem(dto);
+       }
+
+    /**
+     * Transforms the selection into uniform format (ItemDto).
+     * This method must be fast / should never require a server call
+     * as it takes place before the update Job is started and therefore is not
+     * asynchronous.
+     */
+    public ItemDto makeItemDto(Object firstElement) {
+
+        ItemDto dto = new ItemDto();
+        if(firstElement instanceof TreeNode){
+            firstElement = ((TreeNode) firstElement).getValue();
+        }
+        if (firstElement instanceof TaxonNode && !((TaxonNode)firstElement).hasTaxon()){
+            firstElement = ((TaxonNode)firstElement).getClassification();
+        }
+
+        if (firstElement instanceof AbstractTermDto){
+           AbstractTermDto termDto = (AbstractTermDto) firstElement;
+           dto.itemLabel = termDto.getTitleCache();
+           dto.itemUuid= termDto.getUuid();
+           dto.typeName = termDto.getTermType().getLabel();
+           dto.itemId = null;   // id does not yet exist in TermDto
+           if (termDto instanceof TermDto){
+               dto.itemClass = TermBase.class;
+           }else if(termDto instanceof TermTreeDto){
+               dto.itemClass = TermTree.class;
+               dto.typeName = dto.typeName + " Tree";
+           }else if(termDto instanceof TermVocabularyDto){
+               dto.itemClass = TermVocabulary.class;
+               dto.typeName = dto.typeName + " Vocabulary";
+           }else{
+               //make it an unhandled selection
+               dto.itemUuid = null;
+           }
+        }else if (firstElement instanceof TermNodeDto){
+            TermNodeDto termNodeDto = (TermNodeDto) firstElement;
+            dto.itemLabel = (termNodeDto.getTerm() != null? termNodeDto.getTerm().getTitleCache() : termNodeDto.getTreeIndex());
+            dto.itemUuid= termNodeDto.getUuid();
+            dto.typeName = termNodeDto.getType().getLabel() + " Node";
+            dto.itemId = null;  //does not yet exist in TermDto
+            dto.itemClass = TermNode.class;
+        }else if(firstElement instanceof CdmBase){
+                   CdmBase cdmBase = CdmBase.deproxy(firstElement, CdmBase.class);
+                   String label = null;
+               if(cdmBase instanceof IdentifiableEntity){
+                label = (HibernateProxyHelper.deproxy(cdmBase, IdentifiableEntity.class)).getTitleCache();
             }
-            else if(referencedCdmObject.isInstanceOf(DescriptionElementBase.class)){
-                referencedObjectTitleCache = DescriptionHelper.getLabel(referencedCdmObject);
+            else if(cdmBase instanceof DescriptionElementBase){
+                label = DescriptionHelper.getLabel(cdmBase);
             }
-            else if (referencedCdmObject.isInstanceOf(User.class)){
-                referencedObjectTitleCache = ((User)referencedCdmObject).getUsername();
-            }else if (referencedCdmObject.isInstanceOf(TaxonNode.class)){
-                referencedObjectTitleCache = "TaxonNode of "+(HibernateProxyHelper.deproxy(referencedCdmObject, TaxonNode.class)).getTaxon().getTitleCache();
+            else if (cdmBase instanceof User){
+                label = ((User)cdmBase).getUsername();
+            }else if (cdmBase instanceof TaxonNode){
+                label = ((TaxonNode)cdmBase).getTaxon().getTitleCache();
             }
-               if (CdmUtils.isBlank(referencedObjectTitleCache)){
-                   referencedObjectTitleCache = "#"+referencedCdmObject.getId();
+               if (CdmUtils.isBlank(label)){
+                   label = "#"+cdmBase.getId();
                }
-               description = referencedCdmObject.getUserFriendlyTypeName() + " '" + referencedObjectTitleCache + "' is referenced by:";
-               updateDescriptionLabel(description);
-
-                   updateReferencingObjects(referencedCdmObject.getUuid(),firstElement.getClass() );
-
+               dto.typeName = cdmBase.getUserFriendlyTypeName();
+               dto.itemLabel = label;
+               dto.itemUuid= cdmBase.getUuid();
+               dto.itemClass = cdmBase.getClass();
+               dto.itemId = cdmBase.getId();
                }else if  (firstElement instanceof UuidAndTitleCache<?>){
-                   UuidAndTitleCache<?> element = (UuidAndTitleCache<?>) firstElement;
-                   description = element.getType().getSimpleName() + " '" + element.getTitleCache() + "' is referenced by:";
-               updateDescriptionLabel(description);
-            updateReferencingObjects(element.getUuid(),element.getType());
-               }
-               else if (firstElement != null){
-                   updateView();
-            description = "undefined:";
-                   updateDescriptionLabel(description);
+                   UuidAndTitleCache<? extends CdmBase> element = (UuidAndTitleCache<? extends CdmBase>) firstElement;
+                   dto.typeName = CdmUtils.userFriendlyClassName(element.getType());
+                   dto.itemLabel = element.getTitleCache();
+            if (CdmUtils.isBlank(dto.itemLabel)){
+                dto.itemLabel = "id=" + element.getId();
+            }
+            dto.itemUuid= element.getUuid();
+            dto.itemClass = element.getType();
+            dto.itemId = element.getId();
+               }else if (firstElement instanceof String){
+            dto.typeName = "String";
+            dto.itemLabel = firstElement.toString();
+            dto.itemUuid= null;
+            dto.itemClass = null;
+            dto.itemId = null;
+               }else if (firstElement != null){
+                   dto.typeName = CdmUtils.userFriendlyClassName(firstElement.getClass());
+                   dto.itemLabel = firstElement.toString();
+                   dto.itemUuid= null;
+                   dto.itemClass = null;
+                   dto.itemId = null;
+               }else{
+                   dto.typeName = null;
+                   dto.itemLabel = "no selection";
+                   dto.itemUuid= null;
+                   dto.itemClass = null;
+                   dto.itemId = null;
                }
-       }
+        return dto;
+    }
 
        @PreDestroy
        public void dispose() {
-           if(conversation!=null){
-               conversation.close();
-               conversation = null;
-           }
+           //no conversation in this view
        }
 
        @Override
index e39dd38ec42e52c8871c777ba4d7105519d55626..ee461f17229e314b394c26d52d73f1d0c4ee6575 100644 (file)
@@ -35,10 +35,12 @@ import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
+import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
 import eu.etaxonomy.cdm.model.taxon.Synonym;
 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
 import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
+import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
 import eu.etaxonomy.taxeditor.bulkeditor.e4.BulkEditorE4;
 import eu.etaxonomy.taxeditor.bulkeditor.input.TaxonEditorInput;
 import eu.etaxonomy.taxeditor.editor.descriptiveDataSet.DescriptiveDataSetEditor;
@@ -103,7 +105,7 @@ public class EditorUtil extends AbstractUtility {
         editor.init(descriptiveDataSetUuid, true);
     }
 
-    public static void openDistributionEditor(List<TaxonNodeDto> parentTaxonUuidList, EModelService modelService, EPartService partService, MApplication application){
+    public static void openDistributionEditor(List<UuidAndTitleCache<ITaxonTreeNode>> parentTaxonUuidList, EModelService modelService, EPartService partService, MApplication application){
         String partId = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_CHECKLIST_E4_DISTRIBUTIONEDITORPART;
         checkAndCloseFactsAndMediaParts(partService);
         MPart part = showPart(partId, modelService, partService, application);
index 259bdc096be5c4cd59e31c61086b04c310604605..86db330609de2321be655fe53dc88f3caa0ca6c0 100755 (executable)
@@ -44,9 +44,10 @@ import eu.etaxonomy.cdm.api.service.dto.TaxonDistributionDTO;
 import eu.etaxonomy.cdm.compare.taxon.TaxonNodeSortMode;
 import eu.etaxonomy.cdm.model.description.DescriptionBase;
 import eu.etaxonomy.cdm.model.description.TaxonDescription;
+import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
 import eu.etaxonomy.cdm.model.taxon.Taxon;
 import eu.etaxonomy.cdm.persistence.dto.MergeResult;
-import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
+import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
 import eu.etaxonomy.taxeditor.editor.EditorUtil;
 import eu.etaxonomy.taxeditor.editor.IDistributionEditorPart;
@@ -126,7 +127,7 @@ public class DistributionEditorPart
         ContextInjectionFactory.inject(editor, context);
     }
 
-    public void init(List<TaxonNodeDto> uuidAndTitleCaches) {
+    public void init(List<UuidAndTitleCache<ITaxonTreeNode>> uuidAndTitleCaches) {
 
         List<UUID> nodeUuids = new ArrayList<>();
         uuidAndTitleCaches.forEach(element -> nodeUuids.add(element.getUuid()));
index 6eba843ee2ac844606dd3ddaa220bc2412b3529c..1260208f0a05ec9958591f2f1eddf71748d9315e 100644 (file)
@@ -19,29 +19,43 @@ import org.eclipse.e4.ui.services.IServiceConstants;
 import org.eclipse.e4.ui.workbench.modeling.EPartService;
 import org.eclipse.swt.widgets.Shell;
 
+import eu.etaxonomy.cdm.api.service.IClassificationService;
 import eu.etaxonomy.cdm.model.description.Distribution;
 import eu.etaxonomy.cdm.model.metadata.PreferencePredicate;
 import eu.etaxonomy.cdm.model.permission.Operation;
+import eu.etaxonomy.cdm.model.taxon.Classification;
 import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
-import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
+import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
 import eu.etaxonomy.taxeditor.editor.AppModelId;
 import eu.etaxonomy.taxeditor.editor.EditorUtil;
 import eu.etaxonomy.taxeditor.handler.defaultHandler.e4.DefaultOpenSetBaseHandler;
 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
 import eu.etaxonomy.taxeditor.security.RequiredPermissions;
 import eu.etaxonomy.taxeditor.store.CdmStore;
+import eu.etaxonomy.taxeditor.view.DtoWithEntity;
 
 /**
  * Handler to open the distribution editor via context menu
  */
-public class OpenChecklistEditorHandlerE4 extends DefaultOpenSetBaseHandler<ITaxonTreeNode, TaxonNodeDto> {
+public class OpenChecklistEditorHandlerE4 extends DefaultOpenSetBaseHandler<ITaxonTreeNode, UuidAndTitleCache<ITaxonTreeNode>> {
 
        @Override
-    protected void open(List<TaxonNodeDto> entities, Shell shell, EPartService partService) {
+    protected void open(List<UuidAndTitleCache<ITaxonTreeNode>> entities, Shell shell, EPartService partService) {
+           replaceClassificationsByRootNode(entities);
            EditorUtil.openDistributionEditor(entities, modelService, partService, application);
        }
 
+    public void replaceClassificationsByRootNode(List<UuidAndTitleCache<ITaxonTreeNode>> entities) {
+        for (UuidAndTitleCache<ITaxonTreeNode> entity : entities){
+               if (Classification.class.isAssignableFrom(entity.getType())){
+                   Classification c = CdmStore.getService(IClassificationService.class).find(entity.getUuid());
+                   DtoWithEntity<ITaxonTreeNode> dto = new DtoWithEntity<ITaxonTreeNode>(c.getRootNode());
+                   entities.set(entities.indexOf(entity),dto);
+               }
+           }
+    }
+
     @CanExecute
     @Override
     public boolean canExecute(MHandledMenuItem menuItem,
@@ -80,7 +94,7 @@ public class OpenChecklistEditorHandlerE4 extends DefaultOpenSetBaseHandler<ITax
     }
 
     @Override
-    protected boolean canExecute(TaxonNodeDto entity) {
+    protected boolean canExecute(UuidAndTitleCache<ITaxonTreeNode> entity) {
         //FIXME DTO
         return true;
     }
index 0d83a6581b413a87f56ede400e922fa016481b4b..8273040b191af6e42a8bfc405dcff4c988efee33 100755 (executable)
@@ -8,14 +8,12 @@
 */
 package eu.etaxonomy.taxeditor.editor;
 
-import java.util.UUID;
-
 /**
  * @author k.luther
  * @since Mar 12, 2020
  */
 public interface IReferencingObjectsView {
 
-    public void updateReferencingObjects(final UUID entityUUID, final Class objectClass);
+    public void handleNewSelection(Object firstElement);
 
 }
index e40d28b56aacafe3500549e8843b288bab892fe2..b2505b00e9434a55cc4ed9330f6e309407c8c8b5 100644 (file)
@@ -31,7 +31,7 @@ public class OpenReferencingObjectsViewHandler {
 
         if (selectedObjectList != null && !selectedObjectList.isEmpty()) {
             UuidAndTitleCache<? extends ICdmBase> dto = selectedObjectList.get(0);
-            view.updateReferencingObjects(dto.getUuid(), dto.getType());
+            view.handleNewSelection(dto);
         }
     }
 
index 8ee2d4b1efa714d45216ea149bc895ffa508a44e..b973f71e46f4aaf86ed8dee882ce6b0d6f3b65a9 100644 (file)
@@ -133,6 +133,10 @@ public abstract class AbstractCdmEditorPartE4
 
     protected abstract void selectionChanged_internal(Object selection, MPart activePart, MPart thisPart);
 
+    protected boolean showEmptyIfNoActiveEditor(){
+        return true;
+    }
+
     @Inject
     public void selectionChanged(
             @Optional@Named(IServiceConstants.ACTIVE_SELECTION)Object selection,
@@ -148,7 +152,7 @@ public abstract class AbstractCdmEditorPartE4
             return;
         }
         // no active editor found
-        if(activePart==thisPart && WorkbenchUtility.getActiveEditorPart(partService)==null){
+        if(activePart==thisPart && WorkbenchUtility.getActiveEditorPart(partService)==null && showEmptyIfNoActiveEditor()){
             showEmptyPage();
             return;
         }