ref #8890: handle dynamic menu for ref objects view and taxonnode wizard correctly
[taxeditor.git] / eu.etaxonomy.taxeditor.bulkeditor / src / main / java / eu / etaxonomy / taxeditor / bulkeditor / referencingobjects / e4 / ReferencingObjectsViewE4.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
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.
8 */
9
10 package eu.etaxonomy.taxeditor.bulkeditor.referencingobjects.e4;
11
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.Comparator;
15 import java.util.List;
16 import java.util.Set;
17 import java.util.UUID;
18
19 import javax.annotation.PostConstruct;
20 import javax.annotation.PreDestroy;
21
22 import org.apache.log4j.Logger;
23 import org.eclipse.core.runtime.IProgressMonitor;
24 import org.eclipse.core.runtime.IStatus;
25 import org.eclipse.core.runtime.Status;
26 import org.eclipse.core.runtime.jobs.Job;
27 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
28 import org.eclipse.e4.ui.services.EMenuService;
29 import org.eclipse.jface.viewers.CellEditor;
30 import org.eclipse.jface.viewers.ICellModifier;
31 import org.eclipse.jface.viewers.IStructuredSelection;
32 import org.eclipse.jface.viewers.ITableLabelProvider;
33 import org.eclipse.jface.viewers.TableViewer;
34 import org.eclipse.jface.viewers.TableViewerColumn;
35 import org.eclipse.jface.viewers.TextCellEditor;
36 import org.eclipse.jface.viewers.TreeNode;
37 import org.eclipse.jface.viewers.Viewer;
38 import org.eclipse.swt.SWT;
39 import org.eclipse.swt.layout.GridData;
40 import org.eclipse.swt.layout.GridLayout;
41 import org.eclipse.swt.widgets.Composite;
42 import org.eclipse.swt.widgets.Display;
43 import org.eclipse.swt.widgets.Label;
44 import org.eclipse.swt.widgets.Table;
45 import org.springframework.remoting.RemoteAccessException;
46
47 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
48 import eu.etaxonomy.cdm.api.service.IAgentService;
49 import eu.etaxonomy.cdm.api.service.IDescriptionService;
50 import eu.etaxonomy.cdm.api.service.IEventBaseService;
51 import eu.etaxonomy.cdm.api.service.IGroupService;
52 import eu.etaxonomy.cdm.api.service.IMediaService;
53 import eu.etaxonomy.cdm.api.service.INameService;
54 import eu.etaxonomy.cdm.api.service.IOccurrenceService;
55 import eu.etaxonomy.cdm.api.service.IPolytomousKeyNodeService;
56 import eu.etaxonomy.cdm.api.service.IPolytomousKeyService;
57 import eu.etaxonomy.cdm.api.service.IReferenceService;
58 import eu.etaxonomy.cdm.api.service.ITaxonService;
59 import eu.etaxonomy.cdm.api.service.ITermService;
60 import eu.etaxonomy.cdm.api.service.IUserService;
61 import eu.etaxonomy.cdm.api.service.molecular.ISequenceService;
62 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
63 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
64 import eu.etaxonomy.cdm.model.common.CdmBase;
65 import eu.etaxonomy.cdm.model.common.EventBase;
66 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
67 import eu.etaxonomy.cdm.model.description.DescriptionBase;
68 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
69 import eu.etaxonomy.cdm.model.description.PolytomousKey;
70 import eu.etaxonomy.cdm.model.description.PolytomousKeyNode;
71 import eu.etaxonomy.cdm.model.media.Media;
72 import eu.etaxonomy.cdm.model.molecular.Sequence;
73 import eu.etaxonomy.cdm.model.name.TaxonName;
74 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
75 import eu.etaxonomy.cdm.model.permission.Group;
76 import eu.etaxonomy.cdm.model.permission.User;
77 import eu.etaxonomy.cdm.model.reference.Reference;
78 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
79 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
80 import eu.etaxonomy.cdm.model.term.DefinedTermBase;
81 import eu.etaxonomy.cdm.model.term.TermBase;
82 import eu.etaxonomy.cdm.persistence.dto.TermDto;
83 import eu.etaxonomy.taxeditor.bulkeditor.referencingobjects.ReferencingObjectsContentProvider;
84 import eu.etaxonomy.taxeditor.bulkeditor.referencingobjects.ReferencingObjectsLabelProvider;
85 import eu.etaxonomy.taxeditor.editor.IReferencingObjectsView;
86 import eu.etaxonomy.taxeditor.model.AbstractUtility;
87 import eu.etaxonomy.taxeditor.model.DescriptionHelper;
88 import eu.etaxonomy.taxeditor.store.CdmStore;
89 import eu.etaxonomy.taxeditor.view.e4.AbstractCdmEditorPartE4;
90
91 /**
92 *
93 * @author pplitzner
94 * @since Aug 16, 2017
95 *
96 */
97 public class ReferencingObjectsViewE4 extends AbstractCdmEditorPartE4 implements IReferencingObjectsView{
98
99 private static final Logger logger = Logger
100 .getLogger(ReferencingObjectsViewE4.class);
101
102 private Label contentDescription;
103
104 private String referencedObjectTitleCache;
105 private ConversationHolder conversation;
106 private UUID actualUuid;
107 List<CdmBase> referencingObjects = null;
108 Set<CdmBase> referencingObjectsSet = null;
109 IProgressMonitor actualMonitor = null;
110 private Job currentJob = null;
111
112 @PostConstruct
113 public void create(Composite parent, EMenuService menuService) {
114 if (CdmStore.isActive()){
115 if(conversation == null){
116 conversation = CdmStore.createConversation();
117 }
118 }
119 else{
120 return;
121 }
122 parent.setLayout(new GridLayout());
123 contentDescription = new Label(parent, SWT.NONE);
124 contentDescription.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
125 TableViewer tableViewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
126 | SWT.V_SCROLL | SWT.FULL_SELECTION);
127 createColumns(tableViewer);
128 tableViewer.setContentProvider(new ReferencingObjectsContentProvider());
129 tableViewer.setLabelProvider(new ReferencingObjectsLabelProvider());
130 tableViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
131
132 tableViewer.setCellModifier(new ICellModifier() {
133 @Override
134 public void modify(Object element, String property, Object value) {
135 }
136
137 @Override
138 public Object getValue(Object element, String property) {
139 ITableLabelProvider tableLabelProvider = null;
140 if(tableViewer.getLabelProvider() instanceof ITableLabelProvider){
141 tableLabelProvider = (ITableLabelProvider) tableViewer.getLabelProvider();
142 }
143 Object[] columnProperties = tableViewer.getColumnProperties();
144 for (int i=0;i<columnProperties.length;i++) {
145 if(columnProperties[i].equals(property) && tableLabelProvider!=null){
146 return tableLabelProvider.getColumnText(element, i);
147 }
148 }
149 return "";
150 }
151
152 @Override
153 public boolean canModify(Object element, String property) {
154 return true;
155 }
156 });
157
158 viewer = tableViewer;
159
160 // Propagate selection from viewer
161 selectionChangedListener = (event -> selService.setSelection(AbstractUtility.getElementsFromSelectionChangedEvent(event)));
162 viewer.addSelectionChangedListener(selectionChangedListener);
163
164 //create context menu
165 menuService.registerContextMenu(viewer.getControl(), "eu.etaxonomy.taxeditor.bulkeditor.popupmenu.referencingobjectsview");
166
167 }
168
169 /**
170 * Create the columns for the table
171 * @param viewer
172 */
173 private void createColumns(TableViewer viewer) {
174 Table table = viewer.getTable();
175 String[] titles = {"Class", "Description", "UUID", "Object ID" };
176 int[] bounds = { 100, 200, 100, 70};
177
178 CellEditor[] editors = new CellEditor[titles.length];
179
180 for (int i = 0; i < titles.length; i++) {
181 TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
182 editors[i] = new TextCellEditor(table);
183 column.getColumn().setText(titles[i]);
184 column.getColumn().setWidth(bounds[i]);
185 column.getColumn().setResizable(true);
186 column.getColumn().setMoveable(true);
187 }
188 table.setHeaderVisible(true);
189 table.setLinesVisible(true);
190
191 viewer.setCellEditors(editors);
192 viewer.setColumnProperties(titles);
193 }
194
195 @Override
196 public void updateReferencingObjects(final UUID entityUUID, final Class objectClass) {
197 if (actualUuid == entityUUID){
198 return ;
199 }
200
201 if(actualMonitor!=null && !actualMonitor.isCanceled()){
202 while(!actualMonitor.isCanceled()){
203 actualMonitor.setCanceled(true);
204 }
205
206 }
207 currentJob = new Job("Update Referencing Objects") {
208
209 @Override
210 protected IStatus run(final IProgressMonitor monitor) {
211 monitor.beginTask("Calculating referencing objects", 100);
212 actualUuid = entityUUID;
213
214 monitor.worked(5);
215 referencingObjects = new ArrayList<>();
216 if(monitor.isCanceled()) {
217 actualUuid = null;
218 return Status.CANCEL_STATUS;
219 }
220 if (actualMonitor != null){
221 actualMonitor.setCanceled(true);
222
223 }
224 actualMonitor = monitor;
225 if (entityUUID != null){
226 referencingObjectsSet = getReferencingObjects(entityUUID, objectClass);
227
228 if(monitor.isCanceled()) {
229 actualUuid = null;
230
231 return Status.CANCEL_STATUS;
232 }
233 monitor.worked(30);
234 referencingObjects = sortReferencing();
235 if (referencingObjects == null){
236 if (monitor.isCanceled()){
237 actualUuid = null;
238
239 return Status.CANCEL_STATUS;
240 }
241 }
242
243 if(monitor.isCanceled()) {
244 return Status.CANCEL_STATUS;
245 }
246 monitor.worked(80);
247
248 updateView();
249 }
250 monitor.done();
251 actualMonitor = null;
252
253 return Status.OK_STATUS;
254
255
256 }
257 };
258 currentJob.setUser(true);
259
260 currentJob.schedule();
261 }
262
263 private Set<CdmBase> getReferencingObjects(UUID entity, Class objectClass) {
264 CdmBase referencedObject = null;
265 try {
266 if (objectClass.getSuperclass().equals(TeamOrPersonBase.class) ){
267 referencedObject = CdmStore.getService(IAgentService.class).load(entity);
268 } else if (objectClass.getSuperclass().equals(TaxonName.class)){
269 referencedObject = CdmStore.getService(INameService.class).load(entity);
270 } else if (objectClass.getSuperclass().equals(TaxonBase.class)){
271 referencedObject = CdmStore.getService(ITaxonService.class).load(entity);
272 } else if (objectClass.equals(Reference.class)){
273 referencedObject = CdmStore.getService(IReferenceService.class).load(entity);
274 } else if (objectClass.getSuperclass().equals(SpecimenOrObservationBase.class)){
275 referencedObject = CdmStore.getService(IOccurrenceService.class).load(entity);
276 } else if (objectClass.isAssignableFrom(User.class)){
277 referencedObject = CdmStore.getService(IUserService.class).load(entity);
278 } else if (objectClass.isAssignableFrom(Group.class)){
279 referencedObject = CdmStore.getService(IGroupService.class).load(entity);
280 } else if (objectClass.isAssignableFrom(Media.class)){
281 referencedObject = CdmStore.getService(IMediaService.class).load(entity);
282 } else if (DescriptionBase.class.isAssignableFrom(objectClass)){
283 referencedObject = CdmStore.getService(IDescriptionService.class).load(entity);
284 } else if (DescriptionElementBase.class.isAssignableFrom(objectClass)){
285 referencedObject = CdmStore.getService(IDescriptionService.class).loadDescriptionElement(entity, null);
286 } else if (objectClass.equals(Sequence.class)){
287 referencedObject = CdmStore.getService(ISequenceService.class).load(entity, null);
288 } else if (PolytomousKey.class.isAssignableFrom(objectClass)){
289 referencedObject = CdmStore.getService(IPolytomousKeyService.class).load(entity, null);
290 } else if (PolytomousKeyNode.class.isAssignableFrom(objectClass)){
291 referencedObject = CdmStore.getService(IPolytomousKeyNodeService.class).load(entity, null);
292 } else if (DefinedTermBase.class.isAssignableFrom(objectClass)){
293 referencedObject = CdmStore.getService(ITermService.class).load(entity, null);
294 } else if (EventBase.class.isAssignableFrom(objectClass)){
295 referencedObject = CdmStore.getService(IEventBaseService.class).load(entity, null);
296 } else if (User.class.isAssignableFrom(objectClass)){
297 referencedObject = CdmStore.getService(IUserService.class).load(entity, null);
298 } else if (Group.class.isAssignableFrom(objectClass)){
299 referencedObject = CdmStore.getService(IGroupService.class).load(entity, null);
300 }
301 else if(CdmBase.class.isAssignableFrom(objectClass)){
302 referencedObject = CdmStore.getCommonService().find(objectClass, entity);
303 }
304 //referencedObject =(CdmBase) CdmStore.getService(IIdentifiableEntityService.class).load(referencedObject.getUuid());
305 Set<CdmBase> setOfReferencingObjects = null;
306
307 if (referencedObject != null){
308 if(referencedObject.isInstanceOf(IdentifiableEntity.class)){
309 referencedObjectTitleCache = (HibernateProxyHelper.deproxy(referencedObject, IdentifiableEntity.class)).getTitleCache();
310 }
311 else if(referencedObject.isInstanceOf(DescriptionElementBase.class)){
312 referencedObjectTitleCache = DescriptionHelper.getLabel(referencedObject);
313 }
314 else if (referencedObject.isInstanceOf(User.class)){
315 referencedObjectTitleCache = ((User)referencedObject).getUsername();
316 }else{
317 referencedObjectTitleCache = null;
318 }
319 setOfReferencingObjects = CdmStore.getCommonService().getReferencingObjects(referencedObject);
320 return setOfReferencingObjects;
321 }
322
323 } catch (Exception e) {
324 logger.debug("Error retrieving referencing objects", e);
325 e.printStackTrace();
326 updateDescription("The referencing objects view could not be loaded completely. Some Problems occurred.");
327 }
328 return null;
329 }
330
331 private List<CdmBase> sortReferencing(){
332
333 if (referencingObjectsSet != null){
334 List<CdmBase> referencingObjects = new ArrayList<CdmBase>(referencingObjectsSet);
335 try{
336 Collections.sort(referencingObjects, new ReferencingClassComparator());
337 }catch (RemoteAccessException e){
338 logger.debug(e.getStackTrace());
339 return null;
340 }
341 return referencingObjects;
342
343 }
344
345 return null;
346 }
347
348 class ReferencingClassComparator implements Comparator<CdmBase> {
349
350 @Override
351 public int compare(CdmBase o1, CdmBase o2) {
352 String string1 = o1.getClass().getSimpleName();
353 String string2 = o2.getClass().getSimpleName();
354 int result = string1.compareToIgnoreCase(string2);
355 if (result == 0) {
356 string1 = DescriptionHelper.getObjectDescription(o1);
357 string2 = DescriptionHelper.getObjectDescription(o2);
358
359 result = string1.compareToIgnoreCase(string2);
360 if (result == 0){
361 return o1.getUuid().compareTo(o2.getUuid());
362 }
363 }
364 return result;
365 }
366 }
367
368 private void updateView() {
369 Display.getDefault().asyncExec(new Runnable() {
370 @Override
371 public void run() {
372
373 if (viewer != null && !viewer.getControl().isDisposed()){
374 try{
375 viewer.setInput(referencingObjects);
376
377 viewer.refresh();
378
379 //enable/disable table
380 viewer.getControl().setEnabled(referencingObjects!=null);
381 }catch(Exception e){
382 e.printStackTrace();
383 logger.debug(e.getStackTrace());
384 updateDescription("The referencing objects view could not be loaded completely. Some Problems occurred.");
385 }
386 }
387 }
388 });
389 }
390
391
392 private void updateDescription(final String description){
393 Display.getDefault().asyncExec(new Runnable() {
394 @Override
395 public void run() {
396 if(contentDescription!=null && !contentDescription.isDisposed()) {
397 contentDescription.setText(description.replace("&", "&&"));
398 }
399 }
400
401 });
402 }
403
404 @Override
405 public void selectionChanged_internal(Object selection, MPart activePart, MPart thisPart) {
406 if(activePart==thisPart){
407 return;
408 }
409
410 IStructuredSelection structuredSelection = createSelection(selection);
411 if(structuredSelection!=null){
412 //referencedObjectTitleCache = null;
413 showViewer(structuredSelection, activePart, viewer);
414 }
415 }
416
417 /** {@inheritDoc} */
418 @Override
419 public void showViewer(IStructuredSelection selection, MPart activePart, Viewer viewer){
420 // this.part = part;
421
422 Object firstElement = selection.getFirstElement();
423 if (firstElement instanceof TermDto){
424 TermDto termDto = (TermDto) firstElement;
425 updateDescription("'"+termDto.getRepresentation_L10n() + "' is referenced by:");
426 updateReferencingObjects(termDto.getUuid(), TermBase.class );
427 return;
428 }
429 if(firstElement instanceof TreeNode){
430 firstElement = ((TreeNode) firstElement).getValue();
431 }
432 if (firstElement instanceof TaxonNode && !((TaxonNode)firstElement).hasTaxon()){
433 firstElement = ((TaxonNode)firstElement).getClassification();
434 }
435 if(firstElement instanceof CdmBase){
436 CdmBase referencedCdmObject = (CdmBase) firstElement;
437 if (referencedCdmObject.getUuid() == actualUuid){
438 return;
439 }
440 if (referencedCdmObject != null){
441 if(referencedCdmObject.isInstanceOf(IdentifiableEntity.class)){
442 referencedObjectTitleCache = (HibernateProxyHelper.deproxy(referencedCdmObject, IdentifiableEntity.class)).getTitleCache();
443 }
444 else if(referencedCdmObject.isInstanceOf(DescriptionElementBase.class)){
445 referencedObjectTitleCache = DescriptionHelper.getLabel(referencedCdmObject);
446 }
447 else if (referencedCdmObject.isInstanceOf(User.class)){
448 referencedObjectTitleCache = ((User)referencedCdmObject).getUsername();
449 }else if (referencedCdmObject.isInstanceOf(TaxonNode.class)){
450 referencedObjectTitleCache = "TaxonNode of "+(HibernateProxyHelper.deproxy(referencedCdmObject, TaxonNode.class)).getTaxon().getTitleCache();
451 }
452 }
453 if (referencedObjectTitleCache != null){
454 updateDescription(referencedCdmObject.getUserFriendlyTypeName() + " '" + referencedObjectTitleCache + "' is referenced by:");
455 } else{
456 updateDescription("");
457 }
458
459 updateReferencingObjects(referencedCdmObject.getUuid(),firstElement.getClass() );
460
461 }
462 else if (firstElement != null){
463 updateView();
464 updateDescription("");
465 }
466 }
467
468 /** {@inheritDoc} */
469 @PreDestroy
470 public void dispose() {
471 if(conversation!=null){
472 conversation.close();
473 conversation = null;
474 }
475 }
476
477 /** {@inheritDoc} */
478 @Override
479 public void changed(Object object) {
480 // no editing in this view
481 }
482
483 /** {@inheritDoc} */
484 @Override
485 public boolean onComplete() {
486 return false;
487 }
488
489 @Override
490 protected String getViewName() {
491 return "Referencing Objects";
492 }
493
494 }