Project

General

Profile

Download (14.6 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.ITermNodeService;
37
import eu.etaxonomy.cdm.api.service.ITermService;
38
import eu.etaxonomy.cdm.api.service.IVocabularyService;
39
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
40
import eu.etaxonomy.cdm.model.name.TaxonName;
41
import eu.etaxonomy.cdm.model.taxon.Taxon;
42
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
43
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
44
import eu.etaxonomy.cdm.persistence.dto.TermDto;
45
import eu.etaxonomy.cdm.persistence.dto.TermNodeDto;
46
import eu.etaxonomy.cdm.persistence.dto.TermVocabularyDto;
47
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
48
import eu.etaxonomy.taxeditor.editor.ITaxonEditor;
49
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
50
import eu.etaxonomy.taxeditor.model.MessagingUtils;
51
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
52
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
53
import eu.etaxonomy.taxeditor.security.RequiredPermissions;
54
import eu.etaxonomy.taxeditor.store.CdmStore;
55
import eu.etaxonomy.taxeditor.view.e4.details.DetailsPartE4;
56
import eu.etaxonomy.taxeditor.view.e4.details.DetailsViewerE4;
57
import eu.etaxonomy.taxeditor.workbench.WorkbenchUtility;
58
import eu.etaxonomy.taxeditor.workbench.part.ISelectionElementEditingPart;
59

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

    
67
	private static final Logger logger = Logger.getLogger(AbstractCdmEditorPartE4.class);
68

    
69
	private DelaySelection delaySelection = null;
70
    /**
71
     * This is the monitor for the DelaySelection runnable.
72
     * If it is <code>true</code> then it is currently delaying a selection.
73
     */
74
    private boolean isInDelay;
75
    private boolean isEnabled = true;
76

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

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

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

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

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

    
111
        public synchronized void setThisPart(MPart thisPart) {
112
            this.thisPart = thisPart;
113
        }
114
    }
115

    
116
    protected Viewer viewer;
117

    
118
    protected MPart thisPart;
119

    
120
    protected MPart selectionProvidingPart;
121

    
122
    protected Object previousSelection;
123

    
124
    protected ISelectionChangedListener selectionChangedListener;
125

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

    
130
    @Inject
131
    protected ESelectionService selService;
132

    
133
    @Inject
134
    protected IEclipseContext context;
135

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

    
138
    protected boolean showEmptyIfNoActiveEditor(){
139
        return true;
140
    }
141

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

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

    
191
    @Override
192
    public void changed(Object object) {
193
        if(selectionProvidingPart!=null){
194
            Object part = selectionProvidingPart.getObject();
195
            if(part instanceof IDirtyMarkable){
196
                ((IDirtyMarkable) part).changed(object);
197
            }
198
        }
199
    }
200

    
201
    public Viewer getViewer() {
202
        return viewer;
203
    }
204

    
205
    public boolean isEnabled() {
206
        return isEnabled;
207
    }
208

    
209
    public void setEnabled(boolean isEnabled) {
210
        this.isEnabled = isEnabled;
211
    }
212

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

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

    
247
                            //TODO: differ between the views
248
                            this.isEnabled = doEnable;
249
                        }
250
                    }
251
                    if (taxon.isMisapplication() || taxon.isProparteSynonym() ){
252

    
253
                        if(part instanceof ITaxonEditor){
254
                            Taxon accepted = ((ITaxonEditor) part).getTaxon();
255

    
256
                            Set<TaxonRelationship> rels =  taxon.getTaxonRelations(accepted);
257

    
258
                            if (rels != null && rels.iterator().hasNext() && !taxon.equals(accepted)){
259
                                TaxonRelationship rel = rels.iterator().next();
260
                                if ((rel.getType().isMisappliedName() || rel.getType().isAnySynonym()) && !rel.getFromTaxon().equals(((ITaxonEditor) part).getTaxon())){
261
                                    viewer.setInput(rel);
262
                                    selectionProvidingPart = activePart;
263
                                    return;
264
                                }
265
                            }
266
                        }
267
                    }
268
                }
269

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

    
278

    
279
                selectionProvidingPart = activePart;
280
                if (viewer instanceof DetailsViewerE4){
281

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

    
290
                else{
291
                    if(element instanceof TermNodeDto){
292
                        element = CdmStore.getService(ITermNodeService.class).load(((TermNodeDto) element).getUuid());
293
                    }
294
                    if (activePart.getObject() instanceof DetailsPartE4 && element instanceof TaxonName){
295
                        selectionProvidingPart = ((DetailsPartE4)activePart.getObject()).getSelectionProvidingPart();
296
                    }
297

    
298
                    viewer.setInput(element);
299
                    viewer.getControl().setEnabled(isEnabled);
300
                }
301
            }
302
        }
303
    }
304

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

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

    
333
        reset();
334
        if(thisPart!=null){
335
            thisPart.setLabel(getViewName());
336
        }
337
    }
338

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

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

    
361
    @Override
362
    public boolean postOperation(Object objectAffectedByOperation) {
363
        changed(objectAffectedByOperation);
364
        return true;
365
    }
366

    
367
    @Override
368
    public boolean onComplete() {
369
        viewer.refresh();
370
        return true;
371
    }
372

    
373
    @Override
374
    public MPart getSelectionProvidingPart() {
375
        return selectionProvidingPart;
376
    }
377

    
378
    @PreDestroy
379
    private void dispose() {
380
    }
381

    
382
    private void reset(){
383
        previousSelection = null;
384
        selectionProvidingPart = null;
385
        delaySelection = null;
386
        context.deactivate();
387
    }
388

    
389
    @PersistState
390
    private void persistState(){
391

    
392
    }
393

    
394
    @Override
395
    public void update(CdmDataChangeMap arg0) {
396
    }
397

    
398
    @Override
399
    public void forceDirty() {
400
    }
401

    
402
    protected abstract String getViewName();
403

    
404
}
(2-2/2)