Project

General

Profile

Download (14.5 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.log4j.Logger;
19
import org.eclipse.e4.core.contexts.IEclipseContext;
20
import org.eclipse.e4.core.di.annotations.Optional;
21
import org.eclipse.e4.ui.di.PersistState;
22
import org.eclipse.e4.ui.di.UISynchronize;
23
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
24
import org.eclipse.e4.ui.services.IServiceConstants;
25
import org.eclipse.e4.ui.workbench.modeling.EPartService;
26
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
27
import org.eclipse.jface.viewers.ISelectionChangedListener;
28
import org.eclipse.jface.viewers.IStructuredSelection;
29
import org.eclipse.jface.viewers.StructuredSelection;
30
import org.eclipse.jface.viewers.Viewer;
31
import org.eclipse.swt.SWTException;
32
import org.springframework.security.core.GrantedAuthority;
33

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

    
58
/**
59
 * @author pplitzner
60
 * @since Aug 10, 2017
61
 *
62
 */
63
public abstract class AbstractCdmEditorPartE4
64
        implements IConversationEnabled, IDirtyMarkable, ISelectionElementEditingPart, IPostOperationEnabled{
65

    
66
    private DelaySelection delaySelection = null;
67
    /**
68
     * This is the monitor for the DelaySelection runnable.
69
     * If it is <code>true</code> then it is currently delaying a selection.
70
     */
71
    private boolean isInDelay;
72
    private boolean isEnabled = true;
73
    private static final Logger logger = Logger.getLogger(AbstractCdmEditorPartE4.class);
74

    
75
    /**
76
     * This class invokes internal_selectionChanged() in a separate thread.
77
     * This allows an asynchronous and/or delayed handling of selection changes
78
     */
79
    private class DelaySelection implements Runnable{
80
        private Object selection;
81
        private MPart activePart;
82
        private MPart thisPart;
83

    
84
        public DelaySelection(Object selection, MPart activePart, MPart thisPart) {
85
            super();
86
            this.selection = selection;
87
            this.activePart= activePart;
88
            this.thisPart = thisPart;
89
        }
90

    
91
        @Override
92
        public void run() {
93
            try{
94
                selectionChanged_internal(selection, activePart, thisPart);
95
            }
96
            finally{
97
                isInDelay = false;
98
            }
99
        }
100

    
101
        public synchronized void setSelection(Object selection) {
102
            this.selection = selection;
103
        }
104

    
105
        public synchronized void setActivePart(MPart activePart) {
106
            this.activePart = activePart;
107
        }
108

    
109
        public synchronized void setThisPart(MPart thisPart) {
110
            this.thisPart = thisPart;
111
        }
112

    
113
    }
114

    
115
    protected Viewer viewer;
116

    
117
    protected MPart thisPart;
118

    
119
    protected MPart selectionProvidingPart;
120

    
121
    protected Object previousSelection;
122

    
123
    protected ISelectionChangedListener selectionChangedListener;
124

    
125
    public ISelectionChangedListener getSelectionChangedListener() {
126
        return selectionChangedListener;
127
    }
128

    
129
    @Inject
130
    protected ESelectionService selService;
131

    
132
    @Inject
133
    protected IEclipseContext context;
134

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

    
137
    @Inject
138
    public void selectionChanged(
139
            @Optional@Named(IServiceConstants.ACTIVE_SELECTION)Object selection,
140
            @Optional@Named(IServiceConstants.ACTIVE_PART)MPart activePart,
141
            MPart thisPart, UISynchronize sync, EPartService partService){
142
        //multiple selections are not supported
143
        if(activePart!=null
144
                && thisPart!=null
145
                && !activePart.equals(thisPart)
146
                && selection instanceof IStructuredSelection
147
                && ((IStructuredSelection) selection).size()>1){
148
            showEmptyPage();
149
            return;
150
        }
151
        // no active editor found
152
        if(activePart==thisPart && WorkbenchUtility.getActiveEditorPart(partService)==null){
153
            showEmptyPage();
154
            return;
155
        }
156
        if (viewer != null && viewer.getControl()!= null && viewer.getInput() != null && !viewer.getControl().isDisposed()){
157
           try{
158
               viewer.getControl().setEnabled(isEnabled);
159
           }catch(SWTException e){
160
              logger.debug("Something went wrong for viewer.getControl().setEnabled(true) in " + this.getClass().getSimpleName(), e);
161
           }
162

    
163
        }
164

    
165
        if((previousSelection!=null && selection!=null) && (activePart != null &&  selectionProvidingPart != null && activePart.equals(selectionProvidingPart)) &&
166
                (previousSelection==selection
167
                || previousSelection.equals(selection)
168
                || new StructuredSelection(selection).equals(previousSelection))
169
                ) {
170
            return;
171
        }
172
        if(delaySelection==null){
173
            delaySelection = new DelaySelection(selection, activePart, thisPart);
174
        }
175
        delaySelection.setSelection(selection);
176
        delaySelection.setActivePart(activePart);
177
        delaySelection.setThisPart(thisPart);
178
        if(!isInDelay){
179
            isInDelay = true;
180
            sync.asyncExec(delaySelection);
181
            previousSelection = selection;
182
        }
183
    }
184

    
185
    /** {@inheritDoc} */
186
    @Override
187
    public void changed(Object object) {
188
        if(selectionProvidingPart!=null){
189
            Object part = selectionProvidingPart.getObject();
190
            if(part instanceof IDirtyMarkable){
191
                ((IDirtyMarkable) part).changed(object);
192
            }
193
        }
194
    }
195

    
196
    public Viewer getViewer() {
197
        return viewer;
198
    }
199

    
200
    public boolean isEnabled() {
201
        return isEnabled;
202
    }
203

    
204
    public void setEnabled(boolean isEnabled) {
205
        this.isEnabled = isEnabled;
206
    }
207

    
208
    protected void showViewer(IStructuredSelection selection, MPart activePart, Viewer viewer){
209
        if(CdmStore.getCurrentSessionManager().getActiveSession()==null){
210
            return;
211
        }
212
        if(viewer!=null && viewer.getControl()!=null && !viewer.getControl().isDisposed()){
213
            Object element = selection.getFirstElement();
214
            Object part = createPartObject(activePart);
215
            if (viewer.getControl().isDisposed()){
216
                return;
217
            }
218
            viewer.getControl().setEnabled(true);
219
            if(selection.getFirstElement()!=null){
220
                if (element instanceof Taxon){
221

    
222
                    Taxon taxon = HibernateProxyHelper.deproxy(element, Taxon.class);
223
                    if (part instanceof ITaxonEditor){
224
                        TaxonNode node = ((ITaxonEditor) part).getTaxonNode();
225
                        if (node != null){
226
                            boolean doEnable = CdmStore.currentAuthentiationHasPermission(node,
227
                                    RequiredPermissions.TAXON_EDIT);
228
                             if (!doEnable){
229
                                 //check whether there are explicit TaxonNode rights
230
                                 boolean taxonnodePermissionExists = false;
231
                                 Collection<? extends GrantedAuthority> authorities = CdmStore.getCurrentAuthentiation().getAuthorities();
232
                                 for (GrantedAuthority grantedAuthority: authorities){
233
                                     if (grantedAuthority.getAuthority().startsWith("TAXONNODE")){
234
                                         taxonnodePermissionExists = true;
235
                                     }
236
                                 }
237
                                 if (!taxonnodePermissionExists){
238
                                     doEnable = true;
239
                                 }
240
                             }
241

    
242
                            //TODO: differ between the views
243
                            this.isEnabled = doEnable;
244
                        }
245

    
246

    
247
                    }
248
                    if (taxon.isMisapplication() || taxon.isProparteSynonym() || taxon.isInvalidDesignation()){
249

    
250
                        if(part instanceof ITaxonEditor){
251
                            Taxon accepted = ((ITaxonEditor) part).getTaxon();
252

    
253
                            Set<TaxonRelationship> rels =  taxon.getTaxonRelations(accepted);
254

    
255
                            if (rels != null && rels.iterator().hasNext() && !taxon.equals(accepted)){
256
                                TaxonRelationship rel = rels.iterator().next();
257
                                if ((rel.getType().isMisappliedNameOrInvalidDesignation() || rel.getType().isAnySynonym()) && !rel.getFromTaxon().equals(((ITaxonEditor) part).getTaxon())){
258
                                    viewer.setInput(rel);
259
                                    selectionProvidingPart = activePart;
260
                                    return;
261
                                }
262
                            }
263
                        }
264

    
265

    
266
                    }
267
                }
268
                //unwrap term DTOs
269
                if(element instanceof TermDto){
270
                    element = CdmStore.getService(ITermService.class).load(((TermDto) element).getUuid());
271
                }
272
                else if(element instanceof TermVocabularyDto){
273
                    element = CdmStore.getService(IVocabularyService.class).load(((TermVocabularyDto) element).getUuid());
274
                }
275

    
276
                selectionProvidingPart = activePart;
277
                if (viewer instanceof DetailsViewerE4){
278

    
279
                    if (selectionProvidingPart.getElementId().equals("eu.etaxonomy.taxeditor.editor.view.checklist.e4.DistributionEditorPart")){
280
                        ((DetailsViewerE4)viewer).setDetailsEnabled(false);
281
                    }else{
282
                        ((DetailsViewerE4)viewer).setDetailsEnabled(isEnabled);
283
                    }
284
                    ((DetailsViewerE4)viewer).setInput(element, part);
285

    
286
                }
287

    
288
                else{
289
                    if (activePart.getObject() instanceof DetailsPartE4 && element instanceof TaxonName){
290
                        selectionProvidingPart = ((DetailsPartE4)activePart.getObject()).getSelectionProvidingPart();
291
                    }
292

    
293
                    viewer.setInput(element);
294
                    viewer.getControl().setEnabled(isEnabled);
295

    
296

    
297
                }
298
            }
299
        }
300
    }
301

    
302
    protected Object createPartObject(MPart activePart) {
303
        Object partObject = activePart;
304
        Object wrappedPart = WorkbenchUtility.getE4WrappedPart(activePart);
305
        if(wrappedPart!=null){
306
            partObject = wrappedPart;
307
        }
308
        return partObject;
309
    }
310

    
311
    protected void showEmptyPage() {
312
        if(viewer!=null && viewer.getControl()!=null && !viewer.getControl().isDisposed() ){
313
            viewer.setInput(null);
314
            try{
315
	            if (!viewer.getControl().isDisposed()){
316
	                viewer.getControl().setEnabled(false);
317
	            }
318
            }catch(SWTException e){
319
            	if (PreferencesUtil.isShowUpWidgetIsDisposedMessages() && e.getMessage().equals("Widget is disposed")){
320
                    MessagingUtils.errorDialog("Widget is disposed",
321
                            null,
322
                            MessagingUtils.WIDGET_IS_DISPOSED_MESSAGE,
323
                            null,
324
                            e,
325
                            true);
326

    
327
                }
328
            }
329

    
330
        }
331
        reset();
332
        if(thisPart!=null){
333
            thisPart.setLabel(getViewName());
334
        }
335
    }
336

    
337
    protected IStructuredSelection createSelection(Object selection) {
338
        if(selection==null){
339
            return null;
340
        }
341
        IStructuredSelection structuredSelection;
342
        if(!(selection instanceof IStructuredSelection)){
343
            structuredSelection = new StructuredSelection(selection);
344
        }
345
        else{
346
            structuredSelection = (IStructuredSelection) selection;
347
        }
348
        return structuredSelection;
349
    }
350

    
351
    /**
352
     * {@inheritDoc}
353
     */
354
    @Override
355
    public ConversationHolder getConversationHolder() {
356
        if(selectionProvidingPart != null && selectionProvidingPart instanceof IConversationEnabled) {
357
            return ((IConversationEnabled) selectionProvidingPart).getConversationHolder();
358
        }
359
        return null;
360
    }
361

    
362
    /**
363
     * {@inheritDoc}
364
     */
365
    @Override
366
    public boolean postOperation(Object objectAffectedByOperation) {
367
        changed(objectAffectedByOperation);
368
        return true;
369
    }
370

    
371
    /**
372
     * {@inheritDoc}
373
     */
374
    @Override
375
    public boolean onComplete() {
376
        viewer.refresh();
377
        return true;
378
    }
379

    
380
    /**
381
     * {@inheritDoc}
382
     */
383
    @Override
384
    public MPart getSelectionProvidingPart() {
385
        return selectionProvidingPart;
386
    }
387

    
388
    @PreDestroy
389
    private void dispose() {
390
    }
391

    
392
    private void reset(){
393
        previousSelection = null;
394
        selectionProvidingPart = null;
395
        delaySelection = null;
396
        context.deactivate();
397
    }
398

    
399
    @PersistState
400
    private void persistState(){
401

    
402
    }
403

    
404
    /**
405
     * {@inheritDoc}
406
     */
407
    @Override
408
    public void update(CdmDataChangeMap arg0) {
409
    }
410

    
411
    /**
412
     * {@inheritDoc}
413
     */
414
    @Override
415
    public void forceDirty() {
416
    }
417

    
418
    protected abstract String getViewName();
419

    
420
}
(2-2/2)