4b5ecdc494ced5f264093fbb3feb8d229a2f8d9c
[taxeditor.git] / eu.etaxonomy.taxeditor.navigation / src / main / java / eu / etaxonomy / taxeditor / navigation / navigator / e4 / TreeNodeDropAdapterE4.java
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.EnumSet;
13 import java.util.HashSet;
14 import java.util.Iterator;
15 import java.util.Set;
16 import java.util.UUID;
17
18 import org.apache.log4j.Logger;
19 import org.eclipse.core.commands.operations.IUndoContext;
20 import org.eclipse.jface.dialogs.MessageDialog;
21 import org.eclipse.jface.util.LocalSelectionTransfer;
22 import org.eclipse.jface.viewers.ISelection;
23 import org.eclipse.jface.viewers.TreeSelection;
24 import org.eclipse.jface.viewers.ViewerDropAdapter;
25 import org.eclipse.swt.dnd.DND;
26 import org.eclipse.swt.dnd.DropTargetEvent;
27 import org.eclipse.swt.dnd.TransferData;
28
29 import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
30 import eu.etaxonomy.cdm.api.service.UpdateResult;
31 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
32 import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
33 import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
34 import eu.etaxonomy.taxeditor.navigation.l10n.Messages;
35 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
36 import eu.etaxonomy.taxeditor.store.CdmStore;
37
38 /**
39 * @author k.luther
40 * @date 02.06.2015
41 */
42 public class TreeNodeDropAdapterE4 extends ViewerDropAdapter {
43
44 protected static final String TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT_MESSAGE = Messages.TreeNodeDropAdapter_UNSAVED_PARENT_MESSAGE;
45 protected static final String TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT = Messages.TreeNodeDropAdapter_UNSAVED_PARENT;
46 protected static final String TREE_NODE_DROP_ADAPTER_MOVE_TAXON = Messages.TreeNodeDropAdapter_MOVE_TAXON;
47 protected static final String TREE_NODE_DROP_ADAPTER_CANCEL = Messages.TreeNodeDropAdapter_CANCEL;
48 protected static final String TREE_NODE_DROP_ADAPTER_BEHIND = Messages.TreeNodeDropAdapter_BEHIND;
49 protected static final String TREE_NODE_DROP_ADAPTER_CHILD = Messages.TreeNodeDropAdapter_CHILD;
50 protected static final String DO_YOU_WANT_TO_MOVE_THE_TAXONNODE_AS_CHILD_OR_BEHIND_THE_TARGET_NODE = Messages.TreeNodeDropAdapter_MOVE_BEHIND;
51 protected static final String TARGET_NODE = Messages.TreeNodeDropAdapter_TARGET_NODE;
52
53 private static final Logger logger = Logger.getLogger(TreeNodeDropAdapterE4.class);
54
55 private TaxonNavigatorE4 taxonNavigator;
56 UpdateResult result;
57
58 public static final String ID = "eu.etaxonomy.taxeditor.navigation.navigator.dropassistant"; //$NON-NLS-1$
59
60 private static final EnumSet<CRUD> UPDATE = EnumSet.of(CRUD.UPDATE);
61
62 public enum MovingType{
63 CHILD, PREVIOUS, BEHIND
64 }
65
66 protected TreeNodeDropAdapterE4(TaxonNavigatorE4 navigator) {
67 super(navigator.getViewer());
68 this.taxonNavigator = navigator;
69 }
70
71 /** {@inheritDoc} */
72 @Override
73 public boolean performDrop(Object data) {
74 Object target = getCurrentTarget();
75 if (getCurrentTarget() instanceof TaxonNodeDto) {
76 Set<TaxonNodeDto> taxonNodes = getSelectedTaxa();
77 TaxonNodeDto targetTreeNode = (TaxonNodeDto) target;
78 // if (targetTreeNode.getType() != null && targetTreeNode.getType().equals(Classification.class)){
79 // targetTreeNode = ((Classification)targetTreeNode).getRootNode();
80 // targetTreeNode = HibernateProxyHelper.deproxy(targetTreeNode, TaxonNode.class);
81 // }
82 if(taxonNodes != null) {
83 if (taxonNodes.size() == 1){
84 boolean success = moveTaxon(taxonNodes, targetTreeNode);
85 if (success){
86 taxonNavigator.refresh();
87 }
88 return success;
89 } else{
90 if( MessageDialog.openConfirm(null, Messages.TreeNodeDropAdapter_MOVING, Messages.TreeNodeDropAdapter_MOVING_MESSAGE)){
91 return true;
92 }
93 }
94 }
95 }
96 return false;
97 }
98
99 private Set<TaxonNodeDto> getSelectedTaxa(){
100 HashSet<TaxonNodeDto> taxonNodes = new HashSet();
101
102 ISelection selection = LocalSelectionTransfer.getTransfer().getSelection();
103 if (selection instanceof TreeSelection) {
104
105 Iterator<?> selectionIterator = ((TreeSelection) selection).iterator();
106
107 while (selectionIterator.hasNext()){
108 Object object = selectionIterator.next();
109 if(object instanceof TaxonNodeDto){
110 TaxonNodeDto taxonNode = (TaxonNodeDto) object;
111 taxonNodes.add(taxonNode);
112 }
113 }
114 }
115 return taxonNodes;
116 }
117
118 /** {@inheritDoc} */
119 @Override
120 public boolean validateDrop(Object target, int operation,
121 TransferData transferType) {
122
123 if (target instanceof TaxonNodeDto) {
124
125 // check users permissions with target taxonnode and taxon
126 if (target instanceof TaxonNodeDto) {
127 TaxonNodeDto targetNode = (TaxonNodeDto)target;
128 TaxonNode node = CdmStore.getService(ITaxonNodeService.class).load(targetNode.getUuid());
129 boolean hasTargetNodePermission = CdmStore.currentAuthentiationHasPermission(node, UPDATE);
130 boolean hasTargetTaxonPermission = node.getTaxon() == null ?
131 true :
132 CdmStore.currentAuthentiationHasPermission(node.getTaxon(), UPDATE);
133
134 if(!hasTargetNodePermission || ! hasTargetNodePermission){
135 if(logger.isDebugEnabled()){
136 logger.debug("CANCEL_STATUS for target node: " + hasTargetNodePermission + " " + hasTargetTaxonPermission + " "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
137 }
138 return false;
139 }
140 }
141
142 // do not allow to drop onto itself and
143 // check users permissions with all selected taxon nodes and taxa
144 for(TaxonNodeDto taxonNode : getSelectedTaxa()){
145 if (logger.isDebugEnabled()){
146 logger.debug("selectedTaxa: " + taxonNode.getTaxonUuid() == null? "-" : taxonNode.getTitleCache()); //$NON-NLS-1$
147 }
148 boolean isClassification = taxonNode.getTaxonUuid()== null;
149 if (isClassification) {
150 if(logger.isDebugEnabled()){
151 logger.debug("CANCEL_STATUS for selected classification " + taxonNode.getClassificationUUID()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
152 }
153 return false;
154 }
155 boolean isSameTaxonNode = taxonNode.equals(target);
156 TaxonNode node = CdmStore.getService(ITaxonNodeService.class).load(taxonNode.getUuid());
157 boolean hasTaxonNodePermission = CdmStore.currentAuthentiationHasPermission(node, UPDATE);
158
159 boolean hasTaxonPermission =
160 CdmStore.currentAuthentiationHasPermission(node.getTaxon(), UPDATE);CdmStore.currentAuthentiationHasPermission(node.getTaxon(), UPDATE);
161 if (
162 isSameTaxonNode
163 || !hasTaxonNodePermission
164 || !hasTaxonPermission
165 ) {
166 if(logger.isDebugEnabled()){
167 logger.debug("CANCEL_STATUS for selected " + isSameTaxonNode + Messages.TreeNodeDropAdapter_10 + hasTaxonNodePermission + " " + hasTaxonPermission + " "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
168 }
169 return false;
170 }
171 }
172 logger.debug("OK_STATUS"); //$NON-NLS-1$
173 return true;
174 }
175 logger.debug("CANCEL_STATUS"); //$NON-NLS-1$
176 return false;
177 }
178
179
180 private boolean moveTaxon(Set<TaxonNodeDto> taxonNodes, TaxonNodeDto targetITaxonTreeNode) {
181 Iterator<TaxonNodeDto> taxIterator = taxonNodes.iterator();
182 Set<UUID> uuids = new HashSet<UUID>();
183 TaxonNodeDto node = null;
184 while(taxIterator.hasNext()){
185 node = taxIterator.next();
186 uuids.add(node.getUuid());
187 }
188 IUndoContext workspaceUndoContext = taxonNavigator.getUndoContext();
189 if (!PreferencesUtil.getSortNodesNaturally()){
190 if (workspaceUndoContext == null) {
191 logger.error("Workspace undo context is null. DND operation cancelled"); //$NON-NLS-1$
192 return false;
193 }
194 result =CdmStore.getService(ITaxonNodeService.class).moveTaxonNodes(uuids,targetITaxonTreeNode.getUuid(), 0);
195
196 logger.info("Moved taxa to new parent " + targetITaxonTreeNode); //$NON-NLS-1$
197 return true;
198 }else{
199 String[] buttonLables = {TREE_NODE_DROP_ADAPTER_CHILD, TREE_NODE_DROP_ADAPTER_BEHIND,TREE_NODE_DROP_ADAPTER_CANCEL};
200 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);
201 dialog.open();
202 int returnCode = dialog.getReturnCode();
203
204 if (returnCode == 0){
205 if (workspaceUndoContext == null) {
206 logger.error("Workspace undo context is null. DND operation cancelled"); //$NON-NLS-1$
207 return false;
208 }
209
210 result = CdmStore.getService(ITaxonNodeService.class).moveTaxonNodes(uuids,targetITaxonTreeNode.getUuid(), 0);
211
212 logger.info("Moved taxa to new parent " + targetITaxonTreeNode); //$NON-NLS-1$
213 return true;
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
220
221 CdmStore.getService(ITaxonNodeService.class).moveTaxonNodes(uuids,targetITaxonTreeNode.getUuid(), 2);
222 logger.info("Moved taxa to new parent " + targetITaxonTreeNode); //$NON-NLS-1$
223 return true;
224 }
225 // } else if (returnCode == 2){
226 // IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext();
227 // if (workspaceUndoContext == null) {
228 // logger.error("Workspace undo context is null. DND operation cancelled");
229 // return false;
230 // }
231 // TaxonNode targetNode = (TaxonNode) targetITaxonTreeNode;
232 //
233 // AbstractPostOperation operation = new MoveTaxonOperation
234 // ("Move Taxon", workspaceUndoContext, uuids, targetNode, this, taxonNavigator, MovingType.BEHIND);
235 // NavigationUtil.executeOperation(operation);
236 //
237 // logger.info("Moved taxa to new parent " + targetITaxonTreeNode);
238 // return true;
239 // }
240 else{
241 return false;
242 }
243
244
245 }
246 }
247
248 @Override
249 public void dragOver(DropTargetEvent event) {
250 super.dragOver(event);
251 event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_INSERT_AFTER;
252 }
253
254 }