Project

General

Profile

Download (14.2 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
public abstract class AbstractCdmEditorPartE4
63
        implements IConversationEnabled, IDirtyMarkable, ISelectionElementEditingPart, IPostOperationEnabled{
64

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

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

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

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

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

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

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

    
113
    protected Viewer viewer;
114

    
115
    protected MPart thisPart;
116

    
117
    protected MPart selectionProvidingPart;
118

    
119
    protected Object previousSelection;
120

    
121
    protected ISelectionChangedListener selectionChangedListener;
122

    
123
    public ISelectionChangedListener getSelectionChangedListener() {
124
        return selectionChangedListener;
125
    }
126

    
127
    @Inject
128
    protected ESelectionService selService;
129

    
130
    @Inject
131
    protected IEclipseContext context;
132

    
133
    protected abstract void selectionChanged_internal(Object selection, MPart activePart, MPart thisPart);
134

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

    
161
        }
162

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

    
183
    @Override
184
    public void changed(Object object) {
185
        if(selectionProvidingPart!=null){
186
            Object part = selectionProvidingPart.getObject();
187
            if(part instanceof IDirtyMarkable){
188
                ((IDirtyMarkable) part).changed(object);
189
            }
190
        }
191
    }
192

    
193
    public Viewer getViewer() {
194
        return viewer;
195
    }
196

    
197
    public boolean isEnabled() {
198
        return isEnabled;
199
    }
200

    
201
    public void setEnabled(boolean isEnabled) {
202
        this.isEnabled = isEnabled;
203
    }
204

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

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

    
239
                            //TODO: differ between the views
240
                            this.isEnabled = doEnable;
241
                        }
242

    
243

    
244
                    }
245
                    if (taxon.isMisapplication() || taxon.isProparteSynonym() || taxon.isInvalidDesignation()){
246

    
247
                        if(part instanceof ITaxonEditor){
248
                            Taxon accepted = ((ITaxonEditor) part).getTaxon();
249

    
250
                            Set<TaxonRelationship> rels =  taxon.getTaxonRelations(accepted);
251

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

    
262

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

    
273
                selectionProvidingPart = activePart;
274
                if (viewer instanceof DetailsViewerE4){
275

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

    
284
                else{
285
                    if (activePart.getObject() instanceof DetailsPartE4 && element instanceof TaxonName){
286
                        selectionProvidingPart = ((DetailsPartE4)activePart.getObject()).getSelectionProvidingPart();
287
                    }
288

    
289
                    viewer.setInput(element);
290
                    viewer.getControl().setEnabled(isEnabled);
291
                }
292
            }
293
        }
294
    }
295

    
296
    protected Object createPartObject(MPart activePart) {
297
        Object partObject = activePart;
298
        Object wrappedPart = WorkbenchUtility.getE4WrappedPart(activePart);
299
        if(wrappedPart!=null){
300
            partObject = wrappedPart;
301
        }
302
        return partObject;
303
    }
304

    
305
    protected void showEmptyPage() {
306
        if(viewer!=null && viewer.getControl()!=null && !viewer.getControl().isDisposed() ){
307
            viewer.setInput(null);
308
            try{
309
	            if (!viewer.getControl().isDisposed()){
310
	                viewer.getControl().setEnabled(false);
311
	            }
312
            }catch(SWTException e){
313
            	if (PreferencesUtil.isShowUpWidgetIsDisposedMessages() && e.getMessage().equals("Widget is disposed")){
314
                    MessagingUtils.errorDialog("Widget is disposed",
315
                            null,
316
                            MessagingUtils.WIDGET_IS_DISPOSED_MESSAGE,
317
                            null,
318
                            e,
319
                            true);
320

    
321
                }
322
            }
323

    
324
        }
325
        reset();
326
        if(thisPart!=null){
327
            thisPart.setLabel(getViewName());
328
        }
329
    }
330

    
331
    protected IStructuredSelection createSelection(Object selection) {
332
        if(selection==null){
333
            return null;
334
        }
335
        IStructuredSelection structuredSelection;
336
        if(!(selection instanceof IStructuredSelection)){
337
            structuredSelection = new StructuredSelection(selection);
338
        }
339
        else{
340
            structuredSelection = (IStructuredSelection) selection;
341
        }
342
        return structuredSelection;
343
    }
344

    
345
    @Override
346
    public ConversationHolder getConversationHolder() {
347
        if(selectionProvidingPart != null && selectionProvidingPart instanceof IConversationEnabled) {
348
            return ((IConversationEnabled) selectionProvidingPart).getConversationHolder();
349
        }
350
        return null;
351
    }
352

    
353
    @Override
354
    public boolean postOperation(Object objectAffectedByOperation) {
355
        changed(objectAffectedByOperation);
356
        return true;
357
    }
358

    
359
    @Override
360
    public boolean onComplete() {
361
        viewer.refresh();
362
        return true;
363
    }
364

    
365
    @Override
366
    public MPart getSelectionProvidingPart() {
367
        return selectionProvidingPart;
368
    }
369

    
370
    @PreDestroy
371
    private void dispose() {
372
    }
373

    
374
    private void reset(){
375
        previousSelection = null;
376
        selectionProvidingPart = null;
377
        delaySelection = null;
378
        context.deactivate();
379
    }
380

    
381
    @PersistState
382
    private void persistState(){
383

    
384
    }
385

    
386
    @Override
387
    public void update(CdmDataChangeMap arg0) {
388
    }
389

    
390
    @Override
391
    public void forceDirty() {
392
    }
393

    
394
    protected abstract String getViewName();
395

    
396
}
(2-2/2)