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.editor.EditorUtil;
43
import eu.etaxonomy.taxeditor.event.EventUtility;
44
import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
45
import eu.etaxonomy.taxeditor.model.AbstractUtility;
46
import eu.etaxonomy.taxeditor.navigation.l10n.Messages;
47
import eu.etaxonomy.taxeditor.operation.IPostMoniteredOperationEnabled;
48
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
49
import eu.etaxonomy.taxeditor.store.CdmStore;
50

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

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

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

    
68
    private TaxonNavigatorE4 taxonNavigator;
69
    UpdateResult result;
70

    
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
		HashSet<TaxonNodeDto> 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
//				boolean hasTaxonPermission =
173
//	        			CdmStore.currentAuthentiationHasPermission(node.getTaxon(), UPDATE);
174
                if (
175
			        !isNotSameTaxonNode
176
			        || !isNotSameParent
177
			        || !hasPermission
178

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

    
193

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

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

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

    
223
			} else {
224
				return false;
225
			}
226

    
227

    
228
		}
229
		//close possible open name editors for the moved taxon nodes
230

    
231
		taxonNodes.forEach(nodeDto->EditorUtil.closeObsoleteEditor(nodeDto, partService));
232

    
233
		moveNodes(uuids, targetITaxonTreeNode.getUuid(), movingTypeInt);
234
        return true;
235
	}
236

    
237
	private void moveNodes(Set<UUID> taxonNodesToMoveUuid, UUID newParentTreeNodeUuid, int movingTypeInt){
238
	    UUID uuid = CdmApplicationState.getLongRunningTasksService().monitLongRunningTask(taxonNodesToMoveUuid,
239
                newParentTreeNodeUuid, movingTypeInt);
240

    
241
        Display.getDefault().asyncExec(new Runnable() {
242
            @Override
243
            public void run() {
244
                AbstractUtility.executeMoniteredOperation("Move Taxon to new parent: ",
245
                        uuid,
246
                        1000,
247
                        false,
248
                        TreeNodeDropAdapterE4.this,
249
                        null,
250
                        false);
251
            }
252
        });
253
	}
254

    
255

    
256
	@Override
257
	public void dragOver(DropTargetEvent event) {
258
		super.dragOver(event);
259
		event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_INSERT_AFTER | DND.FEEDBACK_SCROLL;
260
	}
261

    
262
    /**
263
     * {@inheritDoc}
264
     */
265
    @Override
266
    public void postOperation(IRemotingProgressMonitor monitor) {
267
        EventUtility.postEvent(WorkbenchEventConstants.REFRESH_NAVIGATOR, true);
268
    }
269

    
270
}
(6-6/6)