Project

General

Profile

Download (10.1 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2015 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.navigation.navigator.e4;
11

    
12
import java.util.ArrayList;
13
import java.util.EnumSet;
14
import java.util.HashSet;
15
import java.util.Iterator;
16
import java.util.List;
17
import java.util.Set;
18
import java.util.UUID;
19

    
20
import javax.inject.Inject;
21

    
22
import org.apache.log4j.Logger;
23
import org.eclipse.core.commands.operations.IUndoContext;
24
import org.eclipse.e4.ui.workbench.modeling.EPartService;
25
import org.eclipse.jface.dialogs.MessageDialog;
26
import org.eclipse.jface.util.LocalSelectionTransfer;
27
import org.eclipse.jface.viewers.ISelection;
28
import org.eclipse.jface.viewers.TreeSelection;
29
import org.eclipse.jface.viewers.ViewerDropAdapter;
30
import org.eclipse.swt.dnd.DND;
31
import org.eclipse.swt.dnd.DropTargetEvent;
32
import org.eclipse.swt.dnd.TransferData;
33
import org.eclipse.swt.widgets.Display;
34

    
35
import eu.etaxonomy.cdm.api.application.CdmApplicationState;
36
import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
37
import eu.etaxonomy.cdm.api.service.UpdateResult;
38
import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
39
import eu.etaxonomy.cdm.model.permission.CRUD;
40
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
41
import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
42
import eu.etaxonomy.taxeditor.event.EventUtility;
43
import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
44
import eu.etaxonomy.taxeditor.model.AbstractUtility;
45
import eu.etaxonomy.taxeditor.navigation.l10n.Messages;
46
import eu.etaxonomy.taxeditor.operation.IPostMoniteredOperationEnabled;
47
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
48
import eu.etaxonomy.taxeditor.store.CdmStore;
49

    
50
/**
51
 * @author k.luther
52
 * @date 02.06.2015
53
 */
54
public class TreeNodeDropAdapterE4 extends ViewerDropAdapter implements IPostMoniteredOperationEnabled{
55

    
56
    protected static final String TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT_MESSAGE = Messages.TreeNodeDropAdapter_UNSAVED_PARENT_MESSAGE;
57
    protected static final String TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT = Messages.TreeNodeDropAdapter_UNSAVED_PARENT;
58
    protected static final String TREE_NODE_DROP_ADAPTER_MOVE_TAXON = Messages.TreeNodeDropAdapter_MOVE_TAXON;
59
    protected static final String TREE_NODE_DROP_ADAPTER_CANCEL = Messages.TreeNodeDropAdapter_CANCEL;
60
    protected static final String TREE_NODE_DROP_ADAPTER_BEHIND = Messages.TreeNodeDropAdapter_BEHIND;
61
    protected static final String TREE_NODE_DROP_ADAPTER_CHILD = Messages.TreeNodeDropAdapter_CHILD;
62
    protected static final String DO_YOU_WANT_TO_MOVE_THE_TAXONNODE_AS_CHILD_OR_BEHIND_THE_TARGET_NODE = Messages.TreeNodeDropAdapter_MOVE_BEHIND;
63
    protected static final String TARGET_NODE = Messages.TreeNodeDropAdapter_TARGET_NODE;
64

    
65
    private static final Logger logger = Logger.getLogger(TreeNodeDropAdapterE4.class);
66

    
67
    private TaxonNavigatorE4 taxonNavigator;
68
    UpdateResult result;
69
    TaxonNodeDto targetITaxonTreeNode;
70
    HashSet<TaxonNodeDto> taxonNodes;
71
	public static final String ID = "eu.etaxonomy.taxeditor.navigation.navigator.dropassistant"; //$NON-NLS-1$
72

    
73
	private static final EnumSet<CRUD> UPDATE = EnumSet.of(CRUD.UPDATE);
74

    
75
	@Inject
76
	private EPartService partService;
77

    
78
	public enum MovingType{
79
	    CHILD, PREVIOUS, BEHIND
80
	}
81

    
82
	protected TreeNodeDropAdapterE4(TaxonNavigatorE4 navigator) {
83
	    super(navigator.getViewer());
84
	    this.taxonNavigator = navigator;
85
	}
86

    
87
	/** {@inheritDoc} */
88
	@Override
89
	public boolean performDrop(Object data) {
90
        Object target = getCurrentTarget();
91
		if (getCurrentTarget() instanceof TaxonNodeDto) {
92
			Set<TaxonNodeDto> taxonNodes = getSelectedTaxa();
93
			TaxonNodeDto targetTreeNode = (TaxonNodeDto) target;
94

    
95
			if(taxonNodes != null) {
96
			    boolean success = moveTaxon(taxonNodes, targetTreeNode);
97
				return success;
98
            }
99
		}
100
		return false;
101
	}
102

    
103
	private Set<TaxonNodeDto> getSelectedTaxa(){
104
		taxonNodes = new HashSet();
105

    
106
		ISelection selection = LocalSelectionTransfer.getTransfer().getSelection();
107
		if (selection instanceof TreeSelection) {
108

    
109
			Iterator<?> selectionIterator = ((TreeSelection) selection).iterator();
110

    
111
			while (selectionIterator.hasNext()){
112
				Object object = selectionIterator.next();
113
				if(object instanceof TaxonNodeDto){
114
					TaxonNodeDto taxonNode = (TaxonNodeDto) object;
115
					taxonNodes.add(taxonNode);
116
				}
117
			}
118
		}
119
		return taxonNodes;
120
	}
121

    
122
	/** {@inheritDoc} */
123
	@Override
124
	public boolean validateDrop(Object target, int operation,
125
			TransferData transferType) {
126

    
127
		if (target instanceof TaxonNodeDto) {
128

    
129
		    // check users permissions with target taxonnode and taxon
130
		    if (target instanceof TaxonNodeDto) {
131
		        TaxonNodeDto targetNode = (TaxonNodeDto)target;
132
		        TaxonNode node = CdmStore.getService(ITaxonNodeService.class).load(targetNode.getUuid());
133
		        boolean hasTargetNodePermission = CdmStore.currentAuthentiationHasPermission(node, UPDATE);
134
		        boolean hasTargetTaxonPermission = node.getTaxon() == null ?
135
		        			true :
136
		        			CdmStore.currentAuthentiationHasPermission(node.getTaxon(), UPDATE);
137

    
138
		        if(!hasTargetNodePermission || ! hasTargetNodePermission){
139
		            if(logger.isDebugEnabled()){
140
		                logger.debug("CANCEL_STATUS for target node: " + hasTargetNodePermission + " " + hasTargetTaxonPermission + " "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
141
		            }
142
		            return false;
143
		        }
144
		    }
145

    
146
		    // do not allow to drop onto itself and
147
		    // check users permissions with all selected taxon nodes and taxa
148
		    List<UUID> nodeUuids = new ArrayList<>();
149
		    boolean isNotSameTaxonNode = true;
150
		    boolean isNotSameParent = true;
151
		    for(TaxonNodeDto taxonNode : getSelectedTaxa()){
152
			    if (logger.isDebugEnabled()){
153
			    	logger.debug("selectedTaxa: " + taxonNode.getTaxonUuid() == null? "-" : taxonNode.getTitleCache()); //$NON-NLS-1$
154
			    }
155
			    boolean isClassification = taxonNode.getTaxonUuid()== null;
156
			    if (isClassification) {
157
	                    if(logger.isDebugEnabled()){
158
	                        logger.debug("CANCEL_STATUS for selected classification " + taxonNode.getClassificationUUID()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
159
	                    }
160
	                    return false;
161
	                }
162
			    isNotSameTaxonNode = isNotSameTaxonNode && !taxonNode.equals(target);
163
			    isNotSameParent = isNotSameParent && !taxonNode.getParentUUID().equals(((TaxonNodeDto) target).getUuid());
164
			    nodeUuids.add(taxonNode.getUuid());
165

    
166
		    }
167
			    List<TaxonNode> nodes = CdmStore.getService(ITaxonNodeService.class).load(nodeUuids, null);
168
			    boolean hasPermission = true;
169
			    for (TaxonNode node: nodes){
170
			        hasPermission = hasPermission && CdmStore.currentAuthentiationHasPermission(node, UPDATE) && CdmStore.currentAuthentiationHasPermission(node.getTaxon(), UPDATE);
171
			    }
172

    
173
                if (
174
			        !isNotSameTaxonNode
175
			        || !isNotSameParent
176
			        || !hasPermission
177

    
178
    	            ) {
179
                    if(logger.isDebugEnabled()){
180
                        logger.debug("CANCEL_STATUS for selected  " + isNotSameTaxonNode + Messages.TreeNodeDropAdapter_10 + hasPermission +  " "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
181
                    }
182
					return false;
183
				}
184
			}
185
			logger.debug("OK_STATUS"); //$NON-NLS-1$
186
			return true;
187

    
188
	}
189

    
190

    
191
	private boolean moveTaxon(Set<TaxonNodeDto> taxonNodes, TaxonNodeDto targetITaxonTreeNode) {
192
		Iterator<TaxonNodeDto> taxIterator = taxonNodes.iterator();
193
		this.targetITaxonTreeNode = targetITaxonTreeNode;
194
        Set<UUID> uuids = new HashSet<UUID>();
195
        TaxonNodeDto node = null;
196
        while(taxIterator.hasNext()){
197
            node = taxIterator.next();
198
            uuids.add(node.getUuid());
199
        }
200
        IUndoContext workspaceUndoContext = taxonNavigator.getUndoContext();
201
         int movingTypeInt = 0;
202
		if (PreferencesUtil.isNodesSortedNaturally()){
203
			String[] buttonLables = {TREE_NODE_DROP_ADAPTER_CHILD, TREE_NODE_DROP_ADAPTER_BEHIND,TREE_NODE_DROP_ADAPTER_CANCEL};
204
			MessageDialog dialog = new MessageDialog(null, TARGET_NODE, null, DO_YOU_WANT_TO_MOVE_THE_TAXONNODE_AS_CHILD_OR_BEHIND_THE_TARGET_NODE, MessageDialog.QUESTION_WITH_CANCEL, buttonLables, 0);
205
			dialog.open();
206
			int returnCode = dialog.getReturnCode();
207

    
208
			if (returnCode == 0){
209
				if (workspaceUndoContext == null) {
210
					logger.error("Workspace undo context is null. DND operation cancelled"); //$NON-NLS-1$
211
					return false;
212
				}
213

    
214
			}else if (returnCode == 1){
215
				if (workspaceUndoContext == null) {
216
					logger.error("Workspace undo context is null. DND operation cancelled"); //$NON-NLS-1$
217
					return false;
218
				}
219
				movingTypeInt = 2;
220

    
221
			} else {
222
				return false;
223
			}
224

    
225

    
226
		}
227
		moveNodes(uuids, targetITaxonTreeNode.getUuid(), movingTypeInt);
228
        return true;
229
	}
230

    
231
	private void moveNodes(Set<UUID> taxonNodesToMoveUuid, UUID newParentTreeNodeUuid, int movingTypeInt){
232
	    UUID uuid = CdmApplicationState.getLongRunningTasksService().monitLongRunningTask(taxonNodesToMoveUuid,
233
                newParentTreeNodeUuid, movingTypeInt);
234

    
235
        Display.getDefault().asyncExec(new Runnable() {
236
            @Override
237
            public void run() {
238
                AbstractUtility.executeMoniteredOperation("Move Taxon to new parent: ",
239
                        uuid,
240
                        1000,
241
                        false,
242
                        TreeNodeDropAdapterE4.this,
243
                        null,
244
                        false);
245
            }
246
        });
247
	}
248

    
249

    
250
	@Override
251
	public void dragOver(DropTargetEvent event) {
252
		super.dragOver(event);
253
		event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_INSERT_AFTER | DND.FEEDBACK_SCROLL;
254
	}
255

    
256
    /**
257
     * {@inheritDoc}
258
     */
259
    @Override
260
    public void postOperation(IRemotingProgressMonitor monitor) {
261
        EventUtility.postEvent(WorkbenchEventConstants.REFRESH_NAVIGATOR, targetITaxonTreeNode);
262
        taxonNodes.forEach(nodeDto->EventUtility.postEvent(WorkbenchEventConstants.REFRESH_NAME_EDITOR, nodeDto.getTaxonUuid()));
263
        EventUtility.postEvent(WorkbenchEventConstants.REFRESH_NAME_EDITOR, targetITaxonTreeNode.getTaxonUuid());
264

    
265
    }
266

    
267
}
(6-6/6)