Project

General

Profile

« Previous | Next » 

Revision 3ce2af15

Added by Andreas Müller about 3 years ago

ref #9541 further fixes for referencing objects and related issues

View differences:

eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/referencingobjects/e4/ReferencingObjectsViewE4.java
23 23
import javax.annotation.PostConstruct;
24 24
import javax.annotation.PreDestroy;
25 25

  
26
import org.apache.commons.lang3.StringUtils;
26 27
import org.apache.log4j.Logger;
27 28
import org.eclipse.core.runtime.IProgressMonitor;
28 29
import org.eclipse.core.runtime.IStatus;
......
47 48
import org.eclipse.swt.widgets.Label;
48 49
import org.eclipse.swt.widgets.Table;
49 50

  
50
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
51 51
import eu.etaxonomy.cdm.api.service.IAgentService;
52 52
import eu.etaxonomy.cdm.api.service.IDescriptionService;
53 53
import eu.etaxonomy.cdm.api.service.IEventBaseService;
......
83 83
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
84 84
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
85 85
import eu.etaxonomy.cdm.model.term.TermBase;
86
import eu.etaxonomy.cdm.model.term.TermNode;
87
import eu.etaxonomy.cdm.model.term.TermTree;
88
import eu.etaxonomy.cdm.model.term.TermVocabulary;
89
import eu.etaxonomy.cdm.persistence.dto.AbstractTermDto;
86 90
import eu.etaxonomy.cdm.persistence.dto.ReferencingObjectDto;
87 91
import eu.etaxonomy.cdm.persistence.dto.TermDto;
92
import eu.etaxonomy.cdm.persistence.dto.TermNodeDto;
93
import eu.etaxonomy.cdm.persistence.dto.TermTreeDto;
94
import eu.etaxonomy.cdm.persistence.dto.TermVocabularyDto;
88 95
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
89 96
import eu.etaxonomy.taxeditor.bulkeditor.referencingobjects.ReferencingObjectsContentProvider;
90 97
import eu.etaxonomy.taxeditor.bulkeditor.referencingobjects.ReferencingObjectsLabelProvider;
......
95 102
import eu.etaxonomy.taxeditor.view.e4.AbstractCdmEditorPartE4;
96 103

  
97 104
/**
105
 * This view loads and presents referencing objects information asynchronously.
106
 *
107
 * Most of the task is done in UpdateRefObjectsJob.run()
108
 *
98 109
 * @author pplitzner
110
 * @author k.luther
111
 * @author a.mueller
99 112
 * @since Aug 16, 2017
100 113
 */
101 114
public class ReferencingObjectsViewE4 extends AbstractCdmEditorPartE4 implements IReferencingObjectsView{
......
105 118
    public static final String IS_LOADING = "Loading ...";
106 119
//    public static final String CANCELED = "Canceled ...";
107 120

  
121
    private static final List<ReferencingObjectDto> EMPTY_LIST = Arrays.asList();  //immutable empty list
122
    private static final RefObjectDtoComparator COMPARATOR = new RefObjectDtoComparator();
123

  
108 124
    private Label contentDescription;
109
    private String description;
110 125

  
111
//	private String referencedObjectTitleCache;
112
	private ConversationHolder conversation;
113
	private UUID actualUuid;
114
	private List<ReferencingObjectDto> referencingObjects = null;
115
	private Set<ReferencingObjectDto> referencingObjectsSet = null;
116
	private IProgressMonitor actualMonitor = null;
117
	private Job currentJob = null;
126
	private volatile UUID actualUuid;  //volatile as it used used between threads but only written in the synchronized method
127
	private Job currentJob = null;  //this variable should only be accessed in synchronized updateToNewItem
118 128

  
119 129
    @PostConstruct
120 130
    public void create(Composite parent, EMenuService menuService) {
121
        if (CdmStore.isActive()){
122
            if(conversation == null){
123
                conversation = CdmStore.createConversation();
124
            }
125
        }
126
        else{
131
        if (!CdmStore.isActive()){
127 132
            return;
128 133
        }
129 134
        parent.setLayout(new GridLayout());
......
170 175

  
171 176
        //create context menu
172 177
        menuService.registerContextMenu(viewer.getControl(), "eu.etaxonomy.taxeditor.bulkeditor.popupmenu.referencingobjectsview");
173

  
174 178
	}
175 179

  
176 180
	/**
......
199 203
		viewer.setColumnProperties(titles);
200 204
	}
201 205

  
202
	@Override
203
    public void updateReferencingObjects(final UUID entityUUID, final Class objectClass) {
204
	    if (actualUuid == entityUUID){
205
	        return ;
206
	    }
207 206

  
208
	    if(actualMonitor!=null && !actualMonitor.isCanceled()){
209
	        while(!actualMonitor.isCanceled()){
210
	            actualMonitor.setCanceled(true);
211
	        }
212
	    }
207
    private class ItemDto {
208
        String typeName;
209
        String itemLabel;
210
        UUID itemUuid;
211
        Integer itemId;
212
        Class<? extends CdmBase> itemClass;
213 213

  
214
		currentJob = new Job("Update Referencing Objects for " + entityUUID) {
215

  
216
			@Override
217
			protected IStatus run(final IProgressMonitor monitor) {
218
				monitor.beginTask("Calculating referencing objects", 100);
219
				actualUuid = entityUUID;
220

  
221
				monitor.worked(2);
222
				ReferencingObjectDto loadDto = new ReferencingObjectDto();
223
				loadDto.setTitleCache(IS_LOADING);
224
				referencingObjects = Arrays.asList(loadDto);
225
				updateView();
226
				if(monitor.isCanceled()) {
227
//				    actualUuid = null;
228
                    return Status.CANCEL_STATUS;
229
                }
230
				if (actualMonitor != null){
231
				    actualMonitor.setCanceled(true);
232
				}
233
				actualMonitor = monitor;
234
				if (entityUUID != null){
235
				    monitor.subTask("Load data from server");
236
				    monitor.worked(1);
237
	                Set<ReferencingObjectDto> refObjectsFromServer = loadReferencingObjects(entityUUID, objectClass);
238
	                if (refObjectsFromServer == null){
239
	                    return Status.CANCEL_STATUS;  //TODO is this correct?, null can happen e.g. if server call throws exception
240
	                }
241
	                monitor.worked(25);
242
	                if(monitor.isCanceled()) {
243
//	                  actualUuid = null;
244
	                    return Status.CANCEL_STATUS;
245
	                }
246
	                referencingObjectsSet = refObjectsFromServer;
214
        private String bestLabel(){
215
            return (StringUtils.isNotBlank(this.typeName)? this.typeName + " " : "")
216
                    + "'"+(StringUtils.isNotBlank(this.itemLabel)? this.itemLabel : this.itemUuid.toString()) +"'"
217
                    + (this.itemId != null? " (id=" + this.itemId+")" : "");
218
        }
219
    }
247 220

  
248
	                monitor.subTask("Show without description");
249
	                monitor.worked(1);//maybe this helps to update the subtask label
221
	private class UpdateRefObjectsJob extends Job{
250 222

  
251
	                //TODO have a status line instead
252
	                int count = referencingObjectsSet == null? 0: referencingObjectsSet.size();
253
	                updateDescriptionLabel(CdmUtils.Nz(description) + "(n="+count+")"); //
223
	    final private ItemDto item;
254 224

  
225
        public UpdateRefObjectsJob(String name, ItemDto item) {
226
            super(name);
227
            this.item = item;
228
            if (item.itemUuid == null){
229
                throw new RuntimeException("Item uuid must always exist at this point");
230
            }
231
        }
255 232

  
256
	                List<ReferencingObjectDto> localDtos = sortToList(referencingObjectsSet, monitor);
257
	                monitor.worked(10);
258
	                if(monitor.isCanceled()) {
259
//	                    actualUuid = null;
260
	                    return Status.CANCEL_STATUS;
261
	                }
262
	                referencingObjects = localDtos;
263
	                updateView();
264

  
265
	                monitor.subTask("Initialize");
266
	                monitor.worked(1);//maybe this helps to update the subtask label
267
                    initializeDtos(localDtos, monitor, 50);
268
                    if (monitor.isCanceled()){
269
//                        actualUuid = null;
270
                        //TODO use status line instead
271
//                        referencingObjects = Arrays.asList(CANCELED);
272
                        updateView();
273
//                        monitor.done();
274
                        return Status.CANCEL_STATUS;
275
                    }
233
        @Override
234
        protected IStatus run(final IProgressMonitor monitor) {
276 235

  
277
	                if(monitor.isCanceled()) {
278
	                    return Status.CANCEL_STATUS;
279
	                }
280
	                monitor.subTask("Update View");
236
            monitor.beginTask("Calculating referencing objects for " + item.itemLabel, 100);
237

  
238
            //set to loading
239
            monitor.subTask("Load empty");
240
            monitor.worked(1);
241
            updateView("Loading " + item.bestLabel(), EMPTY_LIST, item.itemUuid);
242
            if(monitor.isCanceled()) {
243
                return Status.CANCEL_STATUS;
244
            }
281 245

  
282
	                updateView();
283
	                monitor.worked(5);
284
				}
285
				monitor.done();
286
				actualMonitor = null;
246
            //handle transient instance
247
            if (item.itemId != null && item.itemId.equals(0)){
248
                updateView("Not yet persisted: " + item.bestLabel(), EMPTY_LIST, item.itemUuid);
249
                monitor.done();
250
                return Status.OK_STATUS;
251
            }
252
            monitor.worked(1);  //sum = 2
253

  
254
            //load uninitialized DTOs from server
255
            monitor.subTask("Load base data from server");
256
            Set<ReferencingObjectDto> refObjectsFromServer = loadReferencingObjects(item.itemUuid, item.itemClass);
257
            if (refObjectsFromServer == null){
258
                updateView("An error occurred when loading " + item.bestLabel(), EMPTY_LIST, item.itemUuid);
259
                return Status.CANCEL_STATUS;  //TODO is this correct?, null can happen e.g. if server call throws exception
260
            }
261
            if(monitor.isCanceled()) {
262
                return Status.CANCEL_STATUS;
263
            }
264
            monitor.worked(10); //sum = 12
265

  
266
            //show count
267
            monitor.subTask("Show without description");
268
            int count = refObjectsFromServer.size();
269
            updateView("Loading " + count + " items for " + item.bestLabel(), EMPTY_LIST, item.itemUuid);
270
            monitor.worked(1);  //sum = 13
271

  
272
            //sort
273
            List<ReferencingObjectDto> localDtos = sortToList(refObjectsFromServer);
274
            updateView("0/" + count + " items for " + item.bestLabel(), localDtos, item.itemUuid);
275
            if(monitor.isCanceled()) {
276
                return Status.CANCEL_STATUS;
277
            }
278
            monitor.worked(2);  //sum = 15
287 279

  
288
				return Status.OK_STATUS;
289
			}
280
            //initialize
281
            monitor.subTask("Initialize");
282
            initializeDtos(localDtos, item, monitor, 83);  //is calling updateView itself; sum = 95
283
            if(monitor.isCanceled()) {
284
                return Status.CANCEL_STATUS;
285
            }
286
            monitor.worked(2);  //sum = 100 (just in case)
287
            monitor.done();
290 288

  
291
		};
292
		currentJob.setUser(true);
289
            return Status.OK_STATUS;
290
        }
291
	}
293 292

  
293
	private synchronized void updateToNewItem(final ItemDto item) {
294
		if (currentJob != null){
295
		    currentJob.cancel();
296
		}
297
		Job newJob = new UpdateRefObjectsJob("Update Referencing Objects for " + item.bestLabel(), item);
298
		newJob.setUser(true);
299
		actualUuid = item.itemUuid;
300
		currentJob = newJob;
294 301
		currentJob.schedule();
295 302
	}
296 303

  
297
    private List<ReferencingObjectDto> sortToList(Set<ReferencingObjectDto> referencingObjectsSet, IProgressMonitor monitor) {
304
    private List<ReferencingObjectDto> sortToList(Set<ReferencingObjectDto> referencingObjectsSet) {
298 305
        List<ReferencingObjectDto> result = new ArrayList<>(referencingObjectsSet);
299
        //TODO make singleton
300
        Collections.sort(result, new RefObjectDtoComparator());
306
        Collections.sort(result, COMPARATOR);
301 307
        return result;
302 308
    }
303 309

  
304
    protected boolean initializeDtos(List<ReferencingObjectDto> localDtos, IProgressMonitor monitor, int work) {
310
    protected boolean initializeDtos(List<ReferencingObjectDto> localDtos, ItemDto item, IProgressMonitor monitor, int work) {
311

  
305 312
        IProgressMonitor subMonitor = AbstractUtility.getSubProgressMonitor(monitor, work);
306 313
        subMonitor.beginTask("Initialize DTOs", localDtos.size());
307

  
308 314
        int i = 100 - 20;  //the first run should only include 20 records
315
        int initCount = 0;
309 316

  
310 317
        Set<ReferencingObjectDto> toInitialize = new HashSet<>();
311 318
        for (ReferencingObjectDto dto : localDtos){
319
            initCount++;
312 320
            toInitialize.add(dto);
313

  
314
//            dto.setTitleCache(ReferencingObjectFormatter.format(dto.getReferencedEntity(), CdmStore.getDefaultLanguage() ));
315
            if (monitor.isCanceled()){
316
                return false;
317
            }
318 321
            subMonitor.worked(1);
319 322
            if (++i == 100){
320
                initBulk(toInitialize);
321
                updateView();
323
                if (monitor.isCanceled()){
324
                    return false;
325
                }
326
                initBulk(toInitialize, initCount, localDtos, item);
327
                //reset
322 328
                toInitialize = new HashSet<>();
323 329
                i = 0;
324 330
            }
325 331
        }
326
        initBulk(toInitialize);
332
        //final bulk
333
        if (monitor.isCanceled()){
334
            return false;
335
        }
336
        initBulk(toInitialize, initCount, localDtos, item);
327 337
        return true;
328 338
    }
329 339

  
330
    private void initBulk(Set<ReferencingObjectDto> toInitialize) {
340
    private void initBulk(Set<ReferencingObjectDto> toInitialize, int initCount,
341
            List<ReferencingObjectDto> localDtos, ItemDto item) {
331 342
        Set<ReferencingObjectDto> initialized = CdmStore.getCommonService().initializeReferencingObjectDtos(toInitialize, true, true, true, CdmStore.getDefaultLanguage());
332 343
        Map<UUID,ReferencingObjectDto> map = new HashMap<>();
333 344
        initialized.forEach(i->map.put(i.getUuid(), i));
334
        toInitialize.forEach(dto->merge(dto, map.get(dto.getUuid())));
335
        updateView();
336

  
345
        toInitialize.forEach(dto->mergeInitializedData(dto, map.get(dto.getUuid())));
346
        String initStr = initCount < localDtos.size()? initCount + "/" + localDtos.size() + " items": "Items";
347
        updateView(initStr + " for " + item.bestLabel(), localDtos, item.itemUuid);
337 348
    }
338 349

  
339
    private void merge(ReferencingObjectDto to, ReferencingObjectDto from) {
350
    private void mergeInitializedData(ReferencingObjectDto to, ReferencingObjectDto from) {
340 351
        to.setTitleCache(from.getTitleCache());
341 352
        to.setOpenInTarget(from.getOpenInTarget());
342 353
        to.setReferencedEntity(from.getReferencedEntity());
......
384 395
            else if(CdmBase.class.isAssignableFrom(objectClass)){
385 396
                referencedObject = CdmStore.getCommonService().find(objectClass, entity);
386 397
            }
387
	        	//referencedObject =(CdmBase) CdmStore.getService(IIdentifiableEntityService.class).load(referencedObject.getUuid());
388 398
        	Set<ReferencingObjectDto> setOfReferencingObjects = null;
389 399

  
390 400
        	if (referencedObject != null){
391
//        	    if(referencedObject.isInstanceOf(IdentifiableEntity.class)){
392
//        	        referencedObjectTitleCache = (HibernateProxyHelper.deproxy(referencedObject, IdentifiableEntity.class)).getTitleCache();
393
//        	    }
394
//        	    else if(referencedObject.isInstanceOf(DescriptionElementBase.class)){
395
//        	        referencedObjectTitleCache = DescriptionHelper.getLabel(referencedObject);
396
//        	    }
397
//        	    else if (referencedObject.isInstanceOf(User.class)){
398
//        	        referencedObjectTitleCache = ((User)referencedObject).getUsername();
399
//        	    }else{
400
//        	        referencedObjectTitleCache = DescriptionHelper.getLabel(referencedObject);
401
//        	    }
402 401
        		setOfReferencingObjects = CdmStore.getCommonService().getReferencingObjectDtos(referencedObject);
403 402
        		return setOfReferencingObjects;
404 403
        	}
......
411 410
		return null;
412 411
	}
413 412

  
414
	class RefObjectDtoComparator implements Comparator<ReferencingObjectDto>{
413
	/**
414
	 * Compares the referencing object by type and id. Using "description" for
415
	 * comparation has been given up to avoid initialization before comparison.
416
	 */
417
	static class RefObjectDtoComparator implements Comparator<ReferencingObjectDto>{
415 418

  
416 419
        @Override
417 420
        public int compare(ReferencingObjectDto dto1, ReferencingObjectDto dto2) {
......
423 426
        }
424 427
	}
425 428

  
426
	private void updateView() {
427
	    Display.getDefault().asyncExec(()->{
428
	        if (viewer != null && !viewer.getControl().isDisposed()){
429
                try{
430
                    viewer.setInput(referencingObjects);
431
                    viewer.refresh();
432

  
433
                    //enable/disable table
434
                    viewer.getControl().setEnabled(referencingObjects!=null);
435
                }catch(Exception e){
436
                    e.printStackTrace();
437
                    logger.debug(e.getStackTrace());
438
                    updateDescriptionLabel("The referencing objects view could not be updated completely. Some Problems occurred: " + e.getMessage());
439
                }
440
            }
441
	    });
429
	//not sure if it needs to be synchronized, only the local variable actualUuid is read
430
	private void updateView(final String label,
431
	        final List<ReferencingObjectDto> referencingObjects, UUID itemUuid) {
432

  
433
	    if (this.actualUuid == itemUuid){
434
	        Display.getDefault().asyncExec(()->{
435
	            if (contentDescription != null && !contentDescription.isDisposed()){
436
	                contentDescription.setText(label);
437
	            }
438
	            if (viewer != null && !viewer.getControl().isDisposed()){
439
	                try{
440
	                    viewer.setInput(referencingObjects);
441
	                    viewer.refresh();
442

  
443
	                    //enable/disable table
444
	                    viewer.getControl().setEnabled(referencingObjects!=null);
445
	                }catch(Exception e){
446
	                    e.printStackTrace();
447
	                    logger.debug(e.getStackTrace());
448
	                    updateDescriptionLabel("The referencing objects view could not be updated completely. Some Problems occurred: " + e.getMessage());
449
	                }
450
	            }
451
	        });
452
	    }
442 453
	}
443 454

  
444 455

  
......
451 462
         );
452 463
	 }
453 464

  
465
    @Override
466
    protected boolean showEmptyIfNoActiveEditor(){
467
        return false;
468
    }
469

  
454 470
    @Override
455 471
    public void selectionChanged_internal(Object selection, MPart activePart, MPart thisPart) {
456 472
        if(activePart==thisPart){
......
459 475

  
460 476
        IStructuredSelection structuredSelection = createSelection(selection);
461 477
        if(structuredSelection!=null){
462
        	//referencedObjectTitleCache = null;
463 478
        	showViewer(structuredSelection, activePart, viewer);
464 479
        }
465 480
	}
466 481

  
467 482
	@Override
468 483
	public void showViewer(IStructuredSelection selection, MPart activePart, Viewer viewer){
469
	//	this.part = part;
470

  
471
		Object firstElement = selection.getFirstElement();
472
		if (firstElement instanceof TermDto){
473
		   TermDto termDto = (TermDto) firstElement;
474
		   description = "'"+termDto.getRepresentation_L10n() + "' is referenced by:";
475
		   updateDescriptionLabel(description);
476
		   updateReferencingObjects(termDto.getUuid(), TermBase.class );
477
		   return;
478
		}
479
		if(firstElement instanceof TreeNode){
480
		    firstElement = ((TreeNode) firstElement).getValue();
481
		}
482
		if (firstElement instanceof TaxonNode && !((TaxonNode)firstElement).hasTaxon()){
483
			firstElement = ((TaxonNode)firstElement).getClassification();
484
	    handleNewSelection(selection.getFirstElement());
485
	}
486

  
487
	//Note AM: this can probably be done better together with base class methods
488
	//         As I am not so familiar with this structure I only adapt it this way to be on the safe side
489
	@Override
490
    public void handleNewSelection(Object firstElement){
491
        ItemDto dto = makeItemDto(firstElement);
492
		if (dto.itemUuid == null || dto.itemClass == null || dto.itemUuid.equals(this.actualUuid)){
493
		    return;
484 494
		}
485
		if(firstElement instanceof CdmBase){
486
		    firstElement= CdmBase.deproxy(firstElement, CdmBase.class);
487
		    CdmBase referencedCdmObject = (CdmBase)firstElement;
488
		    if (referencedCdmObject.getUuid() == actualUuid){
489
		        return;
490
		    }
491
		    String referencedObjectTitleCache = null;
492
	        if(referencedCdmObject.isInstanceOf(IdentifiableEntity.class)){
493
                referencedObjectTitleCache = (HibernateProxyHelper.deproxy(referencedCdmObject, IdentifiableEntity.class)).getTitleCache();
495
		updateToNewItem(dto);
496
	}
497

  
498
    /**
499
     * Transforms the selection into uniform format (ItemDto).
500
     * This method must be fast / should never require a server call
501
     * as it takes place before the update Job is started and therefore is not
502
     * asynchronous.
503
     */
504
    public ItemDto makeItemDto(Object firstElement) {
505

  
506
        ItemDto dto = new ItemDto();
507
        if(firstElement instanceof TreeNode){
508
            firstElement = ((TreeNode) firstElement).getValue();
509
        }
510
        if (firstElement instanceof TaxonNode && !((TaxonNode)firstElement).hasTaxon()){
511
            firstElement = ((TaxonNode)firstElement).getClassification();
512
        }
513

  
514
        if (firstElement instanceof AbstractTermDto){
515
           AbstractTermDto termDto = (AbstractTermDto) firstElement;
516
           dto.itemLabel = termDto.getTitleCache();
517
           dto.itemUuid= termDto.getUuid();
518
           dto.typeName = termDto.getTermType().getLabel();
519
           dto.itemId = null;   // id does not yet exist in TermDto
520
           if (termDto instanceof TermDto){
521
               dto.itemClass = TermBase.class;
522
           }else if(termDto instanceof TermTreeDto){
523
               dto.itemClass = TermTree.class;
524
               dto.typeName = dto.typeName + " Tree";
525
           }else if(termDto instanceof TermVocabularyDto){
526
               dto.itemClass = TermVocabulary.class;
527
               dto.typeName = dto.typeName + " Vocabulary";
528
           }else{
529
               //make it an unhandled selection
530
               dto.itemUuid = null;
531
           }
532
        }else if (firstElement instanceof TermNodeDto){
533
            TermNodeDto termNodeDto = (TermNodeDto) firstElement;
534
            dto.itemLabel = (termNodeDto.getTerm() != null? termNodeDto.getTerm().getTitleCache() : termNodeDto.getTreeIndex());
535
            dto.itemUuid= termNodeDto.getUuid();
536
            dto.typeName = termNodeDto.getType().getLabel() + " Node";
537
            dto.itemId = null;  //does not yet exist in TermDto
538
            dto.itemClass = TermNode.class;
539
        }else if(firstElement instanceof CdmBase){
540
		    CdmBase cdmBase = CdmBase.deproxy(firstElement, CdmBase.class);
541
		    String label = null;
542
	        if(cdmBase instanceof IdentifiableEntity){
543
                label = (HibernateProxyHelper.deproxy(cdmBase, IdentifiableEntity.class)).getTitleCache();
494 544
            }
495
            else if(referencedCdmObject.isInstanceOf(DescriptionElementBase.class)){
496
                referencedObjectTitleCache = DescriptionHelper.getLabel(referencedCdmObject);
545
            else if(cdmBase instanceof DescriptionElementBase){
546
                label = DescriptionHelper.getLabel(cdmBase);
497 547
            }
498
            else if (referencedCdmObject.isInstanceOf(User.class)){
499
                referencedObjectTitleCache = ((User)referencedCdmObject).getUsername();
500
            }else if (referencedCdmObject.isInstanceOf(TaxonNode.class)){
501
                referencedObjectTitleCache = "TaxonNode of "+(HibernateProxyHelper.deproxy(referencedCdmObject, TaxonNode.class)).getTaxon().getTitleCache();
548
            else if (cdmBase instanceof User){
549
                label = ((User)cdmBase).getUsername();
550
            }else if (cdmBase instanceof TaxonNode){
551
                label = ((TaxonNode)cdmBase).getTaxon().getTitleCache();
502 552
            }
503
	        if (CdmUtils.isBlank(referencedObjectTitleCache)){
504
	            referencedObjectTitleCache = "#"+referencedCdmObject.getId();
553
	        if (CdmUtils.isBlank(label)){
554
	            label = "#"+cdmBase.getId();
505 555
	        }
506
	        description = referencedCdmObject.getUserFriendlyTypeName() + " '" + referencedObjectTitleCache + "' is referenced by:";
507
	        updateDescriptionLabel(description);
508

  
509
		    updateReferencingObjects(referencedCdmObject.getUuid(),firstElement.getClass() );
510

  
556
	        dto.typeName = cdmBase.getUserFriendlyTypeName();
557
	        dto.itemLabel = label;
558
	        dto.itemUuid= cdmBase.getUuid();
559
	        dto.itemClass = cdmBase.getClass();
560
	        dto.itemId = cdmBase.getId();
511 561
		}else if  (firstElement instanceof UuidAndTitleCache<?>){
512
		    UuidAndTitleCache<?> element = (UuidAndTitleCache<?>) firstElement;
513
		    description = element.getType().getSimpleName() + " '" + element.getTitleCache() + "' is referenced by:";
514
	        updateDescriptionLabel(description);
515
            updateReferencingObjects(element.getUuid(),element.getType());
516
		}
517
		else if (firstElement != null){
518
		    updateView();
519
            description = "undefined:";
520
		    updateDescriptionLabel(description);
562
		    UuidAndTitleCache<? extends CdmBase> element = (UuidAndTitleCache<? extends CdmBase>) firstElement;
563
		    dto.typeName = CdmUtils.userFriendlyClassName(element.getType());
564
		    dto.itemLabel = element.getTitleCache();
565
            if (CdmUtils.isBlank(dto.itemLabel)){
566
                dto.itemLabel = "id=" + element.getId();
567
            }
568
            dto.itemUuid= element.getUuid();
569
            dto.itemClass = element.getType();
570
            dto.itemId = element.getId();
571
		}else if (firstElement instanceof String){
572
            dto.typeName = "String";
573
            dto.itemLabel = firstElement.toString();
574
            dto.itemUuid= null;
575
            dto.itemClass = null;
576
            dto.itemId = null;
577
		}else if (firstElement != null){
578
		    dto.typeName = CdmUtils.userFriendlyClassName(firstElement.getClass());
579
		    dto.itemLabel = firstElement.toString();
580
		    dto.itemUuid= null;
581
		    dto.itemClass = null;
582
		    dto.itemId = null;
583
		}else{
584
		    dto.typeName = null;
585
		    dto.itemLabel = "no selection";
586
		    dto.itemUuid= null;
587
		    dto.itemClass = null;
588
		    dto.itemId = null;
521 589
		}
522
	}
590
        return dto;
591
    }
523 592

  
524 593
	@PreDestroy
525 594
	public void dispose() {
526
	    if(conversation!=null){
527
	        conversation.close();
528
	        conversation = null;
529
	    }
595
	    //no conversation in this view
530 596
	}
531 597

  
532 598
	@Override
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/EditorUtil.java
35 35
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
36 36
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
37 37
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
38
import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
38 39
import eu.etaxonomy.cdm.model.taxon.Synonym;
39 40
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
40 41
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
41 42
import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
43
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
42 44
import eu.etaxonomy.taxeditor.bulkeditor.e4.BulkEditorE4;
43 45
import eu.etaxonomy.taxeditor.bulkeditor.input.TaxonEditorInput;
44 46
import eu.etaxonomy.taxeditor.editor.descriptiveDataSet.DescriptiveDataSetEditor;
......
103 105
        editor.init(descriptiveDataSetUuid, true);
104 106
    }
105 107

  
106
    public static void openDistributionEditor(List<TaxonNodeDto> parentTaxonUuidList, EModelService modelService, EPartService partService, MApplication application){
108
    public static void openDistributionEditor(List<UuidAndTitleCache<ITaxonTreeNode>> parentTaxonUuidList, EModelService modelService, EPartService partService, MApplication application){
107 109
        String partId = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_CHECKLIST_E4_DISTRIBUTIONEDITORPART;
108 110
        checkAndCloseFactsAndMediaParts(partService);
109 111
        MPart part = showPart(partId, modelService, partService, application);
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/view/checklist/e4/DistributionEditorPart.java
44 44
import eu.etaxonomy.cdm.compare.taxon.TaxonNodeSortMode;
45 45
import eu.etaxonomy.cdm.model.description.DescriptionBase;
46 46
import eu.etaxonomy.cdm.model.description.TaxonDescription;
47
import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
47 48
import eu.etaxonomy.cdm.model.taxon.Taxon;
48 49
import eu.etaxonomy.cdm.persistence.dto.MergeResult;
49
import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
50
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
50 51
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
51 52
import eu.etaxonomy.taxeditor.editor.EditorUtil;
52 53
import eu.etaxonomy.taxeditor.editor.IDistributionEditorPart;
......
126 127
        ContextInjectionFactory.inject(editor, context);
127 128
    }
128 129

  
129
    public void init(List<TaxonNodeDto> uuidAndTitleCaches) {
130
    public void init(List<UuidAndTitleCache<ITaxonTreeNode>> uuidAndTitleCaches) {
130 131

  
131 132
        List<UUID> nodeUuids = new ArrayList<>();
132 133
        uuidAndTitleCaches.forEach(element -> nodeUuids.add(element.getUuid()));
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/view/checklist/e4/handler/OpenChecklistEditorHandlerE4.java
19 19
import org.eclipse.e4.ui.workbench.modeling.EPartService;
20 20
import org.eclipse.swt.widgets.Shell;
21 21

  
22
import eu.etaxonomy.cdm.api.service.IClassificationService;
22 23
import eu.etaxonomy.cdm.model.description.Distribution;
23 24
import eu.etaxonomy.cdm.model.metadata.PreferencePredicate;
24 25
import eu.etaxonomy.cdm.model.permission.Operation;
26
import eu.etaxonomy.cdm.model.taxon.Classification;
25 27
import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
26 28
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
27
import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
29
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
28 30
import eu.etaxonomy.taxeditor.editor.AppModelId;
29 31
import eu.etaxonomy.taxeditor.editor.EditorUtil;
30 32
import eu.etaxonomy.taxeditor.handler.defaultHandler.e4.DefaultOpenSetBaseHandler;
31 33
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
32 34
import eu.etaxonomy.taxeditor.security.RequiredPermissions;
33 35
import eu.etaxonomy.taxeditor.store.CdmStore;
36
import eu.etaxonomy.taxeditor.view.DtoWithEntity;
34 37

  
35 38
/**
36 39
 * Handler to open the distribution editor via context menu
37 40
 */
38
public class OpenChecklistEditorHandlerE4 extends DefaultOpenSetBaseHandler<ITaxonTreeNode, TaxonNodeDto> {
41
public class OpenChecklistEditorHandlerE4 extends DefaultOpenSetBaseHandler<ITaxonTreeNode, UuidAndTitleCache<ITaxonTreeNode>> {
39 42

  
40 43
	@Override
41
    protected void open(List<TaxonNodeDto> entities, Shell shell, EPartService partService) {
44
    protected void open(List<UuidAndTitleCache<ITaxonTreeNode>> entities, Shell shell, EPartService partService) {
45
	    replaceClassificationsByRootNode(entities);
42 46
	    EditorUtil.openDistributionEditor(entities, modelService, partService, application);
43 47
	}
44 48

  
49
    public void replaceClassificationsByRootNode(List<UuidAndTitleCache<ITaxonTreeNode>> entities) {
50
        for (UuidAndTitleCache<ITaxonTreeNode> entity : entities){
51
	        if (Classification.class.isAssignableFrom(entity.getType())){
52
	            Classification c = CdmStore.getService(IClassificationService.class).find(entity.getUuid());
53
	            DtoWithEntity<ITaxonTreeNode> dto = new DtoWithEntity<ITaxonTreeNode>(c.getRootNode());
54
	            entities.set(entities.indexOf(entity),dto);
55
	        }
56
	    }
57
    }
58

  
45 59
    @CanExecute
46 60
    @Override
47 61
    public boolean canExecute(MHandledMenuItem menuItem,
......
80 94
    }
81 95

  
82 96
    @Override
83
    protected boolean canExecute(TaxonNodeDto entity) {
97
    protected boolean canExecute(UuidAndTitleCache<ITaxonTreeNode> entity) {
84 98
        //FIXME DTO
85 99
        return true;
86 100
    }
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/editor/IReferencingObjectsView.java
8 8
*/
9 9
package eu.etaxonomy.taxeditor.editor;
10 10

  
11
import java.util.UUID;
12

  
13 11
/**
14 12
 * @author k.luther
15 13
 * @since Mar 12, 2020
16 14
 */
17 15
public interface IReferencingObjectsView {
18 16

  
19
    public void updateReferencingObjects(final UUID entityUUID, final Class objectClass);
17
    public void handleNewSelection(Object firstElement);
20 18

  
21 19
}
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/handler/defaultHandler/OpenReferencingObjectsViewHandler.java
31 31

  
32 32
        if (selectedObjectList != null && !selectedObjectList.isEmpty()) {
33 33
            UuidAndTitleCache<? extends ICdmBase> dto = selectedObjectList.get(0);
34
            view.updateReferencingObjects(dto.getUuid(), dto.getType());
34
            view.handleNewSelection(dto);
35 35
        }
36 36
    }
37 37

  
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/view/e4/AbstractCdmEditorPartE4.java
133 133

  
134 134
    protected abstract void selectionChanged_internal(Object selection, MPart activePart, MPart thisPart);
135 135

  
136
    protected boolean showEmptyIfNoActiveEditor(){
137
        return true;
138
    }
139

  
136 140
    @Inject
137 141
    public void selectionChanged(
138 142
            @Optional@Named(IServiceConstants.ACTIVE_SELECTION)Object selection,
......
148 152
            return;
149 153
        }
150 154
        // no active editor found
151
        if(activePart==thisPart && WorkbenchUtility.getActiveEditorPart(partService)==null){
155
        if(activePart==thisPart && WorkbenchUtility.getActiveEditorPart(partService)==null && showEmptyIfNoActiveEditor()){
152 156
            showEmptyPage();
153 157
            return;
154 158
        }

Also available in: Unified diff