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