Project

General

Profile

Download (15.1 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 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
package eu.etaxonomy.taxeditor.view.e4;
10

    
11
import java.util.Collection;
12
import java.util.Set;
13

    
14
import javax.annotation.PreDestroy;
15
import javax.inject.Inject;
16
import javax.inject.Named;
17

    
18
import org.apache.logging.log4j.LogManager;
19
import org.apache.logging.log4j.Logger;
20
import org.eclipse.e4.core.contexts.IEclipseContext;
21
import org.eclipse.e4.core.di.annotations.Optional;
22
import org.eclipse.e4.ui.di.PersistState;
23
import org.eclipse.e4.ui.di.UISynchronize;
24
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
25
import org.eclipse.e4.ui.services.IServiceConstants;
26
import org.eclipse.e4.ui.workbench.modeling.EPartService;
27
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
28
import org.eclipse.jface.viewers.ISelectionChangedListener;
29
import org.eclipse.jface.viewers.IStructuredSelection;
30
import org.eclipse.jface.viewers.StructuredSelection;
31
import org.eclipse.jface.viewers.Viewer;
32
import org.eclipse.swt.SWTException;
33
import org.springframework.security.core.GrantedAuthority;
34

    
35
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
36
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
37
import eu.etaxonomy.cdm.api.service.ITermNodeService;
38
import eu.etaxonomy.cdm.api.service.ITermService;
39
import eu.etaxonomy.cdm.api.service.IVocabularyService;
40
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
41
import eu.etaxonomy.cdm.model.name.TaxonName;
42
import eu.etaxonomy.cdm.model.taxon.Taxon;
43
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
44
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
45
import eu.etaxonomy.cdm.persistence.dto.TermDto;
46
import eu.etaxonomy.cdm.persistence.dto.TermNodeDto;
47
import eu.etaxonomy.cdm.persistence.dto.TermVocabularyDto;
48
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
49
import eu.etaxonomy.taxeditor.editor.IBulkEditor;
50
import eu.etaxonomy.taxeditor.editor.ITaxonEditor;
51
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
52
import eu.etaxonomy.taxeditor.model.MessagingUtils;
53
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
54
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
55
import eu.etaxonomy.taxeditor.security.RequiredPermissions;
56
import eu.etaxonomy.taxeditor.store.CdmStore;
57
import eu.etaxonomy.taxeditor.view.e4.details.DetailsPartE4;
58
import eu.etaxonomy.taxeditor.view.e4.details.DetailsViewerE4;
59
import eu.etaxonomy.taxeditor.workbench.WorkbenchUtility;
60
import eu.etaxonomy.taxeditor.workbench.part.ISelectionElementEditingPart;
61

    
62
/**
63
 * @author pplitzner
64
 * @since Aug 10, 2017
65
 */
66
public abstract class AbstractCdmEditorPartE4
67
        implements IConversationEnabled, IDirtyMarkable, ISelectionElementEditingPart, IPostOperationEnabled{
68

    
69
	private static final Logger logger = LogManager.getLogger(AbstractCdmEditorPartE4.class);
70

    
71
	private DelaySelection delaySelection = null;
72

    
73
    /**
74
     * This is the monitor for the DelaySelection runnable.
75
     * If it is <code>true</code> then it is currently delaying a selection.
76
     */
77
    private boolean isInDelay;
78
    private boolean isEnabled = true;
79

    
80
    /**
81
     * This class invokes internal_selectionChanged() in a separate thread.
82
     * This allows an asynchronous and/or delayed handling of selection changes
83
     */
84
    private class DelaySelection implements Runnable{
85
        private Object selection;
86
        private MPart activePart;
87
        private MPart thisPart;
88

    
89
        public DelaySelection(Object selection, MPart activePart, MPart thisPart) {
90
            super();
91
            this.selection = selection;
92
            this.activePart= activePart;
93
            this.thisPart = thisPart;
94
        }
95

    
96
        @Override
97
        public void run() {
98
            try{
99
                selectionChanged_internal(selection, activePart, thisPart);
100
            }
101
            finally{
102
                isInDelay = false;
103
            }
104
        }
105

    
106
        public synchronized void setSelection(Object selection) {
107
            this.selection = selection;
108
        }
109

    
110
        public synchronized void setActivePart(MPart activePart) {
111
            this.activePart = activePart;
112
        }
113

    
114
        public synchronized void setThisPart(MPart thisPart) {
115
            this.thisPart = thisPart;
116
        }
117
    }
118

    
119
    protected Viewer viewer;
120

    
121
    protected MPart thisPart;
122

    
123
    protected MPart selectionProvidingPart;
124

    
125
    protected Object previousSelection;
126

    
127
    protected ISelectionChangedListener selectionChangedListener;
128

    
129
    public ISelectionChangedListener getSelectionChangedListener() {
130
        return selectionChangedListener;
131
    }
132

    
133
    @Inject
134
    protected ESelectionService selService;
135

    
136
    @Inject
137
    protected IEclipseContext context;
138

    
139
    protected abstract void selectionChanged_internal(Object selection, MPart activePart, MPart thisPart);
140

    
141
    protected boolean showEmptyIfNoActiveEditor(){
142
        return true;
143
    }
144

    
145
    @Inject
146
    public void selectionChanged(
147
            @Optional@Named(IServiceConstants.ACTIVE_SELECTION)Object selection,
148
            @Optional@Named(IServiceConstants.ACTIVE_PART)MPart activePart,
149
            MPart thisPart, UISynchronize sync, EPartService partService){
150

    
151
        //multiple selections are not supported
152
        if(activePart != null
153
                && thisPart != null
154
                && !activePart.equals(thisPart)
155
                && selection instanceof IStructuredSelection
156
                && ((IStructuredSelection) selection).size()>1){
157
            showEmptyPage();
158
            return;
159
        }
160

    
161
        // no active editor found
162
        if(activePart == thisPart && WorkbenchUtility.getActiveEditorPart(partService) == null && showEmptyIfNoActiveEditor()){
163
            showEmptyPage();
164
            return;
165
        }
166

    
167
        if (viewer != null && viewer.getControl()!= null && viewer.getInput() != null && !viewer.getControl().isDisposed()){
168
           try{
169
               viewer.getControl().setEnabled(isEnabled);
170
           }catch(SWTException e){
171
              logger.debug("Something went wrong for viewer.getControl().setEnabled(true) in " + this.getClass().getSimpleName(), e);
172
           }
173
        }
174

    
175
        //same as previous selection? => return
176
        if((previousSelection != null && selection != null)
177
               && (activePart != null && selectionProvidingPart != null
178
                   && activePart.equals(selectionProvidingPart))
179
               && (previousSelection == selection
180
                    || previousSelection.equals(selection)
181
                    || new StructuredSelection(selection).equals(previousSelection))
182
                ) {
183
            return;
184
        }
185
        if(delaySelection == null){
186
            delaySelection = new DelaySelection(selection, activePart, thisPart);
187
        }else{
188
            delaySelection.setSelection(selection);
189
            delaySelection.setActivePart(activePart);
190
            delaySelection.setThisPart(thisPart);
191
        }
192
        if(!isInDelay){
193
            isInDelay = true;
194
            sync.asyncExec(delaySelection);
195
            previousSelection = selection;
196
        }
197
    }
198

    
199
    @Override
200
    public void changed(Object object) {
201
        if(selectionProvidingPart!=null){
202
            Object part = selectionProvidingPart.getObject();
203
            if(part instanceof IDirtyMarkable){
204
                ((IDirtyMarkable) part).changed(object);
205
            }
206
            if (part instanceof IBulkEditor){
207
            	((IBulkEditor)part).setSelection(createSelection(object));
208
            }
209
        }
210
    }
211

    
212
    public Viewer getViewer() {
213
        return viewer;
214
    }
215

    
216
    public boolean isEnabled() {
217
        return isEnabled;
218
    }
219

    
220
    public void setEnabled(boolean isEnabled) {
221
        this.isEnabled = isEnabled;
222
    }
223

    
224
    protected void showViewer(IStructuredSelection selection, MPart activePart, Viewer viewer){
225
        if(CdmStore.getCurrentSessionManager().getActiveSession()==null){
226
            return;
227
        }
228
        if(viewer!=null && viewer.getControl()!=null && !viewer.getControl().isDisposed()){
229
            Object element = selection.getFirstElement();
230
            Object part = createPartObject(activePart);
231
            if (viewer.getControl().isDisposed()){
232
                return;
233
            }
234
            viewer.getControl().setEnabled(true);
235
            if(element != null){
236
                if (element instanceof Taxon){
237

    
238
                    Taxon taxon = HibernateProxyHelper.deproxy(element, Taxon.class);
239
                    if (part instanceof ITaxonEditor){
240
                        TaxonNode node = ((ITaxonEditor) part).getTaxonNode();
241
                        if (node != null){
242
                            boolean doEnable = CdmStore.currentAuthentiationHasPermission(node,
243
                                    RequiredPermissions.TAXON_EDIT);
244
                            if (!doEnable){
245
                                 //check whether there are explicit TaxonNode rights
246
                                 boolean taxonnodePermissionExists = false;
247
                                 Collection<? extends GrantedAuthority> authorities = CdmStore.getCurrentAuthentiation().getAuthorities();
248
                                 for (GrantedAuthority grantedAuthority: authorities){
249
                                     if (grantedAuthority.getAuthority().startsWith("TAXONNODE")){
250
                                         taxonnodePermissionExists = true;
251
                                     }
252
                                 }
253
                                 if (!taxonnodePermissionExists){
254
                                     doEnable = true;
255
                                 }
256
                            }
257

    
258
                            //TODO: differ between the views
259
                            this.isEnabled = doEnable;
260
                        }
261
                    }
262
                    if (taxon.isMisapplication() || taxon.isProparteSynonym() ){
263

    
264
                        if(part instanceof ITaxonEditor){
265
                            Taxon accepted = ((ITaxonEditor) part).getTaxon();
266

    
267
                            Set<TaxonRelationship> rels =  taxon.getTaxonRelations(accepted);
268

    
269
                            if (rels != null && rels.iterator().hasNext() && !taxon.equals(accepted)){
270
                                TaxonRelationship rel = rels.iterator().next();
271
                                if ((rel.getType().isMisappliedName() || rel.getType().isAnySynonym()) && !rel.getFromTaxon().equals(((ITaxonEditor) part).getTaxon())){
272
                                    viewer.setInput(rel);
273
                                    selectionProvidingPart = activePart;
274
                                    return;
275
                                }
276
                            }
277
                        }
278
                    }
279
                }
280

    
281
                //unwrap term DTOs
282
                if(element instanceof TermDto){
283
                    element = CdmStore.getService(ITermService.class).load(((TermDto) element).getUuid());
284
                }
285
                else if(element instanceof TermVocabularyDto){
286
                    element = CdmStore.getService(IVocabularyService.class).load(((TermVocabularyDto) element).getUuid());
287
                }
288

    
289

    
290
                selectionProvidingPart = activePart;
291
                if (viewer instanceof DetailsViewerE4){
292

    
293
                    if (selectionProvidingPart.getElementId().equals("eu.etaxonomy.taxeditor.editor.view.checklist.e4.DistributionEditorPart")){
294
                        ((DetailsViewerE4)viewer).setDetailsEnabled(false);
295
                    }else{
296
                        ((DetailsViewerE4)viewer).setDetailsEnabled(isEnabled);
297
                    }
298
                    ((DetailsViewerE4)viewer).setInput(element, part);
299

    
300
                }
301

    
302
                else{
303
                    if(element instanceof TermNodeDto){
304
                        element = CdmStore.getService(ITermNodeService.class).load(((TermNodeDto) element).getUuid());
305
                    }
306
                    if (activePart.getObject() instanceof DetailsPartE4 && element instanceof TaxonName){
307
                        selectionProvidingPart = ((DetailsPartE4)activePart.getObject()).getSelectionProvidingPart();
308
                    }
309

    
310
                    viewer.setInput(element);
311
                    viewer.getControl().setEnabled(isEnabled);
312
                }
313
            }
314
        }
315
    }
316

    
317
    protected Object createPartObject(MPart activePart) {
318
        Object partObject = activePart;
319
        Object wrappedPart = WorkbenchUtility.getE4WrappedPart(activePart);
320
        if(wrappedPart!=null){
321
            partObject = wrappedPart;
322
        }
323
        return partObject;
324
    }
325

    
326
    protected void showEmptyPage() {
327
        if(viewer!=null && viewer.getControl()!=null && !viewer.getControl().isDisposed() ){
328
            viewer.setInput(null);
329
            try{
330
	            if (!viewer.getControl().isDisposed()){
331
	                viewer.getControl().setEnabled(false);
332
	            }
333
            }catch(SWTException e){
334
            	if (PreferencesUtil.isShowUpWidgetIsDisposedMessages() && e.getMessage().equals("Widget is disposed")){
335
                    MessagingUtils.errorDialog("Widget is disposed",
336
                            null,
337
                            MessagingUtils.WIDGET_IS_DISPOSED_MESSAGE,
338
                            null,
339
                            e,
340
                            true);
341
                }
342
            }
343
        }
344

    
345
        reset();
346
        if(thisPart!=null){
347
            thisPart.setLabel(getViewName());
348
        }
349
    }
350

    
351
    protected IStructuredSelection createSelection(Object selection) {
352
        if(selection==null){
353
            return null;
354
        }
355
        IStructuredSelection structuredSelection;
356
        if(!(selection instanceof IStructuredSelection)){
357
            structuredSelection = new StructuredSelection(selection);
358
        }
359
        else{
360
            structuredSelection = (IStructuredSelection) selection;
361
        }
362
        return structuredSelection;
363
    }
364

    
365
    @Override
366
    public ConversationHolder getConversationHolder() {
367
        if(selectionProvidingPart != null && selectionProvidingPart instanceof IConversationEnabled) {
368
            return ((IConversationEnabled) selectionProvidingPart).getConversationHolder();
369
        }
370
        return null;
371
    }
372

    
373
    @Override
374
    public boolean postOperation(Object objectAffectedByOperation) {
375
        changed(objectAffectedByOperation);
376
//        Object part = selectionProvidingPart.getObject();
377
//        if (part instanceof IBulkEditor){
378
//        	((IBulkEditor)part).setSelection(createSelection(objectAffectedByOperation));
379
//        }
380
        return true;
381
    }
382

    
383
    @Override
384
    public boolean onComplete() {
385
        viewer.refresh();
386
        return true;
387
    }
388

    
389
    @Override
390
    public MPart getSelectionProvidingPart() {
391
        return selectionProvidingPart;
392
    }
393

    
394
    @PreDestroy
395
    private void dispose() {
396
    }
397

    
398
    private void reset(){
399
        previousSelection = null;
400
        selectionProvidingPart = null;
401
        delaySelection = null;
402
        context.deactivate();
403
    }
404

    
405
    @PersistState
406
    private void persistState(){
407

    
408
    }
409

    
410
    @Override
411
    public void update(CdmDataChangeMap arg0) {
412
    }
413

    
414
    @Override
415
    public void forceDirty() {
416
    }
417

    
418
    protected abstract String getViewName();
419

    
420
}
(2-2/2)